diff options
author | Conrad Meyer <cse.cem@gmail.com> | 2014-06-06 17:36:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-06 19:08:10 -0400 |
commit | 190a8843ded231638d0e7ae7d8ca6a712472d114 (patch) | |
tree | 30e99192bc39f30584197eab47b119478d8dfe37 /fs/fat | |
parent | a19189e5535ed8fd191d8989fc39da1637cfa224 (diff) |
fs/fat/: add support for DOS 1.x formatted volumes
Add structure for parsed BPB information, struct fat_bios_param_block,
and move all of the deserialization and validation logic from
fat_fill_super() into fat_read_bpb().
Add a 'dos1xfloppy' mount option to infer DOS 2.x BIOS Parameter Block
defaults from block device geometry for ancient floppies and floppy
images, as a fall-back from the default BPB parsing logic.
When fat_read_bpb() finds an invalid FAT filesystem and dos1xfloppy is
set, fall back to fat_read_static_bpb(). fat_read_static_bpb()
validates that the entire BPB is zero, and that the floppy has a
DOS-style 8086 code bootstrapping header. Then it fills in default BPB
values from media size and a table.[0]
Media size is assumed to be static for archaic FAT volumes. See also:
[1].
Fixes kernel.org bug #42617.
[0]: https://en.wikipedia.org/wiki/File_Allocation_Table#Exceptions
[1]: http://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html
[hirofumi@mail.parknet.co.jp: fix missed error code]
Signed-off-by: Conrad Meyer <cse.cem@gmail.com>
Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Tested-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/fat')
-rw-r--r-- | fs/fat/fat.h | 3 | ||||
-rw-r--r-- | fs/fat/inode.c | 343 |
2 files changed, 269 insertions, 77 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 7c31f4bc74a9..e0c4ba39a377 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h | |||
@@ -52,7 +52,8 @@ struct fat_mount_options { | |||
52 | usefree:1, /* Use free_clusters for FAT32 */ | 52 | usefree:1, /* Use free_clusters for FAT32 */ |
53 | tz_set:1, /* Filesystem timestamps' offset set */ | 53 | tz_set:1, /* Filesystem timestamps' offset set */ |
54 | rodir:1, /* allow ATTR_RO for directory */ | 54 | rodir:1, /* allow ATTR_RO for directory */ |
55 | discard:1; /* Issue discard requests on deletions */ | 55 | discard:1, /* Issue discard requests on deletions */ |
56 | dos1xfloppy:1; /* Assume default BPB for DOS 1.x floppies */ | ||
56 | }; | 57 | }; |
57 | 58 | ||
58 | #define FAT_HASH_BITS 8 | 59 | #define FAT_HASH_BITS 8 |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index b3361fe2bcb5..babff0f40696 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -35,9 +35,71 @@ | |||
35 | #define CONFIG_FAT_DEFAULT_IOCHARSET "" | 35 | #define CONFIG_FAT_DEFAULT_IOCHARSET "" |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #define KB_IN_SECTORS 2 | ||
39 | |||
40 | /* | ||
41 | * A deserialized copy of the on-disk structure laid out in struct | ||
42 | * fat_boot_sector. | ||
43 | */ | ||
44 | struct fat_bios_param_block { | ||
45 | u16 fat_sector_size; | ||
46 | u8 fat_sec_per_clus; | ||
47 | u16 fat_reserved; | ||
48 | u8 fat_fats; | ||
49 | u16 fat_dir_entries; | ||
50 | u16 fat_sectors; | ||
51 | u16 fat_fat_length; | ||
52 | u32 fat_total_sect; | ||
53 | |||
54 | u8 fat16_state; | ||
55 | u32 fat16_vol_id; | ||
56 | |||
57 | u32 fat32_length; | ||
58 | u32 fat32_root_cluster; | ||
59 | u16 fat32_info_sector; | ||
60 | u8 fat32_state; | ||
61 | u32 fat32_vol_id; | ||
62 | }; | ||
63 | |||
38 | static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE; | 64 | static int fat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE; |
39 | static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET; | 65 | static char fat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET; |
40 | 66 | ||
67 | static struct fat_floppy_defaults { | ||
68 | unsigned nr_sectors; | ||
69 | unsigned sec_per_clus; | ||
70 | unsigned dir_entries; | ||
71 | unsigned media; | ||
72 | unsigned fat_length; | ||
73 | } floppy_defaults[] = { | ||
74 | { | ||
75 | .nr_sectors = 160 * KB_IN_SECTORS, | ||
76 | .sec_per_clus = 1, | ||
77 | .dir_entries = 64, | ||
78 | .media = 0xFE, | ||
79 | .fat_length = 1, | ||
80 | }, | ||
81 | { | ||
82 | .nr_sectors = 180 * KB_IN_SECTORS, | ||
83 | .sec_per_clus = 1, | ||
84 | .dir_entries = 64, | ||
85 | .media = 0xFC, | ||
86 | .fat_length = 2, | ||
87 | }, | ||
88 | { | ||
89 | .nr_sectors = 320 * KB_IN_SECTORS, | ||
90 | .sec_per_clus = 2, | ||
91 | .dir_entries = 112, | ||
92 | .media = 0xFF, | ||
93 | .fat_length = 1, | ||
94 | }, | ||
95 | { | ||
96 | .nr_sectors = 360 * KB_IN_SECTORS, | ||
97 | .sec_per_clus = 2, | ||
98 | .dir_entries = 112, | ||
99 | .media = 0xFD, | ||
100 | .fat_length = 2, | ||
101 | }, | ||
102 | }; | ||
41 | 103 | ||
42 | static int fat_add_cluster(struct inode *inode) | 104 | static int fat_add_cluster(struct inode *inode) |
43 | { | 105 | { |
@@ -853,6 +915,8 @@ static int fat_show_options(struct seq_file *m, struct dentry *root) | |||
853 | seq_puts(m, ",nfs=stale_rw"); | 915 | seq_puts(m, ",nfs=stale_rw"); |
854 | if (opts->discard) | 916 | if (opts->discard) |
855 | seq_puts(m, ",discard"); | 917 | seq_puts(m, ",discard"); |
918 | if (opts->dos1xfloppy) | ||
919 | seq_puts(m, ",dos1xfloppy"); | ||
856 | 920 | ||
857 | return 0; | 921 | return 0; |
858 | } | 922 | } |
@@ -867,7 +931,7 @@ enum { | |||
867 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, | 931 | Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, |
868 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, | 932 | Opt_obsolete, Opt_flush, Opt_tz_utc, Opt_rodir, Opt_err_cont, |
869 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, | 933 | Opt_err_panic, Opt_err_ro, Opt_discard, Opt_nfs, Opt_time_offset, |
870 | Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err, | 934 | Opt_nfs_stale_rw, Opt_nfs_nostale_ro, Opt_err, Opt_dos1xfloppy, |
871 | }; | 935 | }; |
872 | 936 | ||
873 | static const match_table_t fat_tokens = { | 937 | static const match_table_t fat_tokens = { |
@@ -900,6 +964,7 @@ static const match_table_t fat_tokens = { | |||
900 | {Opt_nfs_stale_rw, "nfs"}, | 964 | {Opt_nfs_stale_rw, "nfs"}, |
901 | {Opt_nfs_stale_rw, "nfs=stale_rw"}, | 965 | {Opt_nfs_stale_rw, "nfs=stale_rw"}, |
902 | {Opt_nfs_nostale_ro, "nfs=nostale_ro"}, | 966 | {Opt_nfs_nostale_ro, "nfs=nostale_ro"}, |
967 | {Opt_dos1xfloppy, "dos1xfloppy"}, | ||
903 | {Opt_obsolete, "conv=binary"}, | 968 | {Opt_obsolete, "conv=binary"}, |
904 | {Opt_obsolete, "conv=text"}, | 969 | {Opt_obsolete, "conv=text"}, |
905 | {Opt_obsolete, "conv=auto"}, | 970 | {Opt_obsolete, "conv=auto"}, |
@@ -1102,6 +1167,9 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat, | |||
1102 | case Opt_nfs_nostale_ro: | 1167 | case Opt_nfs_nostale_ro: |
1103 | opts->nfs = FAT_NFS_NOSTALE_RO; | 1168 | opts->nfs = FAT_NFS_NOSTALE_RO; |
1104 | break; | 1169 | break; |
1170 | case Opt_dos1xfloppy: | ||
1171 | opts->dos1xfloppy = 1; | ||
1172 | break; | ||
1105 | 1173 | ||
1106 | /* msdos specific */ | 1174 | /* msdos specific */ |
1107 | case Opt_dots: | 1175 | case Opt_dots: |
@@ -1247,6 +1315,169 @@ static unsigned long calc_fat_clusters(struct super_block *sb) | |||
1247 | return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; | 1315 | return sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; |
1248 | } | 1316 | } |
1249 | 1317 | ||
1318 | static bool fat_bpb_is_zero(struct fat_boot_sector *b) | ||
1319 | { | ||
1320 | if (get_unaligned_le16(&b->sector_size)) | ||
1321 | return false; | ||
1322 | if (b->sec_per_clus) | ||
1323 | return false; | ||
1324 | if (b->reserved) | ||
1325 | return false; | ||
1326 | if (b->fats) | ||
1327 | return false; | ||
1328 | if (get_unaligned_le16(&b->dir_entries)) | ||
1329 | return false; | ||
1330 | if (get_unaligned_le16(&b->sectors)) | ||
1331 | return false; | ||
1332 | if (b->media) | ||
1333 | return false; | ||
1334 | if (b->fat_length) | ||
1335 | return false; | ||
1336 | if (b->secs_track) | ||
1337 | return false; | ||
1338 | if (b->heads) | ||
1339 | return false; | ||
1340 | return true; | ||
1341 | } | ||
1342 | |||
1343 | static int fat_read_bpb(struct super_block *sb, struct fat_boot_sector *b, | ||
1344 | int silent, struct fat_bios_param_block *bpb) | ||
1345 | { | ||
1346 | int error = -EINVAL; | ||
1347 | |||
1348 | /* Read in BPB ... */ | ||
1349 | memset(bpb, 0, sizeof(*bpb)); | ||
1350 | bpb->fat_sector_size = get_unaligned_le16(&b->sector_size); | ||
1351 | bpb->fat_sec_per_clus = b->sec_per_clus; | ||
1352 | bpb->fat_reserved = le16_to_cpu(b->reserved); | ||
1353 | bpb->fat_fats = b->fats; | ||
1354 | bpb->fat_dir_entries = get_unaligned_le16(&b->dir_entries); | ||
1355 | bpb->fat_sectors = get_unaligned_le16(&b->sectors); | ||
1356 | bpb->fat_fat_length = le16_to_cpu(b->fat_length); | ||
1357 | bpb->fat_total_sect = le32_to_cpu(b->total_sect); | ||
1358 | |||
1359 | bpb->fat16_state = b->fat16.state; | ||
1360 | bpb->fat16_vol_id = get_unaligned_le32(b->fat16.vol_id); | ||
1361 | |||
1362 | bpb->fat32_length = le32_to_cpu(b->fat32.length); | ||
1363 | bpb->fat32_root_cluster = le32_to_cpu(b->fat32.root_cluster); | ||
1364 | bpb->fat32_info_sector = le16_to_cpu(b->fat32.info_sector); | ||
1365 | bpb->fat32_state = b->fat32.state; | ||
1366 | bpb->fat32_vol_id = get_unaligned_le32(b->fat32.vol_id); | ||
1367 | |||
1368 | /* Validate this looks like a FAT filesystem BPB */ | ||
1369 | if (!bpb->fat_reserved) { | ||
1370 | if (!silent) | ||
1371 | fat_msg(sb, KERN_ERR, | ||
1372 | "bogus number of reserved sectors"); | ||
1373 | goto out; | ||
1374 | } | ||
1375 | if (!bpb->fat_fats) { | ||
1376 | if (!silent) | ||
1377 | fat_msg(sb, KERN_ERR, "bogus number of FAT structure"); | ||
1378 | goto out; | ||
1379 | } | ||
1380 | |||
1381 | /* | ||
1382 | * Earlier we checked here that b->secs_track and b->head are nonzero, | ||
1383 | * but it turns out valid FAT filesystems can have zero there. | ||
1384 | */ | ||
1385 | |||
1386 | if (!fat_valid_media(b->media)) { | ||
1387 | if (!silent) | ||
1388 | fat_msg(sb, KERN_ERR, "invalid media value (0x%02x)", | ||
1389 | (unsigned)b->media); | ||
1390 | goto out; | ||
1391 | } | ||
1392 | |||
1393 | if (!is_power_of_2(bpb->fat_sector_size) | ||
1394 | || (bpb->fat_sector_size < 512) | ||
1395 | || (bpb->fat_sector_size > 4096)) { | ||
1396 | if (!silent) | ||
1397 | fat_msg(sb, KERN_ERR, "bogus logical sector size %u", | ||
1398 | (unsigned)bpb->fat_sector_size); | ||
1399 | goto out; | ||
1400 | } | ||
1401 | |||
1402 | if (!is_power_of_2(bpb->fat_sec_per_clus)) { | ||
1403 | if (!silent) | ||
1404 | fat_msg(sb, KERN_ERR, "bogus sectors per cluster %u", | ||
1405 | (unsigned)bpb->fat_sec_per_clus); | ||
1406 | goto out; | ||
1407 | } | ||
1408 | |||
1409 | error = 0; | ||
1410 | |||
1411 | out: | ||
1412 | return error; | ||
1413 | } | ||
1414 | |||
1415 | static int fat_read_static_bpb(struct super_block *sb, | ||
1416 | struct fat_boot_sector *b, int silent, | ||
1417 | struct fat_bios_param_block *bpb) | ||
1418 | { | ||
1419 | static const char *notdos1x = "This doesn't look like a DOS 1.x volume"; | ||
1420 | |||
1421 | struct fat_floppy_defaults *fdefaults = NULL; | ||
1422 | int error = -EINVAL; | ||
1423 | sector_t bd_sects; | ||
1424 | unsigned i; | ||
1425 | |||
1426 | bd_sects = i_size_read(sb->s_bdev->bd_inode) / SECTOR_SIZE; | ||
1427 | |||
1428 | /* 16-bit DOS 1.x reliably wrote bootstrap short-jmp code */ | ||
1429 | if (b->ignored[0] != 0xeb || b->ignored[2] != 0x90) { | ||
1430 | if (!silent) | ||
1431 | fat_msg(sb, KERN_ERR, | ||
1432 | "%s; no bootstrapping code", notdos1x); | ||
1433 | goto out; | ||
1434 | } | ||
1435 | |||
1436 | /* | ||
1437 | * If any value in this region is non-zero, it isn't archaic | ||
1438 | * DOS. | ||
1439 | */ | ||
1440 | if (!fat_bpb_is_zero(b)) { | ||
1441 | if (!silent) | ||
1442 | fat_msg(sb, KERN_ERR, | ||
1443 | "%s; DOS 2.x BPB is non-zero", notdos1x); | ||
1444 | goto out; | ||
1445 | } | ||
1446 | |||
1447 | for (i = 0; i < ARRAY_SIZE(floppy_defaults); i++) { | ||
1448 | if (floppy_defaults[i].nr_sectors == bd_sects) { | ||
1449 | fdefaults = &floppy_defaults[i]; | ||
1450 | break; | ||
1451 | } | ||
1452 | } | ||
1453 | |||
1454 | if (fdefaults == NULL) { | ||
1455 | if (!silent) | ||
1456 | fat_msg(sb, KERN_WARNING, | ||
1457 | "This looks like a DOS 1.x volume, but isn't a recognized floppy size (%llu sectors)", | ||
1458 | (u64)bd_sects); | ||
1459 | goto out; | ||
1460 | } | ||
1461 | |||
1462 | if (!silent) | ||
1463 | fat_msg(sb, KERN_INFO, | ||
1464 | "This looks like a DOS 1.x volume; assuming default BPB values"); | ||
1465 | |||
1466 | memset(bpb, 0, sizeof(*bpb)); | ||
1467 | bpb->fat_sector_size = SECTOR_SIZE; | ||
1468 | bpb->fat_sec_per_clus = fdefaults->sec_per_clus; | ||
1469 | bpb->fat_reserved = 1; | ||
1470 | bpb->fat_fats = 2; | ||
1471 | bpb->fat_dir_entries = fdefaults->dir_entries; | ||
1472 | bpb->fat_sectors = fdefaults->nr_sectors; | ||
1473 | bpb->fat_fat_length = fdefaults->fat_length; | ||
1474 | |||
1475 | error = 0; | ||
1476 | |||
1477 | out: | ||
1478 | return error; | ||
1479 | } | ||
1480 | |||
1250 | /* | 1481 | /* |
1251 | * Read the super block of an MS-DOS FS. | 1482 | * Read the super block of an MS-DOS FS. |
1252 | */ | 1483 | */ |
@@ -1256,12 +1487,11 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1256 | struct inode *root_inode = NULL, *fat_inode = NULL; | 1487 | struct inode *root_inode = NULL, *fat_inode = NULL; |
1257 | struct inode *fsinfo_inode = NULL; | 1488 | struct inode *fsinfo_inode = NULL; |
1258 | struct buffer_head *bh; | 1489 | struct buffer_head *bh; |
1259 | struct fat_boot_sector *b; | 1490 | struct fat_bios_param_block bpb; |
1260 | struct msdos_sb_info *sbi; | 1491 | struct msdos_sb_info *sbi; |
1261 | u16 logical_sector_size; | 1492 | u16 logical_sector_size; |
1262 | u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors; | 1493 | u32 total_sectors, total_clusters, fat_clusters, rootdir_sectors; |
1263 | int debug; | 1494 | int debug; |
1264 | unsigned int media; | ||
1265 | long error; | 1495 | long error; |
1266 | char buf[50]; | 1496 | char buf[50]; |
1267 | 1497 | ||
@@ -1298,100 +1528,72 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1298 | goto out_fail; | 1528 | goto out_fail; |
1299 | } | 1529 | } |
1300 | 1530 | ||
1301 | b = (struct fat_boot_sector *) bh->b_data; | 1531 | error = fat_read_bpb(sb, (struct fat_boot_sector *)bh->b_data, silent, |
1302 | if (!b->reserved) { | 1532 | &bpb); |
1303 | if (!silent) | 1533 | if (error == -EINVAL && sbi->options.dos1xfloppy) |
1304 | fat_msg(sb, KERN_ERR, "bogus number of reserved sectors"); | 1534 | error = fat_read_static_bpb(sb, |
1305 | brelse(bh); | 1535 | (struct fat_boot_sector *)bh->b_data, silent, &bpb); |
1306 | goto out_invalid; | 1536 | brelse(bh); |
1307 | } | ||
1308 | if (!b->fats) { | ||
1309 | if (!silent) | ||
1310 | fat_msg(sb, KERN_ERR, "bogus number of FAT structure"); | ||
1311 | brelse(bh); | ||
1312 | goto out_invalid; | ||
1313 | } | ||
1314 | |||
1315 | /* | ||
1316 | * Earlier we checked here that b->secs_track and b->head are nonzero, | ||
1317 | * but it turns out valid FAT filesystems can have zero there. | ||
1318 | */ | ||
1319 | 1537 | ||
1320 | media = b->media; | 1538 | if (error == -EINVAL) |
1321 | if (!fat_valid_media(media)) { | ||
1322 | if (!silent) | ||
1323 | fat_msg(sb, KERN_ERR, "invalid media value (0x%02x)", | ||
1324 | media); | ||
1325 | brelse(bh); | ||
1326 | goto out_invalid; | ||
1327 | } | ||
1328 | logical_sector_size = get_unaligned_le16(&b->sector_size); | ||
1329 | if (!is_power_of_2(logical_sector_size) | ||
1330 | || (logical_sector_size < 512) | ||
1331 | || (logical_sector_size > 4096)) { | ||
1332 | if (!silent) | ||
1333 | fat_msg(sb, KERN_ERR, "bogus logical sector size %u", | ||
1334 | logical_sector_size); | ||
1335 | brelse(bh); | ||
1336 | goto out_invalid; | ||
1337 | } | ||
1338 | sbi->sec_per_clus = b->sec_per_clus; | ||
1339 | if (!is_power_of_2(sbi->sec_per_clus)) { | ||
1340 | if (!silent) | ||
1341 | fat_msg(sb, KERN_ERR, "bogus sectors per cluster %u", | ||
1342 | sbi->sec_per_clus); | ||
1343 | brelse(bh); | ||
1344 | goto out_invalid; | 1539 | goto out_invalid; |
1345 | } | 1540 | else if (error) |
1541 | goto out_fail; | ||
1542 | |||
1543 | logical_sector_size = bpb.fat_sector_size; | ||
1544 | sbi->sec_per_clus = bpb.fat_sec_per_clus; | ||
1346 | 1545 | ||
1546 | error = -EIO; | ||
1347 | if (logical_sector_size < sb->s_blocksize) { | 1547 | if (logical_sector_size < sb->s_blocksize) { |
1348 | fat_msg(sb, KERN_ERR, "logical sector size too small for device" | 1548 | fat_msg(sb, KERN_ERR, "logical sector size too small for device" |
1349 | " (logical sector size = %u)", logical_sector_size); | 1549 | " (logical sector size = %u)", logical_sector_size); |
1350 | brelse(bh); | ||
1351 | goto out_fail; | 1550 | goto out_fail; |
1352 | } | 1551 | } |
1552 | |||
1353 | if (logical_sector_size > sb->s_blocksize) { | 1553 | if (logical_sector_size > sb->s_blocksize) { |
1354 | brelse(bh); | 1554 | struct buffer_head *bh_resize; |
1355 | 1555 | ||
1356 | if (!sb_set_blocksize(sb, logical_sector_size)) { | 1556 | if (!sb_set_blocksize(sb, logical_sector_size)) { |
1357 | fat_msg(sb, KERN_ERR, "unable to set blocksize %u", | 1557 | fat_msg(sb, KERN_ERR, "unable to set blocksize %u", |
1358 | logical_sector_size); | 1558 | logical_sector_size); |
1359 | goto out_fail; | 1559 | goto out_fail; |
1360 | } | 1560 | } |
1361 | bh = sb_bread(sb, 0); | 1561 | |
1362 | if (bh == NULL) { | 1562 | /* Verify that the larger boot sector is fully readable */ |
1563 | bh_resize = sb_bread(sb, 0); | ||
1564 | if (bh_resize == NULL) { | ||
1363 | fat_msg(sb, KERN_ERR, "unable to read boot sector" | 1565 | fat_msg(sb, KERN_ERR, "unable to read boot sector" |
1364 | " (logical sector size = %lu)", | 1566 | " (logical sector size = %lu)", |
1365 | sb->s_blocksize); | 1567 | sb->s_blocksize); |
1366 | goto out_fail; | 1568 | goto out_fail; |
1367 | } | 1569 | } |
1368 | b = (struct fat_boot_sector *) bh->b_data; | 1570 | brelse(bh_resize); |
1369 | } | 1571 | } |
1370 | 1572 | ||
1371 | mutex_init(&sbi->s_lock); | 1573 | mutex_init(&sbi->s_lock); |
1372 | sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus; | 1574 | sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus; |
1373 | sbi->cluster_bits = ffs(sbi->cluster_size) - 1; | 1575 | sbi->cluster_bits = ffs(sbi->cluster_size) - 1; |
1374 | sbi->fats = b->fats; | 1576 | sbi->fats = bpb.fat_fats; |
1375 | sbi->fat_bits = 0; /* Don't know yet */ | 1577 | sbi->fat_bits = 0; /* Don't know yet */ |
1376 | sbi->fat_start = le16_to_cpu(b->reserved); | 1578 | sbi->fat_start = bpb.fat_reserved; |
1377 | sbi->fat_length = le16_to_cpu(b->fat_length); | 1579 | sbi->fat_length = bpb.fat_fat_length; |
1378 | sbi->root_cluster = 0; | 1580 | sbi->root_cluster = 0; |
1379 | sbi->free_clusters = -1; /* Don't know yet */ | 1581 | sbi->free_clusters = -1; /* Don't know yet */ |
1380 | sbi->free_clus_valid = 0; | 1582 | sbi->free_clus_valid = 0; |
1381 | sbi->prev_free = FAT_START_ENT; | 1583 | sbi->prev_free = FAT_START_ENT; |
1382 | sb->s_maxbytes = 0xffffffff; | 1584 | sb->s_maxbytes = 0xffffffff; |
1383 | 1585 | ||
1384 | if (!sbi->fat_length && b->fat32.length) { | 1586 | if (!sbi->fat_length && bpb.fat32_length) { |
1385 | struct fat_boot_fsinfo *fsinfo; | 1587 | struct fat_boot_fsinfo *fsinfo; |
1386 | struct buffer_head *fsinfo_bh; | 1588 | struct buffer_head *fsinfo_bh; |
1387 | 1589 | ||
1388 | /* Must be FAT32 */ | 1590 | /* Must be FAT32 */ |
1389 | sbi->fat_bits = 32; | 1591 | sbi->fat_bits = 32; |
1390 | sbi->fat_length = le32_to_cpu(b->fat32.length); | 1592 | sbi->fat_length = bpb.fat32_length; |
1391 | sbi->root_cluster = le32_to_cpu(b->fat32.root_cluster); | 1593 | sbi->root_cluster = bpb.fat32_root_cluster; |
1392 | 1594 | ||
1393 | /* MC - if info_sector is 0, don't multiply by 0 */ | 1595 | /* MC - if info_sector is 0, don't multiply by 0 */ |
1394 | sbi->fsinfo_sector = le16_to_cpu(b->fat32.info_sector); | 1596 | sbi->fsinfo_sector = bpb.fat32_info_sector; |
1395 | if (sbi->fsinfo_sector == 0) | 1597 | if (sbi->fsinfo_sector == 0) |
1396 | sbi->fsinfo_sector = 1; | 1598 | sbi->fsinfo_sector = 1; |
1397 | 1599 | ||
@@ -1399,7 +1601,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1399 | if (fsinfo_bh == NULL) { | 1601 | if (fsinfo_bh == NULL) { |
1400 | fat_msg(sb, KERN_ERR, "bread failed, FSINFO block" | 1602 | fat_msg(sb, KERN_ERR, "bread failed, FSINFO block" |
1401 | " (sector = %lu)", sbi->fsinfo_sector); | 1603 | " (sector = %lu)", sbi->fsinfo_sector); |
1402 | brelse(bh); | ||
1403 | goto out_fail; | 1604 | goto out_fail; |
1404 | } | 1605 | } |
1405 | 1606 | ||
@@ -1422,35 +1623,28 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1422 | 1623 | ||
1423 | /* interpret volume ID as a little endian 32 bit integer */ | 1624 | /* interpret volume ID as a little endian 32 bit integer */ |
1424 | if (sbi->fat_bits == 32) | 1625 | if (sbi->fat_bits == 32) |
1425 | sbi->vol_id = (((u32)b->fat32.vol_id[0]) | | 1626 | sbi->vol_id = bpb.fat32_vol_id; |
1426 | ((u32)b->fat32.vol_id[1] << 8) | | ||
1427 | ((u32)b->fat32.vol_id[2] << 16) | | ||
1428 | ((u32)b->fat32.vol_id[3] << 24)); | ||
1429 | else /* fat 16 or 12 */ | 1627 | else /* fat 16 or 12 */ |
1430 | sbi->vol_id = (((u32)b->fat16.vol_id[0]) | | 1628 | sbi->vol_id = bpb.fat16_vol_id; |
1431 | ((u32)b->fat16.vol_id[1] << 8) | | ||
1432 | ((u32)b->fat16.vol_id[2] << 16) | | ||
1433 | ((u32)b->fat16.vol_id[3] << 24)); | ||
1434 | 1629 | ||
1435 | sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry); | 1630 | sbi->dir_per_block = sb->s_blocksize / sizeof(struct msdos_dir_entry); |
1436 | sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; | 1631 | sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; |
1437 | 1632 | ||
1438 | sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length; | 1633 | sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length; |
1439 | sbi->dir_entries = get_unaligned_le16(&b->dir_entries); | 1634 | sbi->dir_entries = bpb.fat_dir_entries; |
1440 | if (sbi->dir_entries & (sbi->dir_per_block - 1)) { | 1635 | if (sbi->dir_entries & (sbi->dir_per_block - 1)) { |
1441 | if (!silent) | 1636 | if (!silent) |
1442 | fat_msg(sb, KERN_ERR, "bogus directory-entries per block" | 1637 | fat_msg(sb, KERN_ERR, "bogus directory-entries per block" |
1443 | " (%u)", sbi->dir_entries); | 1638 | " (%u)", sbi->dir_entries); |
1444 | brelse(bh); | ||
1445 | goto out_invalid; | 1639 | goto out_invalid; |
1446 | } | 1640 | } |
1447 | 1641 | ||
1448 | rootdir_sectors = sbi->dir_entries | 1642 | rootdir_sectors = sbi->dir_entries |
1449 | * sizeof(struct msdos_dir_entry) / sb->s_blocksize; | 1643 | * sizeof(struct msdos_dir_entry) / sb->s_blocksize; |
1450 | sbi->data_start = sbi->dir_start + rootdir_sectors; | 1644 | sbi->data_start = sbi->dir_start + rootdir_sectors; |
1451 | total_sectors = get_unaligned_le16(&b->sectors); | 1645 | total_sectors = bpb.fat_sectors; |
1452 | if (total_sectors == 0) | 1646 | if (total_sectors == 0) |
1453 | total_sectors = le32_to_cpu(b->total_sect); | 1647 | total_sectors = bpb.fat_total_sect; |
1454 | 1648 | ||
1455 | total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus; | 1649 | total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus; |
1456 | 1650 | ||
@@ -1459,9 +1653,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1459 | 1653 | ||
1460 | /* some OSes set FAT_STATE_DIRTY and clean it on unmount. */ | 1654 | /* some OSes set FAT_STATE_DIRTY and clean it on unmount. */ |
1461 | if (sbi->fat_bits == 32) | 1655 | if (sbi->fat_bits == 32) |
1462 | sbi->dirty = b->fat32.state & FAT_STATE_DIRTY; | 1656 | sbi->dirty = bpb.fat32_state & FAT_STATE_DIRTY; |
1463 | else /* fat 16 or 12 */ | 1657 | else /* fat 16 or 12 */ |
1464 | sbi->dirty = b->fat16.state & FAT_STATE_DIRTY; | 1658 | sbi->dirty = bpb.fat16_state & FAT_STATE_DIRTY; |
1465 | 1659 | ||
1466 | /* check that FAT table does not overflow */ | 1660 | /* check that FAT table does not overflow */ |
1467 | fat_clusters = calc_fat_clusters(sb); | 1661 | fat_clusters = calc_fat_clusters(sb); |
@@ -1470,7 +1664,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1470 | if (!silent) | 1664 | if (!silent) |
1471 | fat_msg(sb, KERN_ERR, "count of clusters too big (%u)", | 1665 | fat_msg(sb, KERN_ERR, "count of clusters too big (%u)", |
1472 | total_clusters); | 1666 | total_clusters); |
1473 | brelse(bh); | ||
1474 | goto out_invalid; | 1667 | goto out_invalid; |
1475 | } | 1668 | } |
1476 | 1669 | ||
@@ -1483,8 +1676,6 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, | |||
1483 | if (sbi->prev_free < FAT_START_ENT) | 1676 | if (sbi->prev_free < FAT_START_ENT) |
1484 | sbi->prev_free = FAT_START_ENT; | 1677 | sbi->prev_free = FAT_START_ENT; |
1485 | 1678 | ||
1486 | brelse(bh); | ||
1487 | |||
1488 | /* set up enough so that it can read an inode */ | 1679 | /* set up enough so that it can read an inode */ |
1489 | fat_hash_init(sb); | 1680 | fat_hash_init(sb); |
1490 | dir_hash_init(sb); | 1681 | dir_hash_init(sb); |