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

Commit cf0a5e81 authored by Miao Xie's avatar Miao Xie Committed by Theodore Ts'o
Browse files

ext4: restructure ext4_expand_extra_isize



Current ext4_expand_extra_isize just tries to expand extra isize, if
someone is holding xattr lock or some check fails, it will give up.
So rename its name to ext4_try_to_expand_extra_isize.

Besides that, we clean up unnecessary check and move some relative checks
into it.

Signed-off-by: default avatarMiao Xie <miaoxie@huawei.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
Reviewed-by: default avatarWang Shilong <wshilong@ddn.com>
parent 3b10fdc6
Loading
Loading
Loading
Loading
+28 −39
Original line number Diff line number Diff line
@@ -5706,7 +5706,7 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
 * Expand an inode by new_extra_isize bytes.
 * Returns 0 on success or negative error number on failure.
 */
static int ext4_expand_extra_isize(struct inode *inode,
static int ext4_try_to_expand_extra_isize(struct inode *inode,
					  unsigned int new_extra_isize,
					  struct ext4_iloc iloc,
					  handle_t *handle)
@@ -5716,11 +5716,25 @@ static int ext4_expand_extra_isize(struct inode *inode,
	int no_expand;
	int error;

	if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
		return 0;
	if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND))
		return -EOVERFLOW;

	/*
	 * In nojournal mode, we can immediately attempt to expand
	 * the inode.  When journaled, we first need to obtain extra
	 * buffer credits since we may write into the EA block
	 * with this same handle. If journal_extend fails, then it will
	 * only result in a minor loss of functionality for that inode.
	 * If this is felt to be critical, then e2fsck should be run to
	 * force a large enough s_min_extra_isize.
	 */
	if (ext4_handle_valid(handle) &&
	    jbd2_journal_extend(handle,
				EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) != 0)
		return -ENOSPC;

	if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
		return 0;
		return -EBUSY;

	raw_inode = ext4_raw_inode(&iloc);

@@ -5747,6 +5761,7 @@ static int ext4_expand_extra_isize(struct inode *inode,
		no_expand = 1;
	}
	ext4_write_unlock_xattr(inode, &no_expand);

	return error;
}

@@ -5767,44 +5782,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
{
	struct ext4_iloc iloc;
	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
	static unsigned int mnt_count;
	int err, ret;
	int err;

	might_sleep();
	trace_ext4_mark_inode_dirty(inode, _RET_IP_);
	err = ext4_reserve_inode_write(handle, inode, &iloc);
	if (err)
		return err;
	if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
	    !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
		/*
		 * In nojournal mode, we can immediately attempt to expand
		 * the inode.  When journaled, we first need to obtain extra
		 * buffer credits since we may write into the EA block
		 * with this same handle. If journal_extend fails, then it will
		 * only result in a minor loss of functionality for that inode.
		 * If this is felt to be critical, then e2fsck should be run to
		 * force a large enough s_min_extra_isize.
		 */
		if (!ext4_handle_valid(handle) ||
		    jbd2_journal_extend(handle,
			     EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) == 0) {
			ret = ext4_expand_extra_isize(inode,
						      sbi->s_want_extra_isize,

	if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize)
		ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize,
					       iloc, handle);
			if (ret) {
				if (mnt_count !=
					le16_to_cpu(sbi->s_es->s_mnt_count)) {
					ext4_warning(inode->i_sb,
					"Unable to expand inode %lu. Delete"
					" some EAs or run e2fsck.",
					inode->i_ino);
					mnt_count =
					  le16_to_cpu(sbi->s_es->s_mnt_count);
				}
			}
		}
	}

	return ext4_mark_iloc_dirty(handle, inode, &iloc);
}

+8 −1
Original line number Diff line number Diff line
@@ -2638,12 +2638,14 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
{
	struct ext4_xattr_ibody_header *header;
	struct buffer_head *bh = NULL;
	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
	static unsigned int mnt_count;
	size_t min_offs;
	size_t ifree, bfree;
	int total_ino;
	void *base, *end;
	int error = 0, tried_min_extra_isize = 0;
	int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
	int s_min_extra_isize = le16_to_cpu(sbi->s_es->s_min_extra_isize);
	int isize_diff;	/* How much do we need to grow i_extra_isize */

retry:
@@ -2731,6 +2733,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,

cleanup:
	brelse(bh);
	if (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count)) {
		ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
			     inode->i_ino);
		mnt_count = le16_to_cpu(sbi->s_es->s_mnt_count);
	}
	return error;
}