Commit 57bda9fb authored by Jan Kara's avatar Jan Kara
Browse files

udf: Convert udf_expand_dir_adinicb() to new directory iteration



Convert udf_expand_dir_adinicb() to new directory iteration code.

Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 7cd7a36a
Loading
Loading
Loading
Loading
+29 −37
Original line number Diff line number Diff line
@@ -326,14 +326,12 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode,
	udf_pblk_t newblock;
	struct buffer_head *dbh = NULL;
	struct kernel_lb_addr eloc;
	uint8_t alloctype;
	struct extent_position epos;

	struct udf_fileident_bh sfibh, dfibh;
	loff_t f_pos = udf_ext0_offset(inode);
	int size = udf_ext0_offset(inode) + inode->i_size;
	struct fileIdentDesc cfi, *sfi, *dfi;
	uint8_t alloctype;
	struct udf_inode_info *iinfo = UDF_I(inode);
	struct udf_fileident_iter iter;
	uint8_t *impuse;
	int ret;

	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
		alloctype = ICBTAG_FLAG_AD_SHORT;
@@ -361,38 +359,14 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode,
	if (!dbh)
		return NULL;
	lock_buffer(dbh);
	memset(dbh->b_data, 0x00, inode->i_sb->s_blocksize);
	memcpy(dbh->b_data, iinfo->i_data, inode->i_size);
	memset(dbh->b_data + inode->i_size, 0,
	       inode->i_sb->s_blocksize - inode->i_size);
	set_buffer_uptodate(dbh);
	unlock_buffer(dbh);
	mark_buffer_dirty_inode(dbh, inode);

	sfibh.soffset = sfibh.eoffset =
			f_pos & (inode->i_sb->s_blocksize - 1);
	sfibh.sbh = sfibh.ebh = NULL;
	dfibh.soffset = dfibh.eoffset = 0;
	dfibh.sbh = dfibh.ebh = dbh;
	while (f_pos < size) {
		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
		sfi = udf_fileident_read(inode, &f_pos, &sfibh, &cfi, NULL,
					 NULL, NULL, NULL);
		if (!sfi) {
			brelse(dbh);
			return NULL;
		}
		iinfo->i_alloc_type = alloctype;
		sfi->descTag.tagLocation = cpu_to_le32(*block);
		dfibh.soffset = dfibh.eoffset;
		dfibh.eoffset += (sfibh.eoffset - sfibh.soffset);
		dfi = (struct fileIdentDesc *)(dbh->b_data + dfibh.soffset);
		if (udf_write_fi(inode, sfi, dfi, &dfibh, sfi->impUse,
				 udf_get_fi_ident(sfi))) {
			iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
			brelse(dbh);
			return NULL;
		}
	}
	mark_buffer_dirty_inode(dbh, inode);

	/* Drop inline data, add block instead */
	iinfo->i_alloc_type = alloctype;
	memset(iinfo->i_data + iinfo->i_lenEAttr, 0, iinfo->i_lenAlloc);
	iinfo->i_lenAlloc = 0;
	eloc.logicalBlockNum = *block;
@@ -403,10 +377,28 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode,
	epos.block = iinfo->i_location;
	epos.offset = udf_file_entry_alloc_offset(inode);
	udf_add_aext(inode, &epos, &eloc, inode->i_size, 0);
	/* UniqueID stuff */

	brelse(epos.bh);
	mark_inode_dirty(inode);

	/* Now fixup tags in moved directory entries */
	for (ret = udf_fiiter_init(&iter, inode, 0);
	     !ret && iter.pos < inode->i_size;
	     ret = udf_fiiter_advance(&iter)) {
		iter.fi.descTag.tagLocation = cpu_to_le32(*block);
		if (iter.fi.lengthOfImpUse != cpu_to_le16(0))
			impuse = dbh->b_data + iter.pos +
						sizeof(struct fileIdentDesc);
		else
			impuse = NULL;
		udf_fiiter_write_fi(&iter, impuse);
	}
	/*
	 * We don't expect the iteration to fail as the directory has been
	 * already verified to be correct
	 */
	WARN_ON_ONCE(ret);
	udf_fiiter_release(&iter);

	return dbh;
}