|
@@ -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);
|
|
|
}
|
|
|
|