Blame view
fs/udf/super.c
67.4 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* * super.c * * PURPOSE * Super block routines for the OSTA-UDF(tm) filesystem. * * DESCRIPTION * OSTA-UDF(tm) = Optical Storage Technology Association * Universal Disk Format. * * This code is based on version 2.00 of the UDF specification, * and revision 3 of the ECMA 167 standard [equivalent to ISO 13346]. * http://www.osta.org/ |
248727a49 udf: Replace HTTP... |
14 15 |
* https://www.ecma.ch/ * https://www.iso.org/ |
1da177e4c Linux-2.6.12-rc2 |
16 |
* |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
* COPYRIGHT * This file is distributed under the terms of the GNU General Public * License (GPL). Copies of the GPL can be obtained from: * ftp://prep.ai.mit.edu/pub/gnu/GPL * Each contributing author retains all rights to their own work. * * (C) 1998 Dave Boynton * (C) 1998-2004 Ben Fennema * (C) 2000 Stelias Computing Inc * * HISTORY * * 09/24/98 dgb changed to allow compiling outside of kernel, and * added some debugging. * 10/01/98 dgb updated to allow (some) possibility of compiling w/2.0.34 * 10/16/98 attempting some multi-session support * 10/17/98 added freespace count for "df" * 11/11/98 gr added novrs option * 11/26/98 dgb added fileset,anchor mount options |
3a71fc5de udf: fix coding s... |
36 37 |
* 12/06/98 blf really hosed things royally. vat/sparing support. sequenced * vol descs. rewrote option handling based on isofs |
1da177e4c Linux-2.6.12-rc2 |
38 39 |
* 12/20/98 find the free space bitmap (if it exists) */ |
cb00ea352 UDF: coding style... |
40 |
#include "udfdecl.h" |
1da177e4c Linux-2.6.12-rc2 |
41 |
|
1da177e4c Linux-2.6.12-rc2 |
42 43 44 45 46 47 48 49 |
#include <linux/blkdev.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/parser.h> #include <linux/stat.h> #include <linux/cdrom.h> #include <linux/nls.h> |
1da177e4c Linux-2.6.12-rc2 |
50 51 |
#include <linux/vfs.h> #include <linux/vmalloc.h> |
dc5d39be6 udf: convert UDF_... |
52 |
#include <linux/errno.h> |
6da80894c mount options: fi... |
53 54 |
#include <linux/mount.h> #include <linux/seq_file.h> |
01b954a36 udf: convert udf_... |
55 |
#include <linux/bitmap.h> |
f845fced9 udf: use crc_itu_... |
56 |
#include <linux/crc-itu-t.h> |
1df2ae31c udf: Fortify load... |
57 |
#include <linux/log2.h> |
1da177e4c Linux-2.6.12-rc2 |
58 |
#include <asm/byteorder.h> |
1da177e4c Linux-2.6.12-rc2 |
59 60 61 62 |
#include "udf_sb.h" #include "udf_i.h" #include <linux/init.h> |
e973606cc udf: use linux/ua... |
63 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
64 |
|
4b8d42521 udf: Convert desc... |
65 66 67 68 |
enum { VDS_POS_PRIMARY_VOL_DESC, VDS_POS_UNALLOC_SPACE_DESC, VDS_POS_LOGICAL_VOL_DESC, |
4b8d42521 udf: Convert desc... |
69 |
VDS_POS_IMP_USE_VOL_DESC, |
4b8d42521 udf: Convert desc... |
70 71 |
VDS_POS_LENGTH }; |
1da177e4c Linux-2.6.12-rc2 |
72 |
|
444996027 udf: fix for path... |
73 74 |
#define VSD_FIRST_SECTOR_OFFSET 32768 #define VSD_MAX_SECTOR_OFFSET 0x800000 |
a47241cde udf: Prevent stac... |
75 76 77 78 79 80 81 82 |
/* * Maximum number of Terminating Descriptor / Logical Volume Integrity * Descriptor redirections. The chosen numbers are arbitrary - just that we * hopefully don't limit any real use of rewritten inode on write-once media * but avoid looping for too long on corrupted media. */ #define UDF_MAX_TD_NESTING 64 #define UDF_MAX_LVID_NESTING 1000 |
8de527787 vfs: check i_nlin... |
83 |
enum { UDF_MAX_LINKS = 0xffff }; |
1da177e4c Linux-2.6.12-rc2 |
84 85 86 |
/* These are the "meat" - everything else is stuffing */ static int udf_fill_super(struct super_block *, void *, int); static void udf_put_super(struct super_block *); |
146bca72c udf: Don't write ... |
87 |
static int udf_sync_fs(struct super_block *, int); |
1da177e4c Linux-2.6.12-rc2 |
88 |
static int udf_remount_fs(struct super_block *, int *, char *); |
5ca4e4be8 Remove struct typ... |
89 |
static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 |
static void udf_open_lvid(struct super_block *); static void udf_close_lvid(struct super_block *); static unsigned int udf_count_free(struct super_block *); |
726c33422 [PATCH] VFS: Perm... |
93 |
static int udf_statfs(struct dentry *, struct kstatfs *); |
34c80b1d9 vfs: switch ->sho... |
94 |
static int udf_show_options(struct seq_file *, struct dentry *); |
1da177e4c Linux-2.6.12-rc2 |
95 |
|
69d75671d udf: Fortify LVID... |
96 |
struct logicalVolIntegrityDescImpUse *udf_sb_lvidiu(struct super_block *sb) |
6c79e987d udf: remove some ... |
97 |
{ |
69d75671d udf: Fortify LVID... |
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
struct logicalVolIntegrityDesc *lvid; unsigned int partnum; unsigned int offset; if (!UDF_SB(sb)->s_lvid_bh) return NULL; lvid = (struct logicalVolIntegrityDesc *)UDF_SB(sb)->s_lvid_bh->b_data; partnum = le32_to_cpu(lvid->numOfPartitions); if ((sb->s_blocksize - sizeof(struct logicalVolIntegrityDescImpUse) - offsetof(struct logicalVolIntegrityDesc, impUse)) / (2 * sizeof(uint32_t)) < partnum) { udf_err(sb, "Logical volume integrity descriptor corrupted " "(numOfPartitions = %u)! ", partnum); return NULL; } /* The offset is to skip freeSpaceTable and sizeTable arrays */ offset = partnum * 2 * sizeof(uint32_t); |
6c79e987d udf: remove some ... |
116 117 |
return (struct logicalVolIntegrityDescImpUse *)&(lvid->impUse[offset]); } |
1da177e4c Linux-2.6.12-rc2 |
118 |
/* UDF filesystem type */ |
152a08366 new helper: mount... |
119 120 |
static struct dentry *udf_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c Linux-2.6.12-rc2 |
121 |
{ |
152a08366 new helper: mount... |
122 |
return mount_bdev(fs_type, flags, dev_name, data, udf_fill_super); |
1da177e4c Linux-2.6.12-rc2 |
123 124 125 |
} static struct file_system_type udf_fstype = { |
28de7948a UDF: coding style... |
126 127 |
.owner = THIS_MODULE, .name = "udf", |
152a08366 new helper: mount... |
128 |
.mount = udf_mount, |
28de7948a UDF: coding style... |
129 130 |
.kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, |
1da177e4c Linux-2.6.12-rc2 |
131 |
}; |
3e64fe5b2 fs: Limit sys_mou... |
132 |
MODULE_ALIAS_FS("udf"); |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
cb00ea352 UDF: coding style... |
134 |
static struct kmem_cache *udf_inode_cachep; |
1da177e4c Linux-2.6.12-rc2 |
135 136 137 138 |
static struct inode *udf_alloc_inode(struct super_block *sb) { struct udf_inode_info *ei; |
3a71fc5de udf: fix coding s... |
139 |
ei = kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
140 141 |
if (!ei) return NULL; |
95f8797f4 [PATCH] initializ... |
142 143 144 |
ei->i_unique = 0; ei->i_lenExtents = 0; |
ab9a3a737 udf: reduce leaka... |
145 |
ei->i_lenStreams = 0; |
95f8797f4 [PATCH] initializ... |
146 147 148 |
ei->i_next_alloc_block = 0; ei->i_next_alloc_goal = 0; ei->i_strat4096 = 0; |
ab9a3a737 udf: reduce leaka... |
149 |
ei->i_streamdir = 0; |
4d0fb621d udf: Replace bkl ... |
150 |
init_rwsem(&ei->i_data_sem); |
99600051b udf: add extent c... |
151 152 |
ei->cached_extent.lstart = -1; spin_lock_init(&ei->i_extent_cache_lock); |
95f8797f4 [PATCH] initializ... |
153 |
|
1da177e4c Linux-2.6.12-rc2 |
154 155 |
return &ei->vfs_inode; } |
a78bb3838 udf: switch to ->... |
156 |
static void udf_free_in_core_inode(struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
157 158 159 |
{ kmem_cache_free(udf_inode_cachep, UDF_I(inode)); } |
51cc50685 SL*B: drop kmem c... |
160 |
static void init_once(void *foo) |
1da177e4c Linux-2.6.12-rc2 |
161 |
{ |
cb00ea352 UDF: coding style... |
162 |
struct udf_inode_info *ei = (struct udf_inode_info *)foo; |
1da177e4c Linux-2.6.12-rc2 |
163 |
|
382a2287b udf: Remove point... |
164 |
ei->i_data = NULL; |
a35afb830 Remove SLAB_CTOR_... |
165 |
inode_init_once(&ei->vfs_inode); |
1da177e4c Linux-2.6.12-rc2 |
166 |
} |
53ea18de2 udf: Add __init m... |
167 |
static int __init init_inodecache(void) |
1da177e4c Linux-2.6.12-rc2 |
168 169 170 |
{ udf_inode_cachep = kmem_cache_create("udf_inode_cache", sizeof(struct udf_inode_info), |
cb00ea352 UDF: coding style... |
171 |
0, (SLAB_RECLAIM_ACCOUNT | |
5d097056c kmemcg: account c... |
172 173 |
SLAB_MEM_SPREAD | SLAB_ACCOUNT), |
20c2df83d mm: Remove slab d... |
174 |
init_once); |
28de7948a UDF: coding style... |
175 |
if (!udf_inode_cachep) |
1da177e4c Linux-2.6.12-rc2 |
176 177 178 179 180 181 |
return -ENOMEM; return 0; } static void destroy_inodecache(void) { |
8c0a85377 fs: push rcu_barr... |
182 183 184 185 186 |
/* * Make sure all delayed rcu free inodes are flushed before we * destroy cache. */ rcu_barrier(); |
1a1d92c10 [PATCH] Really ig... |
187 |
kmem_cache_destroy(udf_inode_cachep); |
1da177e4c Linux-2.6.12-rc2 |
188 189 190 |
} /* Superblock operations */ |
ee9b6d61a [PATCH] Mark stru... |
191 |
static const struct super_operations udf_sb_ops = { |
28de7948a UDF: coding style... |
192 |
.alloc_inode = udf_alloc_inode, |
a78bb3838 udf: switch to ->... |
193 |
.free_inode = udf_free_in_core_inode, |
28de7948a UDF: coding style... |
194 |
.write_inode = udf_write_inode, |
3aac2b62e switch udf to ->e... |
195 |
.evict_inode = udf_evict_inode, |
28de7948a UDF: coding style... |
196 |
.put_super = udf_put_super, |
146bca72c udf: Don't write ... |
197 |
.sync_fs = udf_sync_fs, |
28de7948a UDF: coding style... |
198 199 |
.statfs = udf_statfs, .remount_fs = udf_remount_fs, |
6da80894c mount options: fi... |
200 |
.show_options = udf_show_options, |
1da177e4c Linux-2.6.12-rc2 |
201 |
}; |
cb00ea352 UDF: coding style... |
202 |
struct udf_options { |
1da177e4c Linux-2.6.12-rc2 |
203 204 205 206 207 |
unsigned char novrs; unsigned int blocksize; unsigned int session; unsigned int lastblock; unsigned int anchor; |
1da177e4c Linux-2.6.12-rc2 |
208 |
unsigned int flags; |
faa17292f udf: propagate um... |
209 |
umode_t umask; |
c2ba138a2 userns: Convert t... |
210 211 |
kgid_t gid; kuid_t uid; |
faa17292f udf: propagate um... |
212 213 |
umode_t fmode; umode_t dmode; |
1da177e4c Linux-2.6.12-rc2 |
214 215 216 217 218 219 |
struct nls_table *nls_map; }; static int __init init_udf_fs(void) { int err; |
28de7948a UDF: coding style... |
220 |
|
1da177e4c Linux-2.6.12-rc2 |
221 222 223 224 225 226 |
err = init_inodecache(); if (err) goto out1; err = register_filesystem(&udf_fstype); if (err) goto out; |
28de7948a UDF: coding style... |
227 |
|
1da177e4c Linux-2.6.12-rc2 |
228 |
return 0; |
28de7948a UDF: coding style... |
229 230 |
out: |
1da177e4c Linux-2.6.12-rc2 |
231 |
destroy_inodecache(); |
28de7948a UDF: coding style... |
232 233 |
out1: |
1da177e4c Linux-2.6.12-rc2 |
234 235 236 237 238 239 240 241 |
return err; } static void __exit exit_udf_fs(void) { unregister_filesystem(&udf_fstype); destroy_inodecache(); } |
dc5d39be6 udf: convert UDF_... |
242 243 244 |
static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count) { struct udf_sb_info *sbi = UDF_SB(sb); |
033c9da00 fs-udf: Improve s... |
245 |
sbi->s_partmaps = kcalloc(count, sizeof(*sbi->s_partmaps), GFP_KERNEL); |
dc5d39be6 udf: convert UDF_... |
246 |
if (!sbi->s_partmaps) { |
dc5d39be6 udf: convert UDF_... |
247 248 249 250 251 252 253 |
sbi->s_partitions = 0; return -ENOMEM; } sbi->s_partitions = count; return 0; } |
bff943af6 udf: Fix memory l... |
254 255 256 257 |
static void udf_sb_free_bitmap(struct udf_bitmap *bitmap) { int i; int nr_groups = bitmap->s_nr_groups; |
bff943af6 udf: Fix memory l... |
258 259 |
for (i = 0; i < nr_groups; i++) |
4eb09e111 fs-udf: Delete an... |
260 |
brelse(bitmap->s_block_bitmap[i]); |
bff943af6 udf: Fix memory l... |
261 |
|
1d5cfdb07 tree wide: use kv... |
262 |
kvfree(bitmap); |
bff943af6 udf: Fix memory l... |
263 264 265 266 267 268 269 270 271 |
} static void udf_free_partition(struct udf_part_map *map) { int i; struct udf_meta_data *mdata; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) iput(map->s_uspace.s_table); |
bff943af6 udf: Fix memory l... |
272 273 |
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) udf_sb_free_bitmap(map->s_uspace.s_bitmap); |
bff943af6 udf: Fix memory l... |
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
if (map->s_partition_type == UDF_SPARABLE_MAP15) for (i = 0; i < 4; i++) brelse(map->s_type_specific.s_sparing.s_spar_map[i]); else if (map->s_partition_type == UDF_METADATA_MAP25) { mdata = &map->s_type_specific.s_metadata; iput(mdata->s_metadata_fe); mdata->s_metadata_fe = NULL; iput(mdata->s_mirror_fe); mdata->s_mirror_fe = NULL; iput(mdata->s_bitmap_fe); mdata->s_bitmap_fe = NULL; } } static void udf_sb_free_partitions(struct super_block *sb) { struct udf_sb_info *sbi = UDF_SB(sb); int i; |
ba2eb866a fs-udf: Adjust tw... |
294 295 |
if (!sbi->s_partmaps) |
1b1baff6e UDF: Fix a null p... |
296 |
return; |
bff943af6 udf: Fix memory l... |
297 298 299 300 301 |
for (i = 0; i < sbi->s_partitions; i++) udf_free_partition(&sbi->s_partmaps[i]); kfree(sbi->s_partmaps); sbi->s_partmaps = NULL; } |
34c80b1d9 vfs: switch ->sho... |
302 |
static int udf_show_options(struct seq_file *seq, struct dentry *root) |
6da80894c mount options: fi... |
303 |
{ |
34c80b1d9 vfs: switch ->sho... |
304 |
struct super_block *sb = root->d_sb; |
6da80894c mount options: fi... |
305 306 307 308 |
struct udf_sb_info *sbi = UDF_SB(sb); if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) seq_puts(seq, ",nostrict"); |
1197e4dfc udf: use hardware... |
309 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET)) |
6da80894c mount options: fi... |
310 311 312 313 314 315 316 317 318 319 320 |
seq_printf(seq, ",bs=%lu", sb->s_blocksize); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) seq_puts(seq, ",unhide"); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE)) seq_puts(seq, ",undelete"); if (!UDF_QUERY_FLAG(sb, UDF_FLAG_USE_AD_IN_ICB)) seq_puts(seq, ",noadinicb"); if (UDF_QUERY_FLAG(sb, UDF_FLAG_USE_SHORT_AD)) seq_puts(seq, ",shortad"); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_FORGET)) seq_puts(seq, ",uid=forget"); |
6da80894c mount options: fi... |
321 322 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_FORGET)) seq_puts(seq, ",gid=forget"); |
6da80894c mount options: fi... |
323 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET)) |
c2ba138a2 userns: Convert t... |
324 |
seq_printf(seq, ",uid=%u", from_kuid(&init_user_ns, sbi->s_uid)); |
6da80894c mount options: fi... |
325 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET)) |
c2ba138a2 userns: Convert t... |
326 |
seq_printf(seq, ",gid=%u", from_kgid(&init_user_ns, sbi->s_gid)); |
6da80894c mount options: fi... |
327 |
if (sbi->s_umask != 0) |
faa17292f udf: propagate um... |
328 |
seq_printf(seq, ",umask=%ho", sbi->s_umask); |
87bc730c0 udf: fix default ... |
329 |
if (sbi->s_fmode != UDF_INVALID_MODE) |
faa17292f udf: propagate um... |
330 |
seq_printf(seq, ",mode=%ho", sbi->s_fmode); |
87bc730c0 udf: fix default ... |
331 |
if (sbi->s_dmode != UDF_INVALID_MODE) |
faa17292f udf: propagate um... |
332 |
seq_printf(seq, ",dmode=%ho", sbi->s_dmode); |
6da80894c mount options: fi... |
333 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_SESSION_SET)) |
fcbf7637e udf: Fix signed/u... |
334 |
seq_printf(seq, ",session=%d", sbi->s_session); |
6da80894c mount options: fi... |
335 336 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_LASTBLOCK_SET)) seq_printf(seq, ",lastblock=%u", sbi->s_last_block); |
403460051 udf: Try anchor i... |
337 338 |
if (sbi->s_anchor != 0) seq_printf(seq, ",anchor=%u", sbi->s_anchor); |
6da80894c mount options: fi... |
339 340 341 342 343 344 345 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) seq_puts(seq, ",utf8"); if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP) && sbi->s_nls_map) seq_printf(seq, ",iocharset=%s", sbi->s_nls_map->charset); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
346 347 348 349 350 351 352 353 354 355 356 |
/* * udf_parse_options * * PURPOSE * Parse mount options. * * DESCRIPTION * The following mount options are supported: * * gid= Set the default group. * umask= Set the default umask. |
7ac9bcd5d udf: implement mo... |
357 358 |
* mode= Set the default file permissions. * dmode= Set the default directory permissions. |
1da177e4c Linux-2.6.12-rc2 |
359 360 361 362 363 364 365 366 367 368 369 370 371 |
* uid= Set the default user. * bs= Set the block size. * unhide Show otherwise hidden files. * undelete Show deleted files in lists. * adinicb Embed data in the inode (default) * noadinicb Don't embed data in the inode * shortad Use short ad's * longad Use long ad's (default) * nostrict Unset strict conformance * iocharset= Set the NLS character set * * The remaining are for debugging and disaster recovery: * |
28de7948a UDF: coding style... |
372 |
* novrs Skip volume sequence recognition |
1da177e4c Linux-2.6.12-rc2 |
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
* * The following expect a offset from 0. * * session= Set the CDROM session (default= last session) * anchor= Override standard anchor location. (default= 256) * volume= Override the VolumeDesc location. (unused) * partition= Override the PartitionDesc location. (unused) * lastblock= Set the last block of the filesystem/ * * The following expect a offset from the partition root. * * fileset= Override the fileset block location. (unused) * rootdir= Override the root directory location. (unused) * WARNING: overriding the rootdir to a non-directory may * yield highly unpredictable results. * * PRE-CONDITIONS * options Pointer to mount options string. * uopts Pointer to mount options variable. * * POST-CONDITIONS * <return> 1 Mount options parsed okay. * <return> 0 Error parsing mount options. * * HISTORY * July 1, 1997 - Andrew E. Mileski * Written, tested, and released. */ |
28de7948a UDF: coding style... |
401 |
|
1da177e4c Linux-2.6.12-rc2 |
402 403 404 405 406 407 |
enum { Opt_novrs, Opt_nostrict, Opt_bs, Opt_unhide, Opt_undelete, Opt_noadinicb, Opt_adinicb, Opt_shortad, Opt_longad, Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, Opt_rootdir, Opt_utf8, Opt_iocharset, |
7ac9bcd5d udf: implement mo... |
408 409 |
Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore, Opt_fmode, Opt_dmode |
1da177e4c Linux-2.6.12-rc2 |
410 |
}; |
a447c0932 vfs: Use const fo... |
411 |
static const match_table_t tokens = { |
28de7948a UDF: coding style... |
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
{Opt_novrs, "novrs"}, {Opt_nostrict, "nostrict"}, {Opt_bs, "bs=%u"}, {Opt_unhide, "unhide"}, {Opt_undelete, "undelete"}, {Opt_noadinicb, "noadinicb"}, {Opt_adinicb, "adinicb"}, {Opt_shortad, "shortad"}, {Opt_longad, "longad"}, {Opt_uforget, "uid=forget"}, {Opt_uignore, "uid=ignore"}, {Opt_gforget, "gid=forget"}, {Opt_gignore, "gid=ignore"}, {Opt_gid, "gid=%u"}, {Opt_uid, "uid=%u"}, {Opt_umask, "umask=%o"}, {Opt_session, "session=%u"}, {Opt_lastblock, "lastblock=%u"}, {Opt_anchor, "anchor=%u"}, {Opt_volume, "volume=%u"}, {Opt_partition, "partition=%u"}, {Opt_fileset, "fileset=%u"}, {Opt_rootdir, "rootdir=%u"}, {Opt_utf8, "utf8"}, {Opt_iocharset, "iocharset=%s"}, |
7ac9bcd5d udf: implement mo... |
437 438 |
{Opt_fmode, "mode=%o"}, {Opt_dmode, "dmode=%o"}, |
28de7948a UDF: coding style... |
439 |
{Opt_err, NULL} |
1da177e4c Linux-2.6.12-rc2 |
440 |
}; |
6da80894c mount options: fi... |
441 442 |
static int udf_parse_options(char *options, struct udf_options *uopt, bool remount) |
1da177e4c Linux-2.6.12-rc2 |
443 444 445 446 447 |
{ char *p; int option; uopt->novrs = 0; |
1da177e4c Linux-2.6.12-rc2 |
448 449 450 |
uopt->session = 0xFFFFFFFF; uopt->lastblock = 0; uopt->anchor = 0; |
1da177e4c Linux-2.6.12-rc2 |
451 452 453 |
if (!options) return 1; |
cb00ea352 UDF: coding style... |
454 |
while ((p = strsep(&options, ",")) != NULL) { |
1da177e4c Linux-2.6.12-rc2 |
455 456 |
substring_t args[MAX_OPT_ARGS]; int token; |
8c6915aef fs: udf: parse_op... |
457 |
unsigned n; |
1da177e4c Linux-2.6.12-rc2 |
458 459 460 461 |
if (!*p) continue; token = match_token(p, tokens, args); |
cb00ea352 UDF: coding style... |
462 463 464 |
switch (token) { case Opt_novrs: uopt->novrs = 1; |
4136801ae udf: fix novrs mo... |
465 |
break; |
cb00ea352 UDF: coding style... |
466 467 468 |
case Opt_bs: if (match_int(&args[0], &option)) return 0; |
8c6915aef fs: udf: parse_op... |
469 470 471 472 |
n = option; if (n != 512 && n != 1024 && n != 2048 && n != 4096) return 0; uopt->blocksize = n; |
1197e4dfc udf: use hardware... |
473 |
uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET); |
cb00ea352 UDF: coding style... |
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
break; case Opt_unhide: uopt->flags |= (1 << UDF_FLAG_UNHIDE); break; case Opt_undelete: uopt->flags |= (1 << UDF_FLAG_UNDELETE); break; case Opt_noadinicb: uopt->flags &= ~(1 << UDF_FLAG_USE_AD_IN_ICB); break; case Opt_adinicb: uopt->flags |= (1 << UDF_FLAG_USE_AD_IN_ICB); break; case Opt_shortad: uopt->flags |= (1 << UDF_FLAG_USE_SHORT_AD); break; case Opt_longad: uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD); break; case Opt_gid: if (match_int(args, &option)) return 0; |
c2ba138a2 userns: Convert t... |
496 497 498 |
uopt->gid = make_kgid(current_user_ns(), option); if (!gid_valid(uopt->gid)) return 0; |
ca76d2d80 UDF: fix UID and ... |
499 |
uopt->flags |= (1 << UDF_FLAG_GID_SET); |
cb00ea352 UDF: coding style... |
500 501 502 503 |
break; case Opt_uid: if (match_int(args, &option)) return 0; |
c2ba138a2 userns: Convert t... |
504 505 506 |
uopt->uid = make_kuid(current_user_ns(), option); if (!uid_valid(uopt->uid)) return 0; |
ca76d2d80 UDF: fix UID and ... |
507 |
uopt->flags |= (1 << UDF_FLAG_UID_SET); |
cb00ea352 UDF: coding style... |
508 509 510 511 512 513 514 515 516 517 518 519 520 |
break; case Opt_umask: if (match_octal(args, &option)) return 0; uopt->umask = option; break; case Opt_nostrict: uopt->flags &= ~(1 << UDF_FLAG_STRICT); break; case Opt_session: if (match_int(args, &option)) return 0; uopt->session = option; |
6da80894c mount options: fi... |
521 522 |
if (!remount) uopt->flags |= (1 << UDF_FLAG_SESSION_SET); |
cb00ea352 UDF: coding style... |
523 524 525 526 527 |
break; case Opt_lastblock: if (match_int(args, &option)) return 0; uopt->lastblock = option; |
6da80894c mount options: fi... |
528 529 |
if (!remount) uopt->flags |= (1 << UDF_FLAG_LASTBLOCK_SET); |
cb00ea352 UDF: coding style... |
530 531 532 533 534 535 536 |
break; case Opt_anchor: if (match_int(args, &option)) return 0; uopt->anchor = option; break; case Opt_volume: |
cb00ea352 UDF: coding style... |
537 |
case Opt_partition: |
cb00ea352 UDF: coding style... |
538 |
case Opt_fileset: |
cb00ea352 UDF: coding style... |
539 |
case Opt_rootdir: |
f0c4a8171 udf: Remove never... |
540 |
/* Ignored (never implemented properly) */ |
cb00ea352 UDF: coding style... |
541 542 543 544 |
break; case Opt_utf8: uopt->flags |= (1 << UDF_FLAG_UTF8); break; |
cb00ea352 UDF: coding style... |
545 |
case Opt_iocharset: |
785dffe1d udf: fix potentia... |
546 547 548 |
if (!remount) { if (uopt->nls_map) unload_nls(uopt->nls_map); |
a768a9abc udf: Explain hand... |
549 550 551 552 553 |
/* * load_nls() failure is handled later in * udf_fill_super() after all options are * parsed. */ |
785dffe1d udf: fix potentia... |
554 555 556 |
uopt->nls_map = load_nls(args[0].from); uopt->flags |= (1 << UDF_FLAG_NLS_MAP); } |
cb00ea352 UDF: coding style... |
557 |
break; |
cb00ea352 UDF: coding style... |
558 559 560 |
case Opt_uforget: uopt->flags |= (1 << UDF_FLAG_UID_FORGET); break; |
70260e447 udf: Ignore [ug]i... |
561 |
case Opt_uignore: |
cb00ea352 UDF: coding style... |
562 |
case Opt_gignore: |
70260e447 udf: Ignore [ug]i... |
563 |
/* These options are superseeded by uid=<number> */ |
cb00ea352 UDF: coding style... |
564 565 566 567 |
break; case Opt_gforget: uopt->flags |= (1 << UDF_FLAG_GID_FORGET); break; |
7ac9bcd5d udf: implement mo... |
568 569 570 571 572 573 574 575 576 577 |
case Opt_fmode: if (match_octal(args, &option)) return 0; uopt->fmode = option & 0777; break; case Opt_dmode: if (match_octal(args, &option)) return 0; uopt->dmode = option & 0777; break; |
cb00ea352 UDF: coding style... |
578 |
default: |
78ace70c4 udf: Convert prin... |
579 580 |
pr_err("bad mount option \"%s\" or missing value ", p); |
1da177e4c Linux-2.6.12-rc2 |
581 582 583 584 585 |
return 0; } } return 1; } |
cb00ea352 UDF: coding style... |
586 |
static int udf_remount_fs(struct super_block *sb, int *flags, char *options) |
1da177e4c Linux-2.6.12-rc2 |
587 588 |
{ struct udf_options uopt; |
6c79e987d udf: remove some ... |
589 |
struct udf_sb_info *sbi = UDF_SB(sb); |
c79d967de quota: move remou... |
590 |
int error = 0; |
a9ad01bc7 udf: Prevent writ... |
591 592 593 |
if (!(*flags & SB_RDONLY) && UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT)) return -EACCES; |
1da177e4c Linux-2.6.12-rc2 |
594 |
|
02b9984d6 fs: push sync_fil... |
595 |
sync_filesystem(sb); |
e729eac6f udf: Refuse RW mo... |
596 |
|
6c79e987d udf: remove some ... |
597 598 599 600 |
uopt.flags = sbi->s_flags; uopt.uid = sbi->s_uid; uopt.gid = sbi->s_gid; uopt.umask = sbi->s_umask; |
7ac9bcd5d udf: implement mo... |
601 602 |
uopt.fmode = sbi->s_fmode; uopt.dmode = sbi->s_dmode; |
785dffe1d udf: fix potentia... |
603 |
uopt.nls_map = NULL; |
1da177e4c Linux-2.6.12-rc2 |
604 |
|
6da80894c mount options: fi... |
605 |
if (!udf_parse_options(options, &uopt, true)) |
1da177e4c Linux-2.6.12-rc2 |
606 |
return -EINVAL; |
c03cad241 udf: Protect defa... |
607 |
write_lock(&sbi->s_cred_lock); |
6c79e987d udf: remove some ... |
608 609 610 611 |
sbi->s_flags = uopt.flags; sbi->s_uid = uopt.uid; sbi->s_gid = uopt.gid; sbi->s_umask = uopt.umask; |
7ac9bcd5d udf: implement mo... |
612 613 |
sbi->s_fmode = uopt.fmode; sbi->s_dmode = uopt.dmode; |
c03cad241 udf: Protect defa... |
614 |
write_unlock(&sbi->s_cred_lock); |
1da177e4c Linux-2.6.12-rc2 |
615 |
|
1751e8a6c Rename superblock... |
616 |
if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb)) |
c79d967de quota: move remou... |
617 |
goto out_unlock; |
1751e8a6c Rename superblock... |
618 |
if (*flags & SB_RDONLY) |
1da177e4c Linux-2.6.12-rc2 |
619 |
udf_close_lvid(sb); |
363504628 udf: Remove dead ... |
620 |
else |
1da177e4c Linux-2.6.12-rc2 |
621 |
udf_open_lvid(sb); |
c79d967de quota: move remou... |
622 |
out_unlock: |
c79d967de quota: move remou... |
623 |
return error; |
1da177e4c Linux-2.6.12-rc2 |
624 |
} |
ba54aef03 udf: refactor VRS... |
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
/* * Check VSD descriptor. Returns -1 in case we are at the end of volume * recognition area, 0 if the descriptor is valid but non-interesting, 1 if * we found one of NSR descriptors we are looking for. */ static int identify_vsd(const struct volStructDesc *vsd) { int ret = 0; if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) { switch (vsd->structType) { case 0: udf_debug("ISO9660 Boot Record found "); break; case 1: udf_debug("ISO9660 Primary Volume Descriptor found "); break; case 2: udf_debug("ISO9660 Supplementary Volume Descriptor found "); break; case 3: udf_debug("ISO9660 Volume Partition Descriptor found "); break; case 255: udf_debug("ISO9660 Volume Descriptor Set Terminator found "); break; default: udf_debug("ISO9660 VRS (%u) found ", vsd->structType); break; } } else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN)) ; /* ret = 0 */ else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN)) ret = 1; else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN)) ret = 1; else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN)) ; /* ret = 0 */ else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN)) ; /* ret = 0 */ else { /* TEA01 or invalid id : end of volume recognition area */ ret = -1; } return ret; } /* * Check Volume Structure Descriptors (ECMA 167 2/9.1) * We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) * @return 1 if NSR02 or NSR03 found, * -1 if first sector read error, 0 otherwise */ static int udf_check_vsd(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
686 687 |
{ struct volStructDesc *vsd = NULL; |
444996027 udf: fix for path... |
688 |
loff_t sector = VSD_FIRST_SECTOR_OFFSET; |
1da177e4c Linux-2.6.12-rc2 |
689 690 |
int sectorsize; struct buffer_head *bh = NULL; |
ba54aef03 udf: refactor VRS... |
691 |
int nsr = 0; |
6c79e987d udf: remove some ... |
692 |
struct udf_sb_info *sbi; |
1da177e4c Linux-2.6.12-rc2 |
693 |
|
6c79e987d udf: remove some ... |
694 |
sbi = UDF_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
695 696 697 698 |
if (sb->s_blocksize < sizeof(struct volStructDesc)) sectorsize = sizeof(struct volStructDesc); else sectorsize = sb->s_blocksize; |
abdc0eb06 udf: Avoid overfl... |
699 |
sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits); |
1da177e4c Linux-2.6.12-rc2 |
700 |
|
fcbf7637e udf: Fix signed/u... |
701 702 |
udf_debug("Starting at sector %u (%lu byte sectors) ", |
706047a79 udf: Fix compilat... |
703 704 |
(unsigned int)(sector >> sb->s_blocksize_bits), sb->s_blocksize); |
444996027 udf: fix for path... |
705 706 707 708 709 710 711 712 713 714 |
/* Process the sequence (if applicable). The hard limit on the sector * offset is arbitrary, hopefully large enough so that all valid UDF * filesystems will be recognised. There is no mention of an upper * bound to the size of the volume recognition area in the standard. * The limit will prevent the code to read all the sectors of a * specially crafted image (like a bluray disc full of CD001 sectors), * potentially causing minutes or even hours of uninterruptible I/O * activity. This actually happened with uninitialised SSD partitions * (all 0xFF) before the check for the limit and all valid IDs were * added */ |
ba54aef03 udf: refactor VRS... |
715 |
for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) { |
1da177e4c Linux-2.6.12-rc2 |
716 717 718 719 |
/* Read a block */ bh = udf_tread(sb, sector >> sb->s_blocksize_bits); if (!bh) break; |
1da177e4c Linux-2.6.12-rc2 |
720 |
vsd = (struct volStructDesc *)(bh->b_data + |
3a71fc5de udf: fix coding s... |
721 |
(sector & (sb->s_blocksize - 1))); |
ba54aef03 udf: refactor VRS... |
722 |
nsr = identify_vsd(vsd); |
6fbacb853 udf: support 2048... |
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 |
/* Found NSR or end? */ if (nsr) { brelse(bh); break; } /* * Special handling for improperly formatted VRS (e.g., Win10) * where components are separated by 2048 bytes even though * sectors are 4K */ if (sb->s_blocksize == 4096) { nsr = identify_vsd(vsd + 1); /* Ignore unknown IDs... */ if (nsr < 0) nsr = 0; } |
3bf25cb40 udf: use get_bh() |
739 |
brelse(bh); |
1da177e4c Linux-2.6.12-rc2 |
740 |
} |
ba54aef03 udf: refactor VRS... |
741 742 |
if (nsr > 0) return 1; |
444996027 udf: fix for path... |
743 744 |
else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == VSD_FIRST_SECTOR_OFFSET) |
1da177e4c Linux-2.6.12-rc2 |
745 746 747 748 |
return -1; else return 0; } |
8b47ea6c2 udf: Drop forward... |
749 750 751 |
static int udf_verify_domain_identifier(struct super_block *sb, struct regid *ident, char *dname) { |
871b9b14c udf: Move OSTA Id... |
752 |
struct domainIdentSuffix *suffix; |
8b47ea6c2 udf: Drop forward... |
753 754 755 756 757 758 |
if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) { udf_warn(sb, "Not OSTA UDF compliant %s descriptor. ", dname); goto force_ro; } |
49be68c49 udf: Fix meaning ... |
759 |
if (ident->flags & ENTITYID_FLAGS_DIRTY) { |
8b47ea6c2 udf: Drop forward... |
760 761 762 763 764 |
udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor. ", dname); goto force_ro; } |
871b9b14c udf: Move OSTA Id... |
765 766 767 |
suffix = (struct domainIdentSuffix *)ident->identSuffix; if ((suffix->domainFlags & DOMAIN_FLAGS_HARD_WRITE_PROTECT) || (suffix->domainFlags & DOMAIN_FLAGS_SOFT_WRITE_PROTECT)) { |
8b47ea6c2 udf: Drop forward... |
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 |
if (!sb_rdonly(sb)) { udf_warn(sb, "Descriptor for %s marked write protected." " Forcing read only mount. ", dname); } goto force_ro; } return 0; force_ro: if (!sb_rdonly(sb)) return -EACCES; UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); return 0; } static int udf_load_fileset(struct super_block *sb, struct fileSetDesc *fset, struct kernel_lb_addr *root) { int ret; ret = udf_verify_domain_identifier(sb, &fset->domainIdent, "file set"); if (ret < 0) return ret; *root = lelb_to_cpu(fset->rootDirectoryICB.extLocation); UDF_SB(sb)->s_serial_number = le16_to_cpu(fset->descTag.tagSerialNum); udf_debug("Rootdir at block=%u, partition=%u ", root->logicalBlockNum, root->partitionReferenceNum); return 0; } |
3a71fc5de udf: fix coding s... |
801 |
static int udf_find_fileset(struct super_block *sb, |
5ca4e4be8 Remove struct typ... |
802 803 |
struct kernel_lb_addr *fileset, struct kernel_lb_addr *root) |
1da177e4c Linux-2.6.12-rc2 |
804 805 |
{ struct buffer_head *bh = NULL; |
1da177e4c Linux-2.6.12-rc2 |
806 |
uint16_t ident; |
2dee5aac0 udf: Verify domai... |
807 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
808 |
|
2dee5aac0 udf: Verify domai... |
809 810 811 |
if (fileset->logicalBlockNum == 0xFFFFFFFF && fileset->partitionReferenceNum == 0xFFFF) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
812 |
|
2dee5aac0 udf: Verify domai... |
813 814 815 816 |
bh = udf_read_ptagged(sb, fileset, 0, &ident); if (!bh) return -EIO; if (ident != TAG_IDENT_FSD) { |
3bf25cb40 udf: use get_bh() |
817 |
brelse(bh); |
2dee5aac0 udf: Verify domai... |
818 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
819 |
} |
2dee5aac0 udf: Verify domai... |
820 821 822 823 824 825 826 827 828 |
udf_debug("Fileset at block=%u, partition=%u ", fileset->logicalBlockNum, fileset->partitionReferenceNum); UDF_SB(sb)->s_partition = fileset->partitionReferenceNum; ret = udf_load_fileset(sb, (struct fileSetDesc *)bh->b_data, root); brelse(bh); return ret; |
1da177e4c Linux-2.6.12-rc2 |
829 |
} |
d759bfa4e udf: Standardize ... |
830 831 832 833 834 835 |
/* * Load primary Volume Descriptor Sequence * * Return <0 on error, 0 on success. -EAGAIN is special meaning next sequence * should be tried. */ |
c0eb31ed1 udf: Cleanup volu... |
836 |
static int udf_load_pvoldesc(struct super_block *sb, sector_t block) |
1da177e4c Linux-2.6.12-rc2 |
837 838 |
{ struct primaryVolDesc *pvoldesc; |
9293fcfbc udf: Remove struc... |
839 |
uint8_t *outstr; |
c0eb31ed1 udf: Cleanup volu... |
840 841 |
struct buffer_head *bh; uint16_t ident; |
aa9f6661e udf: Remove redun... |
842 |
int ret; |
0220eddac udf: Simplify cal... |
843 |
struct timestamp *ts; |
ba9aadd80 udf: reduce stack... |
844 |
|
9293fcfbc udf: Remove struc... |
845 |
outstr = kmalloc(128, GFP_NOFS); |
ba9aadd80 udf: reduce stack... |
846 |
if (!outstr) |
9293fcfbc udf: Remove struc... |
847 |
return -ENOMEM; |
c0eb31ed1 udf: Cleanup volu... |
848 849 |
bh = udf_read_tagged(sb, block, block, &ident); |
d759bfa4e udf: Standardize ... |
850 851 |
if (!bh) { ret = -EAGAIN; |
ba9aadd80 udf: reduce stack... |
852 |
goto out2; |
d759bfa4e udf: Standardize ... |
853 |
} |
ba9aadd80 udf: reduce stack... |
854 |
|
d759bfa4e udf: Standardize ... |
855 856 857 858 |
if (ident != TAG_IDENT_PVD) { ret = -EIO; goto out_bh; } |
1da177e4c Linux-2.6.12-rc2 |
859 860 |
pvoldesc = (struct primaryVolDesc *)bh->b_data; |
0220eddac udf: Simplify cal... |
861 862 |
udf_disk_stamp_to_time(&UDF_SB(sb)->s_record_time, pvoldesc->recordingDateAndTime); |
0220eddac udf: Simplify cal... |
863 864 865 866 867 |
ts = &pvoldesc->recordingDateAndTime; udf_debug("recording time %04u/%02u/%02u %02u:%02u (%x) ", le16_to_cpu(ts->year), ts->month, ts->day, ts->hour, ts->minute, le16_to_cpu(ts->typeAndTimezone)); |
1da177e4c Linux-2.6.12-rc2 |
868 |
|
e966fc8d9 udf: Convert iden... |
869 |
ret = udf_dstrCS0toChar(sb, outstr, 31, pvoldesc->volIdent, 32); |
b54e41f5e udf: Allow mounti... |
870 871 872 873 874 875 876 877 |
if (ret < 0) { strcpy(UDF_SB(sb)->s_volume_ident, "InvalidName"); pr_warn("incorrect volume identification, setting to " "'InvalidName' "); } else { strncpy(UDF_SB(sb)->s_volume_ident, outstr, ret); } |
9293fcfbc udf: Remove struc... |
878 879 |
udf_debug("volIdent[] = '%s' ", UDF_SB(sb)->s_volume_ident); |
1da177e4c Linux-2.6.12-rc2 |
880 |
|
e966fc8d9 udf: Convert iden... |
881 |
ret = udf_dstrCS0toChar(sb, outstr, 127, pvoldesc->volSetIdent, 128); |
b54e41f5e udf: Allow mounti... |
882 883 |
if (ret < 0) { ret = 0; |
9293fcfbc udf: Remove struc... |
884 |
goto out_bh; |
b54e41f5e udf: Allow mounti... |
885 |
} |
9293fcfbc udf: Remove struc... |
886 887 888 |
outstr[ret] = 0; udf_debug("volSetIdent[] = '%s' ", outstr); |
c0eb31ed1 udf: Cleanup volu... |
889 |
|
ba9aadd80 udf: reduce stack... |
890 |
ret = 0; |
d759bfa4e udf: Standardize ... |
891 892 |
out_bh: brelse(bh); |
ba9aadd80 udf: reduce stack... |
893 894 |
out2: kfree(outstr); |
ba9aadd80 udf: reduce stack... |
895 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
896 |
} |
3080a74ea udf: Skip mirror ... |
897 |
struct inode *udf_find_metadata_inode_efe(struct super_block *sb, |
7888824b0 udf: Use correct ... |
898 |
u32 meta_file_loc, u32 partition_ref) |
3080a74ea udf: Skip mirror ... |
899 900 901 902 903 |
{ struct kernel_lb_addr addr; struct inode *metadata_fe; addr.logicalBlockNum = meta_file_loc; |
7888824b0 udf: Use correct ... |
904 |
addr.partitionReferenceNum = partition_ref; |
3080a74ea udf: Skip mirror ... |
905 |
|
6174c2eb8 udf: Fix loading ... |
906 |
metadata_fe = udf_iget_special(sb, &addr); |
3080a74ea udf: Skip mirror ... |
907 |
|
6d3d5e860 udf: Make udf_rea... |
908 |
if (IS_ERR(metadata_fe)) { |
3080a74ea udf: Skip mirror ... |
909 910 |
udf_warn(sb, "metadata inode efe not found "); |
6d3d5e860 udf: Make udf_rea... |
911 912 913 |
return metadata_fe; } if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) { |
3080a74ea udf: Skip mirror ... |
914 915 916 |
udf_warn(sb, "metadata inode efe does not have short allocation descriptors! "); iput(metadata_fe); |
6d3d5e860 udf: Make udf_rea... |
917 |
return ERR_PTR(-EIO); |
3080a74ea udf: Skip mirror ... |
918 919 920 921 |
} return metadata_fe; } |
7888824b0 udf: Use correct ... |
922 923 |
static int udf_load_metadata_files(struct super_block *sb, int partition, int type1_index) |
bfb257a59 udf: Add read-onl... |
924 925 926 927 |
{ struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map; struct udf_meta_data *mdata; |
5ca4e4be8 Remove struct typ... |
928 |
struct kernel_lb_addr addr; |
6d3d5e860 udf: Make udf_rea... |
929 |
struct inode *fe; |
bfb257a59 udf: Add read-onl... |
930 931 932 |
map = &sbi->s_partmaps[partition]; mdata = &map->s_type_specific.s_metadata; |
7888824b0 udf: Use correct ... |
933 |
mdata->s_phys_partition_ref = type1_index; |
bfb257a59 udf: Add read-onl... |
934 935 |
/* metadata address */ |
fcbf7637e udf: Fix signed/u... |
936 937 |
udf_debug("Metadata file location: block = %u part = %u ", |
7888824b0 udf: Use correct ... |
938 |
mdata->s_meta_file_loc, mdata->s_phys_partition_ref); |
bfb257a59 udf: Add read-onl... |
939 |
|
6d3d5e860 udf: Make udf_rea... |
940 |
fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc, |
7888824b0 udf: Use correct ... |
941 |
mdata->s_phys_partition_ref); |
6d3d5e860 udf: Make udf_rea... |
942 |
if (IS_ERR(fe)) { |
3080a74ea udf: Skip mirror ... |
943 |
/* mirror file entry */ |
fcbf7637e udf: Fix signed/u... |
944 945 |
udf_debug("Mirror metadata file location: block = %u part = %u ", |
7888824b0 udf: Use correct ... |
946 |
mdata->s_mirror_file_loc, mdata->s_phys_partition_ref); |
bfb257a59 udf: Add read-onl... |
947 |
|
6d3d5e860 udf: Make udf_rea... |
948 |
fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc, |
7888824b0 udf: Use correct ... |
949 |
mdata->s_phys_partition_ref); |
bfb257a59 udf: Add read-onl... |
950 |
|
6d3d5e860 udf: Make udf_rea... |
951 |
if (IS_ERR(fe)) { |
3080a74ea udf: Skip mirror ... |
952 953 |
udf_err(sb, "Both metadata and mirror metadata inode efe can not found "); |
6d3d5e860 udf: Make udf_rea... |
954 |
return PTR_ERR(fe); |
3080a74ea udf: Skip mirror ... |
955 |
} |
6d3d5e860 udf: Make udf_rea... |
956 957 958 |
mdata->s_mirror_fe = fe; } else mdata->s_metadata_fe = fe; |
bfb257a59 udf: Add read-onl... |
959 960 961 962 963 964 965 966 |
/* * bitmap file entry * Note: * Load only if bitmap file location differs from 0xFFFFFFFF (DCN-5102) */ if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) { addr.logicalBlockNum = mdata->s_bitmap_file_loc; |
7888824b0 udf: Use correct ... |
967 |
addr.partitionReferenceNum = mdata->s_phys_partition_ref; |
bfb257a59 udf: Add read-onl... |
968 |
|
fcbf7637e udf: Fix signed/u... |
969 970 |
udf_debug("Bitmap file location: block = %u part = %u ", |
a983f368f udf: Neaten udf_d... |
971 |
addr.logicalBlockNum, addr.partitionReferenceNum); |
bfb257a59 udf: Add read-onl... |
972 |
|
6174c2eb8 udf: Fix loading ... |
973 |
fe = udf_iget_special(sb, &addr); |
6d3d5e860 udf: Make udf_rea... |
974 |
if (IS_ERR(fe)) { |
bc98a42c1 VFS: Convert sb->... |
975 |
if (sb_rdonly(sb)) |
a40ecd7b3 udf: Rename udf_w... |
976 977 |
udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only "); |
bfb257a59 udf: Add read-onl... |
978 |
else { |
8076c363d udf: Rename udf_e... |
979 980 |
udf_err(sb, "bitmap inode efe not found and attempted read-write mount "); |
6d3d5e860 udf: Make udf_rea... |
981 |
return PTR_ERR(fe); |
bfb257a59 udf: Add read-onl... |
982 |
} |
6d3d5e860 udf: Make udf_rea... |
983 984 |
} else mdata->s_bitmap_fe = fe; |
bfb257a59 udf: Add read-onl... |
985 986 987 988 |
} udf_debug("udf_load_metadata_files Ok "); |
bfb257a59 udf: Add read-onl... |
989 |
return 0; |
bfb257a59 udf: Add read-onl... |
990 |
} |
883cb9d18 udf: move calcula... |
991 992 993 |
int udf_compute_nr_groups(struct super_block *sb, u32 partition) { struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
8dee00bb7 fs/udf: Use DIV_R... |
994 995 996 |
return DIV_ROUND_UP(map->s_partition_len + (sizeof(struct spaceBitmapDesc) << 3), sb->s_blocksize * 8); |
883cb9d18 udf: move calcula... |
997 |
} |
66e1da3f4 udf: convert macr... |
998 999 |
static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) { |
66e1da3f4 udf: convert macr... |
1000 |
struct udf_bitmap *bitmap; |
256ccb9ba udf: Use kvzalloc... |
1001 |
int nr_groups = udf_compute_nr_groups(sb, index); |
66e1da3f4 udf: convert macr... |
1002 |
|
256ccb9ba udf: Use kvzalloc... |
1003 1004 |
bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups), GFP_KERNEL); |
ba2eb866a fs-udf: Adjust tw... |
1005 |
if (!bitmap) |
66e1da3f4 udf: convert macr... |
1006 |
return NULL; |
66e1da3f4 udf: convert macr... |
1007 |
|
66e1da3f4 udf: convert macr... |
1008 1009 1010 |
bitmap->s_nr_groups = nr_groups; return bitmap; } |
b085fbe2e udf: Fix crash du... |
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 |
static int check_partition_desc(struct super_block *sb, struct partitionDesc *p, struct udf_part_map *map) { bool umap, utable, fmap, ftable; struct partitionHeaderDesc *phd; switch (le32_to_cpu(p->accessType)) { case PD_ACCESS_TYPE_READ_ONLY: case PD_ACCESS_TYPE_WRITE_ONCE: |
b085fbe2e udf: Fix crash du... |
1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 |
case PD_ACCESS_TYPE_NONE: goto force_ro; } /* No Partition Header Descriptor? */ if (strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02) && strcmp(p->partitionContents.ident, PD_PARTITION_CONTENTS_NSR03)) goto force_ro; phd = (struct partitionHeaderDesc *)p->partitionContentsUse; utable = phd->unallocSpaceTable.extLength; umap = phd->unallocSpaceBitmap.extLength; ftable = phd->freedSpaceTable.extLength; fmap = phd->freedSpaceBitmap.extLength; /* No allocation info? */ if (!utable && !umap && !ftable && !fmap) goto force_ro; /* We don't support blocks that require erasing before overwrite */ if (ftable || fmap) goto force_ro; /* UDF 2.60: 2.3.3 - no mixing of tables & bitmaps, no VAT. */ if (utable && umap) goto force_ro; if (map->s_partition_type == UDF_VIRTUAL_MAP15 || |
57debb815 udf: Disallow R/W... |
1048 1049 |
map->s_partition_type == UDF_VIRTUAL_MAP20 || map->s_partition_type == UDF_METADATA_MAP25) |
b085fbe2e udf: Fix crash du... |
1050 1051 1052 1053 1054 1055 1056 1057 1058 |
goto force_ro; return 0; force_ro: if (!sb_rdonly(sb)) return -EACCES; UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); return 0; } |
3fb38dfa0 udf: Move filling... |
1059 1060 |
static int udf_fill_partdesc_info(struct super_block *sb, struct partitionDesc *p, int p_index) |
1da177e4c Linux-2.6.12-rc2 |
1061 |
{ |
6c79e987d udf: remove some ... |
1062 |
struct udf_part_map *map; |
165923fa4 udf: super.c reor... |
1063 |
struct udf_sb_info *sbi = UDF_SB(sb); |
3fb38dfa0 udf: Move filling... |
1064 |
struct partitionHeaderDesc *phd; |
b085fbe2e udf: Fix crash du... |
1065 |
int err; |
165923fa4 udf: super.c reor... |
1066 |
|
3fb38dfa0 udf: Move filling... |
1067 |
map = &sbi->s_partmaps[p_index]; |
165923fa4 udf: super.c reor... |
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 |
map->s_partition_len = le32_to_cpu(p->partitionLength); /* blocks */ map->s_partition_root = le32_to_cpu(p->partitionStartingLocation); if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY)) map->s_partition_flags |= UDF_PART_FLAG_READ_ONLY; if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE)) map->s_partition_flags |= UDF_PART_FLAG_WRITE_ONCE; if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE)) map->s_partition_flags |= UDF_PART_FLAG_REWRITABLE; if (p->accessType == cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE)) map->s_partition_flags |= UDF_PART_FLAG_OVERWRITABLE; |
fcbf7637e udf: Fix signed/u... |
1080 1081 |
udf_debug("Partition (%d type %x) starts at physical %u, block length %u ", |
a983f368f udf: Neaten udf_d... |
1082 1083 |
p_index, map->s_partition_type, map->s_partition_root, map->s_partition_len); |
165923fa4 udf: super.c reor... |
1084 |
|
b085fbe2e udf: Fix crash du... |
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 |
err = check_partition_desc(sb, p, map); if (err) return err; /* * Skip loading allocation info it we cannot ever write to the fs. * This is a correctness thing as we may have decided to force ro mount * to avoid allocation info we don't support. */ if (UDF_QUERY_FLAG(sb, UDF_FLAG_RW_INCOMPAT)) |
3fb38dfa0 udf: Move filling... |
1095 |
return 0; |
165923fa4 udf: super.c reor... |
1096 1097 1098 |
phd = (struct partitionHeaderDesc *)p->partitionContentsUse; if (phd->unallocSpaceTable.extLength) { |
5ca4e4be8 Remove struct typ... |
1099 |
struct kernel_lb_addr loc = { |
165923fa4 udf: super.c reor... |
1100 1101 |
.logicalBlockNum = le32_to_cpu( phd->unallocSpaceTable.extPosition), |
3fb38dfa0 udf: Move filling... |
1102 |
.partitionReferenceNum = p_index, |
165923fa4 udf: super.c reor... |
1103 |
}; |
6d3d5e860 udf: Make udf_rea... |
1104 |
struct inode *inode; |
165923fa4 udf: super.c reor... |
1105 |
|
6174c2eb8 udf: Fix loading ... |
1106 |
inode = udf_iget_special(sb, &loc); |
6d3d5e860 udf: Make udf_rea... |
1107 |
if (IS_ERR(inode)) { |
165923fa4 udf: super.c reor... |
1108 1109 |
udf_debug("cannot load unallocSpaceTable (part %d) ", |
a983f368f udf: Neaten udf_d... |
1110 |
p_index); |
6d3d5e860 udf: Make udf_rea... |
1111 |
return PTR_ERR(inode); |
165923fa4 udf: super.c reor... |
1112 |
} |
6d3d5e860 udf: Make udf_rea... |
1113 |
map->s_uspace.s_table = inode; |
165923fa4 udf: super.c reor... |
1114 |
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; |
fcbf7637e udf: Fix signed/u... |
1115 1116 |
udf_debug("unallocSpaceTable (part %d) @ %lu ", |
a983f368f udf: Neaten udf_d... |
1117 |
p_index, map->s_uspace.s_table->i_ino); |
165923fa4 udf: super.c reor... |
1118 1119 1120 |
} if (phd->unallocSpaceBitmap.extLength) { |
3fb38dfa0 udf: Move filling... |
1121 1122 |
struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); if (!bitmap) |
d759bfa4e udf: Standardize ... |
1123 |
return -ENOMEM; |
165923fa4 udf: super.c reor... |
1124 |
map->s_uspace.s_bitmap = bitmap; |
2e0838fd0 udf: Improve erro... |
1125 |
bitmap->s_extPosition = le32_to_cpu( |
165923fa4 udf: super.c reor... |
1126 |
phd->unallocSpaceBitmap.extPosition); |
2e0838fd0 udf: Improve erro... |
1127 |
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; |
fcbf7637e udf: Fix signed/u... |
1128 1129 |
udf_debug("unallocSpaceBitmap (part %d) @ %u ", |
a983f368f udf: Neaten udf_d... |
1130 |
p_index, bitmap->s_extPosition); |
165923fa4 udf: super.c reor... |
1131 |
} |
3fb38dfa0 udf: Move filling... |
1132 1133 |
return 0; } |
e971b0b9e udf: Try harder w... |
1134 1135 |
static void udf_find_vat_block(struct super_block *sb, int p_index, int type1_index, sector_t start_block) |
38b74a53e udf: Move process... |
1136 1137 1138 |
{ struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map = &sbi->s_partmaps[p_index]; |
e971b0b9e udf: Try harder w... |
1139 |
sector_t vat_block; |
5ca4e4be8 Remove struct typ... |
1140 |
struct kernel_lb_addr ino; |
6d3d5e860 udf: Make udf_rea... |
1141 |
struct inode *inode; |
e971b0b9e udf: Try harder w... |
1142 1143 1144 1145 1146 1147 1148 1149 |
/* * VAT file entry is in the last recorded block. Some broken disks have * it a few blocks before so try a bit harder... */ ino.partitionReferenceNum = type1_index; for (vat_block = start_block; vat_block >= map->s_partition_root && |
6d3d5e860 udf: Make udf_rea... |
1150 |
vat_block >= start_block - 3; vat_block--) { |
e971b0b9e udf: Try harder w... |
1151 |
ino.logicalBlockNum = vat_block - map->s_partition_root; |
6174c2eb8 udf: Fix loading ... |
1152 |
inode = udf_iget_special(sb, &ino); |
6d3d5e860 udf: Make udf_rea... |
1153 1154 1155 1156 |
if (!IS_ERR(inode)) { sbi->s_vat_inode = inode; break; } |
e971b0b9e udf: Try harder w... |
1157 1158 1159 1160 1161 1162 1163 |
} } static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) { struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map = &sbi->s_partmaps[p_index]; |
fa5e08156 udf: Handle VAT p... |
1164 1165 1166 1167 |
struct buffer_head *bh = NULL; struct udf_inode_info *vati; uint32_t pos; struct virtualAllocationTable20 *vat20; |
23bcda112 udf: atomically r... |
1168 1169 |
sector_t blocks = i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits; |
38b74a53e udf: Move process... |
1170 |
|
e971b0b9e udf: Try harder w... |
1171 |
udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block); |
4bf17af0d udf: Fix loading ... |
1172 1173 |
if (!sbi->s_vat_inode && sbi->s_last_block != blocks - 1) { |
78ace70c4 udf: Convert prin... |
1174 1175 1176 1177 |
pr_notice("Failed to read VAT inode from the last recorded block (%lu), retrying with the last block of the device (%lu). ", (unsigned long)sbi->s_last_block, (unsigned long)blocks - 1); |
e971b0b9e udf: Try harder w... |
1178 |
udf_find_vat_block(sb, p_index, type1_index, blocks - 1); |
4bf17af0d udf: Fix loading ... |
1179 |
} |
38b74a53e udf: Move process... |
1180 |
if (!sbi->s_vat_inode) |
d759bfa4e udf: Standardize ... |
1181 |
return -EIO; |
38b74a53e udf: Move process... |
1182 1183 |
if (map->s_partition_type == UDF_VIRTUAL_MAP15) { |
47c9358a0 udf: Fix bug in V... |
1184 |
map->s_type_specific.s_virtual.s_start_offset = 0; |
38b74a53e udf: Move process... |
1185 1186 1187 |
map->s_type_specific.s_virtual.s_num_entries = (sbi->s_vat_inode->i_size - 36) >> 2; } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) { |
fa5e08156 udf: Handle VAT p... |
1188 1189 1190 1191 1192 |
vati = UDF_I(sbi->s_vat_inode); if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { pos = udf_block_map(sbi->s_vat_inode, 0); bh = sb_bread(sb, pos); if (!bh) |
d759bfa4e udf: Standardize ... |
1193 |
return -EIO; |
fa5e08156 udf: Handle VAT p... |
1194 1195 1196 |
vat20 = (struct virtualAllocationTable20 *)bh->b_data; } else { vat20 = (struct virtualAllocationTable20 *) |
382a2287b udf: Remove point... |
1197 |
vati->i_data; |
fa5e08156 udf: Handle VAT p... |
1198 |
} |
38b74a53e udf: Move process... |
1199 |
|
38b74a53e udf: Move process... |
1200 |
map->s_type_specific.s_virtual.s_start_offset = |
47c9358a0 udf: Fix bug in V... |
1201 |
le16_to_cpu(vat20->lengthHeader); |
38b74a53e udf: Move process... |
1202 1203 1204 1205 1206 1207 1208 1209 |
map->s_type_specific.s_virtual.s_num_entries = (sbi->s_vat_inode->i_size - map->s_type_specific.s_virtual. s_start_offset) >> 2; brelse(bh); } return 0; } |
d759bfa4e udf: Standardize ... |
1210 1211 1212 1213 1214 1215 |
/* * Load partition descriptor block * * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor * sequence. */ |
3fb38dfa0 udf: Move filling... |
1216 1217 1218 1219 1220 1221 |
static int udf_load_partdesc(struct super_block *sb, sector_t block) { struct buffer_head *bh; struct partitionDesc *p; struct udf_part_map *map; struct udf_sb_info *sbi = UDF_SB(sb); |
38b74a53e udf: Move process... |
1222 |
int i, type1_idx; |
3fb38dfa0 udf: Move filling... |
1223 1224 |
uint16_t partitionNumber; uint16_t ident; |
d759bfa4e udf: Standardize ... |
1225 |
int ret; |
3fb38dfa0 udf: Move filling... |
1226 1227 1228 |
bh = udf_read_tagged(sb, block, block, &ident); if (!bh) |
d759bfa4e udf: Standardize ... |
1229 1230 1231 |
return -EAGAIN; if (ident != TAG_IDENT_PD) { ret = 0; |
3fb38dfa0 udf: Move filling... |
1232 |
goto out_bh; |
d759bfa4e udf: Standardize ... |
1233 |
} |
3fb38dfa0 udf: Move filling... |
1234 1235 1236 |
p = (struct partitionDesc *)bh->b_data; partitionNumber = le16_to_cpu(p->partitionNumber); |
38b74a53e udf: Move process... |
1237 |
|
7888824b0 udf: Use correct ... |
1238 |
/* First scan for TYPE1 and SPARABLE partitions */ |
3fb38dfa0 udf: Move filling... |
1239 1240 |
for (i = 0; i < sbi->s_partitions; i++) { map = &sbi->s_partmaps[i]; |
fcbf7637e udf: Fix signed/u... |
1241 1242 |
udf_debug("Searching map: (%u == %u) ", |
3fb38dfa0 udf: Move filling... |
1243 |
map->s_partition_num, partitionNumber); |
38b74a53e udf: Move process... |
1244 1245 1246 |
if (map->s_partition_num == partitionNumber && (map->s_partition_type == UDF_TYPE1_MAP15 || map->s_partition_type == UDF_SPARABLE_MAP15)) |
3fb38dfa0 udf: Move filling... |
1247 1248 |
break; } |
38b74a53e udf: Move process... |
1249 |
if (i >= sbi->s_partitions) { |
fcbf7637e udf: Fix signed/u... |
1250 1251 |
udf_debug("Partition (%u) not found in partition map ", |
3fb38dfa0 udf: Move filling... |
1252 |
partitionNumber); |
d759bfa4e udf: Standardize ... |
1253 |
ret = 0; |
3fb38dfa0 udf: Move filling... |
1254 1255 |
goto out_bh; } |
165923fa4 udf: super.c reor... |
1256 |
|
3fb38dfa0 udf: Move filling... |
1257 |
ret = udf_fill_partdesc_info(sb, p, i); |
d759bfa4e udf: Standardize ... |
1258 1259 |
if (ret < 0) goto out_bh; |
38b74a53e udf: Move process... |
1260 1261 |
/* |
bfb257a59 udf: Add read-onl... |
1262 1263 |
* Now rescan for VIRTUAL or METADATA partitions when SPARABLE and * PHYSICAL partitions are already set up |
38b74a53e udf: Move process... |
1264 1265 |
*/ type1_idx = i; |
444996027 udf: fix for path... |
1266 |
map = NULL; /* supress 'maybe used uninitialized' warning */ |
38b74a53e udf: Move process... |
1267 1268 1269 1270 1271 |
for (i = 0; i < sbi->s_partitions; i++) { map = &sbi->s_partmaps[i]; if (map->s_partition_num == partitionNumber && (map->s_partition_type == UDF_VIRTUAL_MAP15 || |
bfb257a59 udf: Add read-onl... |
1272 1273 |
map->s_partition_type == UDF_VIRTUAL_MAP20 || map->s_partition_type == UDF_METADATA_MAP25)) |
38b74a53e udf: Move process... |
1274 1275 |
break; } |
d759bfa4e udf: Standardize ... |
1276 1277 |
if (i >= sbi->s_partitions) { ret = 0; |
38b74a53e udf: Move process... |
1278 |
goto out_bh; |
d759bfa4e udf: Standardize ... |
1279 |
} |
38b74a53e udf: Move process... |
1280 1281 |
ret = udf_fill_partdesc_info(sb, p, i); |
d759bfa4e udf: Standardize ... |
1282 |
if (ret < 0) |
38b74a53e udf: Move process... |
1283 |
goto out_bh; |
bfb257a59 udf: Add read-onl... |
1284 |
if (map->s_partition_type == UDF_METADATA_MAP25) { |
7888824b0 udf: Use correct ... |
1285 |
ret = udf_load_metadata_files(sb, i, type1_idx); |
d759bfa4e udf: Standardize ... |
1286 |
if (ret < 0) { |
78ace70c4 udf: Convert prin... |
1287 1288 1289 |
udf_err(sb, "error loading MetaData partition map %d ", i); |
bfb257a59 udf: Add read-onl... |
1290 1291 1292 |
goto out_bh; } } else { |
e729eac6f udf: Refuse RW mo... |
1293 1294 1295 1296 1297 |
/* * If we have a partition with virtual map, we don't handle * writing to it (we overwrite blocks instead of relocating * them). */ |
bc98a42c1 VFS: Convert sb->... |
1298 |
if (!sb_rdonly(sb)) { |
e729eac6f udf: Refuse RW mo... |
1299 1300 1301 |
ret = -EACCES; goto out_bh; } |
a9ad01bc7 udf: Prevent writ... |
1302 |
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
bfb257a59 udf: Add read-onl... |
1303 |
ret = udf_load_vat(sb, i, type1_idx); |
d759bfa4e udf: Standardize ... |
1304 |
if (ret < 0) |
bfb257a59 udf: Add read-onl... |
1305 |
goto out_bh; |
bfb257a59 udf: Add read-onl... |
1306 |
} |
d759bfa4e udf: Standardize ... |
1307 |
ret = 0; |
c0eb31ed1 udf: Cleanup volu... |
1308 |
out_bh: |
2e0838fd0 udf: Improve erro... |
1309 |
/* In case loading failed, we handle cleanup in udf_fill_super */ |
c0eb31ed1 udf: Cleanup volu... |
1310 1311 |
brelse(bh); return ret; |
1da177e4c Linux-2.6.12-rc2 |
1312 |
} |
1df2ae31c udf: Fortify load... |
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 |
static int udf_load_sparable_map(struct super_block *sb, struct udf_part_map *map, struct sparablePartitionMap *spm) { uint32_t loc; uint16_t ident; struct sparingTable *st; struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing; int i; struct buffer_head *bh; map->s_partition_type = UDF_SPARABLE_MAP15; sdata->s_packet_len = le16_to_cpu(spm->packetLength); if (!is_power_of_2(sdata->s_packet_len)) { udf_err(sb, "error loading logical volume descriptor: " "Invalid packet length %u ", (unsigned)sdata->s_packet_len); return -EIO; } if (spm->numSparingTables > 4) { udf_err(sb, "error loading logical volume descriptor: " "Too many sparing tables (%d) ", (int)spm->numSparingTables); return -EIO; } |
44ac6b829 udf: Limit sparin... |
1340 1341 1342 1343 1344 1345 1346 |
if (le32_to_cpu(spm->sizeSparingTable) > sb->s_blocksize) { udf_err(sb, "error loading logical volume descriptor: " "Too big sparing table size (%u) ", le32_to_cpu(spm->sizeSparingTable)); return -EIO; } |
1df2ae31c udf: Fortify load... |
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 |
for (i = 0; i < spm->numSparingTables; i++) { loc = le32_to_cpu(spm->locSparingTable[i]); bh = udf_read_tagged(sb, loc, loc, &ident); if (!bh) continue; st = (struct sparingTable *)bh->b_data; if (ident != 0 || strncmp(st->sparingIdent.ident, UDF_ID_SPARING, strlen(UDF_ID_SPARING)) || sizeof(*st) + le16_to_cpu(st->reallocationTableLen) > sb->s_blocksize) { brelse(bh); continue; } sdata->s_spar_map[i] = bh; } map->s_partition_func = udf_get_pblock_spar15; return 0; } |
c0eb31ed1 udf: Cleanup volu... |
1369 |
static int udf_load_logicalvol(struct super_block *sb, sector_t block, |
5ca4e4be8 Remove struct typ... |
1370 |
struct kernel_lb_addr *fileset) |
1da177e4c Linux-2.6.12-rc2 |
1371 1372 |
{ struct logicalVolDesc *lvd; |
1df2ae31c udf: Fortify load... |
1373 |
int i, offset; |
1da177e4c Linux-2.6.12-rc2 |
1374 |
uint8_t type; |
6c79e987d udf: remove some ... |
1375 |
struct udf_sb_info *sbi = UDF_SB(sb); |
4b11111ab udf: fix coding s... |
1376 |
struct genericPartitionMap *gpm; |
c0eb31ed1 udf: Cleanup volu... |
1377 1378 |
uint16_t ident; struct buffer_head *bh; |
adee11b20 udf: Avoid run aw... |
1379 |
unsigned int table_len; |
d759bfa4e udf: Standardize ... |
1380 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
1381 |
|
c0eb31ed1 udf: Cleanup volu... |
1382 1383 |
bh = udf_read_tagged(sb, block, block, &ident); if (!bh) |
d759bfa4e udf: Standardize ... |
1384 |
return -EAGAIN; |
c0eb31ed1 udf: Cleanup volu... |
1385 |
BUG_ON(ident != TAG_IDENT_LVD); |
1da177e4c Linux-2.6.12-rc2 |
1386 |
lvd = (struct logicalVolDesc *)bh->b_data; |
adee11b20 udf: Avoid run aw... |
1387 |
table_len = le32_to_cpu(lvd->mapTableLength); |
57b9655d0 udf: Improve tabl... |
1388 |
if (table_len > sb->s_blocksize - sizeof(*lvd)) { |
adee11b20 udf: Avoid run aw... |
1389 1390 1391 1392 |
udf_err(sb, "error loading logical volume descriptor: " "Partition table too long (%u > %lu) ", table_len, sb->s_blocksize - sizeof(*lvd)); |
d759bfa4e udf: Standardize ... |
1393 |
ret = -EIO; |
adee11b20 udf: Avoid run aw... |
1394 1395 |
goto out_bh; } |
1da177e4c Linux-2.6.12-rc2 |
1396 |
|
2dee5aac0 udf: Verify domai... |
1397 1398 1399 1400 |
ret = udf_verify_domain_identifier(sb, &lvd->domainIdent, "logical volume"); if (ret) goto out_bh; |
cb14d340e udf: Use 'ret' in... |
1401 1402 |
ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps)); if (ret) |
c0eb31ed1 udf: Cleanup volu... |
1403 |
goto out_bh; |
1da177e4c Linux-2.6.12-rc2 |
1404 |
|
cb00ea352 UDF: coding style... |
1405 |
for (i = 0, offset = 0; |
adee11b20 udf: Avoid run aw... |
1406 |
i < sbi->s_partitions && offset < table_len; |
4b11111ab udf: fix coding s... |
1407 1408 1409 1410 1411 |
i++, offset += gpm->partitionMapLength) { struct udf_part_map *map = &sbi->s_partmaps[i]; gpm = (struct genericPartitionMap *) &(lvd->partitionMaps[offset]); type = gpm->partitionMapType; |
cb00ea352 UDF: coding style... |
1412 |
if (type == 1) { |
4b11111ab udf: fix coding s... |
1413 1414 |
struct genericPartitionMap1 *gpm1 = (struct genericPartitionMap1 *)gpm; |
6c79e987d udf: remove some ... |
1415 1416 1417 1418 |
map->s_partition_type = UDF_TYPE1_MAP15; map->s_volumeseqnum = le16_to_cpu(gpm1->volSeqNum); map->s_partition_num = le16_to_cpu(gpm1->partitionNum); map->s_partition_func = NULL; |
cb00ea352 UDF: coding style... |
1419 |
} else if (type == 2) { |
4b11111ab udf: fix coding s... |
1420 1421 1422 1423 1424 1425 1426 |
struct udfPartitionMap2 *upm2 = (struct udfPartitionMap2 *)gpm; if (!strncmp(upm2->partIdent.ident, UDF_ID_VIRTUAL, strlen(UDF_ID_VIRTUAL))) { u16 suf = le16_to_cpu(((__le16 *)upm2->partIdent. identSuffix)[0]); |
c82a12750 udf: Fix detectio... |
1427 |
if (suf < 0x0200) { |
4b11111ab udf: fix coding s... |
1428 1429 1430 1431 |
map->s_partition_type = UDF_VIRTUAL_MAP15; map->s_partition_func = udf_get_pblock_virt15; |
c82a12750 udf: Fix detectio... |
1432 |
} else { |
4b11111ab udf: fix coding s... |
1433 1434 1435 1436 |
map->s_partition_type = UDF_VIRTUAL_MAP20; map->s_partition_func = udf_get_pblock_virt20; |
1da177e4c Linux-2.6.12-rc2 |
1437 |
} |
4b11111ab udf: fix coding s... |
1438 1439 1440 |
} else if (!strncmp(upm2->partIdent.ident, UDF_ID_SPARABLE, strlen(UDF_ID_SPARABLE))) { |
d759bfa4e udf: Standardize ... |
1441 1442 1443 |
ret = udf_load_sparable_map(sb, map, (struct sparablePartitionMap *)gpm); if (ret < 0) |
1df2ae31c udf: Fortify load... |
1444 |
goto out_bh; |
bfb257a59 udf: Add read-onl... |
1445 1446 1447 1448 1449 1450 1451 1452 |
} else if (!strncmp(upm2->partIdent.ident, UDF_ID_METADATA, strlen(UDF_ID_METADATA))) { struct udf_meta_data *mdata = &map->s_type_specific.s_metadata; struct metadataPartitionMap *mdm = (struct metadataPartitionMap *) &(lvd->partitionMaps[offset]); |
fcbf7637e udf: Fix signed/u... |
1453 1454 |
udf_debug("Parsing Logical vol part %d type %u id=%s ", |
a983f368f udf: Neaten udf_d... |
1455 |
i, type, UDF_ID_METADATA); |
bfb257a59 udf: Add read-onl... |
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 |
map->s_partition_type = UDF_METADATA_MAP25; map->s_partition_func = udf_get_pblock_meta25; mdata->s_meta_file_loc = le32_to_cpu(mdm->metadataFileLoc); mdata->s_mirror_file_loc = le32_to_cpu(mdm->metadataMirrorFileLoc); mdata->s_bitmap_file_loc = le32_to_cpu(mdm->metadataBitmapFileLoc); mdata->s_alloc_unit_size = le32_to_cpu(mdm->allocUnitSize); mdata->s_align_unit_size = le16_to_cpu(mdm->alignUnitSize); |
ed47a7d00 udf: Cleanup meta... |
1470 1471 |
if (mdm->flags & 0x01) mdata->s_flags |= MF_DUPLICATE_MD; |
bfb257a59 udf: Add read-onl... |
1472 1473 1474 |
udf_debug("Metadata Ident suffix=0x%x ", |
a983f368f udf: Neaten udf_d... |
1475 1476 |
le16_to_cpu(*(__le16 *) mdm->partIdent.identSuffix)); |
fcbf7637e udf: Fix signed/u... |
1477 1478 |
udf_debug("Metadata part num=%u ", |
a983f368f udf: Neaten udf_d... |
1479 |
le16_to_cpu(mdm->partitionNum)); |
fcbf7637e udf: Fix signed/u... |
1480 1481 |
udf_debug("Metadata part alloc unit size=%u ", |
a983f368f udf: Neaten udf_d... |
1482 |
le32_to_cpu(mdm->allocUnitSize)); |
fcbf7637e udf: Fix signed/u... |
1483 1484 |
udf_debug("Metadata file loc=%u ", |
a983f368f udf: Neaten udf_d... |
1485 |
le32_to_cpu(mdm->metadataFileLoc)); |
fcbf7637e udf: Fix signed/u... |
1486 1487 |
udf_debug("Mirror file loc=%u ", |
a983f368f udf: Neaten udf_d... |
1488 |
le32_to_cpu(mdm->metadataMirrorFileLoc)); |
fcbf7637e udf: Fix signed/u... |
1489 1490 |
udf_debug("Bitmap file loc=%u ", |
a983f368f udf: Neaten udf_d... |
1491 |
le32_to_cpu(mdm->metadataBitmapFileLoc)); |
fcbf7637e udf: Fix signed/u... |
1492 1493 |
udf_debug("Flags: %d %u ", |
ed47a7d00 udf: Cleanup meta... |
1494 |
mdata->s_flags, mdm->flags); |
cb00ea352 UDF: coding style... |
1495 |
} else { |
3a71fc5de udf: fix coding s... |
1496 1497 1498 |
udf_debug("Unknown ident: %s ", upm2->partIdent.ident); |
1da177e4c Linux-2.6.12-rc2 |
1499 1500 |
continue; } |
6c79e987d udf: remove some ... |
1501 1502 |
map->s_volumeseqnum = le16_to_cpu(upm2->volSeqNum); map->s_partition_num = le16_to_cpu(upm2->partitionNum); |
1da177e4c Linux-2.6.12-rc2 |
1503 |
} |
fcbf7637e udf: Fix signed/u... |
1504 1505 |
udf_debug("Partition (%d:%u) type %u on volume %u ", |
a983f368f udf: Neaten udf_d... |
1506 |
i, map->s_partition_num, type, map->s_volumeseqnum); |
1da177e4c Linux-2.6.12-rc2 |
1507 |
} |
cb00ea352 UDF: coding style... |
1508 |
if (fileset) { |
5ca4e4be8 Remove struct typ... |
1509 |
struct long_ad *la = (struct long_ad *)&(lvd->logicalVolContentsUse[0]); |
1da177e4c Linux-2.6.12-rc2 |
1510 1511 |
*fileset = lelb_to_cpu(la->extLocation); |
fcbf7637e udf: Fix signed/u... |
1512 1513 |
udf_debug("FileSet found in LogicalVolDesc at block=%u, partition=%u ", |
a983f368f udf: Neaten udf_d... |
1514 |
fileset->logicalBlockNum, |
28de7948a UDF: coding style... |
1515 |
fileset->partitionReferenceNum); |
1da177e4c Linux-2.6.12-rc2 |
1516 1517 1518 |
} if (lvd->integritySeqExt.extLength) udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); |
d759bfa4e udf: Standardize ... |
1519 |
ret = 0; |
4f5edd82e udf: disallow RW ... |
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 |
if (!sbi->s_lvid_bh) { /* We can't generate unique IDs without a valid LVID */ if (sb_rdonly(sb)) { UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); } else { udf_warn(sb, "Damaged or missing LVID, forcing " "readonly mount "); ret = -EACCES; } } |
c0eb31ed1 udf: Cleanup volu... |
1532 1533 1534 |
out_bh: brelse(bh); return ret; |
1da177e4c Linux-2.6.12-rc2 |
1535 1536 1537 |
} /* |
a47241cde udf: Prevent stac... |
1538 |
* Find the prevailing Logical Volume Integrity Descriptor. |
1da177e4c Linux-2.6.12-rc2 |
1539 |
*/ |
5ca4e4be8 Remove struct typ... |
1540 |
static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc) |
1da177e4c Linux-2.6.12-rc2 |
1541 |
{ |
a47241cde udf: Prevent stac... |
1542 |
struct buffer_head *bh, *final_bh; |
1da177e4c Linux-2.6.12-rc2 |
1543 |
uint16_t ident; |
6c79e987d udf: remove some ... |
1544 1545 |
struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDesc *lvid; |
a47241cde udf: Prevent stac... |
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 |
int indirections = 0; while (++indirections <= UDF_MAX_LVID_NESTING) { final_bh = NULL; while (loc.extLength > 0 && (bh = udf_read_tagged(sb, loc.extLocation, loc.extLocation, &ident))) { if (ident != TAG_IDENT_LVID) { brelse(bh); break; } brelse(final_bh); final_bh = bh; |
1da177e4c Linux-2.6.12-rc2 |
1560 |
|
a47241cde udf: Prevent stac... |
1561 1562 1563 |
loc.extLength -= sb->s_blocksize; loc.extLocation++; } |
cb00ea352 UDF: coding style... |
1564 |
|
a47241cde udf: Prevent stac... |
1565 1566 |
if (!final_bh) return; |
cb00ea352 UDF: coding style... |
1567 |
|
a47241cde udf: Prevent stac... |
1568 1569 1570 1571 1572 1573 1574 1575 |
brelse(sbi->s_lvid_bh); sbi->s_lvid_bh = final_bh; lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data; if (lvid->nextIntegrityExt.extLength == 0) return; loc = leea_to_cpu(lvid->nextIntegrityExt); |
1da177e4c Linux-2.6.12-rc2 |
1576 |
} |
a47241cde udf: Prevent stac... |
1577 1578 1579 1580 1581 1582 |
udf_warn(sb, "Too many LVID indirections (max %u), ignoring. ", UDF_MAX_LVID_NESTING); brelse(sbi->s_lvid_bh); sbi->s_lvid_bh = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1583 |
} |
7b78fd02f udf: Fix handling... |
1584 1585 1586 1587 1588 |
/* * Step for reallocation of table of partition descriptor sequence numbers. * Must be power of 2. */ #define PART_DESC_ALLOC_STEP 32 |
ee4af50ca udf: Fix mounting... |
1589 1590 1591 1592 |
struct part_desc_seq_scan_data { struct udf_vds_record rec; u32 partnum; }; |
7b78fd02f udf: Fix handling... |
1593 1594 1595 |
struct desc_seq_scan_data { struct udf_vds_record vds[VDS_POS_LENGTH]; unsigned int size_part_descs; |
ee4af50ca udf: Fix mounting... |
1596 1597 |
unsigned int num_part_descs; struct part_desc_seq_scan_data *part_descs_loc; |
7b78fd02f udf: Fix handling... |
1598 1599 1600 1601 1602 1603 1604 1605 |
}; static struct udf_vds_record *handle_partition_descriptor( struct buffer_head *bh, struct desc_seq_scan_data *data) { struct partitionDesc *desc = (struct partitionDesc *)bh->b_data; int partnum; |
ee4af50ca udf: Fix mounting... |
1606 |
int i; |
7b78fd02f udf: Fix handling... |
1607 1608 |
partnum = le16_to_cpu(desc->partitionNumber); |
ee4af50ca udf: Fix mounting... |
1609 1610 1611 1612 1613 |
for (i = 0; i < data->num_part_descs; i++) if (partnum == data->part_descs_loc[i].partnum) return &(data->part_descs_loc[i].rec); if (data->num_part_descs >= data->size_part_descs) { struct part_desc_seq_scan_data *new_loc; |
7b78fd02f udf: Fix handling... |
1614 |
unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP); |
6396bb221 treewide: kzalloc... |
1615 |
new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL); |
7b78fd02f udf: Fix handling... |
1616 1617 1618 1619 1620 1621 1622 1623 |
if (!new_loc) return ERR_PTR(-ENOMEM); memcpy(new_loc, data->part_descs_loc, data->size_part_descs * sizeof(*new_loc)); kfree(data->part_descs_loc); data->part_descs_loc = new_loc; data->size_part_descs = new_size; } |
ee4af50ca udf: Fix mounting... |
1624 |
return &(data->part_descs_loc[data->num_part_descs++].rec); |
7b78fd02f udf: Fix handling... |
1625 1626 1627 1628 1629 |
} static struct udf_vds_record *get_volume_descriptor_record(uint16_t ident, struct buffer_head *bh, struct desc_seq_scan_data *data) |
18cf4781c udf: Unify common... |
1630 1631 1632 |
{ switch (ident) { case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */ |
7b78fd02f udf: Fix handling... |
1633 |
return &(data->vds[VDS_POS_PRIMARY_VOL_DESC]); |
18cf4781c udf: Unify common... |
1634 |
case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */ |
7b78fd02f udf: Fix handling... |
1635 |
return &(data->vds[VDS_POS_IMP_USE_VOL_DESC]); |
18cf4781c udf: Unify common... |
1636 |
case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */ |
7b78fd02f udf: Fix handling... |
1637 |
return &(data->vds[VDS_POS_LOGICAL_VOL_DESC]); |
18cf4781c udf: Unify common... |
1638 |
case TAG_IDENT_USD: /* ISO 13346 3/10.8 */ |
7b78fd02f udf: Fix handling... |
1639 1640 1641 |
return &(data->vds[VDS_POS_UNALLOC_SPACE_DESC]); case TAG_IDENT_PD: /* ISO 13346 3/10.5 */ return handle_partition_descriptor(bh, data); |
18cf4781c udf: Unify common... |
1642 1643 1644 |
} return NULL; } |
e7a4eb861 udf: limit the ma... |
1645 1646 |
/* |
d759bfa4e udf: Standardize ... |
1647 1648 1649 1650 |
* Process a main/reserve volume descriptor sequence. * @block First block of first extent of the sequence. * @lastblock Lastblock of first extent of the sequence. * @fileset There we store extent containing root fileset |
1da177e4c Linux-2.6.12-rc2 |
1651 |
* |
d759bfa4e udf: Standardize ... |
1652 1653 |
* Returns <0 on error, 0 on success. -EAGAIN is special - try next descriptor * sequence |
1da177e4c Linux-2.6.12-rc2 |
1654 |
*/ |
d759bfa4e udf: Standardize ... |
1655 1656 1657 1658 |
static noinline int udf_process_sequence( struct super_block *sb, sector_t block, sector_t lastblock, struct kernel_lb_addr *fileset) |
1da177e4c Linux-2.6.12-rc2 |
1659 1660 |
{ struct buffer_head *bh = NULL; |
4b11111ab udf: fix coding s... |
1661 |
struct udf_vds_record *curr; |
1da177e4c Linux-2.6.12-rc2 |
1662 1663 |
struct generic_desc *gd; struct volDescPtr *vdp; |
2b8f94211 udf: use bool for... |
1664 |
bool done = false; |
1da177e4c Linux-2.6.12-rc2 |
1665 1666 |
uint32_t vdsn; uint16_t ident; |
d759bfa4e udf: Standardize ... |
1667 |
int ret; |
e7a4eb861 udf: limit the ma... |
1668 |
unsigned int indirections = 0; |
7b78fd02f udf: Fix handling... |
1669 1670 1671 1672 1673 |
struct desc_seq_scan_data data; unsigned int i; memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); data.size_part_descs = PART_DESC_ALLOC_STEP; |
ee4af50ca udf: Fix mounting... |
1674 |
data.num_part_descs = 0; |
6396bb221 treewide: kzalloc... |
1675 1676 1677 |
data.part_descs_loc = kcalloc(data.size_part_descs, sizeof(*data.part_descs_loc), GFP_KERNEL); |
7b78fd02f udf: Fix handling... |
1678 1679 |
if (!data.part_descs_loc) return -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
1680 |
|
c0eb31ed1 udf: Cleanup volu... |
1681 1682 1683 1684 |
/* * Read the main descriptor sequence and find which descriptors * are in it. */ |
cb00ea352 UDF: coding style... |
1685 |
for (; (!done && block <= lastblock); block++) { |
1da177e4c Linux-2.6.12-rc2 |
1686 |
bh = udf_read_tagged(sb, block, block, &ident); |
67621675e udf: Allow volume... |
1687 1688 |
if (!bh) break; |
1da177e4c Linux-2.6.12-rc2 |
1689 1690 1691 1692 |
/* Process each descriptor (ISO 13346 3/8.3-8.4) */ gd = (struct generic_desc *)bh->b_data; vdsn = le32_to_cpu(gd->volDescSeqNum); |
cb00ea352 UDF: coding style... |
1693 |
switch (ident) { |
28de7948a UDF: coding style... |
1694 |
case TAG_IDENT_VDP: /* ISO 13346 3/10.3 */ |
7b568cba4 udf: Simplify han... |
1695 1696 1697 1698 1699 1700 |
if (++indirections > UDF_MAX_TD_NESTING) { udf_err(sb, "too many Volume Descriptor " "Pointers (max %u supported) ", UDF_MAX_TD_NESTING); brelse(bh); |
a7be300de udf: Fix memory l... |
1701 1702 |
ret = -EIO; goto out; |
cb00ea352 UDF: coding style... |
1703 |
} |
7b568cba4 udf: Simplify han... |
1704 1705 1706 1707 1708 1709 1710 1711 1712 |
vdp = (struct volDescPtr *)bh->b_data; block = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation); lastblock = le32_to_cpu( vdp->nextVolDescSeqExt.extLength) >> sb->s_blocksize_bits; lastblock += block - 1; /* For loop is going to increment 'block' again */ block--; |
cb00ea352 UDF: coding style... |
1713 |
break; |
18cf4781c udf: Unify common... |
1714 |
case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */ |
28de7948a UDF: coding style... |
1715 |
case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */ |
18cf4781c udf: Unify common... |
1716 1717 |
case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */ case TAG_IDENT_USD: /* ISO 13346 3/10.8 */ |
7b78fd02f udf: Fix handling... |
1718 1719 1720 1721 |
case TAG_IDENT_PD: /* ISO 13346 3/10.5 */ curr = get_volume_descriptor_record(ident, bh, &data); if (IS_ERR(curr)) { brelse(bh); |
a7be300de udf: Fix memory l... |
1722 1723 |
ret = PTR_ERR(curr); goto out; |
7b78fd02f udf: Fix handling... |
1724 1725 1726 1727 |
} /* Descriptor we don't care about? */ if (!curr) break; |
4b11111ab udf: fix coding s... |
1728 1729 1730 |
if (vdsn >= curr->volDescSeqNum) { curr->volDescSeqNum = vdsn; curr->block = block; |
cb00ea352 UDF: coding style... |
1731 1732 |
} break; |
28de7948a UDF: coding style... |
1733 |
case TAG_IDENT_TD: /* ISO 13346 3/10.9 */ |
7b568cba4 udf: Simplify han... |
1734 |
done = true; |
cb00ea352 UDF: coding style... |
1735 |
break; |
1da177e4c Linux-2.6.12-rc2 |
1736 |
} |
3bf25cb40 udf: use get_bh() |
1737 |
brelse(bh); |
1da177e4c Linux-2.6.12-rc2 |
1738 |
} |
c0eb31ed1 udf: Cleanup volu... |
1739 1740 1741 1742 |
/* * Now read interesting descriptors again and process them * in a suitable order */ |
7b78fd02f udf: Fix handling... |
1743 |
if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) { |
78ace70c4 udf: Convert prin... |
1744 1745 |
udf_err(sb, "Primary Volume Descriptor not found! "); |
a7be300de udf: Fix memory l... |
1746 1747 |
ret = -EAGAIN; goto out; |
d759bfa4e udf: Standardize ... |
1748 |
} |
7b78fd02f udf: Fix handling... |
1749 |
ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block); |
d759bfa4e udf: Standardize ... |
1750 |
if (ret < 0) |
a7be300de udf: Fix memory l... |
1751 |
goto out; |
d759bfa4e udf: Standardize ... |
1752 |
|
7b78fd02f udf: Fix handling... |
1753 |
if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) { |
d759bfa4e udf: Standardize ... |
1754 |
ret = udf_load_logicalvol(sb, |
7b78fd02f udf: Fix handling... |
1755 1756 |
data.vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset); |
d759bfa4e udf: Standardize ... |
1757 |
if (ret < 0) |
a7be300de udf: Fix memory l... |
1758 |
goto out; |
c0eb31ed1 udf: Cleanup volu... |
1759 |
} |
165923fa4 udf: super.c reor... |
1760 |
|
7b78fd02f udf: Fix handling... |
1761 |
/* Now handle prevailing Partition Descriptors */ |
ee4af50ca udf: Fix mounting... |
1762 1763 1764 |
for (i = 0; i < data.num_part_descs; i++) { ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block); if (ret < 0) |
a7be300de udf: Fix memory l... |
1765 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1766 |
} |
a7be300de udf: Fix memory l... |
1767 1768 1769 1770 |
ret = 0; out: kfree(data.part_descs_loc); return ret; |
1da177e4c Linux-2.6.12-rc2 |
1771 |
} |
d759bfa4e udf: Standardize ... |
1772 1773 1774 1775 1776 |
/* * Load Volume Descriptor Sequence described by anchor in bh * * Returns <0 on error, 0 on success */ |
403460051 udf: Try anchor i... |
1777 1778 |
static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh, struct kernel_lb_addr *fileset) |
1da177e4c Linux-2.6.12-rc2 |
1779 |
{ |
403460051 udf: Try anchor i... |
1780 |
struct anchorVolDescPtr *anchor; |
d759bfa4e udf: Standardize ... |
1781 1782 |
sector_t main_s, main_e, reserve_s, reserve_e; int ret; |
1da177e4c Linux-2.6.12-rc2 |
1783 |
|
403460051 udf: Try anchor i... |
1784 1785 1786 1787 1788 1789 |
anchor = (struct anchorVolDescPtr *)bh->b_data; /* Locate the main sequence */ main_s = le32_to_cpu(anchor->mainVolDescSeqExt.extLocation); main_e = le32_to_cpu(anchor->mainVolDescSeqExt.extLength); main_e = main_e >> sb->s_blocksize_bits; |
91c9c9ec5 udf: Fix off-by-o... |
1790 |
main_e += main_s - 1; |
403460051 udf: Try anchor i... |
1791 1792 1793 1794 1795 |
/* Locate the reserve sequence */ reserve_s = le32_to_cpu(anchor->reserveVolDescSeqExt.extLocation); reserve_e = le32_to_cpu(anchor->reserveVolDescSeqExt.extLength); reserve_e = reserve_e >> sb->s_blocksize_bits; |
91c9c9ec5 udf: Fix off-by-o... |
1796 |
reserve_e += reserve_s - 1; |
403460051 udf: Try anchor i... |
1797 1798 1799 |
/* Process the main & reserve sequences */ /* responsible for finding the PartitionDesc(s) */ |
d759bfa4e udf: Standardize ... |
1800 1801 1802 |
ret = udf_process_sequence(sb, main_s, main_e, fileset); if (ret != -EAGAIN) return ret; |
bff943af6 udf: Fix memory l... |
1803 |
udf_sb_free_partitions(sb); |
d759bfa4e udf: Standardize ... |
1804 1805 1806 1807 1808 1809 1810 1811 |
ret = udf_process_sequence(sb, reserve_s, reserve_e, fileset); if (ret < 0) { udf_sb_free_partitions(sb); /* No sequence was OK, return -EIO */ if (ret == -EAGAIN) ret = -EIO; } return ret; |
1da177e4c Linux-2.6.12-rc2 |
1812 |
} |
403460051 udf: Try anchor i... |
1813 1814 1815 |
/* * Check whether there is an anchor block in the given block and * load Volume Descriptor Sequence if so. |
d759bfa4e udf: Standardize ... |
1816 1817 1818 |
* * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor * block |
403460051 udf: Try anchor i... |
1819 1820 1821 |
*/ static int udf_check_anchor_block(struct super_block *sb, sector_t block, struct kernel_lb_addr *fileset) |
1197e4dfc udf: use hardware... |
1822 |
{ |
403460051 udf: Try anchor i... |
1823 1824 1825 |
struct buffer_head *bh; uint16_t ident; int ret; |
1197e4dfc udf: use hardware... |
1826 |
|
403460051 udf: Try anchor i... |
1827 1828 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && udf_fixed_to_variable(block) >= |
23bcda112 udf: atomically r... |
1829 |
i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits) |
d759bfa4e udf: Standardize ... |
1830 |
return -EAGAIN; |
403460051 udf: Try anchor i... |
1831 1832 1833 |
bh = udf_read_tagged(sb, block, block, &ident); if (!bh) |
d759bfa4e udf: Standardize ... |
1834 |
return -EAGAIN; |
403460051 udf: Try anchor i... |
1835 1836 |
if (ident != TAG_IDENT_AVDP) { brelse(bh); |
d759bfa4e udf: Standardize ... |
1837 |
return -EAGAIN; |
1197e4dfc udf: use hardware... |
1838 |
} |
403460051 udf: Try anchor i... |
1839 1840 1841 |
ret = udf_load_sequence(sb, bh, fileset); brelse(bh); return ret; |
1197e4dfc udf: use hardware... |
1842 |
} |
d759bfa4e udf: Standardize ... |
1843 1844 1845 1846 1847 1848 1849 1850 |
/* * Search for an anchor volume descriptor pointer. * * Returns < 0 on error, 0 on success. -EAGAIN is special - try next set * of anchors. */ static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock, struct kernel_lb_addr *fileset) |
1da177e4c Linux-2.6.12-rc2 |
1851 |
{ |
403460051 udf: Try anchor i... |
1852 |
sector_t last[6]; |
38b74a53e udf: Move process... |
1853 |
int i; |
403460051 udf: Try anchor i... |
1854 1855 |
struct udf_sb_info *sbi = UDF_SB(sb); int last_count = 0; |
d759bfa4e udf: Standardize ... |
1856 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
1857 |
|
403460051 udf: Try anchor i... |
1858 1859 |
/* First try user provided anchor */ if (sbi->s_anchor) { |
d759bfa4e udf: Standardize ... |
1860 1861 1862 |
ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset); if (ret != -EAGAIN) return ret; |
403460051 udf: Try anchor i... |
1863 1864 1865 1866 1867 1868 1869 1870 |
} /* * according to spec, anchor is in either: * block 256 * lastblock-256 * lastblock * however, if the disc isn't closed, it could be 512. */ |
d759bfa4e udf: Standardize ... |
1871 1872 1873 |
ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset); if (ret != -EAGAIN) return ret; |
403460051 udf: Try anchor i... |
1874 1875 1876 1877 |
/* * The trouble is which block is the last one. Drives often misreport * this so we try various possibilities. */ |
d759bfa4e udf: Standardize ... |
1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 |
last[last_count++] = *lastblock; if (*lastblock >= 1) last[last_count++] = *lastblock - 1; last[last_count++] = *lastblock + 1; if (*lastblock >= 2) last[last_count++] = *lastblock - 2; if (*lastblock >= 150) last[last_count++] = *lastblock - 150; if (*lastblock >= 152) last[last_count++] = *lastblock - 152; |
1da177e4c Linux-2.6.12-rc2 |
1888 |
|
403460051 udf: Try anchor i... |
1889 |
for (i = 0; i < last_count; i++) { |
23bcda112 udf: atomically r... |
1890 |
if (last[i] >= i_size_read(sb->s_bdev->bd_inode) >> |
403460051 udf: Try anchor i... |
1891 |
sb->s_blocksize_bits) |
28f7c4d41 udf: improve read... |
1892 |
continue; |
d759bfa4e udf: Standardize ... |
1893 1894 1895 1896 1897 1898 |
ret = udf_check_anchor_block(sb, last[i], fileset); if (ret != -EAGAIN) { if (!ret) *lastblock = last[i]; return ret; } |
403460051 udf: Try anchor i... |
1899 |
if (last[i] < 256) |
28f7c4d41 udf: improve read... |
1900 |
continue; |
d759bfa4e udf: Standardize ... |
1901 1902 1903 1904 1905 1906 |
ret = udf_check_anchor_block(sb, last[i] - 256, fileset); if (ret != -EAGAIN) { if (!ret) *lastblock = last[i]; return ret; } |
403460051 udf: Try anchor i... |
1907 |
} |
28f7c4d41 udf: improve read... |
1908 |
|
403460051 udf: Try anchor i... |
1909 |
/* Finally try block 512 in case media is open */ |
d759bfa4e udf: Standardize ... |
1910 |
return udf_check_anchor_block(sb, sbi->s_session + 512, fileset); |
403460051 udf: Try anchor i... |
1911 |
} |
28f7c4d41 udf: improve read... |
1912 |
|
403460051 udf: Try anchor i... |
1913 1914 1915 1916 1917 |
/* * Find an anchor volume descriptor and load Volume Descriptor Sequence from * area specified by it. The function expects sbi->s_lastblock to be the last * block on the media. * |
d759bfa4e udf: Standardize ... |
1918 1919 |
* Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor * was not found. |
403460051 udf: Try anchor i... |
1920 1921 1922 1923 |
*/ static int udf_find_anchor(struct super_block *sb, struct kernel_lb_addr *fileset) { |
403460051 udf: Try anchor i... |
1924 |
struct udf_sb_info *sbi = UDF_SB(sb); |
d759bfa4e udf: Standardize ... |
1925 1926 |
sector_t lastblock = sbi->s_last_block; int ret; |
28f7c4d41 udf: improve read... |
1927 |
|
d759bfa4e udf: Standardize ... |
1928 1929 |
ret = udf_scan_anchors(sb, &lastblock, fileset); if (ret != -EAGAIN) |
403460051 udf: Try anchor i... |
1930 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1931 |
|
403460051 udf: Try anchor i... |
1932 1933 |
/* No anchor found? Try VARCONV conversion of block numbers */ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); |
d759bfa4e udf: Standardize ... |
1934 |
lastblock = udf_variable_to_fixed(sbi->s_last_block); |
403460051 udf: Try anchor i... |
1935 |
/* Firstly, we try to not convert number of the last block */ |
d759bfa4e udf: Standardize ... |
1936 1937 |
ret = udf_scan_anchors(sb, &lastblock, fileset); if (ret != -EAGAIN) |
403460051 udf: Try anchor i... |
1938 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1939 |
|
d759bfa4e udf: Standardize ... |
1940 |
lastblock = sbi->s_last_block; |
403460051 udf: Try anchor i... |
1941 |
/* Secondly, we try with converted number of the last block */ |
d759bfa4e udf: Standardize ... |
1942 1943 |
ret = udf_scan_anchors(sb, &lastblock, fileset); if (ret < 0) { |
403460051 udf: Try anchor i... |
1944 1945 |
/* VARCONV didn't help. Clear it. */ UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); |
1da177e4c Linux-2.6.12-rc2 |
1946 |
} |
403460051 udf: Try anchor i... |
1947 |
out: |
d759bfa4e udf: Standardize ... |
1948 1949 1950 |
if (ret == 0) sbi->s_last_block = lastblock; return ret; |
403460051 udf: Try anchor i... |
1951 |
} |
1da177e4c Linux-2.6.12-rc2 |
1952 |
|
403460051 udf: Try anchor i... |
1953 1954 |
/* * Check Volume Structure Descriptor, find Anchor block and load Volume |
d759bfa4e udf: Standardize ... |
1955 1956 1957 1958 |
* Descriptor Sequence. * * Returns < 0 on error, 0 on success. -EAGAIN is special meaning anchor * block was not found. |
403460051 udf: Try anchor i... |
1959 1960 1961 1962 1963 |
*/ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, int silent, struct kernel_lb_addr *fileset) { struct udf_sb_info *sbi = UDF_SB(sb); |
ba54aef03 udf: refactor VRS... |
1964 |
int nsr = 0; |
d759bfa4e udf: Standardize ... |
1965 |
int ret; |
403460051 udf: Try anchor i... |
1966 1967 1968 |
if (!sb_set_blocksize(sb, uopt->blocksize)) { if (!silent) |
78ace70c4 udf: Convert prin... |
1969 1970 |
udf_warn(sb, "Bad block size "); |
d759bfa4e udf: Standardize ... |
1971 |
return -EINVAL; |
403460051 udf: Try anchor i... |
1972 1973 1974 1975 |
} sbi->s_last_block = uopt->lastblock; if (!uopt->novrs) { /* Check that it is NSR02 compliant */ |
ba54aef03 udf: refactor VRS... |
1976 1977 |
nsr = udf_check_vsd(sb); if (!nsr) { |
403460051 udf: Try anchor i... |
1978 |
if (!silent) |
78ace70c4 udf: Convert prin... |
1979 1980 |
udf_warn(sb, "No VRS found "); |
70f16cef0 udf: allow implic... |
1981 |
return -EINVAL; |
403460051 udf: Try anchor i... |
1982 |
} |
ba54aef03 udf: refactor VRS... |
1983 |
if (nsr == -1) |
444996027 udf: fix for path... |
1984 1985 1986 1987 |
udf_debug("Failed to read sector at offset %d. " "Assuming open disc. Skipping validity " "check ", VSD_FIRST_SECTOR_OFFSET); |
403460051 udf: Try anchor i... |
1988 1989 1990 1991 1992 |
if (!sbi->s_last_block) sbi->s_last_block = udf_get_last_block(sb); } else { udf_debug("Validity check skipped because of novrs option "); |
28f7c4d41 udf: improve read... |
1993 |
} |
1da177e4c Linux-2.6.12-rc2 |
1994 |
|
403460051 udf: Try anchor i... |
1995 1996 |
/* Look for anchor block and load Volume Descriptor Sequence */ sbi->s_anchor = uopt->anchor; |
d759bfa4e udf: Standardize ... |
1997 1998 1999 |
ret = udf_find_anchor(sb, fileset); if (ret < 0) { if (!silent && ret == -EAGAIN) |
78ace70c4 udf: Convert prin... |
2000 2001 |
udf_warn(sb, "No anchor found "); |
d759bfa4e udf: Standardize ... |
2002 |
return ret; |
403460051 udf: Try anchor i... |
2003 |
} |
d759bfa4e udf: Standardize ... |
2004 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
2005 |
} |
ebbd5e99f udf: factor out L... |
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 |
static void udf_finalize_lvid(struct logicalVolIntegrityDesc *lvid) { struct timespec64 ts; ktime_get_real_ts64(&ts); udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); lvid->descTag.descCRC = cpu_to_le16( crc_itu_t(0, (char *)lvid + sizeof(struct tag), le16_to_cpu(lvid->descTag.descCRCLength))); lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); } |
1da177e4c Linux-2.6.12-rc2 |
2017 2018 |
static void udf_open_lvid(struct super_block *sb) { |
6c79e987d udf: remove some ... |
2019 2020 |
struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = sbi->s_lvid_bh; |
165923fa4 udf: super.c reor... |
2021 2022 |
struct logicalVolIntegrityDesc *lvid; struct logicalVolIntegrityDescImpUse *lvidiu; |
146bca72c udf: Don't write ... |
2023 |
|
165923fa4 udf: super.c reor... |
2024 2025 |
if (!bh) return; |
165923fa4 udf: super.c reor... |
2026 |
lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
69d75671d udf: Fortify LVID... |
2027 2028 2029 |
lvidiu = udf_sb_lvidiu(sb); if (!lvidiu) return; |
165923fa4 udf: super.c reor... |
2030 |
|
69d75671d udf: Fortify LVID... |
2031 |
mutex_lock(&sbi->s_alloc_mutex); |
165923fa4 udf: super.c reor... |
2032 2033 |
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
b72e632c6 udf: Do not mark ... |
2034 2035 2036 2037 |
if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE) lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN); else UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT); |
165923fa4 udf: super.c reor... |
2038 |
|
ebbd5e99f udf: factor out L... |
2039 |
udf_finalize_lvid(lvid); |
165923fa4 udf: super.c reor... |
2040 |
mark_buffer_dirty(bh); |
146bca72c udf: Don't write ... |
2041 |
sbi->s_lvid_dirty = 0; |
949f4a7c0 udf: Protect all ... |
2042 |
mutex_unlock(&sbi->s_alloc_mutex); |
9734c971a udf: Write LVID t... |
2043 2044 |
/* Make opening of filesystem visible on the media immediately */ sync_dirty_buffer(bh); |
1da177e4c Linux-2.6.12-rc2 |
2045 2046 2047 2048 |
} static void udf_close_lvid(struct super_block *sb) { |
6c79e987d udf: remove some ... |
2049 2050 2051 |
struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = sbi->s_lvid_bh; struct logicalVolIntegrityDesc *lvid; |
165923fa4 udf: super.c reor... |
2052 |
struct logicalVolIntegrityDescImpUse *lvidiu; |
28de7948a UDF: coding style... |
2053 |
|
6c79e987d udf: remove some ... |
2054 2055 |
if (!bh) return; |
69d75671d udf: Fortify LVID... |
2056 2057 2058 2059 |
lvid = (struct logicalVolIntegrityDesc *)bh->b_data; lvidiu = udf_sb_lvidiu(sb); if (!lvidiu) return; |
6c79e987d udf: remove some ... |
2060 |
|
949f4a7c0 udf: Protect all ... |
2061 |
mutex_lock(&sbi->s_alloc_mutex); |
165923fa4 udf: super.c reor... |
2062 2063 |
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
165923fa4 udf: super.c reor... |
2064 2065 2066 2067 2068 2069 |
if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) lvidiu->minUDFReadRev = cpu_to_le16(sbi->s_udfrev); if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFWriteRev)) lvidiu->minUDFWriteRev = cpu_to_le16(sbi->s_udfrev); |
b72e632c6 udf: Do not mark ... |
2070 2071 |
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT)) lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
165923fa4 udf: super.c reor... |
2072 |
|
853a0c25b udf: Mark LVID bu... |
2073 2074 2075 2076 2077 2078 |
/* * We set buffer uptodate unconditionally here to avoid spurious * warnings from mark_buffer_dirty() when previous EIO has marked * the buffer as !uptodate */ set_buffer_uptodate(bh); |
ebbd5e99f udf: factor out L... |
2079 |
udf_finalize_lvid(lvid); |
165923fa4 udf: super.c reor... |
2080 |
mark_buffer_dirty(bh); |
146bca72c udf: Don't write ... |
2081 |
sbi->s_lvid_dirty = 0; |
949f4a7c0 udf: Protect all ... |
2082 |
mutex_unlock(&sbi->s_alloc_mutex); |
9734c971a udf: Write LVID t... |
2083 2084 |
/* Make closing of filesystem visible on the media immediately */ sync_dirty_buffer(bh); |
1da177e4c Linux-2.6.12-rc2 |
2085 |
} |
d664b6af6 udf: Move handlin... |
2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 |
u64 lvid_get_unique_id(struct super_block *sb) { struct buffer_head *bh; struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDesc *lvid; struct logicalVolHeaderDesc *lvhd; u64 uniqueID; u64 ret; bh = sbi->s_lvid_bh; if (!bh) return 0; lvid = (struct logicalVolIntegrityDesc *)bh->b_data; lvhd = (struct logicalVolHeaderDesc *)lvid->logicalVolContentsUse; mutex_lock(&sbi->s_alloc_mutex); ret = uniqueID = le64_to_cpu(lvhd->uniqueID); if (!(++uniqueID & 0xFFFFFFFF)) uniqueID += 16; lvhd->uniqueID = cpu_to_le64(uniqueID); |
e8b427473 udf: finalize int... |
2107 |
udf_updated_lvid(sb); |
d664b6af6 udf: Move handlin... |
2108 |
mutex_unlock(&sbi->s_alloc_mutex); |
d664b6af6 udf: Move handlin... |
2109 2110 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2111 |
} |
1da177e4c Linux-2.6.12-rc2 |
2112 2113 |
static int udf_fill_super(struct super_block *sb, void *options, int silent) { |
d759bfa4e udf: Standardize ... |
2114 |
int ret = -EINVAL; |
cb00ea352 UDF: coding style... |
2115 |
struct inode *inode = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2116 |
struct udf_options uopt; |
5ca4e4be8 Remove struct typ... |
2117 |
struct kernel_lb_addr rootdir, fileset; |
1da177e4c Linux-2.6.12-rc2 |
2118 |
struct udf_sb_info *sbi; |
9181f8bf5 udf: Don't modify... |
2119 |
bool lvid_open = false; |
1da177e4c Linux-2.6.12-rc2 |
2120 2121 |
uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); |
116e5258e udf: Provide sane... |
2122 2123 2124 |
/* By default we'll use overflow[ug]id when UDF inode [ug]id == -1 */ uopt.uid = make_kuid(current_user_ns(), overflowuid); uopt.gid = make_kgid(current_user_ns(), overflowgid); |
1da177e4c Linux-2.6.12-rc2 |
2125 |
uopt.umask = 0; |
87bc730c0 udf: fix default ... |
2126 2127 |
uopt.fmode = UDF_INVALID_MODE; uopt.dmode = UDF_INVALID_MODE; |
785dffe1d udf: fix potentia... |
2128 |
uopt.nls_map = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2129 |
|
033c9da00 fs-udf: Improve s... |
2130 |
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
9db9f9e31 udf: Remove unnec... |
2131 |
if (!sbi) |
1da177e4c Linux-2.6.12-rc2 |
2132 |
return -ENOMEM; |
28de7948a UDF: coding style... |
2133 |
|
1da177e4c Linux-2.6.12-rc2 |
2134 |
sb->s_fs_info = sbi; |
1da177e4c Linux-2.6.12-rc2 |
2135 |
|
1e7933def [PATCH] sem2mutex... |
2136 |
mutex_init(&sbi->s_alloc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2137 |
|
6da80894c mount options: fi... |
2138 |
if (!udf_parse_options((char *)options, &uopt, false)) |
fdf2657bc udf: One function... |
2139 |
goto parse_options_failure; |
1da177e4c Linux-2.6.12-rc2 |
2140 2141 |
if (uopt.flags & (1 << UDF_FLAG_UTF8) && |
cb00ea352 UDF: coding style... |
2142 |
uopt.flags & (1 << UDF_FLAG_NLS_MAP)) { |
8076c363d udf: Rename udf_e... |
2143 2144 |
udf_err(sb, "utf8 cannot be combined with iocharset "); |
fdf2657bc udf: One function... |
2145 |
goto parse_options_failure; |
1da177e4c Linux-2.6.12-rc2 |
2146 |
} |
cb00ea352 UDF: coding style... |
2147 |
if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) { |
1da177e4c Linux-2.6.12-rc2 |
2148 2149 2150 2151 2152 2153 2154 |
uopt.nls_map = load_nls_default(); if (!uopt.nls_map) uopt.flags &= ~(1 << UDF_FLAG_NLS_MAP); else udf_debug("Using default NLS map "); } |
1da177e4c Linux-2.6.12-rc2 |
2155 2156 2157 2158 2159 |
if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP))) uopt.flags |= (1 << UDF_FLAG_UTF8); fileset.logicalBlockNum = 0xFFFFFFFF; fileset.partitionReferenceNum = 0xFFFF; |
6c79e987d udf: remove some ... |
2160 2161 2162 2163 |
sbi->s_flags = uopt.flags; sbi->s_uid = uopt.uid; sbi->s_gid = uopt.gid; sbi->s_umask = uopt.umask; |
7ac9bcd5d udf: implement mo... |
2164 2165 |
sbi->s_fmode = uopt.fmode; sbi->s_dmode = uopt.dmode; |
6c79e987d udf: remove some ... |
2166 |
sbi->s_nls_map = uopt.nls_map; |
c03cad241 udf: Protect defa... |
2167 |
rwlock_init(&sbi->s_cred_lock); |
1da177e4c Linux-2.6.12-rc2 |
2168 |
|
cb00ea352 UDF: coding style... |
2169 |
if (uopt.session == 0xFFFFFFFF) |
6c79e987d udf: remove some ... |
2170 |
sbi->s_session = udf_get_last_session(sb); |
1da177e4c Linux-2.6.12-rc2 |
2171 |
else |
6c79e987d udf: remove some ... |
2172 |
sbi->s_session = uopt.session; |
1da177e4c Linux-2.6.12-rc2 |
2173 |
|
6c79e987d udf: remove some ... |
2174 2175 |
udf_debug("Multi-session=%d ", sbi->s_session); |
1da177e4c Linux-2.6.12-rc2 |
2176 |
|
403460051 udf: Try anchor i... |
2177 2178 2179 |
/* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; sb->s_export_op = &udf_export_ops; |
123e9caf1 quota: explicitly... |
2180 |
|
403460051 udf: Try anchor i... |
2181 2182 |
sb->s_magic = UDF_SUPER_MAGIC; sb->s_time_gran = 1000; |
1197e4dfc udf: use hardware... |
2183 |
if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { |
403460051 udf: Try anchor i... |
2184 |
ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
1197e4dfc udf: use hardware... |
2185 |
} else { |
e1defc4ff block: Do away wi... |
2186 |
uopt.blocksize = bdev_logical_block_size(sb->s_bdev); |
70f16cef0 udf: allow implic... |
2187 |
while (uopt.blocksize <= 4096) { |
403460051 udf: Try anchor i... |
2188 |
ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
70f16cef0 udf: allow implic... |
2189 2190 |
if (ret < 0) { if (!silent && ret != -EACCES) { |
fcbf7637e udf: Fix signed/u... |
2191 2192 |
pr_notice("Scanning with blocksize %u failed ", |
70f16cef0 udf: allow implic... |
2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 |
uopt.blocksize); } brelse(sbi->s_lvid_bh); sbi->s_lvid_bh = NULL; /* * EACCES is special - we want to propagate to * upper layers that we cannot handle RW mount. */ if (ret == -EACCES) break; } else break; uopt.blocksize <<= 1; |
1197e4dfc udf: use hardware... |
2207 |
} |
1da177e4c Linux-2.6.12-rc2 |
2208 |
} |
d759bfa4e udf: Standardize ... |
2209 2210 2211 2212 2213 2214 |
if (ret < 0) { if (ret == -EAGAIN) { udf_warn(sb, "No partition found (1) "); ret = -EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
2215 2216 |
goto error_out; } |
fcbf7637e udf: Fix signed/u... |
2217 2218 |
udf_debug("Lastblock=%u ", sbi->s_last_block); |
1da177e4c Linux-2.6.12-rc2 |
2219 |
|
6c79e987d udf: remove some ... |
2220 |
if (sbi->s_lvid_bh) { |
4b11111ab udf: fix coding s... |
2221 |
struct logicalVolIntegrityDescImpUse *lvidiu = |
69d75671d udf: Fortify LVID... |
2222 2223 2224 |
udf_sb_lvidiu(sb); uint16_t minUDFReadRev; uint16_t minUDFWriteRev; |
1da177e4c Linux-2.6.12-rc2 |
2225 |
|
69d75671d udf: Fortify LVID... |
2226 2227 2228 2229 2230 2231 |
if (!lvidiu) { ret = -EINVAL; goto error_out; } minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); |
cb00ea352 UDF: coding style... |
2232 |
if (minUDFReadRev > UDF_MAX_READ_VERSION) { |
78ace70c4 udf: Convert prin... |
2233 2234 |
udf_err(sb, "minUDFReadRev=%x (max is %x) ", |
69d75671d udf: Fortify LVID... |
2235 |
minUDFReadRev, |
78ace70c4 udf: Convert prin... |
2236 |
UDF_MAX_READ_VERSION); |
d759bfa4e udf: Standardize ... |
2237 |
ret = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
2238 |
goto error_out; |
a9ad01bc7 udf: Prevent writ... |
2239 2240 2241 2242 2243 2244 |
} else if (minUDFWriteRev > UDF_MAX_WRITE_VERSION) { if (!sb_rdonly(sb)) { ret = -EACCES; goto error_out; } UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
e729eac6f udf: Refuse RW mo... |
2245 |
} |
1da177e4c Linux-2.6.12-rc2 |
2246 |
|
6c79e987d udf: remove some ... |
2247 |
sbi->s_udfrev = minUDFWriteRev; |
1da177e4c Linux-2.6.12-rc2 |
2248 2249 2250 2251 2252 2253 |
if (minUDFReadRev >= UDF_VERS_USE_EXTENDED_FE) UDF_SET_FLAG(sb, UDF_FLAG_USE_EXTENDED_FE); if (minUDFReadRev >= UDF_VERS_USE_STREAMS) UDF_SET_FLAG(sb, UDF_FLAG_USE_STREAMS); } |
6c79e987d udf: remove some ... |
2254 |
if (!sbi->s_partitions) { |
78ace70c4 udf: Convert prin... |
2255 2256 |
udf_warn(sb, "No partition found (2) "); |
d759bfa4e udf: Standardize ... |
2257 |
ret = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
2258 2259 |
goto error_out; } |
4b11111ab udf: fix coding s... |
2260 |
if (sbi->s_partmaps[sbi->s_partition].s_partition_flags & |
a9ad01bc7 udf: Prevent writ... |
2261 2262 2263 2264 2265 2266 |
UDF_PART_FLAG_READ_ONLY) { if (!sb_rdonly(sb)) { ret = -EACCES; goto error_out; } UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
c1a26e7d4 [PATCH] UDF: Fix ... |
2267 |
} |
39b3f6d6e [PATCH] mount udf... |
2268 |
|
2dee5aac0 udf: Verify domai... |
2269 2270 |
ret = udf_find_fileset(sb, &fileset, &rootdir); if (ret < 0) { |
78ace70c4 udf: Convert prin... |
2271 2272 |
udf_warn(sb, "No fileset found "); |
1da177e4c Linux-2.6.12-rc2 |
2273 2274 |
goto error_out; } |
cb00ea352 UDF: coding style... |
2275 |
if (!silent) { |
5ca4e4be8 Remove struct typ... |
2276 |
struct timestamp ts; |
56774805d udf: convert udf_... |
2277 |
udf_time_to_disk_stamp(&ts, sbi->s_record_time); |
78ace70c4 udf: Convert prin... |
2278 2279 2280 2281 |
udf_info("Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x) ", sbi->s_volume_ident, le16_to_cpu(ts.year), ts.month, ts.day, |
56774805d udf: convert udf_... |
2282 |
ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone)); |
1da177e4c Linux-2.6.12-rc2 |
2283 |
} |
bc98a42c1 VFS: Convert sb->... |
2284 |
if (!sb_rdonly(sb)) { |
1da177e4c Linux-2.6.12-rc2 |
2285 |
udf_open_lvid(sb); |
9181f8bf5 udf: Don't modify... |
2286 2287 |
lvid_open = true; } |
1da177e4c Linux-2.6.12-rc2 |
2288 2289 2290 2291 |
/* Assign the root inode */ /* assign inodes by physical block number */ /* perhaps it's not extensible enough, but for now ... */ |
97e961fdb Fix the udf code ... |
2292 |
inode = udf_iget(sb, &rootdir); |
6d3d5e860 udf: Make udf_rea... |
2293 |
if (IS_ERR(inode)) { |
fcbf7637e udf: Fix signed/u... |
2294 2295 |
udf_err(sb, "Error in udf_iget, block=%u, partition=%u ", |
cb00ea352 UDF: coding style... |
2296 |
rootdir.logicalBlockNum, rootdir.partitionReferenceNum); |
6d3d5e860 udf: Make udf_rea... |
2297 |
ret = PTR_ERR(inode); |
1da177e4c Linux-2.6.12-rc2 |
2298 2299 2300 2301 |
goto error_out; } /* Allocate a dentry for the root inode */ |
48fde701a switch open-coded... |
2302 |
sb->s_root = d_make_root(inode); |
cb00ea352 UDF: coding style... |
2303 |
if (!sb->s_root) { |
78ace70c4 udf: Convert prin... |
2304 2305 |
udf_err(sb, "Couldn't allocate root dentry "); |
d759bfa4e udf: Standardize ... |
2306 |
ret = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
2307 2308 |
goto error_out; } |
31170b6ad udf: support file... |
2309 |
sb->s_maxbytes = MAX_LFS_FILESIZE; |
8de527787 vfs: check i_nlin... |
2310 |
sb->s_max_links = UDF_MAX_LINKS; |
1da177e4c Linux-2.6.12-rc2 |
2311 |
return 0; |
28de7948a UDF: coding style... |
2312 |
error_out: |
0d454e4a4 udf: Deletion of ... |
2313 |
iput(sbi->s_vat_inode); |
fdf2657bc udf: One function... |
2314 |
parse_options_failure: |
785dffe1d udf: fix potentia... |
2315 2316 |
if (uopt.nls_map) unload_nls(uopt.nls_map); |
9181f8bf5 udf: Don't modify... |
2317 |
if (lvid_open) |
1da177e4c Linux-2.6.12-rc2 |
2318 |
udf_close_lvid(sb); |
6c79e987d udf: remove some ... |
2319 |
brelse(sbi->s_lvid_bh); |
bff943af6 udf: Fix memory l... |
2320 |
udf_sb_free_partitions(sb); |
1da177e4c Linux-2.6.12-rc2 |
2321 2322 |
kfree(sbi); sb->s_fs_info = NULL; |
28de7948a UDF: coding style... |
2323 |
|
d759bfa4e udf: Standardize ... |
2324 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2325 |
} |
8076c363d udf: Rename udf_e... |
2326 2327 |
void _udf_err(struct super_block *sb, const char *function, const char *fmt, ...) |
1da177e4c Linux-2.6.12-rc2 |
2328 |
{ |
c2bff36c2 udf: Neaten loggi... |
2329 |
struct va_format vaf; |
1da177e4c Linux-2.6.12-rc2 |
2330 |
va_list args; |
1da177e4c Linux-2.6.12-rc2 |
2331 |
va_start(args, fmt); |
c2bff36c2 udf: Neaten loggi... |
2332 2333 2334 2335 2336 |
vaf.fmt = fmt; vaf.va = &args; pr_err("error (device %s): %s: %pV", sb->s_id, function, &vaf); |
1da177e4c Linux-2.6.12-rc2 |
2337 |
va_end(args); |
1da177e4c Linux-2.6.12-rc2 |
2338 |
} |
a40ecd7b3 udf: Rename udf_w... |
2339 2340 |
void _udf_warn(struct super_block *sb, const char *function, const char *fmt, ...) |
1da177e4c Linux-2.6.12-rc2 |
2341 |
{ |
c2bff36c2 udf: Neaten loggi... |
2342 |
struct va_format vaf; |
1da177e4c Linux-2.6.12-rc2 |
2343 |
va_list args; |
cb00ea352 UDF: coding style... |
2344 |
va_start(args, fmt); |
c2bff36c2 udf: Neaten loggi... |
2345 2346 2347 2348 2349 |
vaf.fmt = fmt; vaf.va = &args; pr_warn("warning (device %s): %s: %pV", sb->s_id, function, &vaf); |
1da177e4c Linux-2.6.12-rc2 |
2350 |
va_end(args); |
1da177e4c Linux-2.6.12-rc2 |
2351 |
} |
cb00ea352 UDF: coding style... |
2352 |
static void udf_put_super(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
2353 |
{ |
6c79e987d udf: remove some ... |
2354 |
struct udf_sb_info *sbi; |
1da177e4c Linux-2.6.12-rc2 |
2355 |
|
6c79e987d udf: remove some ... |
2356 |
sbi = UDF_SB(sb); |
6cfd01484 push BKL down int... |
2357 |
|
0d454e4a4 udf: Deletion of ... |
2358 |
iput(sbi->s_vat_inode); |
1da177e4c Linux-2.6.12-rc2 |
2359 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
6c79e987d udf: remove some ... |
2360 |
unload_nls(sbi->s_nls_map); |
bc98a42c1 VFS: Convert sb->... |
2361 |
if (!sb_rdonly(sb)) |
1da177e4c Linux-2.6.12-rc2 |
2362 |
udf_close_lvid(sb); |
6c79e987d udf: remove some ... |
2363 |
brelse(sbi->s_lvid_bh); |
bff943af6 udf: Fix memory l... |
2364 |
udf_sb_free_partitions(sb); |
bbe48dd81 udf: destroy sbi ... |
2365 |
mutex_destroy(&sbi->s_alloc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2366 2367 2368 |
kfree(sb->s_fs_info); sb->s_fs_info = NULL; } |
146bca72c udf: Don't write ... |
2369 2370 2371 2372 2373 2374 |
static int udf_sync_fs(struct super_block *sb, int wait) { struct udf_sb_info *sbi = UDF_SB(sb); mutex_lock(&sbi->s_alloc_mutex); if (sbi->s_lvid_dirty) { |
e8b427473 udf: finalize int... |
2375 |
struct buffer_head *bh = sbi->s_lvid_bh; |
52b9666ef udf: Drop pointle... |
2376 |
struct logicalVolIntegrityDesc *lvid; |
e8b427473 udf: finalize int... |
2377 |
|
52b9666ef udf: Drop pointle... |
2378 2379 |
lvid = (struct logicalVolIntegrityDesc *)bh->b_data; udf_finalize_lvid(lvid); |
e8b427473 udf: finalize int... |
2380 |
|
146bca72c udf: Don't write ... |
2381 2382 2383 2384 |
/* * Blockdevice will be synced later so we don't have to submit * the buffer for IO */ |
e8b427473 udf: finalize int... |
2385 |
mark_buffer_dirty(bh); |
146bca72c udf: Don't write ... |
2386 2387 2388 2389 2390 2391 |
sbi->s_lvid_dirty = 0; } mutex_unlock(&sbi->s_alloc_mutex); return 0; } |
cb00ea352 UDF: coding style... |
2392 |
static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) |
1da177e4c Linux-2.6.12-rc2 |
2393 |
{ |
726c33422 [PATCH] VFS: Perm... |
2394 |
struct super_block *sb = dentry->d_sb; |
6c79e987d udf: remove some ... |
2395 2396 |
struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDescImpUse *lvidiu; |
557f5a146 udf: return f_fsi... |
2397 |
u64 id = huge_encode_dev(sb->s_bdev->bd_dev); |
6c79e987d udf: remove some ... |
2398 |
|
69d75671d udf: Fortify LVID... |
2399 |
lvidiu = udf_sb_lvidiu(sb); |
1da177e4c Linux-2.6.12-rc2 |
2400 2401 |
buf->f_type = UDF_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; |
6c79e987d udf: remove some ... |
2402 |
buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; |
1da177e4c Linux-2.6.12-rc2 |
2403 2404 |
buf->f_bfree = udf_count_free(sb); buf->f_bavail = buf->f_bfree; |
356557be8 udf: Clarify mean... |
2405 2406 2407 2408 |
/* * Let's pretend each free block is also a free 'inode' since UDF does * not have separate preallocated table of inodes. */ |
6c79e987d udf: remove some ... |
2409 2410 2411 |
buf->f_files = (lvidiu != NULL ? (le32_to_cpu(lvidiu->numFiles) + le32_to_cpu(lvidiu->numDirs)) : 0) + buf->f_bfree; |
1da177e4c Linux-2.6.12-rc2 |
2412 |
buf->f_ffree = buf->f_bfree; |
9fba70569 udf: Adjust UDF_N... |
2413 |
buf->f_namelen = UDF_NAME_LEN; |
6d1349c76 [PATCH] reduce bo... |
2414 |
buf->f_fsid = u64_to_fsid(id); |
1da177e4c Linux-2.6.12-rc2 |
2415 2416 2417 |
return 0; } |
4b11111ab udf: fix coding s... |
2418 2419 |
static unsigned int udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) |
1da177e4c Linux-2.6.12-rc2 |
2420 2421 2422 2423 |
{ struct buffer_head *bh = NULL; unsigned int accum = 0; int index; |
b490bdd63 udf: Fix 64-bit s... |
2424 |
udf_pblk_t block = 0, newblock; |
5ca4e4be8 Remove struct typ... |
2425 |
struct kernel_lb_addr loc; |
1da177e4c Linux-2.6.12-rc2 |
2426 |
uint32_t bytes; |
1da177e4c Linux-2.6.12-rc2 |
2427 2428 2429 |
uint8_t *ptr; uint16_t ident; struct spaceBitmapDesc *bm; |
1da177e4c Linux-2.6.12-rc2 |
2430 |
loc.logicalBlockNum = bitmap->s_extPosition; |
6c79e987d udf: remove some ... |
2431 |
loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
97e961fdb Fix the udf code ... |
2432 |
bh = udf_read_ptagged(sb, &loc, 0, &ident); |
1da177e4c Linux-2.6.12-rc2 |
2433 |
|
cb00ea352 UDF: coding style... |
2434 |
if (!bh) { |
78ace70c4 udf: Convert prin... |
2435 2436 |
udf_err(sb, "udf_count_free failed "); |
1da177e4c Linux-2.6.12-rc2 |
2437 |
goto out; |
cb00ea352 UDF: coding style... |
2438 |
} else if (ident != TAG_IDENT_SBD) { |
3bf25cb40 udf: use get_bh() |
2439 |
brelse(bh); |
78ace70c4 udf: Convert prin... |
2440 2441 |
udf_err(sb, "udf_count_free failed "); |
1da177e4c Linux-2.6.12-rc2 |
2442 2443 2444 2445 2446 |
goto out; } bm = (struct spaceBitmapDesc *)bh->b_data; bytes = le32_to_cpu(bm->numOfBytes); |
28de7948a UDF: coding style... |
2447 2448 |
index = sizeof(struct spaceBitmapDesc); /* offset in first block only */ ptr = (uint8_t *)bh->b_data; |
1da177e4c Linux-2.6.12-rc2 |
2449 |
|
cb00ea352 UDF: coding style... |
2450 |
while (bytes > 0) { |
01b954a36 udf: convert udf_... |
2451 2452 2453 2454 |
u32 cur_bytes = min_t(u32, bytes, sb->s_blocksize - index); accum += bitmap_weight((const unsigned long *)(ptr + index), cur_bytes * 8); bytes -= cur_bytes; |
cb00ea352 UDF: coding style... |
2455 |
if (bytes) { |
3bf25cb40 udf: use get_bh() |
2456 |
brelse(bh); |
97e961fdb Fix the udf code ... |
2457 |
newblock = udf_get_lb_pblock(sb, &loc, ++block); |
1da177e4c Linux-2.6.12-rc2 |
2458 |
bh = udf_tread(sb, newblock); |
cb00ea352 UDF: coding style... |
2459 |
if (!bh) { |
1da177e4c Linux-2.6.12-rc2 |
2460 2461 2462 2463 2464 |
udf_debug("read failed "); goto out; } index = 0; |
28de7948a UDF: coding style... |
2465 |
ptr = (uint8_t *)bh->b_data; |
1da177e4c Linux-2.6.12-rc2 |
2466 2467 |
} } |
3bf25cb40 udf: use get_bh() |
2468 |
brelse(bh); |
28de7948a UDF: coding style... |
2469 |
out: |
1da177e4c Linux-2.6.12-rc2 |
2470 2471 |
return accum; } |
4b11111ab udf: fix coding s... |
2472 2473 |
static unsigned int udf_count_free_table(struct super_block *sb, struct inode *table) |
1da177e4c Linux-2.6.12-rc2 |
2474 2475 |
{ unsigned int accum = 0; |
ff116fc8d UDF: introduce st... |
2476 |
uint32_t elen; |
5ca4e4be8 Remove struct typ... |
2477 |
struct kernel_lb_addr eloc; |
1da177e4c Linux-2.6.12-rc2 |
2478 |
int8_t etype; |
ff116fc8d UDF: introduce st... |
2479 |
struct extent_position epos; |
1da177e4c Linux-2.6.12-rc2 |
2480 |
|
d1668fe39 udf: Remove BKL f... |
2481 |
mutex_lock(&UDF_SB(sb)->s_alloc_mutex); |
c0b344385 udf: remove UDF_I... |
2482 |
epos.block = UDF_I(table)->i_location; |
ff116fc8d UDF: introduce st... |
2483 2484 |
epos.offset = sizeof(struct unallocSpaceEntry); epos.bh = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2485 |
|
3a71fc5de udf: fix coding s... |
2486 |
while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
1da177e4c Linux-2.6.12-rc2 |
2487 |
accum += (elen >> table->i_sb->s_blocksize_bits); |
3a71fc5de udf: fix coding s... |
2488 |
|
3bf25cb40 udf: use get_bh() |
2489 |
brelse(epos.bh); |
d1668fe39 udf: Remove BKL f... |
2490 |
mutex_unlock(&UDF_SB(sb)->s_alloc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2491 2492 2493 |
return accum; } |
cb00ea352 UDF: coding style... |
2494 2495 |
static unsigned int udf_count_free(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
2496 2497 |
{ unsigned int accum = 0; |
a4a8b99ec udf: Fix free spa... |
2498 |
struct udf_sb_info *sbi = UDF_SB(sb); |
6c79e987d udf: remove some ... |
2499 |
struct udf_part_map *map; |
a4a8b99ec udf: Fix free spa... |
2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 |
unsigned int part = sbi->s_partition; int ptype = sbi->s_partmaps[part].s_partition_type; if (ptype == UDF_METADATA_MAP25) { part = sbi->s_partmaps[part].s_type_specific.s_metadata. s_phys_partition_ref; } else if (ptype == UDF_VIRTUAL_MAP15 || ptype == UDF_VIRTUAL_MAP20) { /* * Filesystems with VAT are append-only and we cannot write to * them. Let's just report 0 here. */ return 0; } |
1da177e4c Linux-2.6.12-rc2 |
2513 |
|
6c79e987d udf: remove some ... |
2514 |
if (sbi->s_lvid_bh) { |
4b11111ab udf: fix coding s... |
2515 2516 2517 |
struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *) sbi->s_lvid_bh->b_data; |
a4a8b99ec udf: Fix free spa... |
2518 |
if (le32_to_cpu(lvid->numOfPartitions) > part) { |
4b11111ab udf: fix coding s... |
2519 |
accum = le32_to_cpu( |
a4a8b99ec udf: Fix free spa... |
2520 |
lvid->freeSpaceTable[part]); |
1da177e4c Linux-2.6.12-rc2 |
2521 2522 2523 2524 2525 2526 2527 |
if (accum == 0xFFFFFFFF) accum = 0; } } if (accum) return accum; |
a4a8b99ec udf: Fix free spa... |
2528 |
map = &sbi->s_partmaps[part]; |
6c79e987d udf: remove some ... |
2529 |
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { |
28de7948a UDF: coding style... |
2530 |
accum += udf_count_free_bitmap(sb, |
6c79e987d udf: remove some ... |
2531 |
map->s_uspace.s_bitmap); |
1da177e4c Linux-2.6.12-rc2 |
2532 |
} |
1da177e4c Linux-2.6.12-rc2 |
2533 2534 |
if (accum) return accum; |
6c79e987d udf: remove some ... |
2535 |
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { |
28de7948a UDF: coding style... |
2536 |
accum += udf_count_free_table(sb, |
6c79e987d udf: remove some ... |
2537 |
map->s_uspace.s_table); |
1da177e4c Linux-2.6.12-rc2 |
2538 |
} |
1da177e4c Linux-2.6.12-rc2 |
2539 2540 |
return accum; } |
54bb60d53 udf: merge module... |
2541 2542 2543 2544 2545 2546 |
MODULE_AUTHOR("Ben Fennema"); MODULE_DESCRIPTION("Universal Disk Format Filesystem"); MODULE_LICENSE("GPL"); module_init(init_udf_fs) module_exit(exit_udf_fs) |