]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Joel Becker <joel.becker@oracle.com> |
2 | Date: Fri, 24 Oct 2008 19:13:20 -0700 | |
3 | Subject: ocfs2: Take ocfs2_xattr_bucket structures off of the stack. | |
4 | Patch-mainline: 2.6.29 | |
5 | ||
6 | The ocfs2_xattr_bucket structure is a nice abstraction, but it is a bit | |
7 | large to have on the stack. Just like ocfs2_path, let's allocate it | |
8 | with a ocfs2_xattr_bucket_new() function. | |
9 | ||
10 | We can now store the inode on the bucket, cleaning up all the other | |
11 | bucket functions. While we're here, we catch another place or two that | |
12 | wasn't using ocfs2_read_xattr_bucket(). | |
13 | ||
14 | Updates: | |
15 | - No longer allocating xis.bucket, as it will never be used. | |
16 | ||
17 | Signed-off-by: Joel Becker <joel.becker@oracle.com> | |
18 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
19 | --- | |
20 | fs/ocfs2/xattr.c | 281 ++++++++++++++++++++++++++++++++---------------------- | |
21 | 1 files changed, 166 insertions(+), 115 deletions(-) | |
22 | ||
23 | diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c | |
24 | index 71d9e7b..766494e 100644 | |
25 | --- a/fs/ocfs2/xattr.c | |
26 | +++ b/fs/ocfs2/xattr.c | |
27 | @@ -61,7 +61,14 @@ struct ocfs2_xattr_def_value_root { | |
28 | }; | |
29 | ||
30 | struct ocfs2_xattr_bucket { | |
31 | + /* The inode these xattrs are associated with */ | |
32 | + struct inode *bu_inode; | |
33 | + | |
34 | + /* The actual buffers that make up the bucket */ | |
35 | struct buffer_head *bu_bhs[OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET]; | |
36 | + | |
37 | + /* How many blocks make up one bucket for this filesystem */ | |
38 | + int bu_blocks; | |
39 | }; | |
40 | ||
41 | #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) | |
42 | @@ -97,7 +104,7 @@ struct ocfs2_xattr_search { | |
43 | */ | |
44 | struct buffer_head *xattr_bh; | |
45 | struct ocfs2_xattr_header *header; | |
46 | - struct ocfs2_xattr_bucket bucket; | |
47 | + struct ocfs2_xattr_bucket *bucket; | |
48 | void *base; | |
49 | void *end; | |
50 | struct ocfs2_xattr_entry *here; | |
51 | @@ -157,69 +164,91 @@ static inline u16 ocfs2_xattr_max_xe_in_bucket(struct super_block *sb) | |
52 | #define bucket_block(_b, _n) ((_b)->bu_bhs[(_n)]->b_data) | |
53 | #define bucket_xh(_b) ((struct ocfs2_xattr_header *)bucket_block((_b), 0)) | |
54 | ||
55 | -static void ocfs2_xattr_bucket_relse(struct inode *inode, | |
56 | - struct ocfs2_xattr_bucket *bucket) | |
57 | +static struct ocfs2_xattr_bucket *ocfs2_xattr_bucket_new(struct inode *inode) | |
58 | { | |
59 | - int i, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
60 | + struct ocfs2_xattr_bucket *bucket; | |
61 | + int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
62 | ||
63 | - for (i = 0; i < blks; i++) { | |
64 | + BUG_ON(blks > OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET); | |
65 | + | |
66 | + bucket = kzalloc(sizeof(struct ocfs2_xattr_bucket), GFP_NOFS); | |
67 | + if (bucket) { | |
68 | + bucket->bu_inode = inode; | |
69 | + bucket->bu_blocks = blks; | |
70 | + } | |
71 | + | |
72 | + return bucket; | |
73 | +} | |
74 | + | |
75 | +static void ocfs2_xattr_bucket_relse(struct ocfs2_xattr_bucket *bucket) | |
76 | +{ | |
77 | + int i; | |
78 | + | |
79 | + for (i = 0; i < bucket->bu_blocks; i++) { | |
80 | brelse(bucket->bu_bhs[i]); | |
81 | bucket->bu_bhs[i] = NULL; | |
82 | } | |
83 | } | |
84 | ||
85 | +static void ocfs2_xattr_bucket_free(struct ocfs2_xattr_bucket *bucket) | |
86 | +{ | |
87 | + if (bucket) { | |
88 | + ocfs2_xattr_bucket_relse(bucket); | |
89 | + bucket->bu_inode = NULL; | |
90 | + kfree(bucket); | |
91 | + } | |
92 | +} | |
93 | + | |
94 | /* | |
95 | * A bucket that has never been written to disk doesn't need to be | |
96 | * read. We just need the buffer_heads. Don't call this for | |
97 | * buckets that are already on disk. ocfs2_read_xattr_bucket() initializes | |
98 | * them fully. | |
99 | */ | |
100 | -static int ocfs2_init_xattr_bucket(struct inode *inode, | |
101 | - struct ocfs2_xattr_bucket *bucket, | |
102 | +static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | |
103 | u64 xb_blkno) | |
104 | { | |
105 | int i, rc = 0; | |
106 | - int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
107 | ||
108 | - for (i = 0; i < blks; i++) { | |
109 | - bucket->bu_bhs[i] = sb_getblk(inode->i_sb, xb_blkno + i); | |
110 | + for (i = 0; i < bucket->bu_blocks; i++) { | |
111 | + bucket->bu_bhs[i] = sb_getblk(bucket->bu_inode->i_sb, | |
112 | + xb_blkno + i); | |
113 | if (!bucket->bu_bhs[i]) { | |
114 | rc = -EIO; | |
115 | mlog_errno(rc); | |
116 | break; | |
117 | } | |
118 | ||
119 | - ocfs2_set_new_buffer_uptodate(inode, bucket->bu_bhs[i]); | |
120 | + ocfs2_set_new_buffer_uptodate(bucket->bu_inode, | |
121 | + bucket->bu_bhs[i]); | |
122 | } | |
123 | ||
124 | if (rc) | |
125 | - ocfs2_xattr_bucket_relse(inode, bucket); | |
126 | + ocfs2_xattr_bucket_relse(bucket); | |
127 | return rc; | |
128 | } | |
129 | ||
130 | /* Read the xattr bucket at xb_blkno */ | |
131 | -static int ocfs2_read_xattr_bucket(struct inode *inode, | |
132 | - struct ocfs2_xattr_bucket *bucket, | |
133 | +static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | |
134 | u64 xb_blkno) | |
135 | { | |
136 | - int rc, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
137 | + int rc; | |
138 | ||
139 | - rc = ocfs2_read_blocks(inode, xb_blkno, blks, bucket->bu_bhs, 0); | |
140 | + rc = ocfs2_read_blocks(bucket->bu_inode, xb_blkno, | |
141 | + bucket->bu_blocks, bucket->bu_bhs, 0); | |
142 | if (rc) | |
143 | - ocfs2_xattr_bucket_relse(inode, bucket); | |
144 | + ocfs2_xattr_bucket_relse(bucket); | |
145 | return rc; | |
146 | } | |
147 | ||
148 | static int ocfs2_xattr_bucket_journal_access(handle_t *handle, | |
149 | - struct inode *inode, | |
150 | struct ocfs2_xattr_bucket *bucket, | |
151 | int type) | |
152 | { | |
153 | int i, rc = 0; | |
154 | - int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
155 | ||
156 | - for (i = 0; i < blks; i++) { | |
157 | - rc = ocfs2_journal_access(handle, inode, | |
158 | + for (i = 0; i < bucket->bu_blocks; i++) { | |
159 | + rc = ocfs2_journal_access(handle, bucket->bu_inode, | |
160 | bucket->bu_bhs[i], type); | |
161 | if (rc) { | |
162 | mlog_errno(rc); | |
163 | @@ -231,24 +260,24 @@ static int ocfs2_xattr_bucket_journal_access(handle_t *handle, | |
164 | } | |
165 | ||
166 | static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle, | |
167 | - struct inode *inode, | |
168 | struct ocfs2_xattr_bucket *bucket) | |
169 | { | |
170 | - int i, blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
171 | + int i; | |
172 | ||
173 | - for (i = 0; i < blks; i++) | |
174 | + for (i = 0; i < bucket->bu_blocks; i++) | |
175 | ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); | |
176 | } | |
177 | ||
178 | -static void ocfs2_xattr_bucket_copy_data(struct inode *inode, | |
179 | - struct ocfs2_xattr_bucket *dest, | |
180 | +static void ocfs2_xattr_bucket_copy_data(struct ocfs2_xattr_bucket *dest, | |
181 | struct ocfs2_xattr_bucket *src) | |
182 | { | |
183 | int i; | |
184 | - int blocksize = inode->i_sb->s_blocksize; | |
185 | - int blks = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
186 | + int blocksize = src->bu_inode->i_sb->s_blocksize; | |
187 | + | |
188 | + BUG_ON(dest->bu_blocks != src->bu_blocks); | |
189 | + BUG_ON(dest->bu_inode != src->bu_inode); | |
190 | ||
191 | - for (i = 0; i < blks; i++) { | |
192 | + for (i = 0; i < src->bu_blocks; i++) { | |
193 | memcpy(bucket_block(dest, i), bucket_block(src, i), | |
194 | blocksize); | |
195 | } | |
196 | @@ -869,7 +898,12 @@ static int ocfs2_xattr_block_get(struct inode *inode, | |
197 | size_t size; | |
198 | int ret = -ENODATA, name_offset, name_len, block_off, i; | |
199 | ||
200 | - memset(&xs->bucket, 0, sizeof(xs->bucket)); | |
201 | + xs->bucket = ocfs2_xattr_bucket_new(inode); | |
202 | + if (!xs->bucket) { | |
203 | + ret = -ENOMEM; | |
204 | + mlog_errno(ret); | |
205 | + goto cleanup; | |
206 | + } | |
207 | ||
208 | ret = ocfs2_xattr_block_find(inode, name_index, name, xs); | |
209 | if (ret) { | |
210 | @@ -895,11 +929,11 @@ static int ocfs2_xattr_block_get(struct inode *inode, | |
211 | ||
212 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { | |
213 | ret = ocfs2_xattr_bucket_get_name_value(inode, | |
214 | - bucket_xh(&xs->bucket), | |
215 | + bucket_xh(xs->bucket), | |
216 | i, | |
217 | &block_off, | |
218 | &name_offset); | |
219 | - xs->base = bucket_block(&xs->bucket, block_off); | |
220 | + xs->base = bucket_block(xs->bucket, block_off); | |
221 | } | |
222 | if (ocfs2_xattr_is_local(xs->here)) { | |
223 | memcpy(buffer, (void *)xs->base + | |
224 | @@ -917,8 +951,7 @@ static int ocfs2_xattr_block_get(struct inode *inode, | |
225 | } | |
226 | ret = size; | |
227 | cleanup: | |
228 | - ocfs2_xattr_bucket_relse(inode, &xs->bucket); | |
229 | - memset(&xs->bucket, 0, sizeof(xs->bucket)); | |
230 | + ocfs2_xattr_bucket_free(xs->bucket); | |
231 | ||
232 | brelse(xs->xattr_bh); | |
233 | xs->xattr_bh = NULL; | |
234 | @@ -2047,10 +2080,20 @@ int ocfs2_xattr_set(struct inode *inode, | |
235 | if (!ocfs2_supports_xattr(OCFS2_SB(inode->i_sb))) | |
236 | return -EOPNOTSUPP; | |
237 | ||
238 | + /* | |
239 | + * Only xbs will be used on indexed trees. xis doesn't need a | |
240 | + * bucket. | |
241 | + */ | |
242 | + xbs.bucket = ocfs2_xattr_bucket_new(inode); | |
243 | + if (!xbs.bucket) { | |
244 | + mlog_errno(-ENOMEM); | |
245 | + return -ENOMEM; | |
246 | + } | |
247 | + | |
248 | ret = ocfs2_inode_lock(inode, &di_bh, 1); | |
249 | if (ret < 0) { | |
250 | mlog_errno(ret); | |
251 | - return ret; | |
252 | + goto cleanup_nolock; | |
253 | } | |
254 | xis.inode_bh = xbs.inode_bh = di_bh; | |
255 | di = (struct ocfs2_dinode *)di_bh->b_data; | |
256 | @@ -2127,9 +2170,10 @@ int ocfs2_xattr_set(struct inode *inode, | |
257 | cleanup: | |
258 | up_write(&OCFS2_I(inode)->ip_xattr_sem); | |
259 | ocfs2_inode_unlock(inode, 1); | |
260 | +cleanup_nolock: | |
261 | brelse(di_bh); | |
262 | brelse(xbs.xattr_bh); | |
263 | - ocfs2_xattr_bucket_relse(inode, &xbs.bucket); | |
264 | + ocfs2_xattr_bucket_free(xbs.bucket); | |
265 | ||
266 | return ret; | |
267 | } | |
268 | @@ -2373,11 +2417,11 @@ static int ocfs2_xattr_bucket_find(struct inode *inode, | |
269 | lower_bh = bh; | |
270 | bh = NULL; | |
271 | } | |
272 | - xs->bucket.bu_bhs[0] = lower_bh; | |
273 | + xs->bucket->bu_bhs[0] = lower_bh; | |
274 | lower_bh = NULL; | |
275 | ||
276 | - xs->header = bucket_xh(&xs->bucket); | |
277 | - xs->base = bucket_block(&xs->bucket, 0); | |
278 | + xs->header = bucket_xh(xs->bucket); | |
279 | + xs->base = bucket_block(xs->bucket, 0); | |
280 | xs->end = xs->base + inode->i_sb->s_blocksize; | |
281 | ||
282 | if (found) { | |
283 | @@ -2385,8 +2429,8 @@ static int ocfs2_xattr_bucket_find(struct inode *inode, | |
284 | * If we have found the xattr enty, read all the blocks in | |
285 | * this bucket. | |
286 | */ | |
287 | - ret = ocfs2_read_blocks(inode, bucket_blkno(&xs->bucket) + 1, | |
288 | - blk_per_bucket - 1, &xs->bucket.bu_bhs[1], | |
289 | + ret = ocfs2_read_blocks(inode, bucket_blkno(xs->bucket) + 1, | |
290 | + blk_per_bucket - 1, &xs->bucket->bu_bhs[1], | |
291 | 0); | |
292 | if (ret) { | |
293 | mlog_errno(ret); | |
294 | @@ -2395,7 +2439,7 @@ static int ocfs2_xattr_bucket_find(struct inode *inode, | |
295 | ||
296 | xs->here = &xs->header->xh_entries[index]; | |
297 | mlog(0, "find xattr %s in bucket %llu, entry = %u\n", name, | |
298 | - (unsigned long long)bucket_blkno(&xs->bucket), index); | |
299 | + (unsigned long long)bucket_blkno(xs->bucket), index); | |
300 | } else | |
301 | ret = -ENODATA; | |
302 | ||
303 | @@ -2453,22 +2497,24 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode, | |
304 | void *para) | |
305 | { | |
306 | int i, ret = 0; | |
307 | - int blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
308 | u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)); | |
309 | u32 num_buckets = clusters * bpc; | |
310 | - struct ocfs2_xattr_bucket bucket; | |
311 | + struct ocfs2_xattr_bucket *bucket; | |
312 | ||
313 | - memset(&bucket, 0, sizeof(bucket)); | |
314 | + bucket = ocfs2_xattr_bucket_new(inode); | |
315 | + if (!bucket) { | |
316 | + mlog_errno(-ENOMEM); | |
317 | + return -ENOMEM; | |
318 | + } | |
319 | ||
320 | mlog(0, "iterating xattr buckets in %u clusters starting from %llu\n", | |
321 | clusters, (unsigned long long)blkno); | |
322 | ||
323 | - for (i = 0; i < num_buckets; i++, blkno += blk_per_bucket) { | |
324 | - ret = ocfs2_read_blocks(inode, blkno, blk_per_bucket, | |
325 | - bucket.bu_bhs, 0); | |
326 | + for (i = 0; i < num_buckets; i++, blkno += bucket->bu_blocks) { | |
327 | + ret = ocfs2_read_xattr_bucket(bucket, blkno); | |
328 | if (ret) { | |
329 | mlog_errno(ret); | |
330 | - goto out; | |
331 | + break; | |
332 | } | |
333 | ||
334 | /* | |
335 | @@ -2476,26 +2522,24 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode, | |
336 | * in the 1st bucket. | |
337 | */ | |
338 | if (i == 0) | |
339 | - num_buckets = le16_to_cpu(bucket_xh(&bucket)->xh_num_buckets); | |
340 | + num_buckets = le16_to_cpu(bucket_xh(bucket)->xh_num_buckets); | |
341 | ||
342 | mlog(0, "iterating xattr bucket %llu, first hash %u\n", | |
343 | (unsigned long long)blkno, | |
344 | - le32_to_cpu(bucket_xh(&bucket)->xh_entries[0].xe_name_hash)); | |
345 | + le32_to_cpu(bucket_xh(bucket)->xh_entries[0].xe_name_hash)); | |
346 | if (func) { | |
347 | - ret = func(inode, &bucket, para); | |
348 | - if (ret) { | |
349 | + ret = func(inode, bucket, para); | |
350 | + if (ret) | |
351 | mlog_errno(ret); | |
352 | - break; | |
353 | - } | |
354 | + /* Fall through to bucket_relse() */ | |
355 | } | |
356 | ||
357 | - ocfs2_xattr_bucket_relse(inode, &bucket); | |
358 | - memset(&bucket, 0, sizeof(bucket)); | |
359 | + ocfs2_xattr_bucket_relse(bucket); | |
360 | + if (ret) | |
361 | + break; | |
362 | } | |
363 | ||
364 | -out: | |
365 | - ocfs2_xattr_bucket_relse(inode, &bucket); | |
366 | - | |
367 | + ocfs2_xattr_bucket_free(bucket); | |
368 | return ret; | |
369 | } | |
370 | ||
371 | @@ -2718,9 +2762,9 @@ static int ocfs2_xattr_update_xattr_search(struct inode *inode, | |
372 | int i, blocksize = inode->i_sb->s_blocksize; | |
373 | u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
374 | ||
375 | - xs->bucket.bu_bhs[0] = new_bh; | |
376 | + xs->bucket->bu_bhs[0] = new_bh; | |
377 | get_bh(new_bh); | |
378 | - xs->header = bucket_xh(&xs->bucket); | |
379 | + xs->header = bucket_xh(xs->bucket); | |
380 | ||
381 | xs->base = new_bh->b_data; | |
382 | xs->end = xs->base + inode->i_sb->s_blocksize; | |
383 | @@ -2728,8 +2772,8 @@ static int ocfs2_xattr_update_xattr_search(struct inode *inode, | |
384 | if (!xs->not_found) { | |
385 | if (OCFS2_XATTR_BUCKET_SIZE != blocksize) { | |
386 | ret = ocfs2_read_blocks(inode, | |
387 | - bucket_blkno(&xs->bucket) + 1, | |
388 | - blk_per_bucket - 1, &xs->bucket.bu_bhs[1], | |
389 | + bucket_blkno(xs->bucket) + 1, | |
390 | + blk_per_bucket - 1, &xs->bucket->bu_bhs[1], | |
391 | 0); | |
392 | if (ret) { | |
393 | mlog_errno(ret); | |
394 | @@ -3244,8 +3288,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |
395 | { | |
396 | int ret, i; | |
397 | int count, start, len, name_value_len = 0, xe_len, name_offset = 0; | |
398 | - u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | |
399 | - struct ocfs2_xattr_bucket s_bucket, t_bucket; | |
400 | + struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL; | |
401 | struct ocfs2_xattr_header *xh; | |
402 | struct ocfs2_xattr_entry *xe; | |
403 | int blocksize = inode->i_sb->s_blocksize; | |
404 | @@ -3253,16 +3296,21 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |
405 | mlog(0, "move some of xattrs from bucket %llu to %llu\n", | |
406 | (unsigned long long)blk, (unsigned long long)new_blk); | |
407 | ||
408 | - memset(&s_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); | |
409 | - memset(&t_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); | |
410 | + s_bucket = ocfs2_xattr_bucket_new(inode); | |
411 | + t_bucket = ocfs2_xattr_bucket_new(inode); | |
412 | + if (!s_bucket || !t_bucket) { | |
413 | + ret = -ENOMEM; | |
414 | + mlog_errno(ret); | |
415 | + goto out; | |
416 | + } | |
417 | ||
418 | - ret = ocfs2_read_xattr_bucket(inode, &s_bucket, blk); | |
419 | + ret = ocfs2_read_xattr_bucket(s_bucket, blk); | |
420 | if (ret) { | |
421 | mlog_errno(ret); | |
422 | goto out; | |
423 | } | |
424 | ||
425 | - ret = ocfs2_xattr_bucket_journal_access(handle, inode, &s_bucket, | |
426 | + ret = ocfs2_xattr_bucket_journal_access(handle, s_bucket, | |
427 | OCFS2_JOURNAL_ACCESS_WRITE); | |
428 | if (ret) { | |
429 | mlog_errno(ret); | |
430 | @@ -3273,13 +3321,13 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |
431 | * Even if !new_bucket_head, we're overwriting t_bucket. Thus, | |
432 | * there's no need to read it. | |
433 | */ | |
434 | - ret = ocfs2_init_xattr_bucket(inode, &t_bucket, new_blk); | |
435 | + ret = ocfs2_init_xattr_bucket(t_bucket, new_blk); | |
436 | if (ret) { | |
437 | mlog_errno(ret); | |
438 | goto out; | |
439 | } | |
440 | ||
441 | - ret = ocfs2_xattr_bucket_journal_access(handle, inode, &t_bucket, | |
442 | + ret = ocfs2_xattr_bucket_journal_access(handle, t_bucket, | |
443 | new_bucket_head ? | |
444 | OCFS2_JOURNAL_ACCESS_CREATE : | |
445 | OCFS2_JOURNAL_ACCESS_WRITE); | |
446 | @@ -3288,7 +3336,7 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |
447 | goto out; | |
448 | } | |
449 | ||
450 | - xh = bucket_xh(&s_bucket); | |
451 | + xh = bucket_xh(s_bucket); | |
452 | count = le16_to_cpu(xh->xh_count); | |
453 | start = ocfs2_xattr_find_divide_pos(xh); | |
454 | ||
455 | @@ -3300,10 +3348,10 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |
456 | * The hash value is set as one larger than | |
457 | * that of the last entry in the previous bucket. | |
458 | */ | |
459 | - for (i = 0; i < blk_per_bucket; i++) | |
460 | - memset(bucket_block(&t_bucket, i), 0, blocksize); | |
461 | + for (i = 0; i < t_bucket->bu_blocks; i++) | |
462 | + memset(bucket_block(t_bucket, i), 0, blocksize); | |
463 | ||
464 | - xh = bucket_xh(&t_bucket); | |
465 | + xh = bucket_xh(t_bucket); | |
466 | xh->xh_free_start = cpu_to_le16(blocksize); | |
467 | xh->xh_entries[0].xe_name_hash = xe->xe_name_hash; | |
468 | le32_add_cpu(&xh->xh_entries[0].xe_name_hash, 1); | |
469 | @@ -3312,10 +3360,10 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode, | |
470 | } | |
471 | ||
472 | /* copy the whole bucket to the new first. */ | |
473 | - ocfs2_xattr_bucket_copy_data(inode, &t_bucket, &s_bucket); | |
474 | + ocfs2_xattr_bucket_copy_data(t_bucket, s_bucket); | |
475 | ||
476 | /* update the new bucket. */ | |
477 | - xh = bucket_xh(&t_bucket); | |
478 | + xh = bucket_xh(t_bucket); | |
479 | ||
480 | /* | |
481 | * Calculate the total name/value len and xh_free_start for | |
482 | @@ -3379,7 +3427,7 @@ set_num_buckets: | |
483 | else | |
484 | xh->xh_num_buckets = 0; | |
485 | ||
486 | - ocfs2_xattr_bucket_journal_dirty(handle, inode, &t_bucket); | |
487 | + ocfs2_xattr_bucket_journal_dirty(handle, t_bucket); | |
488 | ||
489 | /* store the first_hash of the new bucket. */ | |
490 | if (first_hash) | |
491 | @@ -3393,18 +3441,18 @@ set_num_buckets: | |
492 | if (start == count) | |
493 | goto out; | |
494 | ||
495 | - xh = bucket_xh(&s_bucket); | |
496 | + xh = bucket_xh(s_bucket); | |
497 | memset(&xh->xh_entries[start], 0, | |
498 | sizeof(struct ocfs2_xattr_entry) * (count - start)); | |
499 | xh->xh_count = cpu_to_le16(start); | |
500 | xh->xh_free_start = cpu_to_le16(name_offset); | |
501 | xh->xh_name_value_len = cpu_to_le16(name_value_len); | |
502 | ||
503 | - ocfs2_xattr_bucket_journal_dirty(handle, inode, &s_bucket); | |
504 | + ocfs2_xattr_bucket_journal_dirty(handle, s_bucket); | |
505 | ||
506 | out: | |
507 | - ocfs2_xattr_bucket_relse(inode, &s_bucket); | |
508 | - ocfs2_xattr_bucket_relse(inode, &t_bucket); | |
509 | + ocfs2_xattr_bucket_free(s_bucket); | |
510 | + ocfs2_xattr_bucket_free(t_bucket); | |
511 | ||
512 | return ret; | |
513 | } | |
514 | @@ -3422,7 +3470,7 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode, | |
515 | int t_is_new) | |
516 | { | |
517 | int ret; | |
518 | - struct ocfs2_xattr_bucket s_bucket, t_bucket; | |
519 | + struct ocfs2_xattr_bucket *s_bucket = NULL, *t_bucket = NULL; | |
520 | ||
521 | BUG_ON(s_blkno == t_blkno); | |
522 | ||
523 | @@ -3430,10 +3478,15 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode, | |
524 | (unsigned long long)s_blkno, (unsigned long long)t_blkno, | |
525 | t_is_new); | |
526 | ||
527 | - memset(&s_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); | |
528 | - memset(&t_bucket, 0, sizeof(struct ocfs2_xattr_bucket)); | |
529 | - | |
530 | - ret = ocfs2_read_xattr_bucket(inode, &s_bucket, s_blkno); | |
531 | + s_bucket = ocfs2_xattr_bucket_new(inode); | |
532 | + t_bucket = ocfs2_xattr_bucket_new(inode); | |
533 | + if (!s_bucket || !t_bucket) { | |
534 | + ret = -ENOMEM; | |
535 | + mlog_errno(ret); | |
536 | + goto out; | |
537 | + } | |
538 | + | |
539 | + ret = ocfs2_read_xattr_bucket(s_bucket, s_blkno); | |
540 | if (ret) | |
541 | goto out; | |
542 | ||
543 | @@ -3441,23 +3494,23 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode, | |
544 | * Even if !t_is_new, we're overwriting t_bucket. Thus, | |
545 | * there's no need to read it. | |
546 | */ | |
547 | - ret = ocfs2_init_xattr_bucket(inode, &t_bucket, t_blkno); | |
548 | + ret = ocfs2_init_xattr_bucket(t_bucket, t_blkno); | |
549 | if (ret) | |
550 | goto out; | |
551 | ||
552 | - ret = ocfs2_xattr_bucket_journal_access(handle, inode, &t_bucket, | |
553 | + ret = ocfs2_xattr_bucket_journal_access(handle, t_bucket, | |
554 | t_is_new ? | |
555 | OCFS2_JOURNAL_ACCESS_CREATE : | |
556 | OCFS2_JOURNAL_ACCESS_WRITE); | |
557 | if (ret) | |
558 | goto out; | |
559 | ||
560 | - ocfs2_xattr_bucket_copy_data(inode, &t_bucket, &s_bucket); | |
561 | - ocfs2_xattr_bucket_journal_dirty(handle, inode, &t_bucket); | |
562 | + ocfs2_xattr_bucket_copy_data(t_bucket, s_bucket); | |
563 | + ocfs2_xattr_bucket_journal_dirty(handle, t_bucket); | |
564 | ||
565 | out: | |
566 | - ocfs2_xattr_bucket_relse(inode, &s_bucket); | |
567 | - ocfs2_xattr_bucket_relse(inode, &t_bucket); | |
568 | + ocfs2_xattr_bucket_free(t_bucket); | |
569 | + ocfs2_xattr_bucket_free(s_bucket); | |
570 | ||
571 | return ret; | |
572 | } | |
573 | @@ -4009,7 +4062,7 @@ static void ocfs2_xattr_set_entry_normal(struct inode *inode, | |
574 | xe->xe_value_size = 0; | |
575 | ||
576 | val = ocfs2_xattr_bucket_get_val(inode, | |
577 | - &xs->bucket, offs); | |
578 | + xs->bucket, offs); | |
579 | memset(val + OCFS2_XATTR_SIZE(name_len), 0, | |
580 | size - OCFS2_XATTR_SIZE(name_len)); | |
581 | if (OCFS2_XATTR_SIZE(xi->value_len) > 0) | |
582 | @@ -4087,8 +4140,7 @@ set_new_name_value: | |
583 | xh->xh_free_start = cpu_to_le16(offs); | |
584 | } | |
585 | ||
586 | - val = ocfs2_xattr_bucket_get_val(inode, | |
587 | - &xs->bucket, offs - size); | |
588 | + val = ocfs2_xattr_bucket_get_val(inode, xs->bucket, offs - size); | |
589 | xe->xe_name_offset = cpu_to_le16(offs - size); | |
590 | ||
591 | memset(val, 0, size); | |
592 | @@ -4122,12 +4174,12 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode, | |
593 | ||
594 | mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n", | |
595 | (unsigned long)xi->value_len, xi->name_index, | |
596 | - (unsigned long long)bucket_blkno(&xs->bucket)); | |
597 | + (unsigned long long)bucket_blkno(xs->bucket)); | |
598 | ||
599 | - if (!xs->bucket.bu_bhs[1]) { | |
600 | + if (!xs->bucket->bu_bhs[1]) { | |
601 | ret = ocfs2_read_blocks(inode, | |
602 | - bucket_blkno(&xs->bucket) + 1, | |
603 | - blk_per_bucket - 1, &xs->bucket.bu_bhs[1], | |
604 | + bucket_blkno(xs->bucket) + 1, | |
605 | + blk_per_bucket - 1, &xs->bucket->bu_bhs[1], | |
606 | 0); | |
607 | if (ret) { | |
608 | mlog_errno(ret); | |
609 | @@ -4143,7 +4195,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode, | |
610 | goto out; | |
611 | } | |
612 | ||
613 | - ret = ocfs2_xattr_bucket_journal_access(handle, inode, &xs->bucket, | |
614 | + ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, | |
615 | OCFS2_JOURNAL_ACCESS_WRITE); | |
616 | if (ret < 0) { | |
617 | mlog_errno(ret); | |
618 | @@ -4151,7 +4203,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode, | |
619 | } | |
620 | ||
621 | ocfs2_xattr_set_entry_normal(inode, xi, xs, name_hash, local); | |
622 | - ocfs2_xattr_bucket_journal_dirty(handle, inode, &xs->bucket); | |
623 | + ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket); | |
624 | ||
625 | out: | |
626 | ocfs2_commit_trans(osb, handle); | |
627 | @@ -4264,10 +4316,10 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode, | |
628 | struct ocfs2_xattr_entry *xe = xs->here; | |
629 | struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *)xs->base; | |
630 | ||
631 | - BUG_ON(!xs->bucket.bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe)); | |
632 | + BUG_ON(!xs->bucket->bu_bhs[0] || !xe || ocfs2_xattr_is_local(xe)); | |
633 | ||
634 | offset = xe - xh->xh_entries; | |
635 | - ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket.bu_bhs[0], | |
636 | + ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket->bu_bhs[0], | |
637 | offset, len); | |
638 | if (ret) | |
639 | mlog_errno(ret); | |
640 | @@ -4387,7 +4439,7 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode, | |
641 | struct ocfs2_xattr_search *xs) | |
642 | { | |
643 | handle_t *handle = NULL; | |
644 | - struct ocfs2_xattr_header *xh = bucket_xh(&xs->bucket); | |
645 | + struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); | |
646 | struct ocfs2_xattr_entry *last = &xh->xh_entries[ | |
647 | le16_to_cpu(xh->xh_count) - 1]; | |
648 | int ret = 0; | |
649 | @@ -4400,7 +4452,7 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode, | |
650 | return; | |
651 | } | |
652 | ||
653 | - ret = ocfs2_xattr_bucket_journal_access(handle, inode, &xs->bucket, | |
654 | + ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, | |
655 | OCFS2_JOURNAL_ACCESS_WRITE); | |
656 | if (ret) { | |
657 | mlog_errno(ret); | |
658 | @@ -4413,7 +4465,7 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode, | |
659 | memset(last, 0, sizeof(struct ocfs2_xattr_entry)); | |
660 | le16_add_cpu(&xh->xh_count, -1); | |
661 | ||
662 | - ocfs2_xattr_bucket_journal_dirty(handle, inode, &xs->bucket); | |
663 | + ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket); | |
664 | ||
665 | out_commit: | |
666 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | |
667 | @@ -4565,7 +4617,7 @@ try_again: | |
668 | ||
669 | mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " | |
670 | "of %u which exceed block size\n", | |
671 | - (unsigned long long)bucket_blkno(&xs->bucket), | |
672 | + (unsigned long long)bucket_blkno(xs->bucket), | |
673 | header_size); | |
674 | ||
675 | if (xi->value && xi->value_len > OCFS2_XATTR_INLINE_SIZE) | |
676 | @@ -4605,7 +4657,7 @@ try_again: | |
677 | mlog(0, "xs->not_found = %d, in xattr bucket %llu: free = %d, " | |
678 | "need = %d, max_free = %d, xh_free_start = %u, xh_name_value_len =" | |
679 | " %u\n", xs->not_found, | |
680 | - (unsigned long long)bucket_blkno(&xs->bucket), | |
681 | + (unsigned long long)bucket_blkno(xs->bucket), | |
682 | free, need, max_free, le16_to_cpu(xh->xh_free_start), | |
683 | le16_to_cpu(xh->xh_name_value_len)); | |
684 | ||
685 | @@ -4617,7 +4669,7 @@ try_again: | |
686 | * name/value will be moved, the xe shouldn't be changed | |
687 | * in xs. | |
688 | */ | |
689 | - ret = ocfs2_defrag_xattr_bucket(inode, &xs->bucket); | |
690 | + ret = ocfs2_defrag_xattr_bucket(inode, xs->bucket); | |
691 | if (ret) { | |
692 | mlog_errno(ret); | |
693 | goto out; | |
694 | @@ -4649,7 +4701,7 @@ try_again: | |
695 | * add a new bucket for the insert. | |
696 | */ | |
697 | ret = ocfs2_check_xattr_bucket_collision(inode, | |
698 | - &xs->bucket, | |
699 | + xs->bucket, | |
700 | xi->name); | |
701 | if (ret) { | |
702 | mlog_errno(ret); | |
703 | @@ -4658,14 +4710,13 @@ try_again: | |
704 | ||
705 | ret = ocfs2_add_new_xattr_bucket(inode, | |
706 | xs->xattr_bh, | |
707 | - xs->bucket.bu_bhs[0]); | |
708 | + xs->bucket->bu_bhs[0]); | |
709 | if (ret) { | |
710 | mlog_errno(ret); | |
711 | goto out; | |
712 | } | |
713 | ||
714 | - ocfs2_xattr_bucket_relse(inode, &xs->bucket); | |
715 | - memset(&xs->bucket, 0, sizeof(xs->bucket)); | |
716 | + ocfs2_xattr_bucket_relse(xs->bucket); | |
717 | ||
718 | ret = ocfs2_xattr_index_block_find(inode, xs->xattr_bh, | |
719 | xi->name_index, | |
720 | -- | |
721 | 1.5.6 | |
722 |