diff options
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/super.c | 70 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 1 |
2 files changed, 50 insertions, 21 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 36a467ca162..f8fece43f6c 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -86,7 +86,6 @@ static int udf_remount_fs(struct super_block *, int *, char *); static int udf_check_valid(struct super_block *, int, int); static int udf_vrs(struct super_block *sb, int silent); static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); -static void udf_find_anchor(struct super_block *); static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, struct kernel_lb_addr *); static void udf_load_fileset(struct super_block *, struct buffer_head *, @@ -260,7 +259,7 @@ static int udf_show_options(struct seq_file *seq, struct vfsmount *mnt) if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) seq_puts(seq, ",nostrict"); - if (sb->s_blocksize != UDF_DEFAULT_BLOCKSIZE) + if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET)) seq_printf(seq, ",bs=%lu", sb->s_blocksize); if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) seq_puts(seq, ",unhide"); @@ -416,7 +415,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, int option; uopt->novrs = 0; - uopt->blocksize = UDF_DEFAULT_BLOCKSIZE; uopt->partition = 0xFFFF; uopt->session = 0xFFFFFFFF; uopt->lastblock = 0; @@ -444,6 +442,7 @@ static int udf_parse_options(char *options, struct udf_options *uopt, if (match_int(&args[0], &option)) return 0; uopt->blocksize = option; + uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET); break; case Opt_unhide: uopt->flags |= (1 << UDF_FLAG_UNHIDE); @@ -789,12 +788,13 @@ static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) * Return 1 if not found, 0 if ok * */ -static void udf_find_anchor(struct super_block *sb) +static int udf_find_anchor(struct super_block *sb) { sector_t lastblock; struct buffer_head *bh = NULL; uint16_t ident; int i; + int anchor_found = 0; struct udf_sb_info *sbi = UDF_SB(sb); lastblock = udf_scan_anchors(sb, sbi->s_last_block); @@ -832,10 +832,13 @@ check_anchor: brelse(bh); if (ident != TAG_IDENT_AVDP) sbi->s_anchor[i] = 0; + else + anchor_found = 1; } } sbi->s_last_block = lastblock; + return anchor_found; } static int udf_find_fileset(struct super_block *sb, @@ -1721,6 +1724,32 @@ static int udf_check_valid(struct super_block *sb, int novrs, int silent) return !block; } +static int udf_check_volume(struct super_block *sb, + struct udf_options *uopt, int silent) +{ + struct udf_sb_info *sbi = UDF_SB(sb); + + if (!sb_set_blocksize(sb, uopt->blocksize)) { + if (!silent) + printk(KERN_WARNING "UDF-fs: Bad block size\n"); + return 0; + } + sbi->s_last_block = uopt->lastblock; + if (udf_check_valid(sb, uopt->novrs, silent)) { + if (!silent) + printk(KERN_WARNING "UDF-fs: No VRS found\n"); + return 0; + } + sbi->s_anchor[0] = sbi->s_anchor[1] = 0; + sbi->s_anchor[2] = uopt->anchor; + if (!udf_find_anchor(sb)) { + if (!silent) + printk(KERN_WARNING "UDF-fs: No anchor found\n"); + return 0; + } + return 1; +} + static int udf_load_sequence(struct super_block *sb, struct kernel_lb_addr *fileset) { struct anchorVolDescPtr *anchor; @@ -1889,6 +1918,7 @@ static void udf_free_partition(struct udf_part_map *map) static int udf_fill_super(struct super_block *sb, void *options, int silent) { int i; + int found_anchor; struct inode *inode = NULL; struct udf_options uopt; struct kernel_lb_addr rootdir, fileset; @@ -1941,13 +1971,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) sbi->s_dmode = uopt.dmode; sbi->s_nls_map = uopt.nls_map; - /* Set the block size for all transfers */ - if (!sb_min_blocksize(sb, uopt.blocksize)) { - udf_debug("Bad block size (%d)\n", uopt.blocksize); - printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize); - goto error_out; - } - if (uopt.session == 0xFFFFFFFF) sbi->s_session = udf_get_last_session(sb); else @@ -1955,17 +1978,22 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) udf_debug("Multi-session=%d\n", sbi->s_session); - sbi->s_last_block = uopt.lastblock; - sbi->s_anchor[0] = sbi->s_anchor[1] = 0; - sbi->s_anchor[2] = uopt.anchor; - - if (udf_check_valid(sb, uopt.novrs, silent)) { - /* read volume recognition sequences */ - printk(KERN_WARNING "UDF-fs: No VRS found\n"); - goto error_out; + if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { + found_anchor = udf_check_volume(sb, &uopt, silent); + } else { + uopt.blocksize = bdev_hardsect_size(sb->s_bdev); + found_anchor = udf_check_volume(sb, &uopt, silent); + if (!found_anchor && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { + if (!silent) + printk(KERN_NOTICE + "UDF-fs: Rescanning with blocksize " + "%d\n", UDF_DEFAULT_BLOCKSIZE); + uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; + found_anchor = udf_check_volume(sb, &uopt, silent); + } } - - udf_find_anchor(sb); + if (!found_anchor) + goto error_out; /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 158221ecdc4..2dd92192833 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h @@ -30,6 +30,7 @@ #define UDF_FLAG_GID_SET 16 #define UDF_FLAG_SESSION_SET 17 #define UDF_FLAG_LASTBLOCK_SET 18 +#define UDF_FLAG_BLOCKSIZE_SET 19 #define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 #define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 |