diff options
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 70 |
1 files changed, 49 insertions, 21 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index 36a467ca1622..f8fece43f6c6 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 *); | |||
86 | static int udf_check_valid(struct super_block *, int, int); | 86 | static int udf_check_valid(struct super_block *, int, int); |
87 | static int udf_vrs(struct super_block *sb, int silent); | 87 | static int udf_vrs(struct super_block *sb, int silent); |
88 | static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); | 88 | static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); |
89 | static void udf_find_anchor(struct super_block *); | ||
90 | static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, | 89 | static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, |
91 | struct kernel_lb_addr *); | 90 | struct kernel_lb_addr *); |
92 | static void udf_load_fileset(struct super_block *, struct buffer_head *, | 91 | 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) | |||
260 | 259 | ||
261 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) | 260 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) |
262 | seq_puts(seq, ",nostrict"); | 261 | seq_puts(seq, ",nostrict"); |
263 | if (sb->s_blocksize != UDF_DEFAULT_BLOCKSIZE) | 262 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_BLOCKSIZE_SET)) |
264 | seq_printf(seq, ",bs=%lu", sb->s_blocksize); | 263 | seq_printf(seq, ",bs=%lu", sb->s_blocksize); |
265 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) | 264 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) |
266 | seq_puts(seq, ",unhide"); | 265 | seq_puts(seq, ",unhide"); |
@@ -416,7 +415,6 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
416 | int option; | 415 | int option; |
417 | 416 | ||
418 | uopt->novrs = 0; | 417 | uopt->novrs = 0; |
419 | uopt->blocksize = UDF_DEFAULT_BLOCKSIZE; | ||
420 | uopt->partition = 0xFFFF; | 418 | uopt->partition = 0xFFFF; |
421 | uopt->session = 0xFFFFFFFF; | 419 | uopt->session = 0xFFFFFFFF; |
422 | uopt->lastblock = 0; | 420 | uopt->lastblock = 0; |
@@ -444,6 +442,7 @@ static int udf_parse_options(char *options, struct udf_options *uopt, | |||
444 | if (match_int(&args[0], &option)) | 442 | if (match_int(&args[0], &option)) |
445 | return 0; | 443 | return 0; |
446 | uopt->blocksize = option; | 444 | uopt->blocksize = option; |
445 | uopt->flags |= (1 << UDF_FLAG_BLOCKSIZE_SET); | ||
447 | break; | 446 | break; |
448 | case Opt_unhide: | 447 | case Opt_unhide: |
449 | uopt->flags |= (1 << UDF_FLAG_UNHIDE); | 448 | uopt->flags |= (1 << UDF_FLAG_UNHIDE); |
@@ -789,12 +788,13 @@ static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock) | |||
789 | * Return 1 if not found, 0 if ok | 788 | * Return 1 if not found, 0 if ok |
790 | * | 789 | * |
791 | */ | 790 | */ |
792 | static void udf_find_anchor(struct super_block *sb) | 791 | static int udf_find_anchor(struct super_block *sb) |
793 | { | 792 | { |
794 | sector_t lastblock; | 793 | sector_t lastblock; |
795 | struct buffer_head *bh = NULL; | 794 | struct buffer_head *bh = NULL; |
796 | uint16_t ident; | 795 | uint16_t ident; |
797 | int i; | 796 | int i; |
797 | int anchor_found = 0; | ||
798 | struct udf_sb_info *sbi = UDF_SB(sb); | 798 | struct udf_sb_info *sbi = UDF_SB(sb); |
799 | 799 | ||
800 | lastblock = udf_scan_anchors(sb, sbi->s_last_block); | 800 | lastblock = udf_scan_anchors(sb, sbi->s_last_block); |
@@ -832,10 +832,13 @@ check_anchor: | |||
832 | brelse(bh); | 832 | brelse(bh); |
833 | if (ident != TAG_IDENT_AVDP) | 833 | if (ident != TAG_IDENT_AVDP) |
834 | sbi->s_anchor[i] = 0; | 834 | sbi->s_anchor[i] = 0; |
835 | else | ||
836 | anchor_found = 1; | ||
835 | } | 837 | } |
836 | } | 838 | } |
837 | 839 | ||
838 | sbi->s_last_block = lastblock; | 840 | sbi->s_last_block = lastblock; |
841 | return anchor_found; | ||
839 | } | 842 | } |
840 | 843 | ||
841 | static int udf_find_fileset(struct super_block *sb, | 844 | 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) | |||
1721 | return !block; | 1724 | return !block; |
1722 | } | 1725 | } |
1723 | 1726 | ||
1727 | static int udf_check_volume(struct super_block *sb, | ||
1728 | struct udf_options *uopt, int silent) | ||
1729 | { | ||
1730 | struct udf_sb_info *sbi = UDF_SB(sb); | ||
1731 | |||
1732 | if (!sb_set_blocksize(sb, uopt->blocksize)) { | ||
1733 | if (!silent) | ||
1734 | printk(KERN_WARNING "UDF-fs: Bad block size\n"); | ||
1735 | return 0; | ||
1736 | } | ||
1737 | sbi->s_last_block = uopt->lastblock; | ||
1738 | if (udf_check_valid(sb, uopt->novrs, silent)) { | ||
1739 | if (!silent) | ||
1740 | printk(KERN_WARNING "UDF-fs: No VRS found\n"); | ||
1741 | return 0; | ||
1742 | } | ||
1743 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; | ||
1744 | sbi->s_anchor[2] = uopt->anchor; | ||
1745 | if (!udf_find_anchor(sb)) { | ||
1746 | if (!silent) | ||
1747 | printk(KERN_WARNING "UDF-fs: No anchor found\n"); | ||
1748 | return 0; | ||
1749 | } | ||
1750 | return 1; | ||
1751 | } | ||
1752 | |||
1724 | static int udf_load_sequence(struct super_block *sb, struct kernel_lb_addr *fileset) | 1753 | static int udf_load_sequence(struct super_block *sb, struct kernel_lb_addr *fileset) |
1725 | { | 1754 | { |
1726 | struct anchorVolDescPtr *anchor; | 1755 | struct anchorVolDescPtr *anchor; |
@@ -1889,6 +1918,7 @@ static void udf_free_partition(struct udf_part_map *map) | |||
1889 | static int udf_fill_super(struct super_block *sb, void *options, int silent) | 1918 | static int udf_fill_super(struct super_block *sb, void *options, int silent) |
1890 | { | 1919 | { |
1891 | int i; | 1920 | int i; |
1921 | int found_anchor; | ||
1892 | struct inode *inode = NULL; | 1922 | struct inode *inode = NULL; |
1893 | struct udf_options uopt; | 1923 | struct udf_options uopt; |
1894 | struct kernel_lb_addr rootdir, fileset; | 1924 | struct kernel_lb_addr rootdir, fileset; |
@@ -1941,13 +1971,6 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1941 | sbi->s_dmode = uopt.dmode; | 1971 | sbi->s_dmode = uopt.dmode; |
1942 | sbi->s_nls_map = uopt.nls_map; | 1972 | sbi->s_nls_map = uopt.nls_map; |
1943 | 1973 | ||
1944 | /* Set the block size for all transfers */ | ||
1945 | if (!sb_min_blocksize(sb, uopt.blocksize)) { | ||
1946 | udf_debug("Bad block size (%d)\n", uopt.blocksize); | ||
1947 | printk(KERN_ERR "udf: bad block size (%d)\n", uopt.blocksize); | ||
1948 | goto error_out; | ||
1949 | } | ||
1950 | |||
1951 | if (uopt.session == 0xFFFFFFFF) | 1974 | if (uopt.session == 0xFFFFFFFF) |
1952 | sbi->s_session = udf_get_last_session(sb); | 1975 | sbi->s_session = udf_get_last_session(sb); |
1953 | else | 1976 | else |
@@ -1955,17 +1978,22 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1955 | 1978 | ||
1956 | udf_debug("Multi-session=%d\n", sbi->s_session); | 1979 | udf_debug("Multi-session=%d\n", sbi->s_session); |
1957 | 1980 | ||
1958 | sbi->s_last_block = uopt.lastblock; | 1981 | if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { |
1959 | sbi->s_anchor[0] = sbi->s_anchor[1] = 0; | 1982 | found_anchor = udf_check_volume(sb, &uopt, silent); |
1960 | sbi->s_anchor[2] = uopt.anchor; | 1983 | } else { |
1961 | 1984 | uopt.blocksize = bdev_hardsect_size(sb->s_bdev); | |
1962 | if (udf_check_valid(sb, uopt.novrs, silent)) { | 1985 | found_anchor = udf_check_volume(sb, &uopt, silent); |
1963 | /* read volume recognition sequences */ | 1986 | if (!found_anchor && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { |
1964 | printk(KERN_WARNING "UDF-fs: No VRS found\n"); | 1987 | if (!silent) |
1965 | goto error_out; | 1988 | printk(KERN_NOTICE |
1989 | "UDF-fs: Rescanning with blocksize " | ||
1990 | "%d\n", UDF_DEFAULT_BLOCKSIZE); | ||
1991 | uopt.blocksize = UDF_DEFAULT_BLOCKSIZE; | ||
1992 | found_anchor = udf_check_volume(sb, &uopt, silent); | ||
1993 | } | ||
1966 | } | 1994 | } |
1967 | 1995 | if (!found_anchor) | |
1968 | udf_find_anchor(sb); | 1996 | goto error_out; |
1969 | 1997 | ||
1970 | /* Fill in the rest of the superblock */ | 1998 | /* Fill in the rest of the superblock */ |
1971 | sb->s_op = &udf_sb_ops; | 1999 | sb->s_op = &udf_sb_ops; |