mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
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
2 changed files with 36 additions and 40 deletions
|
@ -5706,21 +5706,35 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
|
||||||
* Expand an inode by new_extra_isize bytes.
|
* Expand an inode by new_extra_isize bytes.
|
||||||
* Returns 0 on success or negative error number on failure.
|
* 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,
|
unsigned int new_extra_isize,
|
||||||
struct ext4_iloc iloc,
|
struct ext4_iloc iloc,
|
||||||
handle_t *handle)
|
handle_t *handle)
|
||||||
{
|
{
|
||||||
struct ext4_inode *raw_inode;
|
struct ext4_inode *raw_inode;
|
||||||
struct ext4_xattr_ibody_header *header;
|
struct ext4_xattr_ibody_header *header;
|
||||||
int no_expand;
|
int no_expand;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
|
if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND))
|
||||||
return 0;
|
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)
|
if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
|
||||||
return 0;
|
return -EBUSY;
|
||||||
|
|
||||||
raw_inode = ext4_raw_inode(&iloc);
|
raw_inode = ext4_raw_inode(&iloc);
|
||||||
|
|
||||||
|
@ -5747,6 +5761,7 @@ static int ext4_expand_extra_isize(struct inode *inode,
|
||||||
no_expand = 1;
|
no_expand = 1;
|
||||||
}
|
}
|
||||||
ext4_write_unlock_xattr(inode, &no_expand);
|
ext4_write_unlock_xattr(inode, &no_expand);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5767,44 +5782,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
|
||||||
{
|
{
|
||||||
struct ext4_iloc iloc;
|
struct ext4_iloc iloc;
|
||||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||||
static unsigned int mnt_count;
|
int err;
|
||||||
int err, ret;
|
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
trace_ext4_mark_inode_dirty(inode, _RET_IP_);
|
trace_ext4_mark_inode_dirty(inode, _RET_IP_);
|
||||||
err = ext4_reserve_inode_write(handle, inode, &iloc);
|
err = ext4_reserve_inode_write(handle, inode, &iloc);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
|
|
||||||
!ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
|
if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize)
|
||||||
/*
|
ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize,
|
||||||
* In nojournal mode, we can immediately attempt to expand
|
iloc, handle);
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ext4_mark_iloc_dirty(handle, inode, &iloc);
|
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 ext4_xattr_ibody_header *header;
|
||||||
struct buffer_head *bh = NULL;
|
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 min_offs;
|
||||||
size_t ifree, bfree;
|
size_t ifree, bfree;
|
||||||
int total_ino;
|
int total_ino;
|
||||||
void *base, *end;
|
void *base, *end;
|
||||||
int error = 0, tried_min_extra_isize = 0;
|
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 */
|
int isize_diff; /* How much do we need to grow i_extra_isize */
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
@ -2731,6 +2733,11 @@ out:
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
brelse(bh);
|
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;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue