add patch project-expand-inode-extra-size-if-needed
[ext4-patch-queue.git] / restructure-ext4_expand_extra_isize
blobeca00aa915ec70ba1b45992e3221ae3f2685af6e
1 ext4: restructure ext4_expand_extra_isize
3 From: Miao Xie <miaoxie@huawei.com>
5 Current ext4_expand_extra_isize just tries to expand extra isize, if
6 someone is holding xattr lock or some check fails, it will give up.
7 So rename its name to ext4_try_to_expand_extra_isize.
9 Besides that, we clean up unnecessary check and move some relative checks
10 into it.
12 Signed-off-by: Miao Xie <miaoxie@huawei.com>
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 Reviewed-by: Wang Shilong <wshilong@ddn.com>
15 ---
16  fs/ext4/inode.c | 67 ++++++++++++++++++++++++++++---------------------------------------
17  fs/ext4/xattr.c |  9 ++++++++-
18  2 files changed, 36 insertions(+), 40 deletions(-)
20 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
21 index 5dabbf276651..713b67e85f73 100644
22 --- a/fs/ext4/inode.c
23 +++ b/fs/ext4/inode.c
24 @@ -5706,21 +5706,35 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode,
25   * Expand an inode by new_extra_isize bytes.
26   * Returns 0 on success or negative error number on failure.
27   */
28 -static int ext4_expand_extra_isize(struct inode *inode,
29 -                                  unsigned int new_extra_isize,
30 -                                  struct ext4_iloc iloc,
31 -                                  handle_t *handle)
32 +static int ext4_try_to_expand_extra_isize(struct inode *inode,
33 +                                         unsigned int new_extra_isize,
34 +                                         struct ext4_iloc iloc,
35 +                                         handle_t *handle)
36  {
37         struct ext4_inode *raw_inode;
38         struct ext4_xattr_ibody_header *header;
39         int no_expand;
40         int error;
42 -       if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
43 -               return 0;
44 +       if (ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND))
45 +               return -EOVERFLOW;
47 +       /*
48 +        * In nojournal mode, we can immediately attempt to expand
49 +        * the inode.  When journaled, we first need to obtain extra
50 +        * buffer credits since we may write into the EA block
51 +        * with this same handle. If journal_extend fails, then it will
52 +        * only result in a minor loss of functionality for that inode.
53 +        * If this is felt to be critical, then e2fsck should be run to
54 +        * force a large enough s_min_extra_isize.
55 +        */
56 +       if (ext4_handle_valid(handle) &&
57 +           jbd2_journal_extend(handle,
58 +                               EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) != 0)
59 +               return -ENOSPC;
61         if (ext4_write_trylock_xattr(inode, &no_expand) == 0)
62 -               return 0;
63 +               return -EBUSY;
65         raw_inode = ext4_raw_inode(&iloc);
67 @@ -5747,6 +5761,7 @@ static int ext4_expand_extra_isize(struct inode *inode,
68                 no_expand = 1;
69         }
70         ext4_write_unlock_xattr(inode, &no_expand);
72         return error;
73  }
75 @@ -5767,44 +5782,18 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
76  {
77         struct ext4_iloc iloc;
78         struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
79 -       static unsigned int mnt_count;
80 -       int err, ret;
81 +       int err;
83         might_sleep();
84         trace_ext4_mark_inode_dirty(inode, _RET_IP_);
85         err = ext4_reserve_inode_write(handle, inode, &iloc);
86         if (err)
87                 return err;
88 -       if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
89 -           !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
90 -               /*
91 -                * In nojournal mode, we can immediately attempt to expand
92 -                * the inode.  When journaled, we first need to obtain extra
93 -                * buffer credits since we may write into the EA block
94 -                * with this same handle. If journal_extend fails, then it will
95 -                * only result in a minor loss of functionality for that inode.
96 -                * If this is felt to be critical, then e2fsck should be run to
97 -                * force a large enough s_min_extra_isize.
98 -                */
99 -               if (!ext4_handle_valid(handle) ||
100 -                   jbd2_journal_extend(handle,
101 -                            EXT4_DATA_TRANS_BLOCKS(inode->i_sb)) == 0) {
102 -                       ret = ext4_expand_extra_isize(inode,
103 -                                                     sbi->s_want_extra_isize,
104 -                                                     iloc, handle);
105 -                       if (ret) {
106 -                               if (mnt_count !=
107 -                                       le16_to_cpu(sbi->s_es->s_mnt_count)) {
108 -                                       ext4_warning(inode->i_sb,
109 -                                       "Unable to expand inode %lu. Delete"
110 -                                       " some EAs or run e2fsck.",
111 -                                       inode->i_ino);
112 -                                       mnt_count =
113 -                                         le16_to_cpu(sbi->s_es->s_mnt_count);
114 -                               }
115 -                       }
116 -               }
117 -       }
119 +       if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize)
120 +               ext4_try_to_expand_extra_isize(inode, sbi->s_want_extra_isize,
121 +                                              iloc, handle);
123         return ext4_mark_iloc_dirty(handle, inode, &iloc);
126 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
127 index 862ba3891398..7f5f4b63782b 100644
128 --- a/fs/ext4/xattr.c
129 +++ b/fs/ext4/xattr.c
130 @@ -2638,12 +2638,14 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
132         struct ext4_xattr_ibody_header *header;
133         struct buffer_head *bh = NULL;
134 +       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
135 +       static unsigned int mnt_count;
136         size_t min_offs;
137         size_t ifree, bfree;
138         int total_ino;
139         void *base, *end;
140         int error = 0, tried_min_extra_isize = 0;
141 -       int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
142 +       int s_min_extra_isize = le16_to_cpu(sbi->s_es->s_min_extra_isize);
143         int isize_diff; /* How much do we need to grow i_extra_isize */
145  retry:
146 @@ -2731,6 +2733,11 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
148  cleanup:
149         brelse(bh);
150 +       if (mnt_count != le16_to_cpu(sbi->s_es->s_mnt_count)) {
151 +               ext4_warning(inode->i_sb, "Unable to expand inode %lu. Delete some EAs or run e2fsck.",
152 +                            inode->i_ino);
153 +               mnt_count = le16_to_cpu(sbi->s_es->s_mnt_count);
154 +       }
155         return error;