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: Miao Xie <miaoxie@huawei.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Wang Shilong <wshilong@ddn.com>
This commit is contained in:
parent
3b10fdc6d8
commit
cf0a5e818f
|
@ -5706,21 +5706,35 @@ 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,
|
||||
unsigned int new_extra_isize,
|
||||
struct ext4_iloc iloc,
|
||||
handle_t *handle)
|
||||
static int ext4_try_to_expand_extra_isize(struct inode *inode,
|
||||
unsigned int new_extra_isize,
|
||||
struct ext4_iloc iloc,
|
||||
handle_t *handle)
|
||||
{
|
||||
struct ext4_inode *raw_inode;
|
||||
struct ext4_xattr_ibody_header *header;
|
||||
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,
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return ext4_mark_iloc_dirty(handle, inode, &iloc);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ out:
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue