1 ext4: modify ext4_xattr_ino_array to hold struct inode *
3 From: Tahsin Erdogan <tahsin@google.com>
5 Tracking struct inode * rather than the inode number eliminates the
6 repeated ext4_xattr_inode_iget() call later. The second call cannot
7 fail in practice but still requires explanation when it wants to ignore
8 the return value. Avoid the trouble and make things simple.
10 Signed-off-by: Tahsin Erdogan <tahsin@google.com>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
13 fs/ext4/ext4.h | 6 ++--
14 fs/ext4/inode.c | 8 ++---
15 fs/ext4/xattr.c | 93 ++++++++++++++++++++++++++++-----------------------------
16 fs/ext4/xattr.h | 5 ++--
17 4 files changed, 53 insertions(+), 59 deletions(-)
19 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
20 index 2cdd6070e348..603edb5ff304 100644
23 @@ -2232,9 +2232,9 @@ struct mmpd_data {
24 # define ATTRIB_NORET __attribute__((noreturn))
25 # define NORET_AND noreturn,
27 -struct ext4_xattr_ino_array {
28 - unsigned int xia_count; /* # of used item in the array */
29 - unsigned int xia_inodes[0];
30 +struct ext4_xattr_inode_array {
31 + unsigned int count; /* # of used items in the array */
32 + struct inode *inodes[0];
35 extern unsigned int ext4_count_free(char *bitmap, unsigned numchars);
36 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
37 index d095bf7ad390..8ee20b586567 100644
40 @@ -188,7 +188,7 @@ void ext4_evict_inode(struct inode *inode)
43 int extra_credits = 3;
44 - struct ext4_xattr_ino_array *lea_ino_array = NULL;
45 + struct ext4_xattr_inode_array *ea_inode_array = NULL;
47 trace_ext4_evict_inode(inode);
49 @@ -257,7 +257,7 @@ void ext4_evict_inode(struct inode *inode)
51 * Delete xattr inode before deleting the main inode.
53 - err = ext4_xattr_delete_inode(handle, inode, &lea_ino_array);
54 + err = ext4_xattr_delete_inode(handle, inode, &ea_inode_array);
56 ext4_warning(inode->i_sb,
57 "couldn't delete inode's xattr (err %d)", err);
58 @@ -345,9 +345,7 @@ void ext4_evict_inode(struct inode *inode)
60 ext4_journal_stop(handle);
61 sb_end_intwrite(inode->i_sb);
63 - if (lea_ino_array != NULL)
64 - ext4_xattr_inode_array_free(inode, lea_ino_array);
65 + ext4_xattr_inode_array_free(ea_inode_array);
68 ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
69 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
70 index fd017faaf221..c09fcffb0878 100644
73 @@ -1942,44 +1942,44 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
75 #define EIA_INCR 16 /* must be 2^n */
76 #define EIA_MASK (EIA_INCR - 1)
77 -/* Add the large xattr @ino into @lea_ino_array for later deletion.
78 - * If @lea_ino_array is new or full it will be grown and the old
79 +/* Add the large xattr @inode into @ea_inode_array for later deletion.
80 + * If @ea_inode_array is new or full it will be grown and the old
81 * contents copied over.
84 -ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
85 +ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array,
86 + struct inode *inode)
88 - if (*lea_ino_array == NULL) {
89 + if (*ea_inode_array == NULL) {
91 * Start with 15 inodes, so it fits into a power-of-two size.
92 - * If *lea_ino_array is NULL, this is essentially offsetof()
93 + * If *ea_inode_array is NULL, this is essentially offsetof()
96 - kmalloc(offsetof(struct ext4_xattr_ino_array,
97 - xia_inodes[EIA_MASK]),
99 + kmalloc(offsetof(struct ext4_xattr_inode_array,
102 - if (*lea_ino_array == NULL)
103 + if (*ea_inode_array == NULL)
105 - (*lea_ino_array)->xia_count = 0;
106 - } else if (((*lea_ino_array)->xia_count & EIA_MASK) == EIA_MASK) {
107 + (*ea_inode_array)->count = 0;
108 + } else if (((*ea_inode_array)->count & EIA_MASK) == EIA_MASK) {
109 /* expand the array once all 15 + n * 16 slots are full */
110 - struct ext4_xattr_ino_array *new_array = NULL;
111 - int count = (*lea_ino_array)->xia_count;
112 + struct ext4_xattr_inode_array *new_array = NULL;
113 + int count = (*ea_inode_array)->count;
115 /* if new_array is NULL, this is essentially offsetof() */
117 - offsetof(struct ext4_xattr_ino_array,
118 - xia_inodes[count + EIA_INCR]),
119 + offsetof(struct ext4_xattr_inode_array,
120 + inodes[count + EIA_INCR]),
122 if (new_array == NULL)
124 - memcpy(new_array, *lea_ino_array,
125 - offsetof(struct ext4_xattr_ino_array,
126 - xia_inodes[count]));
127 - kfree(*lea_ino_array);
128 - *lea_ino_array = new_array;
129 + memcpy(new_array, *ea_inode_array,
130 + offsetof(struct ext4_xattr_inode_array, inodes[count]));
131 + kfree(*ea_inode_array);
132 + *ea_inode_array = new_array;
134 - (*lea_ino_array)->xia_inodes[(*lea_ino_array)->xia_count++] = ino;
135 + (*ea_inode_array)->inodes[(*ea_inode_array)->count++] = inode;
139 @@ -1987,16 +1987,16 @@ ext4_expand_ino_array(struct ext4_xattr_ino_array **lea_ino_array, __u32 ino)
140 * Add xattr inode to orphan list
143 -ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
144 - int credits, struct ext4_xattr_ino_array *lea_ino_array)
145 +ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode, int credits,
146 + struct ext4_xattr_inode_array *ea_inode_array)
148 - struct inode *ea_inode;
149 int idx = 0, error = 0;
150 + struct inode *ea_inode;
152 - if (lea_ino_array == NULL)
153 + if (ea_inode_array == NULL)
156 - for (; idx < lea_ino_array->xia_count; ++idx) {
157 + for (; idx < ea_inode_array->count; ++idx) {
158 if (!ext4_handle_has_enough_credits(handle, credits)) {
159 error = ext4_journal_extend(handle, credits);
161 @@ -2009,10 +2009,7 @@ ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
165 - error = ext4_xattr_inode_iget(inode,
166 - lea_ino_array->xia_inodes[idx], &ea_inode);
169 + ea_inode = ea_inode_array->inodes[idx];
170 inode_lock(ea_inode);
171 ext4_orphan_add(handle, ea_inode);
172 inode_unlock(ea_inode);
173 @@ -2034,13 +2031,14 @@ ext4_xattr_inode_orphan_add(handle_t *handle, struct inode *inode,
176 ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
177 - struct ext4_xattr_ino_array **lea_ino_array)
178 + struct ext4_xattr_inode_array **ea_inode_array)
180 struct buffer_head *bh = NULL;
181 struct ext4_xattr_ibody_header *header;
182 struct ext4_inode *raw_inode;
183 struct ext4_iloc iloc;
184 struct ext4_xattr_entry *entry;
185 + struct inode *ea_inode;
187 int credits = 3, error = 0;
189 @@ -2057,8 +2055,12 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
190 if (!entry->e_value_inum)
192 ea_ino = le32_to_cpu(entry->e_value_inum);
193 - error = ext4_expand_ino_array(lea_ino_array, ea_ino);
194 + error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode);
197 + error = ext4_expand_inode_array(ea_inode_array, ea_inode);
203 @@ -2070,7 +2072,7 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
204 if (!EXT4_I(inode)->i_file_acl) {
205 /* add xattr inode to orphan list */
206 error = ext4_xattr_inode_orphan_add(handle, inode, credits,
211 bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
212 @@ -2093,7 +2095,10 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
213 if (!entry->e_value_inum)
215 ea_ino = le32_to_cpu(entry->e_value_inum);
216 - error = ext4_expand_ino_array(lea_ino_array, ea_ino);
217 + error = ext4_xattr_inode_iget(inode, ea_ino, &ea_inode);
220 + error = ext4_expand_inode_array(ea_inode_array, ea_inode);
223 entry->e_value_inum = 0;
224 @@ -2101,7 +2106,7 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
226 /* add xattr inode to orphan list */
227 error = ext4_xattr_inode_orphan_add(handle, inode, credits,
233 @@ -2128,28 +2133,20 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
238 -ext4_xattr_inode_array_free(struct inode *inode,
239 - struct ext4_xattr_ino_array *lea_ino_array)
240 +void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *ea_inode_array)
242 struct inode *ea_inode;
246 - if (lea_ino_array == NULL)
247 + if (ea_inode_array == NULL)
250 - for (; idx < lea_ino_array->xia_count; ++idx) {
251 - err = ext4_xattr_inode_iget(inode,
252 - lea_ino_array->xia_inodes[idx], &ea_inode);
255 - /* for inode's i_count get from ext4_xattr_delete_inode */
257 + for (; idx < ea_inode_array->count; ++idx) {
258 + ea_inode = ea_inode_array->inodes[idx];
259 clear_nlink(ea_inode);
262 - kfree(lea_ino_array);
263 + kfree(ea_inode_array);
267 diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
268 index e82c5fe36a26..323eba54f72f 100644
269 --- a/fs/ext4/xattr.h
270 +++ b/fs/ext4/xattr.h
271 @@ -164,9 +164,8 @@ extern int ext4_xattr_set_credits(struct inode *inode, size_t value_len);
273 extern int ext4_xattr_inode_unlink(struct inode *inode, unsigned long ea_ino);
274 extern int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
275 - struct ext4_xattr_ino_array **array);
276 -extern void ext4_xattr_inode_array_free(struct inode *inode,
277 - struct ext4_xattr_ino_array *array);
278 + struct ext4_xattr_inode_array **array);
279 +extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);
281 extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
282 struct ext4_inode *raw_inode, handle_t *handle);
284 2.13.1.611.g7e3b11ae1-goog