aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/udf/super.c70
-rw-r--r--fs/udf/udf_sb.h1
2 files changed, 50 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 *);
86static int udf_check_valid(struct super_block *, int, int); 86static int udf_check_valid(struct super_block *, int, int);
87static int udf_vrs(struct super_block *sb, int silent); 87static int udf_vrs(struct super_block *sb, int silent);
88static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad); 88static void udf_load_logicalvolint(struct super_block *, struct kernel_extent_ad);
89static void udf_find_anchor(struct super_block *);
90static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *, 89static int udf_find_fileset(struct super_block *, struct kernel_lb_addr *,
91 struct kernel_lb_addr *); 90 struct kernel_lb_addr *);
92static void udf_load_fileset(struct super_block *, struct buffer_head *, 91static 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 */
792static void udf_find_anchor(struct super_block *sb) 791static 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
841static int udf_find_fileset(struct super_block *sb, 844static 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
1727static 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
1724static int udf_load_sequence(struct super_block *sb, struct kernel_lb_addr *fileset) 1753static 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)
1889static int udf_fill_super(struct super_block *sb, void *options, int silent) 1918static 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;
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h
index 158221ecdc42..2dd921928338 100644
--- a/fs/udf/udf_sb.h
+++ b/fs/udf/udf_sb.h
@@ -30,6 +30,7 @@
30#define UDF_FLAG_GID_SET 16 30#define UDF_FLAG_GID_SET 16
31#define UDF_FLAG_SESSION_SET 17 31#define UDF_FLAG_SESSION_SET 17
32#define UDF_FLAG_LASTBLOCK_SET 18 32#define UDF_FLAG_LASTBLOCK_SET 18
33#define UDF_FLAG_BLOCKSIZE_SET 19
33 34
34#define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 35#define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001
35#define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 36#define UDF_PART_FLAG_UNALLOC_TABLE 0x0002