Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3080a74e authored by Namjae Jeon's avatar Namjae Jeon Committed by Jan Kara
Browse files

udf: Skip mirror metadata FE loading when metadata FE is ok



It is not necessary to load mirror metadata FE when metadata FE is OK.  So try
to read it only the first time udf_get_pblock_meta25() fails to map the block
from metadata FE.

Signed-off-by: default avatarAshish Sangwan <ashishsangwan2@gmail.com>
Signed-off-by: default avatarNamjae Jeon <linkinjeon@gmail.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 6360e21f
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -321,8 +321,14 @@ uint32_t udf_get_pblock_meta25(struct super_block *sb, uint32_t block,
	/* We shouldn't mount such media... */
	BUG_ON(!inode);
	retblk = udf_try_read_meta(inode, block, partition, offset);
	if (retblk == 0xFFFFFFFF) {
	if (retblk == 0xFFFFFFFF && mdata->s_metadata_fe) {
		udf_warn(sb, "error reading from METADATA, trying to read from MIRROR\n");
		if (!mdata->s_mirror_loaded_flag) {
			mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb,
				mdata->s_mirror_file_loc, map->s_partition_num);
			mdata->s_mirror_loaded_flag = 1;
		}

		inode = mdata->s_mirror_fe;
		if (!inode)
			return 0xFFFFFFFF;
+33 −35
Original line number Diff line number Diff line
@@ -826,60 +826,58 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
	return ret;
}

struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
					u32 meta_file_loc, u32 partition_num)
{
	struct kernel_lb_addr addr;
	struct inode *metadata_fe;

	addr.logicalBlockNum = meta_file_loc;
	addr.partitionReferenceNum = partition_num;

	metadata_fe = udf_iget(sb, &addr);

	if (metadata_fe == NULL)
		udf_warn(sb, "metadata inode efe not found\n");
	else if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) {
		udf_warn(sb, "metadata inode efe does not have short allocation descriptors!\n");
		iput(metadata_fe);
		metadata_fe = NULL;
	}

	return metadata_fe;
}

static int udf_load_metadata_files(struct super_block *sb, int partition)
{
	struct udf_sb_info *sbi = UDF_SB(sb);
	struct udf_part_map *map;
	struct udf_meta_data *mdata;
	struct kernel_lb_addr addr;
	int fe_error = 0;

	map = &sbi->s_partmaps[partition];
	mdata = &map->s_type_specific.s_metadata;

	/* metadata address */
	addr.logicalBlockNum =  mdata->s_meta_file_loc;
	addr.partitionReferenceNum = map->s_partition_num;

	udf_debug("Metadata file location: block = %d part = %d\n",
		  addr.logicalBlockNum, addr.partitionReferenceNum);
		  mdata->s_meta_file_loc, map->s_partition_num);

	mdata->s_metadata_fe = udf_iget(sb, &addr);
	mdata->s_metadata_fe = udf_find_metadata_inode_efe(sb,
		mdata->s_meta_file_loc, map->s_partition_num);

	if (mdata->s_metadata_fe == NULL) {
		udf_warn(sb, "metadata inode efe not found, will try mirror inode\n");
		fe_error = 1;
	} else if (UDF_I(mdata->s_metadata_fe)->i_alloc_type !=
		 ICBTAG_FLAG_AD_SHORT) {
		udf_warn(sb, "metadata inode efe does not have short allocation descriptors!\n");
		fe_error = 1;
		iput(mdata->s_metadata_fe);
		mdata->s_metadata_fe = NULL;
	}

		/* mirror file entry */
	addr.logicalBlockNum = mdata->s_mirror_file_loc;
	addr.partitionReferenceNum = map->s_partition_num;

		udf_debug("Mirror metadata file location: block = %d part = %d\n",
		  addr.logicalBlockNum, addr.partitionReferenceNum);
			  mdata->s_mirror_file_loc, map->s_partition_num);

	mdata->s_mirror_fe = udf_iget(sb, &addr);
		mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb,
			mdata->s_mirror_file_loc, map->s_partition_num);

		if (mdata->s_mirror_fe == NULL) {
		if (fe_error) {
			udf_err(sb, "mirror inode efe not found and metadata inode is missing too, exiting...\n");
			goto error_exit;
		} else
			udf_warn(sb, "mirror inode efe not found, but metadata inode is OK\n");
	} else if (UDF_I(mdata->s_mirror_fe)->i_alloc_type !=
		 ICBTAG_FLAG_AD_SHORT) {
		udf_warn(sb, "mirror inode efe does not have short allocation descriptors!\n");
		iput(mdata->s_mirror_fe);
		mdata->s_mirror_fe = NULL;
		if (fe_error)
			udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n");
			goto error_exit;
		}
	}

	/*
	 * bitmap file entry
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ struct udf_meta_data {
	__u32	s_alloc_unit_size;
	__u16	s_align_unit_size;
	__u8 	s_dup_md_flag;
	__u8	s_mirror_loaded_flag;
	struct inode *s_metadata_fe;
	struct inode *s_mirror_fe;
	struct inode *s_bitmap_fe;
+2 −0
Original line number Diff line number Diff line
@@ -135,6 +135,8 @@ static inline void udf_updated_lvid(struct super_block *sb)
	UDF_SB(sb)->s_lvid_dirty = 1;
}
extern u64 lvid_get_unique_id(struct super_block *sb);
struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
					u32 meta_file_loc, u32 partition_num);

/* namei.c */
extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,