diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-19 13:05:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-19 13:05:14 -0400 |
commit | c3695331f3a326a468bd6a5b6f05b481b399726b (patch) | |
tree | 7ba112e687646068c0081015a1abf843122c4572 /fs | |
parent | 9af1f5d8f20f97884da55817ab80a6fcd170f296 (diff) | |
parent | b9d8905e4a751e2cdc0fb474856b7183c594dcc6 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF fixes and a reiserfs fix from Jan Kara:
"A couple of udf fixes (most notably a bug in parsing UDF partitions
which led to inability to mount recent Windows installation media) and
a reiserfs fix for handling kstrdup failure"
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
reiserfs: check kstrdup failure
udf: Use correct partition reference number for metadata
udf: Use IS_ERR when loading metadata mirror file entry
udf: Don't BUG on missing metadata partition descriptor
Diffstat (limited to 'fs')
-rw-r--r-- | fs/reiserfs/super.c | 9 | ||||
-rw-r--r-- | fs/udf/partition.c | 13 | ||||
-rw-r--r-- | fs/udf/super.c | 22 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 5 |
4 files changed, 33 insertions, 16 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b8f2d1e8c645..c72c16c5a60f 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -1393,7 +1393,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1393 | unsigned long safe_mask = 0; | 1393 | unsigned long safe_mask = 0; |
1394 | unsigned int commit_max_age = (unsigned int)-1; | 1394 | unsigned int commit_max_age = (unsigned int)-1; |
1395 | struct reiserfs_journal *journal = SB_JOURNAL(s); | 1395 | struct reiserfs_journal *journal = SB_JOURNAL(s); |
1396 | char *new_opts = kstrdup(arg, GFP_KERNEL); | 1396 | char *new_opts; |
1397 | int err; | 1397 | int err; |
1398 | char *qf_names[REISERFS_MAXQUOTAS]; | 1398 | char *qf_names[REISERFS_MAXQUOTAS]; |
1399 | unsigned int qfmt = 0; | 1399 | unsigned int qfmt = 0; |
@@ -1401,6 +1401,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1401 | int i; | 1401 | int i; |
1402 | #endif | 1402 | #endif |
1403 | 1403 | ||
1404 | new_opts = kstrdup(arg, GFP_KERNEL); | ||
1405 | if (arg && !new_opts) | ||
1406 | return -ENOMEM; | ||
1407 | |||
1404 | sync_filesystem(s); | 1408 | sync_filesystem(s); |
1405 | reiserfs_write_lock(s); | 1409 | reiserfs_write_lock(s); |
1406 | 1410 | ||
@@ -1546,7 +1550,8 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1546 | } | 1550 | } |
1547 | 1551 | ||
1548 | out_ok_unlocked: | 1552 | out_ok_unlocked: |
1549 | replace_mount_options(s, new_opts); | 1553 | if (new_opts) |
1554 | replace_mount_options(s, new_opts); | ||
1550 | return 0; | 1555 | return 0; |
1551 | 1556 | ||
1552 | out_err_unlock: | 1557 | out_err_unlock: |
diff --git a/fs/udf/partition.c b/fs/udf/partition.c index 5f861ed287c3..888c364b2fe9 100644 --- a/fs/udf/partition.c +++ b/fs/udf/partition.c | |||
@@ -295,7 +295,8 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, | |||
295 | map = &UDF_SB(sb)->s_partmaps[partition]; | 295 | map = &UDF_SB(sb)->s_partmaps[partition]; |
296 | /* map to sparable/physical partition desc */ | 296 | /* map to sparable/physical partition desc */ |
297 | phyblock = udf_get_pblock(sb, eloc.logicalBlockNum, | 297 | phyblock = udf_get_pblock(sb, eloc.logicalBlockNum, |
298 | map->s_partition_num, ext_offset + offset); | 298 | map->s_type_specific.s_metadata.s_phys_partition_ref, |
299 | ext_offset + offset); | ||
299 | } | 300 | } |
300 | 301 | ||
301 | brelse(epos.bh); | 302 | brelse(epos.bh); |
@@ -317,14 +318,18 @@ uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block, | |||
317 | mdata = &map->s_type_specific.s_metadata; | 318 | mdata = &map->s_type_specific.s_metadata; |
318 | inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe; | 319 | inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe; |
319 | 320 | ||
320 | /* We shouldn't mount such media... */ | 321 | if (!inode) |
321 | BUG_ON(!inode); | 322 | return 0xFFFFFFFF; |
323 | |||
322 | retblk = udf_try_read_meta(inode, block, partition, offset); | 324 | retblk = udf_try_read_meta(inode, block, partition, offset); |
323 | if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) { | 325 | if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) { |
324 | udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n"); | 326 | udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n"); |
325 | if (!(mdata->s_flags & MF_MIRROR_FE_LOADED)) { | 327 | if (!(mdata->s_flags & MF_MIRROR_FE_LOADED)) { |
326 | mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb, | 328 | mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb, |
327 | mdata->s_mirror_file_loc, map->s_partition_num); | 329 | mdata->s_mirror_file_loc, |
330 | mdata->s_phys_partition_ref); | ||
331 | if (IS_ERR(mdata->s_mirror_fe)) | ||
332 | mdata->s_mirror_fe = NULL; | ||
328 | mdata->s_flags |= MF_MIRROR_FE_LOADED; | 333 | mdata->s_flags |= MF_MIRROR_FE_LOADED; |
329 | } | 334 | } |
330 | 335 | ||
diff --git a/fs/udf/super.c b/fs/udf/super.c index 5e2c8c814e1b..4942549e7dc8 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -951,13 +951,13 @@ out2: | |||
951 | } | 951 | } |
952 | 952 | ||
953 | struct inode *udf_find_metadata_inode_efe(struct super_block *sb, | 953 | struct inode *udf_find_metadata_inode_efe(struct super_block *sb, |
954 | u32 meta_file_loc, u32 partition_num) | 954 | u32 meta_file_loc, u32 partition_ref) |
955 | { | 955 | { |
956 | struct kernel_lb_addr addr; | 956 | struct kernel_lb_addr addr; |
957 | struct inode *metadata_fe; | 957 | struct inode *metadata_fe; |
958 | 958 | ||
959 | addr.logicalBlockNum = meta_file_loc; | 959 | addr.logicalBlockNum = meta_file_loc; |
960 | addr.partitionReferenceNum = partition_num; | 960 | addr.partitionReferenceNum = partition_ref; |
961 | 961 | ||
962 | metadata_fe = udf_iget_special(sb, &addr); | 962 | metadata_fe = udf_iget_special(sb, &addr); |
963 | 963 | ||
@@ -974,7 +974,8 @@ struct inode *udf_find_metadata_inode_efe(struct super_block *sb, | |||
974 | return metadata_fe; | 974 | return metadata_fe; |
975 | } | 975 | } |
976 | 976 | ||
977 | static int udf_load_metadata_files(struct super_block *sb, int partition) | 977 | static int udf_load_metadata_files(struct super_block *sb, int partition, |
978 | int type1_index) | ||
978 | { | 979 | { |
979 | struct udf_sb_info *sbi = UDF_SB(sb); | 980 | struct udf_sb_info *sbi = UDF_SB(sb); |
980 | struct udf_part_map *map; | 981 | struct udf_part_map *map; |
@@ -984,20 +985,21 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) | |||
984 | 985 | ||
985 | map = &sbi->s_partmaps[partition]; | 986 | map = &sbi->s_partmaps[partition]; |
986 | mdata = &map->s_type_specific.s_metadata; | 987 | mdata = &map->s_type_specific.s_metadata; |
988 | mdata->s_phys_partition_ref = type1_index; | ||
987 | 989 | ||
988 | /* metadata address */ | 990 | /* metadata address */ |
989 | udf_debug("Metadata file location: block = %d part = %d\n", | 991 | udf_debug("Metadata file location: block = %d part = %d\n", |
990 | mdata->s_meta_file_loc, map->s_partition_num); | 992 | mdata->s_meta_file_loc, mdata->s_phys_partition_ref); |
991 | 993 | ||
992 | fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc, | 994 | fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc, |
993 | map->s_partition_num); | 995 | mdata->s_phys_partition_ref); |
994 | if (IS_ERR(fe)) { | 996 | if (IS_ERR(fe)) { |
995 | /* mirror file entry */ | 997 | /* mirror file entry */ |
996 | udf_debug("Mirror metadata file location: block = %d part = %d\n", | 998 | udf_debug("Mirror metadata file location: block = %d part = %d\n", |
997 | mdata->s_mirror_file_loc, map->s_partition_num); | 999 | mdata->s_mirror_file_loc, mdata->s_phys_partition_ref); |
998 | 1000 | ||
999 | fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc, | 1001 | fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc, |
1000 | map->s_partition_num); | 1002 | mdata->s_phys_partition_ref); |
1001 | 1003 | ||
1002 | if (IS_ERR(fe)) { | 1004 | if (IS_ERR(fe)) { |
1003 | udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n"); | 1005 | udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n"); |
@@ -1015,7 +1017,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) | |||
1015 | */ | 1017 | */ |
1016 | if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) { | 1018 | if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) { |
1017 | addr.logicalBlockNum = mdata->s_bitmap_file_loc; | 1019 | addr.logicalBlockNum = mdata->s_bitmap_file_loc; |
1018 | addr.partitionReferenceNum = map->s_partition_num; | 1020 | addr.partitionReferenceNum = mdata->s_phys_partition_ref; |
1019 | 1021 | ||
1020 | udf_debug("Bitmap file location: block = %d part = %d\n", | 1022 | udf_debug("Bitmap file location: block = %d part = %d\n", |
1021 | addr.logicalBlockNum, addr.partitionReferenceNum); | 1023 | addr.logicalBlockNum, addr.partitionReferenceNum); |
@@ -1283,7 +1285,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
1283 | p = (struct partitionDesc *)bh->b_data; | 1285 | p = (struct partitionDesc *)bh->b_data; |
1284 | partitionNumber = le16_to_cpu(p->partitionNumber); | 1286 | partitionNumber = le16_to_cpu(p->partitionNumber); |
1285 | 1287 | ||
1286 | /* First scan for TYPE1, SPARABLE and METADATA partitions */ | 1288 | /* First scan for TYPE1 and SPARABLE partitions */ |
1287 | for (i = 0; i < sbi->s_partitions; i++) { | 1289 | for (i = 0; i < sbi->s_partitions; i++) { |
1288 | map = &sbi->s_partmaps[i]; | 1290 | map = &sbi->s_partmaps[i]; |
1289 | udf_debug("Searching map: (%d == %d)\n", | 1291 | udf_debug("Searching map: (%d == %d)\n", |
@@ -1333,7 +1335,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) | |||
1333 | goto out_bh; | 1335 | goto out_bh; |
1334 | 1336 | ||
1335 | if (map->s_partition_type == UDF_METADATA_MAP25) { | 1337 | if (map->s_partition_type == UDF_METADATA_MAP25) { |
1336 | ret = udf_load_metadata_files(sb, i); | 1338 | ret = udf_load_metadata_files(sb, i, type1_idx); |
1337 | if (ret < 0) { | 1339 | if (ret < 0) { |
1338 | udf_err(sb, "error loading MetaData partition map %d\n", | 1340 | udf_err(sb, "error loading MetaData partition map %d\n", |
1339 | i); | 1341 | i); |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 27b5335730c9..c13875d669c0 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -61,6 +61,11 @@ struct udf_meta_data { | |||
61 | __u32 s_bitmap_file_loc; | 61 | __u32 s_bitmap_file_loc; |
62 | __u32 s_alloc_unit_size; | 62 | __u32 s_alloc_unit_size; |
63 | __u16 s_align_unit_size; | 63 | __u16 s_align_unit_size; |
64 | /* | ||
65 | * Partition Reference Number of the associated physical / sparable | ||
66 | * partition | ||
67 | */ | ||
68 | __u16 s_phys_partition_ref; | ||
64 | int s_flags; | 69 | int s_flags; |
65 | struct inode *s_metadata_fe; | 70 | struct inode *s_metadata_fe; |
66 | struct inode *s_mirror_fe; | 71 | struct inode *s_mirror_fe; |