aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c67
-rw-r--r--fs/ext4/xattr.c9
2 files changed, 36 insertions, 40 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 5dabbf276651..713b67e85f73 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5706,21 +5706,35 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
5706 * Expand an inode by new_extra_isize bytes. 5706 * Expand an inode by new_extra_isize bytes.
5707 * Returns 0 on success or negative error number on failure. 5707 * Returns 0 on success or negative error number on failure.
5708 */ 5708 */
5709static int ext4_expand_extra_isize(struct inode *inode, 5709static int ext4_try_to_expand_extra_isize(struct inode *inode,
5710 unsigned int new_extra_isize, 5710 unsigned int new_extra_isize,
5711 struct ext4_iloc iloc, 5711 struct ext4_iloc iloc,
5712 handle_t *handle) 5712 handle_t *handle)
5713{ 5713{
5714 struct ext4_inode *raw_inode; 5714 struct ext4_inode *raw_inode;
5715 struct ext4_xattr_ibody_header *header; 5715 struct ext4_xattr_ibody_header *header;
5716 int no_expand; 5716 int no_expand;
5717 int error; 5717 int error;
5718 5718
5719 if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) 5719 if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND))
5720 return 0; 5720 return -EOVERFLOW;
5721
5722 /*
5723 * In nojournal mode, we can immediately attempt to expand
5724 * the inode. When journaled, we first need to obtain extra
5725 * buffer credits since we may write into the EA block
5726 * with this same handle. If journal_extend fails, then it will
5727 * only result in a minor loss of functionality for that inode.
5728 * If this is felt to be critical, then e2fsck should be run to
5729 * force a large enough s_min_extra_isize.
5730 */
5731 if (ext4_handle_valid(handle) &&
5732 jbd2_journal_extend(handle,
5733 EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) != 0)
5734 return -ENOSPC;
5721 5735
5722 if (ext4_write_trylock_xattr(inode, &no_expand) == 0) 5736 if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
5723 return 0; 5737 return -EBUSY;
5724 5738
5725 raw_inode = ext4_raw_inode(&iloc); 5739 raw_inode = ext4_raw_inode(&iloc);
5726 5740
@@ -5747,6 +5761,7 @@ static int ext4_expand_extra_isize(struct inode *inode,
5747 no_expand = 1; 5761 no_expand = 1;
5748 } 5762 }
5749 ext4_write_unlock_xattr(inode, &no_expand); 5763 ext4_write_unlock_xattr(inode, &no_expand);
5764
5750 return error; 5765 return error;
5751} 5766}
5752 5767
@@ -5767,44 +5782,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
5767{ 5782{
5768 struct ext4_iloc iloc; 5783 struct ext4_iloc iloc;
5769 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 5784 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
5770 static unsigned int mnt_count; 5785 int err;
5771 int err, ret;
5772 5786
5773 might_sleep(); 5787 might_sleep();
5774 trace_ext4_mark_inode_dirty(inode, _RET_IP_); 5788 trace_ext4_mark_inode_dirty(inode, _RET_IP_);
5775 err = ext4_reserve_inode_write(handle, inode, &iloc); 5789 err = ext4_reserve_inode_write(handle, inode, &iloc);
5776 if (err) 5790 if (err)
5777 return err; 5791 return err;
5778 if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && 5792
5779 !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { 5793 if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize)
5780 /* 5794 ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize,
5781 * In nojournal mode, we can immediately attempt to expand 5795 iloc, handle);
5782 * the inode. When journaled, we first need to obtain extra 5796
5783 * buffer credits since we may write into the EA block
5784 * with this same handle. If journal_extend fails, then it will
5785 * only result in a minor loss of functionality for that inode.
5786 * If this is felt to be critical, then e2fsck should be run to
5787 * force a large enough s_min_extra_isize.
5788 */
5789 if (!ext4_handle_valid(handle) ||
5790 jbd2_journal_extend(handle,
5791 EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) == 0) {
5792 ret = ext4_expand_extra_isize(inode,
5793 sbi->s_want_extra_isize,
5794 iloc, handle);
5795 if (ret) {
5796 if (mnt_count !=
5797 le16_to_cpu(sbi->s_es->s_mnt_count)) {
5798 ext4_warning(inode->i_sb,
5799 "Unable to expand inode %lu. Delete"
5800 " some EAs or run e2fsck.",
5801 inode->i_ino);
5802 mnt_count =
5803 le16_to_cpu(sbi->s_es->s_mnt_count);
5804 }
5805 }
5806 }
5807 }
5808 return ext4_mark_iloc_dirty(handle, inode, &iloc); 5797 return ext4_mark_iloc_dirty(handle, inode, &iloc);
5809} 5798}
5810 5799
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 862ba3891398..7f5f4b63782b 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -2638,12 +2638,14 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
2638{ 2638{
2639 struct ext4_xattr_ibody_header *header; 2639 struct ext4_xattr_ibody_header *header;
2640 struct buffer_head *bh = NULL; 2640 struct buffer_head *bh = NULL;
2641 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
2642 static unsigned int mnt_count;
2641 size_t min_offs; 2643 size_t min_offs;
2642 size_t ifree, bfree; 2644 size_t ifree, bfree;
2643 int total_ino; 2645 int total_ino;
2644 void *base, *end; 2646 void *base, *end;
2645 int error = 0, tried_min_extra_isize = 0; 2647 int error = 0, tried_min_extra_isize = 0;
2646 int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); 2648 int s_min_extra_isize = le16_to_cpu(sbi->s_es->s_min_extra_isize);
2647 int isize_diff; /* How much do we need to grow i_extra_isize */ 2649 int isize_diff; /* How much do we need to grow i_extra_isize */
2648 2650
2649retry: 2651retry:
@@ -2731,6 +2733,11 @@ out:
2731 2733
2732cleanup: 2734cleanup:
2733 brelse(bh); 2735 brelse(bh);
2736 if (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count)) {
2737 ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
2738 inode->i_ino);
2739 mnt_count = le16_to_cpu(sbi->s_es->s_mnt_count);
2740 }
2734 return error; 2741 return error;
2735} 2742}
2736 2743