Blame view
fs/udf/super.c
66.8 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* * 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/ * http://www.ecma.ch/ * http://www.iso.org/ * |
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 |
|
a35afb830 Remove SLAB_CTOR_... |
164 165 |
ei->i_ext.i_data = NULL; 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 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 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 |
static int udf_verify_domain_identifier(struct super_block *sb, struct regid *ident, char *dname) { struct domainEntityIDSuffix *suffix; if (memcmp(ident->ident, UDF_ID_COMPLIANT, strlen(UDF_ID_COMPLIANT))) { udf_warn(sb, "Not OSTA UDF compliant %s descriptor. ", dname); goto force_ro; } if (ident->flags & (1 << ENTITYID_FLAGS_DIRTY)) { udf_warn(sb, "Possibly not OSTA UDF compliant %s descriptor. ", dname); goto force_ro; } suffix = (struct domainEntityIDSuffix *)ident->identSuffix; if (suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_HARDWRITEPROTECT) || suffix->flags & (1 << ENTITYIDSUFFIX_FLAGS_SOFTWRITEPROTECT)) { 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; |
d759bfa4e udf: Standardize ... |
842 |
int ret = -ENOMEM; |
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 1001 1002 |
struct udf_bitmap *bitmap; int nr_groups; int size; |
883cb9d18 udf: move calcula... |
1003 |
nr_groups = udf_compute_nr_groups(sb, index); |
66e1da3f4 udf: convert macr... |
1004 1005 1006 1007 |
size = sizeof(struct udf_bitmap) + (sizeof(struct buffer_head *) * nr_groups); if (size <= PAGE_SIZE) |
ed2ae6f69 fs/udf: Use vzalloc |
1008 |
bitmap = kzalloc(size, GFP_KERNEL); |
66e1da3f4 udf: convert macr... |
1009 |
else |
ed2ae6f69 fs/udf: Use vzalloc |
1010 |
bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ |
66e1da3f4 udf: convert macr... |
1011 |
|
ba2eb866a fs-udf: Adjust tw... |
1012 |
if (!bitmap) |
66e1da3f4 udf: convert macr... |
1013 |
return NULL; |
66e1da3f4 udf: convert macr... |
1014 |
|
66e1da3f4 udf: convert macr... |
1015 1016 1017 |
bitmap->s_nr_groups = nr_groups; return bitmap; } |
b085fbe2e udf: Fix crash du... |
1018 1019 1020 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 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 |
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: case PD_ACCESS_TYPE_REWRITABLE: 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 || map->s_partition_type == UDF_VIRTUAL_MAP20) 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... |
1066 1067 |
static int udf_fill_partdesc_info(struct super_block *sb, struct partitionDesc *p, int p_index) |
1da177e4c Linux-2.6.12-rc2 |
1068 |
{ |
6c79e987d udf: remove some ... |
1069 |
struct udf_part_map *map; |
165923fa4 udf: super.c reor... |
1070 |
struct udf_sb_info *sbi = UDF_SB(sb); |
3fb38dfa0 udf: Move filling... |
1071 |
struct partitionHeaderDesc *phd; |
b085fbe2e udf: Fix crash du... |
1072 |
int err; |
165923fa4 udf: super.c reor... |
1073 |
|
3fb38dfa0 udf: Move filling... |
1074 |
map = &sbi->s_partmaps[p_index]; |
165923fa4 udf: super.c reor... |
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 |
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... |
1087 1088 |
udf_debug("Partition (%d type %x) starts at physical %u, block length %u ", |
a983f368f udf: Neaten udf_d... |
1089 1090 |
p_index, map->s_partition_type, map->s_partition_root, map->s_partition_len); |
165923fa4 udf: super.c reor... |
1091 |
|
b085fbe2e udf: Fix crash du... |
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 |
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... |
1102 |
return 0; |
165923fa4 udf: super.c reor... |
1103 1104 1105 |
phd = (struct partitionHeaderDesc *)p->partitionContentsUse; if (phd->unallocSpaceTable.extLength) { |
5ca4e4be8 Remove struct typ... |
1106 |
struct kernel_lb_addr loc = { |
165923fa4 udf: super.c reor... |
1107 1108 |
.logicalBlockNum = le32_to_cpu( phd->unallocSpaceTable.extPosition), |
3fb38dfa0 udf: Move filling... |
1109 |
.partitionReferenceNum = p_index, |
165923fa4 udf: super.c reor... |
1110 |
}; |
6d3d5e860 udf: Make udf_rea... |
1111 |
struct inode *inode; |
165923fa4 udf: super.c reor... |
1112 |
|
6174c2eb8 udf: Fix loading ... |
1113 |
inode = udf_iget_special(sb, &loc); |
6d3d5e860 udf: Make udf_rea... |
1114 |
if (IS_ERR(inode)) { |
165923fa4 udf: super.c reor... |
1115 1116 |
udf_debug("cannot load unallocSpaceTable (part %d) ", |
a983f368f udf: Neaten udf_d... |
1117 |
p_index); |
6d3d5e860 udf: Make udf_rea... |
1118 |
return PTR_ERR(inode); |
165923fa4 udf: super.c reor... |
1119 |
} |
6d3d5e860 udf: Make udf_rea... |
1120 |
map->s_uspace.s_table = inode; |
165923fa4 udf: super.c reor... |
1121 |
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE; |
fcbf7637e udf: Fix signed/u... |
1122 1123 |
udf_debug("unallocSpaceTable (part %d) @ %lu ", |
a983f368f udf: Neaten udf_d... |
1124 |
p_index, map->s_uspace.s_table->i_ino); |
165923fa4 udf: super.c reor... |
1125 1126 1127 |
} if (phd->unallocSpaceBitmap.extLength) { |
3fb38dfa0 udf: Move filling... |
1128 1129 |
struct udf_bitmap *bitmap = udf_sb_alloc_bitmap(sb, p_index); if (!bitmap) |
d759bfa4e udf: Standardize ... |
1130 |
return -ENOMEM; |
165923fa4 udf: super.c reor... |
1131 |
map->s_uspace.s_bitmap = bitmap; |
2e0838fd0 udf: Improve erro... |
1132 |
bitmap->s_extPosition = le32_to_cpu( |
165923fa4 udf: super.c reor... |
1133 |
phd->unallocSpaceBitmap.extPosition); |
2e0838fd0 udf: Improve erro... |
1134 |
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP; |
fcbf7637e udf: Fix signed/u... |
1135 1136 |
udf_debug("unallocSpaceBitmap (part %d) @ %u ", |
a983f368f udf: Neaten udf_d... |
1137 |
p_index, bitmap->s_extPosition); |
165923fa4 udf: super.c reor... |
1138 |
} |
3fb38dfa0 udf: Move filling... |
1139 1140 |
return 0; } |
e971b0b9e udf: Try harder w... |
1141 1142 |
static void udf_find_vat_block(struct super_block *sb, int p_index, int type1_index, sector_t start_block) |
38b74a53e udf: Move process... |
1143 1144 1145 |
{ struct udf_sb_info *sbi = UDF_SB(sb); struct udf_part_map *map = &sbi->s_partmaps[p_index]; |
e971b0b9e udf: Try harder w... |
1146 |
sector_t vat_block; |
5ca4e4be8 Remove struct typ... |
1147 |
struct kernel_lb_addr ino; |
6d3d5e860 udf: Make udf_rea... |
1148 |
struct inode *inode; |
e971b0b9e udf: Try harder w... |
1149 1150 1151 1152 1153 1154 1155 1156 |
/* * 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... |
1157 |
vat_block >= start_block - 3; vat_block--) { |
e971b0b9e udf: Try harder w... |
1158 |
ino.logicalBlockNum = vat_block - map->s_partition_root; |
6174c2eb8 udf: Fix loading ... |
1159 |
inode = udf_iget_special(sb, &ino); |
6d3d5e860 udf: Make udf_rea... |
1160 1161 1162 1163 |
if (!IS_ERR(inode)) { sbi->s_vat_inode = inode; break; } |
e971b0b9e udf: Try harder w... |
1164 1165 1166 1167 1168 1169 1170 |
} } 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... |
1171 1172 1173 1174 |
struct buffer_head *bh = NULL; struct udf_inode_info *vati; uint32_t pos; struct virtualAllocationTable20 *vat20; |
23bcda112 udf: atomically r... |
1175 1176 |
sector_t blocks = i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits; |
38b74a53e udf: Move process... |
1177 |
|
e971b0b9e udf: Try harder w... |
1178 |
udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block); |
4bf17af0d udf: Fix loading ... |
1179 1180 |
if (!sbi->s_vat_inode && sbi->s_last_block != blocks - 1) { |
78ace70c4 udf: Convert prin... |
1181 1182 1183 1184 |
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... |
1185 |
udf_find_vat_block(sb, p_index, type1_index, blocks - 1); |
4bf17af0d udf: Fix loading ... |
1186 |
} |
38b74a53e udf: Move process... |
1187 |
if (!sbi->s_vat_inode) |
d759bfa4e udf: Standardize ... |
1188 |
return -EIO; |
38b74a53e udf: Move process... |
1189 1190 |
if (map->s_partition_type == UDF_VIRTUAL_MAP15) { |
47c9358a0 udf: Fix bug in V... |
1191 |
map->s_type_specific.s_virtual.s_start_offset = 0; |
38b74a53e udf: Move process... |
1192 1193 1194 |
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... |
1195 1196 1197 1198 1199 |
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 ... |
1200 |
return -EIO; |
fa5e08156 udf: Handle VAT p... |
1201 1202 1203 1204 1205 |
vat20 = (struct virtualAllocationTable20 *)bh->b_data; } else { vat20 = (struct virtualAllocationTable20 *) vati->i_ext.i_data; } |
38b74a53e udf: Move process... |
1206 |
|
38b74a53e udf: Move process... |
1207 |
map->s_type_specific.s_virtual.s_start_offset = |
47c9358a0 udf: Fix bug in V... |
1208 |
le16_to_cpu(vat20->lengthHeader); |
38b74a53e udf: Move process... |
1209 1210 1211 1212 1213 1214 1215 1216 |
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 ... |
1217 1218 1219 1220 1221 1222 |
/* * Load partition descriptor block * * Returns <0 on error, 0 on success, -EAGAIN is special - try next descriptor * sequence. */ |
3fb38dfa0 udf: Move filling... |
1223 1224 1225 1226 1227 1228 |
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... |
1229 |
int i, type1_idx; |
3fb38dfa0 udf: Move filling... |
1230 1231 |
uint16_t partitionNumber; uint16_t ident; |
d759bfa4e udf: Standardize ... |
1232 |
int ret; |
3fb38dfa0 udf: Move filling... |
1233 1234 1235 |
bh = udf_read_tagged(sb, block, block, &ident); if (!bh) |
d759bfa4e udf: Standardize ... |
1236 1237 1238 |
return -EAGAIN; if (ident != TAG_IDENT_PD) { ret = 0; |
3fb38dfa0 udf: Move filling... |
1239 |
goto out_bh; |
d759bfa4e udf: Standardize ... |
1240 |
} |
3fb38dfa0 udf: Move filling... |
1241 1242 1243 |
p = (struct partitionDesc *)bh->b_data; partitionNumber = le16_to_cpu(p->partitionNumber); |
38b74a53e udf: Move process... |
1244 |
|
7888824b0 udf: Use correct ... |
1245 |
/* First scan for TYPE1 and SPARABLE partitions */ |
3fb38dfa0 udf: Move filling... |
1246 1247 |
for (i = 0; i < sbi->s_partitions; i++) { map = &sbi->s_partmaps[i]; |
fcbf7637e udf: Fix signed/u... |
1248 1249 |
udf_debug("Searching map: (%u == %u) ", |
3fb38dfa0 udf: Move filling... |
1250 |
map->s_partition_num, partitionNumber); |
38b74a53e udf: Move process... |
1251 1252 1253 |
if (map->s_partition_num == partitionNumber && (map->s_partition_type == UDF_TYPE1_MAP15 || map->s_partition_type == UDF_SPARABLE_MAP15)) |
3fb38dfa0 udf: Move filling... |
1254 1255 |
break; } |
38b74a53e udf: Move process... |
1256 |
if (i >= sbi->s_partitions) { |
fcbf7637e udf: Fix signed/u... |
1257 1258 |
udf_debug("Partition (%u) not found in partition map ", |
3fb38dfa0 udf: Move filling... |
1259 |
partitionNumber); |
d759bfa4e udf: Standardize ... |
1260 |
ret = 0; |
3fb38dfa0 udf: Move filling... |
1261 1262 |
goto out_bh; } |
165923fa4 udf: super.c reor... |
1263 |
|
3fb38dfa0 udf: Move filling... |
1264 |
ret = udf_fill_partdesc_info(sb, p, i); |
d759bfa4e udf: Standardize ... |
1265 1266 |
if (ret < 0) goto out_bh; |
38b74a53e udf: Move process... |
1267 1268 |
/* |
bfb257a59 udf: Add read-onl... |
1269 1270 |
* Now rescan for VIRTUAL or METADATA partitions when SPARABLE and * PHYSICAL partitions are already set up |
38b74a53e udf: Move process... |
1271 1272 |
*/ type1_idx = i; |
444996027 udf: fix for path... |
1273 |
map = NULL; /* supress 'maybe used uninitialized' warning */ |
38b74a53e udf: Move process... |
1274 1275 1276 1277 1278 |
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... |
1279 1280 |
map->s_partition_type == UDF_VIRTUAL_MAP20 || map->s_partition_type == UDF_METADATA_MAP25)) |
38b74a53e udf: Move process... |
1281 1282 |
break; } |
d759bfa4e udf: Standardize ... |
1283 1284 |
if (i >= sbi->s_partitions) { ret = 0; |
38b74a53e udf: Move process... |
1285 |
goto out_bh; |
d759bfa4e udf: Standardize ... |
1286 |
} |
38b74a53e udf: Move process... |
1287 1288 |
ret = udf_fill_partdesc_info(sb, p, i); |
d759bfa4e udf: Standardize ... |
1289 |
if (ret < 0) |
38b74a53e udf: Move process... |
1290 |
goto out_bh; |
bfb257a59 udf: Add read-onl... |
1291 |
if (map->s_partition_type == UDF_METADATA_MAP25) { |
7888824b0 udf: Use correct ... |
1292 |
ret = udf_load_metadata_files(sb, i, type1_idx); |
d759bfa4e udf: Standardize ... |
1293 |
if (ret < 0) { |
78ace70c4 udf: Convert prin... |
1294 1295 1296 |
udf_err(sb, "error loading MetaData partition map %d ", i); |
bfb257a59 udf: Add read-onl... |
1297 1298 1299 |
goto out_bh; } } else { |
e729eac6f udf: Refuse RW mo... |
1300 1301 1302 1303 1304 |
/* * 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->... |
1305 |
if (!sb_rdonly(sb)) { |
e729eac6f udf: Refuse RW mo... |
1306 1307 1308 |
ret = -EACCES; goto out_bh; } |
a9ad01bc7 udf: Prevent writ... |
1309 |
UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); |
bfb257a59 udf: Add read-onl... |
1310 |
ret = udf_load_vat(sb, i, type1_idx); |
d759bfa4e udf: Standardize ... |
1311 |
if (ret < 0) |
bfb257a59 udf: Add read-onl... |
1312 |
goto out_bh; |
bfb257a59 udf: Add read-onl... |
1313 |
} |
d759bfa4e udf: Standardize ... |
1314 |
ret = 0; |
c0eb31ed1 udf: Cleanup volu... |
1315 |
out_bh: |
2e0838fd0 udf: Improve erro... |
1316 |
/* In case loading failed, we handle cleanup in udf_fill_super */ |
c0eb31ed1 udf: Cleanup volu... |
1317 1318 |
brelse(bh); return ret; |
1da177e4c Linux-2.6.12-rc2 |
1319 |
} |
1df2ae31c udf: Fortify load... |
1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 |
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; } 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 1701 |
if (++indirections > UDF_MAX_TD_NESTING) { udf_err(sb, "too many Volume Descriptor " "Pointers (max %u supported) ", UDF_MAX_TD_NESTING); brelse(bh); return -EIO; |
cb00ea352 UDF: coding style... |
1702 |
} |
7b568cba4 udf: Simplify han... |
1703 1704 1705 1706 1707 1708 1709 1710 1711 |
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... |
1712 |
break; |
18cf4781c udf: Unify common... |
1713 |
case TAG_IDENT_PVD: /* ISO 13346 3/10.1 */ |
28de7948a UDF: coding style... |
1714 |
case TAG_IDENT_IUVD: /* ISO 13346 3/10.4 */ |
18cf4781c udf: Unify common... |
1715 1716 |
case TAG_IDENT_LVD: /* ISO 13346 3/10.6 */ case TAG_IDENT_USD: /* ISO 13346 3/10.8 */ |
7b78fd02f udf: Fix handling... |
1717 1718 1719 1720 1721 1722 1723 1724 1725 |
case TAG_IDENT_PD: /* ISO 13346 3/10.5 */ curr = get_volume_descriptor_record(ident, bh, &data); if (IS_ERR(curr)) { brelse(bh); return PTR_ERR(curr); } /* Descriptor we don't care about? */ if (!curr) break; |
4b11111ab udf: fix coding s... |
1726 1727 1728 |
if (vdsn >= curr->volDescSeqNum) { curr->volDescSeqNum = vdsn; curr->block = block; |
cb00ea352 UDF: coding style... |
1729 1730 |
} break; |
28de7948a UDF: coding style... |
1731 |
case TAG_IDENT_TD: /* ISO 13346 3/10.9 */ |
7b568cba4 udf: Simplify han... |
1732 |
done = true; |
cb00ea352 UDF: coding style... |
1733 |
break; |
1da177e4c Linux-2.6.12-rc2 |
1734 |
} |
3bf25cb40 udf: use get_bh() |
1735 |
brelse(bh); |
1da177e4c Linux-2.6.12-rc2 |
1736 |
} |
c0eb31ed1 udf: Cleanup volu... |
1737 1738 1739 1740 |
/* * Now read interesting descriptors again and process them * in a suitable order */ |
7b78fd02f udf: Fix handling... |
1741 |
if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) { |
78ace70c4 udf: Convert prin... |
1742 1743 |
udf_err(sb, "Primary Volume Descriptor not found! "); |
d759bfa4e udf: Standardize ... |
1744 1745 |
return -EAGAIN; } |
7b78fd02f udf: Fix handling... |
1746 |
ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block); |
d759bfa4e udf: Standardize ... |
1747 1748 |
if (ret < 0) return ret; |
7b78fd02f udf: Fix handling... |
1749 |
if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) { |
d759bfa4e udf: Standardize ... |
1750 |
ret = udf_load_logicalvol(sb, |
7b78fd02f udf: Fix handling... |
1751 1752 |
data.vds[VDS_POS_LOGICAL_VOL_DESC].block, fileset); |
d759bfa4e udf: Standardize ... |
1753 1754 |
if (ret < 0) return ret; |
c0eb31ed1 udf: Cleanup volu... |
1755 |
} |
165923fa4 udf: super.c reor... |
1756 |
|
7b78fd02f udf: Fix handling... |
1757 |
/* Now handle prevailing Partition Descriptors */ |
ee4af50ca udf: Fix mounting... |
1758 1759 1760 1761 |
for (i = 0; i < data.num_part_descs; i++) { ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block); if (ret < 0) return ret; |
1da177e4c Linux-2.6.12-rc2 |
1762 1763 1764 1765 |
} return 0; } |
d759bfa4e udf: Standardize ... |
1766 1767 1768 1769 1770 |
/* * Load Volume Descriptor Sequence described by anchor in bh * * Returns <0 on error, 0 on success */ |
403460051 udf: Try anchor i... |
1771 1772 |
static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh, struct kernel_lb_addr *fileset) |
1da177e4c Linux-2.6.12-rc2 |
1773 |
{ |
403460051 udf: Try anchor i... |
1774 |
struct anchorVolDescPtr *anchor; |
d759bfa4e udf: Standardize ... |
1775 1776 |
sector_t main_s, main_e, reserve_s, reserve_e; int ret; |
1da177e4c Linux-2.6.12-rc2 |
1777 |
|
403460051 udf: Try anchor i... |
1778 1779 1780 1781 1782 1783 |
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... |
1784 |
main_e += main_s - 1; |
403460051 udf: Try anchor i... |
1785 1786 1787 1788 1789 |
/* 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... |
1790 |
reserve_e += reserve_s - 1; |
403460051 udf: Try anchor i... |
1791 1792 1793 |
/* Process the main & reserve sequences */ /* responsible for finding the PartitionDesc(s) */ |
d759bfa4e udf: Standardize ... |
1794 1795 1796 |
ret = udf_process_sequence(sb, main_s, main_e, fileset); if (ret != -EAGAIN) return ret; |
bff943af6 udf: Fix memory l... |
1797 |
udf_sb_free_partitions(sb); |
d759bfa4e udf: Standardize ... |
1798 1799 1800 1801 1802 1803 1804 1805 |
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 |
1806 |
} |
403460051 udf: Try anchor i... |
1807 1808 1809 |
/* * Check whether there is an anchor block in the given block and * load Volume Descriptor Sequence if so. |
d759bfa4e udf: Standardize ... |
1810 1811 1812 |
* * Returns <0 on error, 0 on success, -EAGAIN is special - try next anchor * block |
403460051 udf: Try anchor i... |
1813 1814 1815 |
*/ static int udf_check_anchor_block(struct super_block *sb, sector_t block, struct kernel_lb_addr *fileset) |
1197e4dfc udf: use hardware... |
1816 |
{ |
403460051 udf: Try anchor i... |
1817 1818 1819 |
struct buffer_head *bh; uint16_t ident; int ret; |
1197e4dfc udf: use hardware... |
1820 |
|
403460051 udf: Try anchor i... |
1821 1822 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) && udf_fixed_to_variable(block) >= |
23bcda112 udf: atomically r... |
1823 |
i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits) |
d759bfa4e udf: Standardize ... |
1824 |
return -EAGAIN; |
403460051 udf: Try anchor i... |
1825 1826 1827 |
bh = udf_read_tagged(sb, block, block, &ident); if (!bh) |
d759bfa4e udf: Standardize ... |
1828 |
return -EAGAIN; |
403460051 udf: Try anchor i... |
1829 1830 |
if (ident != TAG_IDENT_AVDP) { brelse(bh); |
d759bfa4e udf: Standardize ... |
1831 |
return -EAGAIN; |
1197e4dfc udf: use hardware... |
1832 |
} |
403460051 udf: Try anchor i... |
1833 1834 1835 |
ret = udf_load_sequence(sb, bh, fileset); brelse(bh); return ret; |
1197e4dfc udf: use hardware... |
1836 |
} |
d759bfa4e udf: Standardize ... |
1837 1838 1839 1840 1841 1842 1843 1844 |
/* * 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 |
1845 |
{ |
403460051 udf: Try anchor i... |
1846 |
sector_t last[6]; |
38b74a53e udf: Move process... |
1847 |
int i; |
403460051 udf: Try anchor i... |
1848 1849 |
struct udf_sb_info *sbi = UDF_SB(sb); int last_count = 0; |
d759bfa4e udf: Standardize ... |
1850 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
1851 |
|
403460051 udf: Try anchor i... |
1852 1853 |
/* First try user provided anchor */ if (sbi->s_anchor) { |
d759bfa4e udf: Standardize ... |
1854 1855 1856 |
ret = udf_check_anchor_block(sb, sbi->s_anchor, fileset); if (ret != -EAGAIN) return ret; |
403460051 udf: Try anchor i... |
1857 1858 1859 1860 1861 1862 1863 1864 |
} /* * 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 ... |
1865 1866 1867 |
ret = udf_check_anchor_block(sb, sbi->s_session + 256, fileset); if (ret != -EAGAIN) return ret; |
403460051 udf: Try anchor i... |
1868 1869 1870 1871 |
/* * The trouble is which block is the last one. Drives often misreport * this so we try various possibilities. */ |
d759bfa4e udf: Standardize ... |
1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 |
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 |
1882 |
|
403460051 udf: Try anchor i... |
1883 |
for (i = 0; i < last_count; i++) { |
23bcda112 udf: atomically r... |
1884 |
if (last[i] >= i_size_read(sb->s_bdev->bd_inode) >> |
403460051 udf: Try anchor i... |
1885 |
sb->s_blocksize_bits) |
28f7c4d41 udf: improve read... |
1886 |
continue; |
d759bfa4e udf: Standardize ... |
1887 1888 1889 1890 1891 1892 |
ret = udf_check_anchor_block(sb, last[i], fileset); if (ret != -EAGAIN) { if (!ret) *lastblock = last[i]; return ret; } |
403460051 udf: Try anchor i... |
1893 |
if (last[i] < 256) |
28f7c4d41 udf: improve read... |
1894 |
continue; |
d759bfa4e udf: Standardize ... |
1895 1896 1897 1898 1899 1900 |
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... |
1901 |
} |
28f7c4d41 udf: improve read... |
1902 |
|
403460051 udf: Try anchor i... |
1903 |
/* Finally try block 512 in case media is open */ |
d759bfa4e udf: Standardize ... |
1904 |
return udf_check_anchor_block(sb, sbi->s_session + 512, fileset); |
403460051 udf: Try anchor i... |
1905 |
} |
28f7c4d41 udf: improve read... |
1906 |
|
403460051 udf: Try anchor i... |
1907 1908 1909 1910 1911 |
/* * 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 ... |
1912 1913 |
* Return <0 on error, 0 if anchor found. -EAGAIN is special meaning anchor * was not found. |
403460051 udf: Try anchor i... |
1914 1915 1916 1917 |
*/ static int udf_find_anchor(struct super_block *sb, struct kernel_lb_addr *fileset) { |
403460051 udf: Try anchor i... |
1918 |
struct udf_sb_info *sbi = UDF_SB(sb); |
d759bfa4e udf: Standardize ... |
1919 1920 |
sector_t lastblock = sbi->s_last_block; int ret; |
28f7c4d41 udf: improve read... |
1921 |
|
d759bfa4e udf: Standardize ... |
1922 1923 |
ret = udf_scan_anchors(sb, &lastblock, fileset); if (ret != -EAGAIN) |
403460051 udf: Try anchor i... |
1924 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1925 |
|
403460051 udf: Try anchor i... |
1926 1927 |
/* No anchor found? Try VARCONV conversion of block numbers */ UDF_SET_FLAG(sb, UDF_FLAG_VARCONV); |
d759bfa4e udf: Standardize ... |
1928 |
lastblock = udf_variable_to_fixed(sbi->s_last_block); |
403460051 udf: Try anchor i... |
1929 |
/* Firstly, we try to not convert number of the last block */ |
d759bfa4e udf: Standardize ... |
1930 1931 |
ret = udf_scan_anchors(sb, &lastblock, fileset); if (ret != -EAGAIN) |
403460051 udf: Try anchor i... |
1932 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1933 |
|
d759bfa4e udf: Standardize ... |
1934 |
lastblock = sbi->s_last_block; |
403460051 udf: Try anchor i... |
1935 |
/* Secondly, we try with converted number of the last block */ |
d759bfa4e udf: Standardize ... |
1936 1937 |
ret = udf_scan_anchors(sb, &lastblock, fileset); if (ret < 0) { |
403460051 udf: Try anchor i... |
1938 1939 |
/* VARCONV didn't help. Clear it. */ UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV); |
1da177e4c Linux-2.6.12-rc2 |
1940 |
} |
403460051 udf: Try anchor i... |
1941 |
out: |
d759bfa4e udf: Standardize ... |
1942 1943 1944 |
if (ret == 0) sbi->s_last_block = lastblock; return ret; |
403460051 udf: Try anchor i... |
1945 |
} |
1da177e4c Linux-2.6.12-rc2 |
1946 |
|
403460051 udf: Try anchor i... |
1947 1948 |
/* * Check Volume Structure Descriptor, find Anchor block and load Volume |
d759bfa4e udf: Standardize ... |
1949 1950 1951 1952 |
* Descriptor Sequence. * * Returns < 0 on error, 0 on success. -EAGAIN is special meaning anchor * block was not found. |
403460051 udf: Try anchor i... |
1953 1954 1955 1956 1957 |
*/ 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... |
1958 |
int nsr = 0; |
d759bfa4e udf: Standardize ... |
1959 |
int ret; |
403460051 udf: Try anchor i... |
1960 1961 1962 |
if (!sb_set_blocksize(sb, uopt->blocksize)) { if (!silent) |
78ace70c4 udf: Convert prin... |
1963 1964 |
udf_warn(sb, "Bad block size "); |
d759bfa4e udf: Standardize ... |
1965 |
return -EINVAL; |
403460051 udf: Try anchor i... |
1966 1967 1968 1969 |
} sbi->s_last_block = uopt->lastblock; if (!uopt->novrs) { /* Check that it is NSR02 compliant */ |
ba54aef03 udf: refactor VRS... |
1970 1971 |
nsr = udf_check_vsd(sb); if (!nsr) { |
403460051 udf: Try anchor i... |
1972 |
if (!silent) |
78ace70c4 udf: Convert prin... |
1973 1974 |
udf_warn(sb, "No VRS found "); |
70f16cef0 udf: allow implic... |
1975 |
return -EINVAL; |
403460051 udf: Try anchor i... |
1976 |
} |
ba54aef03 udf: refactor VRS... |
1977 |
if (nsr == -1) |
444996027 udf: fix for path... |
1978 1979 1980 1981 |
udf_debug("Failed to read sector at offset %d. " "Assuming open disc. Skipping validity " "check ", VSD_FIRST_SECTOR_OFFSET); |
403460051 udf: Try anchor i... |
1982 1983 1984 1985 1986 |
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... |
1987 |
} |
1da177e4c Linux-2.6.12-rc2 |
1988 |
|
403460051 udf: Try anchor i... |
1989 1990 |
/* Look for anchor block and load Volume Descriptor Sequence */ sbi->s_anchor = uopt->anchor; |
d759bfa4e udf: Standardize ... |
1991 1992 1993 |
ret = udf_find_anchor(sb, fileset); if (ret < 0) { if (!silent && ret == -EAGAIN) |
78ace70c4 udf: Convert prin... |
1994 1995 |
udf_warn(sb, "No anchor found "); |
d759bfa4e udf: Standardize ... |
1996 |
return ret; |
403460051 udf: Try anchor i... |
1997 |
} |
d759bfa4e udf: Standardize ... |
1998 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1999 |
} |
ebbd5e99f udf: factor out L... |
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 |
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 |
2011 2012 |
static void udf_open_lvid(struct super_block *sb) { |
6c79e987d udf: remove some ... |
2013 2014 |
struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = sbi->s_lvid_bh; |
165923fa4 udf: super.c reor... |
2015 2016 |
struct logicalVolIntegrityDesc *lvid; struct logicalVolIntegrityDescImpUse *lvidiu; |
146bca72c udf: Don't write ... |
2017 |
|
165923fa4 udf: super.c reor... |
2018 2019 |
if (!bh) return; |
165923fa4 udf: super.c reor... |
2020 |
lvid = (struct logicalVolIntegrityDesc *)bh->b_data; |
69d75671d udf: Fortify LVID... |
2021 2022 2023 |
lvidiu = udf_sb_lvidiu(sb); if (!lvidiu) return; |
165923fa4 udf: super.c reor... |
2024 |
|
69d75671d udf: Fortify LVID... |
2025 |
mutex_lock(&sbi->s_alloc_mutex); |
165923fa4 udf: super.c reor... |
2026 2027 |
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
b72e632c6 udf: Do not mark ... |
2028 2029 2030 2031 |
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... |
2032 |
|
ebbd5e99f udf: factor out L... |
2033 |
udf_finalize_lvid(lvid); |
165923fa4 udf: super.c reor... |
2034 |
mark_buffer_dirty(bh); |
146bca72c udf: Don't write ... |
2035 |
sbi->s_lvid_dirty = 0; |
949f4a7c0 udf: Protect all ... |
2036 |
mutex_unlock(&sbi->s_alloc_mutex); |
9734c971a udf: Write LVID t... |
2037 2038 |
/* Make opening of filesystem visible on the media immediately */ sync_dirty_buffer(bh); |
1da177e4c Linux-2.6.12-rc2 |
2039 2040 2041 2042 |
} static void udf_close_lvid(struct super_block *sb) { |
6c79e987d udf: remove some ... |
2043 2044 2045 |
struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = sbi->s_lvid_bh; struct logicalVolIntegrityDesc *lvid; |
165923fa4 udf: super.c reor... |
2046 |
struct logicalVolIntegrityDescImpUse *lvidiu; |
28de7948a UDF: coding style... |
2047 |
|
6c79e987d udf: remove some ... |
2048 2049 |
if (!bh) return; |
69d75671d udf: Fortify LVID... |
2050 2051 2052 2053 |
lvid = (struct logicalVolIntegrityDesc *)bh->b_data; lvidiu = udf_sb_lvidiu(sb); if (!lvidiu) return; |
6c79e987d udf: remove some ... |
2054 |
|
949f4a7c0 udf: Protect all ... |
2055 |
mutex_lock(&sbi->s_alloc_mutex); |
165923fa4 udf: super.c reor... |
2056 2057 |
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
165923fa4 udf: super.c reor... |
2058 2059 2060 2061 2062 2063 |
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 ... |
2064 2065 |
if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT)) lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
165923fa4 udf: super.c reor... |
2066 |
|
853a0c25b udf: Mark LVID bu... |
2067 2068 2069 2070 2071 2072 |
/* * 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... |
2073 |
udf_finalize_lvid(lvid); |
165923fa4 udf: super.c reor... |
2074 |
mark_buffer_dirty(bh); |
146bca72c udf: Don't write ... |
2075 |
sbi->s_lvid_dirty = 0; |
949f4a7c0 udf: Protect all ... |
2076 |
mutex_unlock(&sbi->s_alloc_mutex); |
9734c971a udf: Write LVID t... |
2077 2078 |
/* Make closing of filesystem visible on the media immediately */ sync_dirty_buffer(bh); |
1da177e4c Linux-2.6.12-rc2 |
2079 |
} |
d664b6af6 udf: Move handlin... |
2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 |
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... |
2101 |
udf_updated_lvid(sb); |
d664b6af6 udf: Move handlin... |
2102 |
mutex_unlock(&sbi->s_alloc_mutex); |
d664b6af6 udf: Move handlin... |
2103 2104 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2105 |
} |
1da177e4c Linux-2.6.12-rc2 |
2106 2107 |
static int udf_fill_super(struct super_block *sb, void *options, int silent) { |
d759bfa4e udf: Standardize ... |
2108 |
int ret = -EINVAL; |
cb00ea352 UDF: coding style... |
2109 |
struct inode *inode = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2110 |
struct udf_options uopt; |
5ca4e4be8 Remove struct typ... |
2111 |
struct kernel_lb_addr rootdir, fileset; |
1da177e4c Linux-2.6.12-rc2 |
2112 |
struct udf_sb_info *sbi; |
9181f8bf5 udf: Don't modify... |
2113 |
bool lvid_open = false; |
1da177e4c Linux-2.6.12-rc2 |
2114 2115 |
uopt.flags = (1 << UDF_FLAG_USE_AD_IN_ICB) | (1 << UDF_FLAG_STRICT); |
116e5258e udf: Provide sane... |
2116 2117 2118 |
/* 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 |
2119 |
uopt.umask = 0; |
87bc730c0 udf: fix default ... |
2120 2121 |
uopt.fmode = UDF_INVALID_MODE; uopt.dmode = UDF_INVALID_MODE; |
785dffe1d udf: fix potentia... |
2122 |
uopt.nls_map = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2123 |
|
033c9da00 fs-udf: Improve s... |
2124 |
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
9db9f9e31 udf: Remove unnec... |
2125 |
if (!sbi) |
1da177e4c Linux-2.6.12-rc2 |
2126 |
return -ENOMEM; |
28de7948a UDF: coding style... |
2127 |
|
1da177e4c Linux-2.6.12-rc2 |
2128 |
sb->s_fs_info = sbi; |
1da177e4c Linux-2.6.12-rc2 |
2129 |
|
1e7933def [PATCH] sem2mutex... |
2130 |
mutex_init(&sbi->s_alloc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2131 |
|
6da80894c mount options: fi... |
2132 |
if (!udf_parse_options((char *)options, &uopt, false)) |
fdf2657bc udf: One function... |
2133 |
goto parse_options_failure; |
1da177e4c Linux-2.6.12-rc2 |
2134 2135 |
if (uopt.flags & (1 << UDF_FLAG_UTF8) && |
cb00ea352 UDF: coding style... |
2136 |
uopt.flags & (1 << UDF_FLAG_NLS_MAP)) { |
8076c363d udf: Rename udf_e... |
2137 2138 |
udf_err(sb, "utf8 cannot be combined with iocharset "); |
fdf2657bc udf: One function... |
2139 |
goto parse_options_failure; |
1da177e4c Linux-2.6.12-rc2 |
2140 |
} |
cb00ea352 UDF: coding style... |
2141 |
if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map) { |
1da177e4c Linux-2.6.12-rc2 |
2142 2143 2144 2145 2146 2147 2148 |
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 |
2149 2150 2151 2152 2153 |
if (!(uopt.flags & (1 << UDF_FLAG_NLS_MAP))) uopt.flags |= (1 << UDF_FLAG_UTF8); fileset.logicalBlockNum = 0xFFFFFFFF; fileset.partitionReferenceNum = 0xFFFF; |
6c79e987d udf: remove some ... |
2154 2155 2156 2157 |
sbi->s_flags = uopt.flags; sbi->s_uid = uopt.uid; sbi->s_gid = uopt.gid; sbi->s_umask = uopt.umask; |
7ac9bcd5d udf: implement mo... |
2158 2159 |
sbi->s_fmode = uopt.fmode; sbi->s_dmode = uopt.dmode; |
6c79e987d udf: remove some ... |
2160 |
sbi->s_nls_map = uopt.nls_map; |
c03cad241 udf: Protect defa... |
2161 |
rwlock_init(&sbi->s_cred_lock); |
1da177e4c Linux-2.6.12-rc2 |
2162 |
|
cb00ea352 UDF: coding style... |
2163 |
if (uopt.session == 0xFFFFFFFF) |
6c79e987d udf: remove some ... |
2164 |
sbi->s_session = udf_get_last_session(sb); |
1da177e4c Linux-2.6.12-rc2 |
2165 |
else |
6c79e987d udf: remove some ... |
2166 |
sbi->s_session = uopt.session; |
1da177e4c Linux-2.6.12-rc2 |
2167 |
|
6c79e987d udf: remove some ... |
2168 2169 |
udf_debug("Multi-session=%d ", sbi->s_session); |
1da177e4c Linux-2.6.12-rc2 |
2170 |
|
403460051 udf: Try anchor i... |
2171 2172 2173 |
/* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; sb->s_export_op = &udf_export_ops; |
123e9caf1 quota: explicitly... |
2174 |
|
403460051 udf: Try anchor i... |
2175 2176 |
sb->s_magic = UDF_SUPER_MAGIC; sb->s_time_gran = 1000; |
1197e4dfc udf: use hardware... |
2177 |
if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { |
403460051 udf: Try anchor i... |
2178 |
ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
1197e4dfc udf: use hardware... |
2179 |
} else { |
e1defc4ff block: Do away wi... |
2180 |
uopt.blocksize = bdev_logical_block_size(sb->s_bdev); |
70f16cef0 udf: allow implic... |
2181 |
while (uopt.blocksize <= 4096) { |
403460051 udf: Try anchor i... |
2182 |
ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
70f16cef0 udf: allow implic... |
2183 2184 |
if (ret < 0) { if (!silent && ret != -EACCES) { |
fcbf7637e udf: Fix signed/u... |
2185 2186 |
pr_notice("Scanning with blocksize %u failed ", |
70f16cef0 udf: allow implic... |
2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 |
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... |
2201 |
} |
1da177e4c Linux-2.6.12-rc2 |
2202 |
} |
d759bfa4e udf: Standardize ... |
2203 2204 2205 2206 2207 2208 |
if (ret < 0) { if (ret == -EAGAIN) { udf_warn(sb, "No partition found (1) "); ret = -EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
2209 2210 |
goto error_out; } |
fcbf7637e udf: Fix signed/u... |
2211 2212 |
udf_debug("Lastblock=%u ", sbi->s_last_block); |
1da177e4c Linux-2.6.12-rc2 |
2213 |
|
6c79e987d udf: remove some ... |
2214 |
if (sbi->s_lvid_bh) { |
4b11111ab udf: fix coding s... |
2215 |
struct logicalVolIntegrityDescImpUse *lvidiu = |
69d75671d udf: Fortify LVID... |
2216 2217 2218 |
udf_sb_lvidiu(sb); uint16_t minUDFReadRev; uint16_t minUDFWriteRev; |
1da177e4c Linux-2.6.12-rc2 |
2219 |
|
69d75671d udf: Fortify LVID... |
2220 2221 2222 2223 2224 2225 |
if (!lvidiu) { ret = -EINVAL; goto error_out; } minUDFReadRev = le16_to_cpu(lvidiu->minUDFReadRev); minUDFWriteRev = le16_to_cpu(lvidiu->minUDFWriteRev); |
cb00ea352 UDF: coding style... |
2226 |
if (minUDFReadRev > UDF_MAX_READ_VERSION) { |
78ace70c4 udf: Convert prin... |
2227 2228 |
udf_err(sb, "minUDFReadRev=%x (max is %x) ", |
69d75671d udf: Fortify LVID... |
2229 |
minUDFReadRev, |
78ace70c4 udf: Convert prin... |
2230 |
UDF_MAX_READ_VERSION); |
d759bfa4e udf: Standardize ... |
2231 |
ret = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
2232 |
goto error_out; |
a9ad01bc7 udf: Prevent writ... |
2233 2234 2235 2236 2237 2238 |
} 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... |
2239 |
} |
1da177e4c Linux-2.6.12-rc2 |
2240 |
|
6c79e987d udf: remove some ... |
2241 |
sbi->s_udfrev = minUDFWriteRev; |
1da177e4c Linux-2.6.12-rc2 |
2242 2243 2244 2245 2246 2247 |
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 ... |
2248 |
if (!sbi->s_partitions) { |
78ace70c4 udf: Convert prin... |
2249 2250 |
udf_warn(sb, "No partition found (2) "); |
d759bfa4e udf: Standardize ... |
2251 |
ret = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
2252 2253 |
goto error_out; } |
4b11111ab udf: fix coding s... |
2254 |
if (sbi->s_partmaps[sbi->s_partition].s_partition_flags & |
a9ad01bc7 udf: Prevent writ... |
2255 2256 2257 2258 2259 2260 |
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 ... |
2261 |
} |
39b3f6d6e [PATCH] mount udf... |
2262 |
|
2dee5aac0 udf: Verify domai... |
2263 2264 |
ret = udf_find_fileset(sb, &fileset, &rootdir); if (ret < 0) { |
78ace70c4 udf: Convert prin... |
2265 2266 |
udf_warn(sb, "No fileset found "); |
1da177e4c Linux-2.6.12-rc2 |
2267 2268 |
goto error_out; } |
cb00ea352 UDF: coding style... |
2269 |
if (!silent) { |
5ca4e4be8 Remove struct typ... |
2270 |
struct timestamp ts; |
56774805d udf: convert udf_... |
2271 |
udf_time_to_disk_stamp(&ts, sbi->s_record_time); |
78ace70c4 udf: Convert prin... |
2272 2273 2274 2275 |
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_... |
2276 |
ts.hour, ts.minute, le16_to_cpu(ts.typeAndTimezone)); |
1da177e4c Linux-2.6.12-rc2 |
2277 |
} |
bc98a42c1 VFS: Convert sb->... |
2278 |
if (!sb_rdonly(sb)) { |
1da177e4c Linux-2.6.12-rc2 |
2279 |
udf_open_lvid(sb); |
9181f8bf5 udf: Don't modify... |
2280 2281 |
lvid_open = true; } |
1da177e4c Linux-2.6.12-rc2 |
2282 2283 2284 2285 |
/* Assign the root inode */ /* assign inodes by physical block number */ /* perhaps it's not extensible enough, but for now ... */ |
97e961fdb Fix the udf code ... |
2286 |
inode = udf_iget(sb, &rootdir); |
6d3d5e860 udf: Make udf_rea... |
2287 |
if (IS_ERR(inode)) { |
fcbf7637e udf: Fix signed/u... |
2288 2289 |
udf_err(sb, "Error in udf_iget, block=%u, partition=%u ", |
cb00ea352 UDF: coding style... |
2290 |
rootdir.logicalBlockNum, rootdir.partitionReferenceNum); |
6d3d5e860 udf: Make udf_rea... |
2291 |
ret = PTR_ERR(inode); |
1da177e4c Linux-2.6.12-rc2 |
2292 2293 2294 2295 |
goto error_out; } /* Allocate a dentry for the root inode */ |
48fde701a switch open-coded... |
2296 |
sb->s_root = d_make_root(inode); |
cb00ea352 UDF: coding style... |
2297 |
if (!sb->s_root) { |
78ace70c4 udf: Convert prin... |
2298 2299 |
udf_err(sb, "Couldn't allocate root dentry "); |
d759bfa4e udf: Standardize ... |
2300 |
ret = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
2301 2302 |
goto error_out; } |
31170b6ad udf: support file... |
2303 |
sb->s_maxbytes = MAX_LFS_FILESIZE; |
8de527787 vfs: check i_nlin... |
2304 |
sb->s_max_links = UDF_MAX_LINKS; |
1da177e4c Linux-2.6.12-rc2 |
2305 |
return 0; |
28de7948a UDF: coding style... |
2306 |
error_out: |
0d454e4a4 udf: Deletion of ... |
2307 |
iput(sbi->s_vat_inode); |
fdf2657bc udf: One function... |
2308 |
parse_options_failure: |
785dffe1d udf: fix potentia... |
2309 2310 |
if (uopt.nls_map) unload_nls(uopt.nls_map); |
9181f8bf5 udf: Don't modify... |
2311 |
if (lvid_open) |
1da177e4c Linux-2.6.12-rc2 |
2312 |
udf_close_lvid(sb); |
6c79e987d udf: remove some ... |
2313 |
brelse(sbi->s_lvid_bh); |
bff943af6 udf: Fix memory l... |
2314 |
udf_sb_free_partitions(sb); |
1da177e4c Linux-2.6.12-rc2 |
2315 2316 |
kfree(sbi); sb->s_fs_info = NULL; |
28de7948a UDF: coding style... |
2317 |
|
d759bfa4e udf: Standardize ... |
2318 |
return ret; |
1da177e4c Linux-2.6.12-rc2 |
2319 |
} |
8076c363d udf: Rename udf_e... |
2320 2321 |
void _udf_err(struct super_block *sb, const char *function, const char *fmt, ...) |
1da177e4c Linux-2.6.12-rc2 |
2322 |
{ |
c2bff36c2 udf: Neaten loggi... |
2323 |
struct va_format vaf; |
1da177e4c Linux-2.6.12-rc2 |
2324 |
va_list args; |
1da177e4c Linux-2.6.12-rc2 |
2325 |
va_start(args, fmt); |
c2bff36c2 udf: Neaten loggi... |
2326 2327 2328 2329 2330 |
vaf.fmt = fmt; vaf.va = &args; pr_err("error (device %s): %s: %pV", sb->s_id, function, &vaf); |
1da177e4c Linux-2.6.12-rc2 |
2331 |
va_end(args); |
1da177e4c Linux-2.6.12-rc2 |
2332 |
} |
a40ecd7b3 udf: Rename udf_w... |
2333 2334 |
void _udf_warn(struct super_block *sb, const char *function, const char *fmt, ...) |
1da177e4c Linux-2.6.12-rc2 |
2335 |
{ |
c2bff36c2 udf: Neaten loggi... |
2336 |
struct va_format vaf; |
1da177e4c Linux-2.6.12-rc2 |
2337 |
va_list args; |
cb00ea352 UDF: coding style... |
2338 |
va_start(args, fmt); |
c2bff36c2 udf: Neaten loggi... |
2339 2340 2341 2342 2343 |
vaf.fmt = fmt; vaf.va = &args; pr_warn("warning (device %s): %s: %pV", sb->s_id, function, &vaf); |
1da177e4c Linux-2.6.12-rc2 |
2344 |
va_end(args); |
1da177e4c Linux-2.6.12-rc2 |
2345 |
} |
cb00ea352 UDF: coding style... |
2346 |
static void udf_put_super(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
2347 |
{ |
6c79e987d udf: remove some ... |
2348 |
struct udf_sb_info *sbi; |
1da177e4c Linux-2.6.12-rc2 |
2349 |
|
6c79e987d udf: remove some ... |
2350 |
sbi = UDF_SB(sb); |
6cfd01484 push BKL down int... |
2351 |
|
0d454e4a4 udf: Deletion of ... |
2352 |
iput(sbi->s_vat_inode); |
1da177e4c Linux-2.6.12-rc2 |
2353 |
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP)) |
6c79e987d udf: remove some ... |
2354 |
unload_nls(sbi->s_nls_map); |
bc98a42c1 VFS: Convert sb->... |
2355 |
if (!sb_rdonly(sb)) |
1da177e4c Linux-2.6.12-rc2 |
2356 |
udf_close_lvid(sb); |
6c79e987d udf: remove some ... |
2357 |
brelse(sbi->s_lvid_bh); |
bff943af6 udf: Fix memory l... |
2358 |
udf_sb_free_partitions(sb); |
bbe48dd81 udf: destroy sbi ... |
2359 |
mutex_destroy(&sbi->s_alloc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2360 2361 2362 |
kfree(sb->s_fs_info); sb->s_fs_info = NULL; } |
146bca72c udf: Don't write ... |
2363 2364 2365 2366 2367 2368 |
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... |
2369 |
struct buffer_head *bh = sbi->s_lvid_bh; |
52b9666ef udf: Drop pointle... |
2370 |
struct logicalVolIntegrityDesc *lvid; |
e8b427473 udf: finalize int... |
2371 |
|
52b9666ef udf: Drop pointle... |
2372 2373 |
lvid = (struct logicalVolIntegrityDesc *)bh->b_data; udf_finalize_lvid(lvid); |
e8b427473 udf: finalize int... |
2374 |
|
146bca72c udf: Don't write ... |
2375 2376 2377 2378 |
/* * Blockdevice will be synced later so we don't have to submit * the buffer for IO */ |
e8b427473 udf: finalize int... |
2379 |
mark_buffer_dirty(bh); |
146bca72c udf: Don't write ... |
2380 2381 2382 2383 2384 2385 |
sbi->s_lvid_dirty = 0; } mutex_unlock(&sbi->s_alloc_mutex); return 0; } |
cb00ea352 UDF: coding style... |
2386 |
static int udf_statfs(struct dentry *dentry, struct kstatfs *buf) |
1da177e4c Linux-2.6.12-rc2 |
2387 |
{ |
726c33422 [PATCH] VFS: Perm... |
2388 |
struct super_block *sb = dentry->d_sb; |
6c79e987d udf: remove some ... |
2389 2390 |
struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDescImpUse *lvidiu; |
557f5a146 udf: return f_fsi... |
2391 |
u64 id = huge_encode_dev(sb->s_bdev->bd_dev); |
6c79e987d udf: remove some ... |
2392 |
|
69d75671d udf: Fortify LVID... |
2393 |
lvidiu = udf_sb_lvidiu(sb); |
1da177e4c Linux-2.6.12-rc2 |
2394 2395 |
buf->f_type = UDF_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; |
6c79e987d udf: remove some ... |
2396 |
buf->f_blocks = sbi->s_partmaps[sbi->s_partition].s_partition_len; |
1da177e4c Linux-2.6.12-rc2 |
2397 2398 |
buf->f_bfree = udf_count_free(sb); buf->f_bavail = buf->f_bfree; |
6c79e987d udf: remove some ... |
2399 2400 2401 |
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 |
2402 |
buf->f_ffree = buf->f_bfree; |
9fba70569 udf: Adjust UDF_N... |
2403 |
buf->f_namelen = UDF_NAME_LEN; |
557f5a146 udf: return f_fsi... |
2404 2405 |
buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); |
1da177e4c Linux-2.6.12-rc2 |
2406 2407 2408 |
return 0; } |
4b11111ab udf: fix coding s... |
2409 2410 |
static unsigned int udf_count_free_bitmap(struct super_block *sb, struct udf_bitmap *bitmap) |
1da177e4c Linux-2.6.12-rc2 |
2411 2412 2413 2414 |
{ struct buffer_head *bh = NULL; unsigned int accum = 0; int index; |
b490bdd63 udf: Fix 64-bit s... |
2415 |
udf_pblk_t block = 0, newblock; |
5ca4e4be8 Remove struct typ... |
2416 |
struct kernel_lb_addr loc; |
1da177e4c Linux-2.6.12-rc2 |
2417 |
uint32_t bytes; |
1da177e4c Linux-2.6.12-rc2 |
2418 2419 2420 |
uint8_t *ptr; uint16_t ident; struct spaceBitmapDesc *bm; |
1da177e4c Linux-2.6.12-rc2 |
2421 |
loc.logicalBlockNum = bitmap->s_extPosition; |
6c79e987d udf: remove some ... |
2422 |
loc.partitionReferenceNum = UDF_SB(sb)->s_partition; |
97e961fdb Fix the udf code ... |
2423 |
bh = udf_read_ptagged(sb, &loc, 0, &ident); |
1da177e4c Linux-2.6.12-rc2 |
2424 |
|
cb00ea352 UDF: coding style... |
2425 |
if (!bh) { |
78ace70c4 udf: Convert prin... |
2426 2427 |
udf_err(sb, "udf_count_free failed "); |
1da177e4c Linux-2.6.12-rc2 |
2428 |
goto out; |
cb00ea352 UDF: coding style... |
2429 |
} else if (ident != TAG_IDENT_SBD) { |
3bf25cb40 udf: use get_bh() |
2430 |
brelse(bh); |
78ace70c4 udf: Convert prin... |
2431 2432 |
udf_err(sb, "udf_count_free failed "); |
1da177e4c Linux-2.6.12-rc2 |
2433 2434 2435 2436 2437 |
goto out; } bm = (struct spaceBitmapDesc *)bh->b_data; bytes = le32_to_cpu(bm->numOfBytes); |
28de7948a UDF: coding style... |
2438 2439 |
index = sizeof(struct spaceBitmapDesc); /* offset in first block only */ ptr = (uint8_t *)bh->b_data; |
1da177e4c Linux-2.6.12-rc2 |
2440 |
|
cb00ea352 UDF: coding style... |
2441 |
while (bytes > 0) { |
01b954a36 udf: convert udf_... |
2442 2443 2444 2445 |
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... |
2446 |
if (bytes) { |
3bf25cb40 udf: use get_bh() |
2447 |
brelse(bh); |
97e961fdb Fix the udf code ... |
2448 |
newblock = udf_get_lb_pblock(sb, &loc, ++block); |
1da177e4c Linux-2.6.12-rc2 |
2449 |
bh = udf_tread(sb, newblock); |
cb00ea352 UDF: coding style... |
2450 |
if (!bh) { |
1da177e4c Linux-2.6.12-rc2 |
2451 2452 2453 2454 2455 |
udf_debug("read failed "); goto out; } index = 0; |
28de7948a UDF: coding style... |
2456 |
ptr = (uint8_t *)bh->b_data; |
1da177e4c Linux-2.6.12-rc2 |
2457 2458 |
} } |
3bf25cb40 udf: use get_bh() |
2459 |
brelse(bh); |
28de7948a UDF: coding style... |
2460 |
out: |
1da177e4c Linux-2.6.12-rc2 |
2461 2462 |
return accum; } |
4b11111ab udf: fix coding s... |
2463 2464 |
static unsigned int udf_count_free_table(struct super_block *sb, struct inode *table) |
1da177e4c Linux-2.6.12-rc2 |
2465 2466 |
{ unsigned int accum = 0; |
ff116fc8d UDF: introduce st... |
2467 |
uint32_t elen; |
5ca4e4be8 Remove struct typ... |
2468 |
struct kernel_lb_addr eloc; |
1da177e4c Linux-2.6.12-rc2 |
2469 |
int8_t etype; |
ff116fc8d UDF: introduce st... |
2470 |
struct extent_position epos; |
1da177e4c Linux-2.6.12-rc2 |
2471 |
|
d1668fe39 udf: Remove BKL f... |
2472 |
mutex_lock(&UDF_SB(sb)->s_alloc_mutex); |
c0b344385 udf: remove UDF_I... |
2473 |
epos.block = UDF_I(table)->i_location; |
ff116fc8d UDF: introduce st... |
2474 2475 |
epos.offset = sizeof(struct unallocSpaceEntry); epos.bh = NULL; |
1da177e4c Linux-2.6.12-rc2 |
2476 |
|
3a71fc5de udf: fix coding s... |
2477 |
while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1) |
1da177e4c Linux-2.6.12-rc2 |
2478 |
accum += (elen >> table->i_sb->s_blocksize_bits); |
3a71fc5de udf: fix coding s... |
2479 |
|
3bf25cb40 udf: use get_bh() |
2480 |
brelse(epos.bh); |
d1668fe39 udf: Remove BKL f... |
2481 |
mutex_unlock(&UDF_SB(sb)->s_alloc_mutex); |
1da177e4c Linux-2.6.12-rc2 |
2482 2483 2484 |
return accum; } |
cb00ea352 UDF: coding style... |
2485 2486 |
static unsigned int udf_count_free(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
2487 2488 |
{ unsigned int accum = 0; |
6c79e987d udf: remove some ... |
2489 2490 |
struct udf_sb_info *sbi; struct udf_part_map *map; |
1da177e4c Linux-2.6.12-rc2 |
2491 |
|
6c79e987d udf: remove some ... |
2492 2493 |
sbi = UDF_SB(sb); if (sbi->s_lvid_bh) { |
4b11111ab udf: fix coding s... |
2494 2495 2496 |
struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *) sbi->s_lvid_bh->b_data; |
6c79e987d udf: remove some ... |
2497 |
if (le32_to_cpu(lvid->numOfPartitions) > sbi->s_partition) { |
4b11111ab udf: fix coding s... |
2498 2499 |
accum = le32_to_cpu( lvid->freeSpaceTable[sbi->s_partition]); |
1da177e4c Linux-2.6.12-rc2 |
2500 2501 2502 2503 2504 2505 2506 |
if (accum == 0xFFFFFFFF) accum = 0; } } if (accum) return accum; |
6c79e987d udf: remove some ... |
2507 2508 |
map = &sbi->s_partmaps[sbi->s_partition]; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { |
28de7948a UDF: coding style... |
2509 |
accum += udf_count_free_bitmap(sb, |
6c79e987d udf: remove some ... |
2510 |
map->s_uspace.s_bitmap); |
1da177e4c Linux-2.6.12-rc2 |
2511 |
} |
1da177e4c Linux-2.6.12-rc2 |
2512 2513 |
if (accum) return accum; |
6c79e987d udf: remove some ... |
2514 |
if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { |
28de7948a UDF: coding style... |
2515 |
accum += udf_count_free_table(sb, |
6c79e987d udf: remove some ... |
2516 |
map->s_uspace.s_table); |
1da177e4c Linux-2.6.12-rc2 |
2517 |
} |
1da177e4c Linux-2.6.12-rc2 |
2518 2519 |
return accum; } |
54bb60d53 udf: merge module... |
2520 2521 2522 2523 2524 2525 |
MODULE_AUTHOR("Ben Fennema"); MODULE_DESCRIPTION("Universal Disk Format Filesystem"); MODULE_LICENSE("GPL"); module_init(init_udf_fs) module_exit(exit_udf_fs) |