add patch fscrypto-improved-validation-when-loading-inode-encryption-metadata
[ext4-patch-queue.git] / factor-out-loop-for-freeing-inode-xattr-space
blobbce97edd1e24dbed74859c1c5f3f8e953133c579
1 ext4: factor out loop for freeing inode xattr space
3 From: Jan Kara <jack@suse.cz>
5 Move loop to make enough space in the inode from
6 ext4_expand_extra_isize_ea() into a separate function to make that
7 function smaller and better readable and also to avoid delaration of
8 variables inside a loop block.
10 Signed-off-by: Jan Kara <jack@suse.cz>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 ---
13  fs/ext4/xattr.c | 121 ++++++++++++++++++++++++++++++++------------------------
14  1 file changed, 69 insertions(+), 52 deletions(-)
16 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
17 index 2ef687620205..c15d63389957 100644
18 --- a/fs/ext4/xattr.c
19 +++ b/fs/ext4/xattr.c
20 @@ -1417,6 +1417,63 @@ out:
21         return error;
22  }
24 +static int ext4_xattr_make_inode_space(handle_t *handle, struct inode *inode,
25 +                                      struct ext4_inode *raw_inode,
26 +                                      int isize_diff, size_t ifree,
27 +                                      size_t bfree, int *total_ino)
29 +       struct ext4_xattr_ibody_header *header = IHDR(inode, raw_inode);
30 +       struct ext4_xattr_entry *small_entry;
31 +       struct ext4_xattr_entry *entry;
32 +       struct ext4_xattr_entry *last;
33 +       unsigned int entry_size;        /* EA entry size */
34 +       unsigned int total_size;        /* EA entry size + value size */
35 +       unsigned int min_total_size;
36 +       int error;
38 +       while (isize_diff > ifree) {
39 +               entry = NULL;
40 +               small_entry = NULL;
41 +               min_total_size = ~0U;
42 +               last = IFIRST(header);
43 +               /* Find the entry best suited to be pushed into EA block */
44 +               for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
45 +                       total_size =
46 +                       EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
47 +                                       EXT4_XATTR_LEN(last->e_name_len);
48 +                       if (total_size <= bfree &&
49 +                           total_size < min_total_size) {
50 +                               if (total_size + ifree < isize_diff) {
51 +                                       small_entry = last;
52 +                               } else {
53 +                                       entry = last;
54 +                                       min_total_size = total_size;
55 +                               }
56 +                       }
57 +               }
59 +               if (entry == NULL) {
60 +                       if (small_entry == NULL)
61 +                               return -ENOSPC;
62 +                       entry = small_entry;
63 +               }
65 +               entry_size = EXT4_XATTR_LEN(entry->e_name_len);
66 +               total_size = entry_size +
67 +                       EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
68 +               error = ext4_xattr_move_to_block(handle, inode, raw_inode,
69 +                                                entry);
70 +               if (error)
71 +                       return error;
73 +               *total_ino -= entry_size;
74 +               ifree += total_size;
75 +               bfree -= total_size;
76 +       }
78 +       return 0;
81  /*
82   * Expand an inode by new_extra_isize bytes when EAs are present.
83   * Returns 0 on success or negative error number on failure.
84 @@ -1491,66 +1548,26 @@ retry:
85                                 brelse(bh);
86                                 goto retry;
87                         }
88 -                       error = -1;
89 +                       error = -ENOSPC;
90                         goto cleanup;
91                 }
92         } else {
93                 bfree = inode->i_sb->s_blocksize;
94         }
96 -       while (isize_diff > ifree) {
97 -               struct ext4_xattr_entry *small_entry = NULL, *entry = NULL;
98 -               struct ext4_xattr_entry *last;
99 -               unsigned int entry_size;        /* EA entry size */
100 -               unsigned int total_size;        /* EA entry size + value size */
101 -               unsigned int min_total_size = ~0U;
103 -               last = IFIRST(header);
104 -               /* Find the entry best suited to be pushed into EA block */
105 -               for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
106 -                       total_size =
107 -                       EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
108 -                                       EXT4_XATTR_LEN(last->e_name_len);
109 -                       if (total_size <= bfree &&
110 -                           total_size < min_total_size) {
111 -                               if (total_size + ifree < isize_diff) {
112 -                                       small_entry = last;
113 -                               } else {
114 -                                       entry = last;
115 -                                       min_total_size = total_size;
116 -                               }
117 -                       }
118 -               }
120 -               if (entry == NULL) {
121 -                       if (small_entry) {
122 -                               entry = small_entry;
123 -                       } else {
124 -                               if (!tried_min_extra_isize &&
125 -                                   s_min_extra_isize) {
126 -                                       tried_min_extra_isize++;
127 -                                       new_extra_isize = s_min_extra_isize;
128 -                                       brelse(bh);
129 -                                       goto retry;
130 -                               }
131 -                               error = -1;
132 -                               goto cleanup;
133 -                       }
134 +       error = ext4_xattr_make_inode_space(handle, inode, raw_inode,
135 +                                           isize_diff, ifree, bfree,
136 +                                           &total_ino);
137 +       if (error) {
138 +               if (error == -ENOSPC && !tried_min_extra_isize &&
139 +                   s_min_extra_isize) {
140 +                       tried_min_extra_isize++;
141 +                       new_extra_isize = s_min_extra_isize;
142 +                       brelse(bh);
143 +                       goto retry;
144                 }
146 -               entry_size = EXT4_XATTR_LEN(entry->e_name_len);
147 -               total_size = entry_size +
148 -                       EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size));
149 -               error = ext4_xattr_move_to_block(handle, inode, raw_inode,
150 -                                                entry);
151 -               if (error)
152 -                       goto cleanup;
154 -               total_ino -= entry_size;
155 -               ifree += total_size;
156 -               bfree -= total_size;
157 +               goto cleanup;
158         }
160  shift:
161         /* Adjust the offsets and shift the remaining entries ahead */
162         ext4_xattr_shift_entries(IFIRST(header), EXT4_I(inode)->i_extra_isize
163 -- 
164 2.6.6