Commit c3695331 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 9af1f5d8 b9d8905e
...@@ -1393,7 +1393,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) ...@@ -1393,7 +1393,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
unsigned long safe_mask = 0; unsigned long safe_mask = 0;
unsigned int commit_max_age = (unsigned int)-1; unsigned int commit_max_age = (unsigned int)-1;
struct reiserfs_journal *journal = SB_JOURNAL(s); struct reiserfs_journal *journal = SB_JOURNAL(s);
char *new_opts = kstrdup(arg, GFP_KERNEL); char *new_opts;
int err; int err;
char *qf_names[REISERFS_MAXQUOTAS]; char *qf_names[REISERFS_MAXQUOTAS];
unsigned int qfmt = 0; unsigned int qfmt = 0;
...@@ -1401,6 +1401,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) ...@@ -1401,6 +1401,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
int i; int i;
#endif #endif
new_opts = kstrdup(arg, GFP_KERNEL);
if (arg && !new_opts)
return -ENOMEM;
sync_filesystem(s); sync_filesystem(s);
reiserfs_write_lock(s); reiserfs_write_lock(s);
...@@ -1546,7 +1550,8 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) ...@@ -1546,7 +1550,8 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
} }
out_ok_unlocked: out_ok_unlocked:
replace_mount_options(s, new_opts); if (new_opts)
replace_mount_options(s, new_opts);
return 0; return 0;
out_err_unlock: out_err_unlock:
......
...@@ -295,7 +295,8 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block, ...@@ -295,7 +295,8 @@ static uint32_t udf_try_read_meta(struct inode *inode, uint32_t block,
map = &UDF_SB(sb)->s_partmaps[partition]; map = &UDF_SB(sb)->s_partmaps[partition];
/* map to sparable/physical partition desc */ /* map to sparable/physical partition desc */
phyblock = udf_get_pblock(sb, eloc.logicalBlockNum, phyblock = udf_get_pblock(sb, eloc.logicalBlockNum,
map->s_partition_num, ext_offset + offset); map->s_type_specific.s_metadata.s_phys_partition_ref,
ext_offset + offset);
} }
brelse(epos.bh); brelse(epos.bh);
...@@ -317,14 +318,18 @@ uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block, ...@@ -317,14 +318,18 @@ uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block,
mdata = &map->s_type_specific.s_metadata; mdata = &map->s_type_specific.s_metadata;
inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe; inode = mdata->s_metadata_fe ? : mdata->s_mirror_fe;
/* We shouldn't mount such media... */ if (!inode)
BUG_ON(!inode); return 0xFFFFFFFF;
retblk = udf_try_read_meta(inode, block, partition, offset); retblk = udf_try_read_meta(inode, block, partition, offset);
if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) { if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) {
udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n"); udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n");
if (!(mdata->s_flags & MF_MIRROR_FE_LOADED)) { if (!(mdata->s_flags & MF_MIRROR_FE_LOADED)) {
mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb,
mdata->s_mirror_file_loc, map->s_partition_num); mdata->s_mirror_file_loc,
mdata->s_phys_partition_ref);
if (IS_ERR(mdata->s_mirror_fe))
mdata->s_mirror_fe = NULL;
mdata->s_flags |= MF_MIRROR_FE_LOADED; mdata->s_flags |= MF_MIRROR_FE_LOADED;
} }
......
...@@ -951,13 +951,13 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block) ...@@ -951,13 +951,13 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
} }
struct inode *udf_find_metadata_inode_efe(struct super_block *sb, struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
u32 meta_file_loc, u32 partition_num) u32 meta_file_loc, u32 partition_ref)
{ {
struct kernel_lb_addr addr; struct kernel_lb_addr addr;
struct inode *metadata_fe; struct inode *metadata_fe;
addr.logicalBlockNum = meta_file_loc; addr.logicalBlockNum = meta_file_loc;
addr.partitionReferenceNum = partition_num; addr.partitionReferenceNum = partition_ref;
metadata_fe = udf_iget_special(sb, &addr); metadata_fe = udf_iget_special(sb, &addr);
...@@ -974,7 +974,8 @@ struct inode *udf_find_metadata_inode_efe(struct super_block *sb, ...@@ -974,7 +974,8 @@ struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
return metadata_fe; return metadata_fe;
} }
static int udf_load_metadata_files(struct super_block *sb, int partition) static int udf_load_metadata_files(struct super_block *sb, int partition,
int type1_index)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map; struct udf_part_map *map;
...@@ -984,20 +985,21 @@ static int udf_load_metadata_files(struct super_block *sb, int partition) ...@@ -984,20 +985,21 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
map = &sbi->s_partmaps[partition]; map = &sbi->s_partmaps[partition];
mdata = &map->s_type_specific.s_metadata; mdata = &map->s_type_specific.s_metadata;
mdata->s_phys_partition_ref = type1_index;
/* metadata address */ /* metadata address */
udf_debug("Metadata file location: block = %d part = %d\n", udf_debug("Metadata file location: block = %d part = %d\n",
mdata->s_meta_file_loc, map->s_partition_num); mdata->s_meta_file_loc, mdata->s_phys_partition_ref);
fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc, fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc,
map->s_partition_num); mdata->s_phys_partition_ref);
if (IS_ERR(fe)) { if (IS_ERR(fe)) {
/* mirror file entry */ /* mirror file entry */
udf_debug("Mirror metadata file location: block = %d part = %d\n", udf_debug("Mirror metadata file location: block = %d part = %d\n",
mdata->s_mirror_file_loc, map->s_partition_num); mdata->s_mirror_file_loc, mdata->s_phys_partition_ref);
fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc, fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc,
map->s_partition_num); mdata->s_phys_partition_ref);
if (IS_ERR(fe)) { if (IS_ERR(fe)) {
udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n"); 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,7 +1017,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
*/ */
if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) { if (mdata->s_bitmap_file_loc != 0xFFFFFFFF) {
addr.logicalBlockNum = mdata->s_bitmap_file_loc; addr.logicalBlockNum = mdata->s_bitmap_file_loc;
addr.partitionReferenceNum = map->s_partition_num; addr.partitionReferenceNum = mdata->s_phys_partition_ref;
udf_debug("Bitmap file location: block = %d part = %d\n", udf_debug("Bitmap file location: block = %d part = %d\n",
addr.logicalBlockNum, addr.partitionReferenceNum); addr.logicalBlockNum, addr.partitionReferenceNum);
...@@ -1283,7 +1285,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) ...@@ -1283,7 +1285,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
p = (struct partitionDesc *)bh->b_data; p = (struct partitionDesc *)bh->b_data;
partitionNumber = le16_to_cpu(p->partitionNumber); partitionNumber = le16_to_cpu(p->partitionNumber);
/* First scan for TYPE1, SPARABLE and METADATA partitions */ /* First scan for TYPE1 and SPARABLE partitions */
for (i = 0; i < sbi->s_partitions; i++) { for (i = 0; i < sbi->s_partitions; i++) {
map = &sbi->s_partmaps[i]; map = &sbi->s_partmaps[i];
udf_debug("Searching map: (%d == %d)\n", udf_debug("Searching map: (%d == %d)\n",
...@@ -1333,7 +1335,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block) ...@@ -1333,7 +1335,7 @@ static int udf_load_partdesc(struct super_block *sb, sector_t block)
goto out_bh; goto out_bh;
if (map->s_partition_type == UDF_METADATA_MAP25) { if (map->s_partition_type == UDF_METADATA_MAP25) {
ret = udf_load_metadata_files(sb, i); ret = udf_load_metadata_files(sb, i, type1_idx);
if (ret < 0) { if (ret < 0) {
udf_err(sb, "error loading MetaData partition map %d\n", udf_err(sb, "error loading MetaData partition map %d\n",
i); i);
......
...@@ -61,6 +61,11 @@ struct udf_meta_data { ...@@ -61,6 +61,11 @@ struct udf_meta_data {
__u32 s_bitmap_file_loc; __u32 s_bitmap_file_loc;
__u32 s_alloc_unit_size; __u32 s_alloc_unit_size;
__u16 s_align_unit_size; __u16 s_align_unit_size;
/*
* Partition Reference Number of the associated physical / sparable
* partition
*/
__u16 s_phys_partition_ref;
int s_flags; int s_flags;
struct inode *s_metadata_fe; struct inode *s_metadata_fe;
struct inode *s_mirror_fe; struct inode *s_mirror_fe;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment