]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/ocfs2-xattr-Merge-xattr-set-transaction.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / ocfs2-xattr-Merge-xattr-set-transaction.patch
1 From: Tao Ma <tao.ma@oracle.com>
2 Date: Wed, 12 Nov 2008 08:27:01 +0800
3 Subject: ocfs2/xattr: Merge xattr set transaction.
4 Patch-mainline: 2.6.29
5
6 In current ocfs2/xattr, the whole xattr set is divided into
7 many steps are many transaction are used, this make the
8 xattr set process isn't like a real transaction, so this
9 patch try to merge all the transaction into one. Another
10 benefit is that acl can use it easily now.
11
12 I don't merge the transaction of deleting xattr when we
13 remove an inode. The reason is that if we have a large number
14 of xattrs and every xattrs has large values(large enough
15 for outside storage), the whole transaction will be very
16 huge and it looks like jbd can't handle it(I meet with a
17 jbd complain once). And the old inode removal is also divided
18 into many steps, so I'd like to leave as it is.
19
20 Note:
21 In xattr set, I try to avoid ocfs2_extend_trans since if
22 the credits aren't enough for the extension, it will commit
23 all the dirty blocks and create a new transaction which may
24 lead to inconsistency in metadata. All ocfs2_extend_trans
25 remained are safe now.
26
27 Signed-off-by: Tao Ma <tao.ma@oracle.com>
28 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
29 ---
30 fs/ocfs2/xattr.c | 673 ++++++++++++++++++++++++++----------------------------
31 1 files changed, 325 insertions(+), 348 deletions(-)
32
33 diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
34 index 4fd201a..7a90892 100644
35 --- a/fs/ocfs2/xattr.c
36 +++ b/fs/ocfs2/xattr.c
37 @@ -72,6 +72,7 @@ struct ocfs2_xattr_bucket {
38 };
39
40 struct ocfs2_xattr_set_ctxt {
41 + handle_t *handle;
42 struct ocfs2_alloc_context *meta_ac;
43 struct ocfs2_alloc_context *data_ac;
44 struct ocfs2_cached_dealloc_ctxt dealloc;
45 @@ -346,9 +347,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
46 struct ocfs2_xattr_set_ctxt *ctxt)
47 {
48 int status = 0;
49 - int restart_func = 0;
50 - int credits = 0;
51 - handle_t *handle = NULL;
52 + handle_t *handle = ctxt->handle;
53 enum ocfs2_alloc_restarted why;
54 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
55 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters);
56 @@ -358,19 +357,6 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
57
58 ocfs2_init_xattr_value_extent_tree(&et, inode, xattr_bh, xv);
59
60 -restart_all:
61 -
62 - credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
63 - clusters_to_add);
64 - handle = ocfs2_start_trans(osb, credits);
65 - if (IS_ERR(handle)) {
66 - status = PTR_ERR(handle);
67 - handle = NULL;
68 - mlog_errno(status);
69 - goto leave;
70 - }
71 -
72 -restarted_transaction:
73 status = ocfs2_journal_access(handle, inode, xattr_bh,
74 OCFS2_JOURNAL_ACCESS_WRITE);
75 if (status < 0) {
76 @@ -389,9 +375,8 @@ restarted_transaction:
77 ctxt->data_ac,
78 ctxt->meta_ac,
79 &why);
80 - if ((status < 0) && (status != -EAGAIN)) {
81 - if (status != -ENOSPC)
82 - mlog_errno(status);
83 + if (status < 0) {
84 + mlog_errno(status);
85 goto leave;
86 }
87
88 @@ -403,39 +388,13 @@ restarted_transaction:
89
90 clusters_to_add -= le32_to_cpu(xv->xr_clusters) - prev_clusters;
91
92 - if (why != RESTART_NONE && clusters_to_add) {
93 - if (why == RESTART_META) {
94 - mlog(0, "restarting function.\n");
95 - restart_func = 1;
96 - } else {
97 - BUG_ON(why != RESTART_TRANS);
98 -
99 - mlog(0, "restarting transaction.\n");
100 - /* TODO: This can be more intelligent. */
101 - credits = ocfs2_calc_extend_credits(osb->sb,
102 - et.et_root_el,
103 - clusters_to_add);
104 - status = ocfs2_extend_trans(handle, credits);
105 - if (status < 0) {
106 - /* handle still has to be committed at
107 - * this point. */
108 - status = -ENOMEM;
109 - mlog_errno(status);
110 - goto leave;
111 - }
112 - goto restarted_transaction;
113 - }
114 - }
115 + /*
116 + * We should have already allocated enough space before the transaction,
117 + * so no need to restart.
118 + */
119 + BUG_ON(why != RESTART_NONE || clusters_to_add);
120
121 leave:
122 - if (handle) {
123 - ocfs2_commit_trans(osb, handle);
124 - handle = NULL;
125 - }
126 - if ((!status) && restart_func) {
127 - restart_func = 0;
128 - goto restart_all;
129 - }
130
131 return status;
132 }
133 @@ -448,31 +407,23 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
134 {
135 int ret;
136 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
137 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
138 - handle_t *handle;
139 + handle_t *handle = ctxt->handle;
140 struct ocfs2_extent_tree et;
141
142 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv);
143
144 - handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
145 - if (IS_ERR(handle)) {
146 - ret = PTR_ERR(handle);
147 - mlog_errno(ret);
148 - goto out;
149 - }
150 -
151 ret = ocfs2_journal_access(handle, inode, root_bh,
152 OCFS2_JOURNAL_ACCESS_WRITE);
153 if (ret) {
154 mlog_errno(ret);
155 - goto out_commit;
156 + goto out;
157 }
158
159 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac,
160 &ctxt->dealloc);
161 if (ret) {
162 mlog_errno(ret);
163 - goto out_commit;
164 + goto out;
165 }
166
167 le32_add_cpu(&xv->xr_clusters, -len);
168 @@ -480,15 +431,13 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
169 ret = ocfs2_journal_dirty(handle, root_bh);
170 if (ret) {
171 mlog_errno(ret);
172 - goto out_commit;
173 + goto out;
174 }
175
176 ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len);
177 if (ret)
178 mlog_errno(ret);
179
180 -out_commit:
181 - ocfs2_commit_trans(osb, handle);
182 out:
183 return ret;
184 }
185 @@ -975,6 +924,7 @@ static int ocfs2_xattr_get(struct inode *inode,
186 }
187
188 static int __ocfs2_xattr_set_value_outside(struct inode *inode,
189 + handle_t *handle,
190 struct ocfs2_xattr_value_root *xv,
191 const void *value,
192 int value_len)
193 @@ -986,14 +936,17 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
194 u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len);
195 u64 blkno;
196 struct buffer_head *bh = NULL;
197 - handle_t *handle;
198
199 BUG_ON(clusters > le32_to_cpu(xv->xr_clusters));
200
201 + /*
202 + * In __ocfs2_xattr_set_value_outside has already been dirtied,
203 + * so we don't need to worry about whether ocfs2_extend_trans
204 + * will create a new transactio for us or not.
205 + */
206 credits = clusters * bpc;
207 - handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb), credits);
208 - if (IS_ERR(handle)) {
209 - ret = PTR_ERR(handle);
210 + ret = ocfs2_extend_trans(handle, credits);
211 + if (ret) {
212 mlog_errno(ret);
213 goto out;
214 }
215 @@ -1003,7 +956,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
216 &num_clusters, &xv->xr_list);
217 if (ret) {
218 mlog_errno(ret);
219 - goto out_commit;
220 + goto out;
221 }
222
223 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
224 @@ -1012,7 +965,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
225 ret = ocfs2_read_block(inode, blkno, &bh);
226 if (ret) {
227 mlog_errno(ret);
228 - goto out_commit;
229 + goto out;
230 }
231
232 ret = ocfs2_journal_access(handle,
233 @@ -1021,7 +974,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
234 OCFS2_JOURNAL_ACCESS_WRITE);
235 if (ret < 0) {
236 mlog_errno(ret);
237 - goto out_commit;
238 + goto out;
239 }
240
241 cp_len = value_len > blocksize ? blocksize : value_len;
242 @@ -1035,7 +988,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
243 ret = ocfs2_journal_dirty(handle, bh);
244 if (ret < 0) {
245 mlog_errno(ret);
246 - goto out_commit;
247 + goto out;
248 }
249 brelse(bh);
250 bh = NULL;
251 @@ -1049,8 +1002,6 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
252 }
253 cpos += num_clusters;
254 }
255 -out_commit:
256 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
257 out:
258 brelse(bh);
259
260 @@ -1058,28 +1009,21 @@ out:
261 }
262
263 static int ocfs2_xattr_cleanup(struct inode *inode,
264 + handle_t *handle,
265 struct ocfs2_xattr_info *xi,
266 struct ocfs2_xattr_search *xs,
267 size_t offs)
268 {
269 - handle_t *handle = NULL;
270 int ret = 0;
271 size_t name_len = strlen(xi->name);
272 void *val = xs->base + offs;
273 size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
274
275 - handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
276 - OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
277 - if (IS_ERR(handle)) {
278 - ret = PTR_ERR(handle);
279 - mlog_errno(ret);
280 - goto out;
281 - }
282 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
283 OCFS2_JOURNAL_ACCESS_WRITE);
284 if (ret) {
285 mlog_errno(ret);
286 - goto out_commit;
287 + goto out;
288 }
289 /* Decrease xattr count */
290 le16_add_cpu(&xs->header->xh_count, -1);
291 @@ -1090,32 +1034,23 @@ static int ocfs2_xattr_cleanup(struct inode *inode,
292 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
293 if (ret < 0)
294 mlog_errno(ret);
295 -out_commit:
296 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
297 out:
298 return ret;
299 }
300
301 static int ocfs2_xattr_update_entry(struct inode *inode,
302 + handle_t *handle,
303 struct ocfs2_xattr_info *xi,
304 struct ocfs2_xattr_search *xs,
305 size_t offs)
306 {
307 - handle_t *handle = NULL;
308 - int ret = 0;
309 + int ret;
310
311 - handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
312 - OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
313 - if (IS_ERR(handle)) {
314 - ret = PTR_ERR(handle);
315 - mlog_errno(ret);
316 - goto out;
317 - }
318 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
319 OCFS2_JOURNAL_ACCESS_WRITE);
320 if (ret) {
321 mlog_errno(ret);
322 - goto out_commit;
323 + goto out;
324 }
325
326 xs->here->xe_name_offset = cpu_to_le16(offs);
327 @@ -1129,8 +1064,6 @@ static int ocfs2_xattr_update_entry(struct inode *inode,
328 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
329 if (ret < 0)
330 mlog_errno(ret);
331 -out_commit:
332 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
333 out:
334 return ret;
335 }
336 @@ -1168,13 +1101,13 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode,
337 mlog_errno(ret);
338 return ret;
339 }
340 - ret = __ocfs2_xattr_set_value_outside(inode, xv, xi->value,
341 - xi->value_len);
342 + ret = ocfs2_xattr_update_entry(inode, ctxt->handle, xi, xs, offs);
343 if (ret < 0) {
344 mlog_errno(ret);
345 return ret;
346 }
347 - ret = ocfs2_xattr_update_entry(inode, xi, xs, offs);
348 + ret = __ocfs2_xattr_set_value_outside(inode, ctxt->handle, xv,
349 + xi->value, xi->value_len);
350 if (ret < 0)
351 mlog_errno(ret);
352
353 @@ -1302,7 +1235,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
354 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
355 size_t min_offs = xs->end - xs->base, name_len = strlen(xi->name);
356 size_t size_l = 0;
357 - handle_t *handle = NULL;
358 + handle_t *handle = ctxt->handle;
359 int free, i, ret;
360 struct ocfs2_xattr_info xi_l = {
361 .name_index = xi->name_index,
362 @@ -1391,19 +1324,21 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
363 goto out;
364 }
365
366 - ret = __ocfs2_xattr_set_value_outside(inode,
367 - xv,
368 - xi->value,
369 - xi->value_len);
370 + ret = ocfs2_xattr_update_entry(inode,
371 + handle,
372 + xi,
373 + xs,
374 + offs);
375 if (ret < 0) {
376 mlog_errno(ret);
377 goto out;
378 }
379
380 - ret = ocfs2_xattr_update_entry(inode,
381 - xi,
382 - xs,
383 - offs);
384 + ret = __ocfs2_xattr_set_value_outside(inode,
385 + handle,
386 + xv,
387 + xi->value,
388 + xi->value_len);
389 if (ret < 0)
390 mlog_errno(ret);
391 goto out;
392 @@ -1413,45 +1348,29 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
393 * just trucate old value to zero.
394 */
395 ret = ocfs2_xattr_value_truncate(inode,
396 - xs->xattr_bh,
397 - xv,
398 - 0,
399 - ctxt);
400 + xs->xattr_bh,
401 + xv,
402 + 0,
403 + ctxt);
404 if (ret < 0)
405 mlog_errno(ret);
406 }
407 }
408 }
409
410 - handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
411 - OCFS2_INODE_UPDATE_CREDITS);
412 - if (IS_ERR(handle)) {
413 - ret = PTR_ERR(handle);
414 - mlog_errno(ret);
415 - goto out;
416 - }
417 -
418 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
419 OCFS2_JOURNAL_ACCESS_WRITE);
420 if (ret) {
421 mlog_errno(ret);
422 - goto out_commit;
423 + goto out;
424 }
425
426 if (!(flag & OCFS2_INLINE_XATTR_FL)) {
427 - /* set extended attribute in external block. */
428 - ret = ocfs2_extend_trans(handle,
429 - OCFS2_INODE_UPDATE_CREDITS +
430 - OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
431 - if (ret) {
432 - mlog_errno(ret);
433 - goto out_commit;
434 - }
435 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
436 OCFS2_JOURNAL_ACCESS_WRITE);
437 if (ret) {
438 mlog_errno(ret);
439 - goto out_commit;
440 + goto out;
441 }
442 }
443
444 @@ -1465,7 +1384,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
445 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
446 if (ret < 0) {
447 mlog_errno(ret);
448 - goto out_commit;
449 + goto out;
450 }
451 }
452
453 @@ -1502,9 +1421,6 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
454 if (ret < 0)
455 mlog_errno(ret);
456
457 -out_commit:
458 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
459 -
460 if (!ret && xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
461 /*
462 * Set value outside in B tree.
463 @@ -1520,14 +1436,14 @@ out_commit:
464 * If set value outside failed, we have to clean
465 * the junk tree root we have already set in local.
466 */
467 - ret2 = ocfs2_xattr_cleanup(inode, xi, xs, offs);
468 + ret2 = ocfs2_xattr_cleanup(inode, ctxt->handle,
469 + xi, xs, offs);
470 if (ret2 < 0)
471 mlog_errno(ret2);
472 }
473 }
474 out:
475 return ret;
476 -
477 }
478
479 static int ocfs2_remove_value_outside(struct inode*inode,
480 @@ -1540,6 +1456,13 @@ static int ocfs2_remove_value_outside(struct inode*inode,
481
482 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
483
484 + ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
485 + if (IS_ERR(ctxt.handle)) {
486 + ret = PTR_ERR(ctxt.handle);
487 + mlog_errno(ret);
488 + goto out;
489 + }
490 +
491 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
492 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
493
494 @@ -1560,8 +1483,10 @@ static int ocfs2_remove_value_outside(struct inode*inode,
495 }
496 }
497
498 + ocfs2_commit_trans(osb, ctxt.handle);
499 ocfs2_schedule_truncate_log_flush(osb, 1);
500 ocfs2_run_deallocs(osb, &ctxt.dealloc);
501 +out:
502 return ret;
503 }
504
505 @@ -1920,7 +1845,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
506 struct buffer_head *new_bh = NULL;
507 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
508 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
509 - handle_t *handle = NULL;
510 + handle_t *handle = ctxt->handle;
511 struct ocfs2_xattr_block *xblk = NULL;
512 u16 suballoc_bit_start;
513 u32 num_got;
514 @@ -1928,18 +1853,11 @@ static int ocfs2_xattr_block_set(struct inode *inode,
515 int ret;
516
517 if (!xs->xattr_bh) {
518 - handle = ocfs2_start_trans(osb,
519 - OCFS2_XATTR_BLOCK_CREATE_CREDITS);
520 - if (IS_ERR(handle)) {
521 - ret = PTR_ERR(handle);
522 - mlog_errno(ret);
523 - goto out;
524 - }
525 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
526 OCFS2_JOURNAL_ACCESS_CREATE);
527 if (ret < 0) {
528 mlog_errno(ret);
529 - goto out_commit;
530 + goto end;
531 }
532
533 ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1,
534 @@ -1947,7 +1865,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
535 &first_blkno);
536 if (ret < 0) {
537 mlog_errno(ret);
538 - goto out_commit;
539 + goto end;
540 }
541
542 new_bh = sb_getblk(inode->i_sb, first_blkno);
543 @@ -1957,7 +1875,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
544 OCFS2_JOURNAL_ACCESS_CREATE);
545 if (ret < 0) {
546 mlog_errno(ret);
547 - goto out_commit;
548 + goto end;
549 }
550
551 /* Initialize ocfs2_xattr_block */
552 @@ -1978,17 +1896,10 @@ static int ocfs2_xattr_block_set(struct inode *inode,
553 ret = ocfs2_journal_dirty(handle, new_bh);
554 if (ret < 0) {
555 mlog_errno(ret);
556 - goto out_commit;
557 + goto end;
558 }
559 di->i_xattr_loc = cpu_to_le64(first_blkno);
560 - ret = ocfs2_journal_dirty(handle, xs->inode_bh);
561 - if (ret < 0)
562 - mlog_errno(ret);
563 -out_commit:
564 - ocfs2_commit_trans(osb, handle);
565 -out:
566 - if (ret < 0)
567 - return ret;
568 + ocfs2_journal_dirty(handle, xs->inode_bh);
569 } else
570 xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
571
572 @@ -2057,10 +1968,11 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
573 struct ocfs2_xattr_search *xis,
574 struct ocfs2_xattr_search *xbs,
575 int *clusters_need,
576 - int *meta_need)
577 + int *meta_need,
578 + int *credits_need)
579 {
580 int ret = 0, old_in_xb = 0;
581 - int clusters_add = 0, meta_add = 0;
582 + int clusters_add = 0, meta_add = 0, credits = 0;
583 struct buffer_head *bh = NULL;
584 struct ocfs2_xattr_block *xb = NULL;
585 struct ocfs2_xattr_entry *xe = NULL;
586 @@ -2071,16 +1983,15 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
587 xi->value_len);
588 u64 value_size;
589
590 - /*
591 - * delete a xattr doesn't need metadata and cluster allocation.
592 - * so return.
593 - */
594 - if (!xi->value)
595 - goto out;
596 -
597 if (xis->not_found && xbs->not_found) {
598 - if (xi->value_len > OCFS2_XATTR_INLINE_SIZE)
599 + credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
600 +
601 + if (xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
602 clusters_add += new_clusters;
603 + credits += ocfs2_calc_extend_credits(inode->i_sb,
604 + &def_xv.xv.xr_list,
605 + new_clusters);
606 + }
607
608 goto meta_guess;
609 }
610 @@ -2090,6 +2001,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
611 name_offset = le16_to_cpu(xe->xe_name_offset);
612 name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
613 base = xis->base;
614 + credits += OCFS2_INODE_UPDATE_CREDITS;
615 } else {
616 int i, block_off;
617 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
618 @@ -2105,8 +2017,25 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
619 i, &block_off,
620 &name_offset);
621 base = bucket_block(xbs->bucket, block_off);
622 - } else
623 + credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
624 + } else {
625 base = xbs->base;
626 + credits += OCFS2_XATTR_BLOCK_UPDATE_CREDITS;
627 + }
628 + }
629 +
630 + /*
631 + * delete a xattr doesn't need metadata and cluster allocation.
632 + * so just calculate the credits and return.
633 + *
634 + * The credits for removing the value tree will be extended
635 + * by ocfs2_remove_extent itself.
636 + */
637 + if (!xi->value) {
638 + if (!ocfs2_xattr_is_local(xe))
639 + credits += OCFS2_REMOVE_EXTENT_CREDITS;
640 +
641 + goto out;
642 }
643
644 /* do cluster allocation guess first. */
645 @@ -2121,6 +2050,13 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
646 */
647 if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) {
648 clusters_add += new_clusters;
649 + credits += OCFS2_REMOVE_EXTENT_CREDITS +
650 + OCFS2_INODE_UPDATE_CREDITS;
651 + if (!ocfs2_xattr_is_local(xe))
652 + credits += ocfs2_calc_extend_credits(
653 + inode->i_sb,
654 + &def_xv.xv.xr_list,
655 + new_clusters);
656 goto out;
657 }
658 }
659 @@ -2137,11 +2073,16 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
660 } else
661 xv = &def_xv.xv;
662
663 - if (old_clusters >= new_clusters)
664 + if (old_clusters >= new_clusters) {
665 + credits += OCFS2_REMOVE_EXTENT_CREDITS;
666 goto out;
667 - else {
668 + } else {
669 meta_add += ocfs2_extend_meta_needed(&xv->xr_list);
670 clusters_add += new_clusters - old_clusters;
671 + credits += ocfs2_calc_extend_credits(inode->i_sb,
672 + &xv->xr_list,
673 + new_clusters -
674 + old_clusters);
675 goto out;
676 }
677 } else {
678 @@ -2177,6 +2118,8 @@ meta_guess:
679 struct ocfs2_extent_list *el =
680 &xb->xb_attrs.xb_root.xt_list;
681 meta_add += ocfs2_extend_meta_needed(el);
682 + credits += ocfs2_calc_extend_credits(inode->i_sb,
683 + el, 1);
684 }
685
686 /*
687 @@ -2187,16 +2130,23 @@ meta_guess:
688 * also.
689 */
690 clusters_add += 1;
691 + credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
692 if (OCFS2_XATTR_BUCKET_SIZE ==
693 - OCFS2_SB(inode->i_sb)->s_clustersize)
694 + OCFS2_SB(inode->i_sb)->s_clustersize) {
695 + credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
696 clusters_add += 1;
697 - } else
698 + }
699 + } else {
700 meta_add += 1;
701 + credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
702 + }
703 out:
704 if (clusters_need)
705 *clusters_need = clusters_add;
706 if (meta_need)
707 *meta_need = meta_add;
708 + if (credits_need)
709 + *credits_need = credits;
710 brelse(bh);
711 return ret;
712 }
713 @@ -2206,7 +2156,8 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
714 struct ocfs2_xattr_info *xi,
715 struct ocfs2_xattr_search *xis,
716 struct ocfs2_xattr_search *xbs,
717 - struct ocfs2_xattr_set_ctxt *ctxt)
718 + struct ocfs2_xattr_set_ctxt *ctxt,
719 + int *credits)
720 {
721 int clusters_add, meta_add, ret;
722 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
723 @@ -2216,14 +2167,14 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
724 ocfs2_init_dealloc_ctxt(&ctxt->dealloc);
725
726 ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs,
727 - &clusters_add, &meta_add);
728 + &clusters_add, &meta_add, credits);
729 if (ret) {
730 mlog_errno(ret);
731 return ret;
732 }
733
734 - mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d\n",
735 - xi->name, meta_add, clusters_add);
736 + mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d, "
737 + "credits = %d\n", xi->name, meta_add, clusters_add, *credits);
738
739 if (meta_add) {
740 ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
741 @@ -2254,6 +2205,126 @@ out:
742 return ret;
743 }
744
745 +static int __ocfs2_xattr_set_handle(struct inode *inode,
746 + struct ocfs2_dinode *di,
747 + struct ocfs2_xattr_info *xi,
748 + struct ocfs2_xattr_search *xis,
749 + struct ocfs2_xattr_search *xbs,
750 + struct ocfs2_xattr_set_ctxt *ctxt)
751 +{
752 + int ret = 0, credits;
753 +
754 + if (!xi->value) {
755 + /* Remove existing extended attribute */
756 + if (!xis->not_found)
757 + ret = ocfs2_xattr_ibody_set(inode, xi, xis, ctxt);
758 + else if (!xbs->not_found)
759 + ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
760 + } else {
761 + /* We always try to set extended attribute into inode first*/
762 + ret = ocfs2_xattr_ibody_set(inode, xi, xis, ctxt);
763 + if (!ret && !xbs->not_found) {
764 + /*
765 + * If succeed and that extended attribute existing in
766 + * external block, then we will remove it.
767 + */
768 + xi->value = NULL;
769 + xi->value_len = 0;
770 +
771 + xis->not_found = -ENODATA;
772 + ret = ocfs2_calc_xattr_set_need(inode,
773 + di,
774 + xi,
775 + xis,
776 + xbs,
777 + NULL,
778 + NULL,
779 + &credits);
780 + if (ret) {
781 + mlog_errno(ret);
782 + goto out;
783 + }
784 +
785 + ret = ocfs2_extend_trans(ctxt->handle, credits +
786 + ctxt->handle->h_buffer_credits);
787 + if (ret) {
788 + mlog_errno(ret);
789 + goto out;
790 + }
791 + ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
792 + } else if (ret == -ENOSPC) {
793 + if (di->i_xattr_loc && !xbs->xattr_bh) {
794 + ret = ocfs2_xattr_block_find(inode,
795 + xi->name_index,
796 + xi->name, xbs);
797 + if (ret)
798 + goto out;
799 +
800 + xis->not_found = -ENODATA;
801 + ret = ocfs2_calc_xattr_set_need(inode,
802 + di,
803 + xi,
804 + xis,
805 + xbs,
806 + NULL,
807 + NULL,
808 + &credits);
809 + if (ret) {
810 + mlog_errno(ret);
811 + goto out;
812 + }
813 +
814 + ret = ocfs2_extend_trans(ctxt->handle, credits +
815 + ctxt->handle->h_buffer_credits);
816 + if (ret) {
817 + mlog_errno(ret);
818 + goto out;
819 + }
820 + }
821 + /*
822 + * If no space in inode, we will set extended attribute
823 + * into external block.
824 + */
825 + ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
826 + if (ret)
827 + goto out;
828 + if (!xis->not_found) {
829 + /*
830 + * If succeed and that extended attribute
831 + * existing in inode, we will remove it.
832 + */
833 + xi->value = NULL;
834 + xi->value_len = 0;
835 + xbs->not_found = -ENODATA;
836 + ret = ocfs2_calc_xattr_set_need(inode,
837 + di,
838 + xi,
839 + xis,
840 + xbs,
841 + NULL,
842 + NULL,
843 + &credits);
844 + if (ret) {
845 + mlog_errno(ret);
846 + goto out;
847 + }
848 +
849 + ret = ocfs2_extend_trans(ctxt->handle, credits +
850 + ctxt->handle->h_buffer_credits);
851 + if (ret) {
852 + mlog_errno(ret);
853 + goto out;
854 + }
855 + ret = ocfs2_xattr_ibody_set(inode, xi,
856 + xis, ctxt);
857 + }
858 + }
859 + }
860 +
861 +out:
862 + return ret;
863 +}
864 +
865 /*
866 * ocfs2_xattr_set()
867 *
868 @@ -2270,8 +2341,9 @@ int ocfs2_xattr_set(struct inode *inode,
869 {
870 struct buffer_head *di_bh = NULL;
871 struct ocfs2_dinode *di;
872 - int ret;
873 + int ret, credits;
874 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
875 + struct inode *tl_inode = osb->osb_tl_inode;
876 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
877
878 struct ocfs2_xattr_info xi = {
879 @@ -2337,56 +2409,37 @@ int ocfs2_xattr_set(struct inode *inode,
880 goto cleanup;
881 }
882
883 - ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, &xbs, &ctxt);
884 +
885 + mutex_lock(&tl_inode->i_mutex);
886 +
887 + if (ocfs2_truncate_log_needs_flush(osb)) {
888 + ret = __ocfs2_flush_truncate_log(osb);
889 + if (ret < 0) {
890 + mutex_unlock(&tl_inode->i_mutex);
891 + mlog_errno(ret);
892 + goto cleanup;
893 + }
894 + }
895 + mutex_unlock(&tl_inode->i_mutex);
896 +
897 + ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis,
898 + &xbs, &ctxt, &credits);
899 if (ret) {
900 mlog_errno(ret);
901 goto cleanup;
902 }
903
904 - if (!value) {
905 - /* Remove existing extended attribute */
906 - if (!xis.not_found)
907 - ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
908 - else if (!xbs.not_found)
909 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
910 - } else {
911 - /* We always try to set extended attribute into inode first*/
912 - ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
913 - if (!ret && !xbs.not_found) {
914 - /*
915 - * If succeed and that extended attribute existing in
916 - * external block, then we will remove it.
917 - */
918 - xi.value = NULL;
919 - xi.value_len = 0;
920 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
921 - } else if (ret == -ENOSPC) {
922 - if (di->i_xattr_loc && !xbs.xattr_bh) {
923 - ret = ocfs2_xattr_block_find(inode, name_index,
924 - name, &xbs);
925 - if (ret)
926 - goto cleanup;
927 - }
928 - /*
929 - * If no space in inode, we will set extended attribute
930 - * into external block.
931 - */
932 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
933 - if (ret)
934 - goto free;
935 - if (!xis.not_found) {
936 - /*
937 - * If succeed and that extended attribute
938 - * existing in inode, we will remove it.
939 - */
940 - xi.value = NULL;
941 - xi.value_len = 0;
942 - ret = ocfs2_xattr_ibody_set(inode, &xi,
943 - &xis, &ctxt);
944 - }
945 - }
946 + ctxt.handle = ocfs2_start_trans(osb, credits);
947 + if (IS_ERR(ctxt.handle)) {
948 + ret = PTR_ERR(ctxt.handle);
949 + mlog_errno(ret);
950 + goto cleanup;
951 }
952 -free:
953 +
954 + ret = __ocfs2_xattr_set_handle(inode, di, &xi, &xis, &xbs, &ctxt);
955 +
956 + ocfs2_commit_trans(osb, ctxt.handle);
957 +
958 if (ctxt.data_ac)
959 ocfs2_free_alloc_context(ctxt.data_ac);
960 if (ctxt.meta_ac)
961 @@ -2974,10 +3027,10 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
962 struct ocfs2_xattr_search *xs,
963 struct ocfs2_xattr_set_ctxt *ctxt)
964 {
965 - int ret, credits = OCFS2_SUBALLOC_ALLOC;
966 + int ret;
967 u32 bit_off, len;
968 u64 blkno;
969 - handle_t *handle;
970 + handle_t *handle = ctxt->handle;
971 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
972 struct ocfs2_inode_info *oi = OCFS2_I(inode);
973 struct buffer_head *xb_bh = xs->xattr_bh;
974 @@ -2999,30 +3052,18 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
975 */
976 down_write(&oi->ip_alloc_sem);
977
978 - /*
979 - * We need more credits. One for the xattr block update and one
980 - * for each block of the new xattr bucket.
981 - */
982 - credits += 1 + ocfs2_blocks_per_xattr_bucket(inode->i_sb);
983 - handle = ocfs2_start_trans(osb, credits);
984 - if (IS_ERR(handle)) {
985 - ret = PTR_ERR(handle);
986 - mlog_errno(ret);
987 - goto out_sem;
988 - }
989 -
990 ret = ocfs2_journal_access(handle, inode, xb_bh,
991 OCFS2_JOURNAL_ACCESS_WRITE);
992 if (ret) {
993 mlog_errno(ret);
994 - goto out_commit;
995 + goto out;
996 }
997
998 ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac,
999 1, 1, &bit_off, &len);
1000 if (ret) {
1001 mlog_errno(ret);
1002 - goto out_commit;
1003 + goto out;
1004 }
1005
1006 /*
1007 @@ -3038,14 +3079,14 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
1008 ret = ocfs2_init_xattr_bucket(xs->bucket, blkno);
1009 if (ret) {
1010 mlog_errno(ret);
1011 - goto out_commit;
1012 + goto out;
1013 }
1014
1015 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
1016 OCFS2_JOURNAL_ACCESS_CREATE);
1017 if (ret) {
1018 mlog_errno(ret);
1019 - goto out_commit;
1020 + goto out;
1021 }
1022
1023 ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket);
1024 @@ -3070,16 +3111,9 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
1025
1026 xb->xb_flags = cpu_to_le16(xb_flags | OCFS2_XATTR_INDEXED);
1027
1028 - ret = ocfs2_journal_dirty(handle, xb_bh);
1029 - if (ret) {
1030 - mlog_errno(ret);
1031 - goto out_commit;
1032 - }
1033 + ocfs2_journal_dirty(handle, xb_bh);
1034
1035 -out_commit:
1036 - ocfs2_commit_trans(osb, handle);
1037 -
1038 -out_sem:
1039 +out:
1040 up_write(&oi->ip_alloc_sem);
1041
1042 return ret;
1043 @@ -3105,6 +3139,7 @@ static int cmp_xe_offset(const void *a, const void *b)
1044 * so that we can spare some space for insertion.
1045 */
1046 static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1047 + handle_t *handle,
1048 struct ocfs2_xattr_bucket *bucket)
1049 {
1050 int ret, i;
1051 @@ -3114,7 +3149,6 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1052 u64 blkno = bucket_blkno(bucket);
1053 u16 xh_free_start;
1054 size_t blocksize = inode->i_sb->s_blocksize;
1055 - handle_t *handle;
1056 struct ocfs2_xattr_entry *xe;
1057
1058 /*
1059 @@ -3133,19 +3167,11 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1060 for (i = 0; i < bucket->bu_blocks; i++, buf += blocksize)
1061 memcpy(buf, bucket_block(bucket, i), blocksize);
1062
1063 - handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)), bucket->bu_blocks);
1064 - if (IS_ERR(handle)) {
1065 - ret = PTR_ERR(handle);
1066 - handle = NULL;
1067 - mlog_errno(ret);
1068 - goto out;
1069 - }
1070 -
1071 ret = ocfs2_xattr_bucket_journal_access(handle, bucket,
1072 OCFS2_JOURNAL_ACCESS_WRITE);
1073 if (ret < 0) {
1074 mlog_errno(ret);
1075 - goto commit;
1076 + goto out;
1077 }
1078
1079 xh = (struct ocfs2_xattr_header *)bucket_buf;
1080 @@ -3203,7 +3229,7 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1081 "bucket %llu\n", (unsigned long long)blkno);
1082
1083 if (xh_free_start == end)
1084 - goto commit;
1085 + goto out;
1086
1087 memset(bucket_buf + xh_free_start, 0, end - xh_free_start);
1088 xh->xh_free_start = cpu_to_le16(end);
1089 @@ -3218,8 +3244,6 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1090 memcpy(bucket_block(bucket, i), buf, blocksize);
1091 ocfs2_xattr_bucket_journal_dirty(handle, bucket);
1092
1093 -commit:
1094 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1095 out:
1096 kfree(bucket_buf);
1097 return ret;
1098 @@ -3270,7 +3294,7 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
1099 * 1 more for the update of the 1st bucket of the previous
1100 * extent record.
1101 */
1102 - credits = bpc / 2 + 1;
1103 + credits = bpc / 2 + 1 + handle->h_buffer_credits;
1104 ret = ocfs2_extend_trans(handle, credits);
1105 if (ret) {
1106 mlog_errno(ret);
1107 @@ -3662,7 +3686,7 @@ static int ocfs2_cp_xattr_cluster(struct inode *inode,
1108 * We need to update the new cluster and 1 more for the update of
1109 * the 1st bucket of the previous extent rec.
1110 */
1111 - credits = bpc + 1;
1112 + credits = bpc + 1 + handle->h_buffer_credits;
1113 ret = ocfs2_extend_trans(handle, credits);
1114 if (ret) {
1115 mlog_errno(ret);
1116 @@ -3732,7 +3756,7 @@ static int ocfs2_divide_xattr_cluster(struct inode *inode,
1117 u32 *first_hash)
1118 {
1119 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
1120 - int ret, credits = 2 * blk_per_bucket;
1121 + int ret, credits = 2 * blk_per_bucket + handle->h_buffer_credits;
1122
1123 BUG_ON(OCFS2_XATTR_BUCKET_SIZE < OCFS2_SB(inode->i_sb)->s_clustersize);
1124
1125 @@ -3845,12 +3869,12 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1126 int *extend,
1127 struct ocfs2_xattr_set_ctxt *ctxt)
1128 {
1129 - int ret, credits;
1130 + int ret;
1131 u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
1132 u32 prev_clusters = *num_clusters;
1133 u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0;
1134 u64 block;
1135 - handle_t *handle = NULL;
1136 + handle_t *handle = ctxt->handle;
1137 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1138 struct ocfs2_extent_tree et;
1139
1140 @@ -3861,16 +3885,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1141
1142 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
1143
1144 - credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
1145 - clusters_to_add);
1146 - handle = ocfs2_start_trans(osb, credits);
1147 - if (IS_ERR(handle)) {
1148 - ret = PTR_ERR(handle);
1149 - handle = NULL;
1150 - mlog_errno(ret);
1151 - goto leave;
1152 - }
1153 -
1154 ret = ocfs2_journal_access(handle, inode, root_bh,
1155 OCFS2_JOURNAL_ACCESS_WRITE);
1156 if (ret < 0) {
1157 @@ -3924,18 +3938,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1158 }
1159 }
1160
1161 - if (handle->h_buffer_credits < credits) {
1162 - /*
1163 - * The journal has been restarted before, and don't
1164 - * have enough space for the insertion, so extend it
1165 - * here.
1166 - */
1167 - ret = ocfs2_extend_trans(handle, credits);
1168 - if (ret) {
1169 - mlog_errno(ret);
1170 - goto leave;
1171 - }
1172 - }
1173 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
1174 num_bits, (unsigned long long)block, v_start);
1175 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block,
1176 @@ -3946,15 +3948,10 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1177 }
1178
1179 ret = ocfs2_journal_dirty(handle, root_bh);
1180 - if (ret < 0) {
1181 + if (ret < 0)
1182 mlog_errno(ret);
1183 - goto leave;
1184 - }
1185
1186 leave:
1187 - if (handle)
1188 - ocfs2_commit_trans(osb, handle);
1189 -
1190 return ret;
1191 }
1192
1193 @@ -3963,6 +3960,7 @@ leave:
1194 * We meet with start_bh. Only move half of the xattrs to the bucket after it.
1195 */
1196 static int ocfs2_extend_xattr_bucket(struct inode *inode,
1197 + handle_t *handle,
1198 struct buffer_head *first_bh,
1199 struct buffer_head *start_bh,
1200 u32 num_clusters)
1201 @@ -3972,7 +3970,6 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
1202 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
1203 u64 start_blk = start_bh->b_blocknr, end_blk;
1204 u32 num_buckets = num_clusters * ocfs2_xattr_buckets_per_cluster(osb);
1205 - handle_t *handle;
1206 struct ocfs2_xattr_header *first_xh =
1207 (struct ocfs2_xattr_header *)first_bh->b_data;
1208 u16 bucket = le16_to_cpu(first_xh->xh_num_buckets);
1209 @@ -3989,11 +3986,10 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
1210 * We will touch all the buckets after the start_bh(include it).
1211 * Then we add one more bucket.
1212 */
1213 - credits = end_blk - start_blk + 3 * blk_per_bucket + 1;
1214 - handle = ocfs2_start_trans(osb, credits);
1215 - if (IS_ERR(handle)) {
1216 - ret = PTR_ERR(handle);
1217 - handle = NULL;
1218 + credits = end_blk - start_blk + 3 * blk_per_bucket + 1 +
1219 + handle->h_buffer_credits;
1220 + ret = ocfs2_extend_trans(handle, credits);
1221 + if (ret) {
1222 mlog_errno(ret);
1223 goto out;
1224 }
1225 @@ -4002,14 +3998,14 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
1226 OCFS2_JOURNAL_ACCESS_WRITE);
1227 if (ret) {
1228 mlog_errno(ret);
1229 - goto commit;
1230 + goto out;
1231 }
1232
1233 while (end_blk != start_blk) {
1234 ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk,
1235 end_blk + blk_per_bucket, 0);
1236 if (ret)
1237 - goto commit;
1238 + goto out;
1239 end_blk -= blk_per_bucket;
1240 }
1241
1242 @@ -4020,8 +4016,6 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
1243 le16_add_cpu(&first_xh->xh_num_buckets, 1);
1244 ocfs2_journal_dirty(handle, first_bh);
1245
1246 -commit:
1247 - ocfs2_commit_trans(osb, handle);
1248 out:
1249 return ret;
1250 }
1251 @@ -4099,6 +4093,7 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
1252
1253 if (extend)
1254 ret = ocfs2_extend_xattr_bucket(inode,
1255 + ctxt->handle,
1256 first_bh,
1257 header_bh,
1258 num_clusters);
1259 @@ -4272,14 +4267,13 @@ set_new_name_value:
1260 * space for the xattr insertion.
1261 */
1262 static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
1263 + handle_t *handle,
1264 struct ocfs2_xattr_info *xi,
1265 struct ocfs2_xattr_search *xs,
1266 u32 name_hash,
1267 int local)
1268 {
1269 int ret;
1270 - handle_t *handle = NULL;
1271 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1272 u64 blkno;
1273
1274 mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n",
1275 @@ -4296,14 +4290,6 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
1276 }
1277 }
1278
1279 - handle = ocfs2_start_trans(osb, xs->bucket->bu_blocks);
1280 - if (IS_ERR(handle)) {
1281 - ret = PTR_ERR(handle);
1282 - handle = NULL;
1283 - mlog_errno(ret);
1284 - goto out;
1285 - }
1286 -
1287 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
1288 OCFS2_JOURNAL_ACCESS_WRITE);
1289 if (ret < 0) {
1290 @@ -4315,32 +4301,22 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
1291 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
1292
1293 out:
1294 - ocfs2_commit_trans(osb, handle);
1295 -
1296 return ret;
1297 }
1298
1299 static int ocfs2_xattr_value_update_size(struct inode *inode,
1300 + handle_t *handle,
1301 struct buffer_head *xe_bh,
1302 struct ocfs2_xattr_entry *xe,
1303 u64 new_size)
1304 {
1305 int ret;
1306 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1307 - handle_t *handle = NULL;
1308 -
1309 - handle = ocfs2_start_trans(osb, 1);
1310 - if (IS_ERR(handle)) {
1311 - ret = -ENOMEM;
1312 - mlog_errno(ret);
1313 - goto out;
1314 - }
1315
1316 ret = ocfs2_journal_access(handle, inode, xe_bh,
1317 OCFS2_JOURNAL_ACCESS_WRITE);
1318 if (ret < 0) {
1319 mlog_errno(ret);
1320 - goto out_commit;
1321 + goto out;
1322 }
1323
1324 xe->xe_value_size = cpu_to_le64(new_size);
1325 @@ -4349,8 +4325,6 @@ static int ocfs2_xattr_value_update_size(struct inode *inode,
1326 if (ret < 0)
1327 mlog_errno(ret);
1328
1329 -out_commit:
1330 - ocfs2_commit_trans(osb, handle);
1331 out:
1332 return ret;
1333 }
1334 @@ -4407,7 +4381,8 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
1335 goto out;
1336 }
1337
1338 - ret = ocfs2_xattr_value_update_size(inode, header_bh, xe, len);
1339 + ret = ocfs2_xattr_value_update_size(inode, ctxt->handle,
1340 + header_bh, xe, len);
1341 if (ret) {
1342 mlog_errno(ret);
1343 goto out;
1344 @@ -4439,6 +4414,7 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
1345 }
1346
1347 static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
1348 + handle_t *handle,
1349 struct ocfs2_xattr_search *xs,
1350 char *val,
1351 int value_len)
1352 @@ -4454,7 +4430,8 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
1353
1354 xv = (struct ocfs2_xattr_value_root *)(xs->base + offset);
1355
1356 - return __ocfs2_xattr_set_value_outside(inode, xv, val, value_len);
1357 + return __ocfs2_xattr_set_value_outside(inode, handle,
1358 + xv, val, value_len);
1359 }
1360
1361 static int ocfs2_rm_xattr_cluster(struct inode *inode,
1362 @@ -4547,27 +4524,19 @@ out:
1363 }
1364
1365 static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
1366 + handle_t *handle,
1367 struct ocfs2_xattr_search *xs)
1368 {
1369 - handle_t *handle = NULL;
1370 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket);
1371 struct ocfs2_xattr_entry *last = &xh->xh_entries[
1372 le16_to_cpu(xh->xh_count) - 1];
1373 int ret = 0;
1374
1375 - handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
1376 - ocfs2_blocks_per_xattr_bucket(inode->i_sb));
1377 - if (IS_ERR(handle)) {
1378 - ret = PTR_ERR(handle);
1379 - mlog_errno(ret);
1380 - return;
1381 - }
1382 -
1383 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
1384 OCFS2_JOURNAL_ACCESS_WRITE);
1385 if (ret) {
1386 mlog_errno(ret);
1387 - goto out_commit;
1388 + return;
1389 }
1390
1391 /* Remove the old entry. */
1392 @@ -4577,9 +4546,6 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
1393 le16_add_cpu(&xh->xh_count, -1);
1394
1395 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
1396 -
1397 -out_commit:
1398 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1399 }
1400
1401 /*
1402 @@ -4645,7 +4611,8 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
1403 xi->value_len = OCFS2_XATTR_ROOT_SIZE;
1404 }
1405
1406 - ret = ocfs2_xattr_set_entry_in_bucket(inode, xi, xs, name_hash, local);
1407 + ret = ocfs2_xattr_set_entry_in_bucket(inode, ctxt->handle, xi, xs,
1408 + name_hash, local);
1409 if (ret) {
1410 mlog_errno(ret);
1411 goto out;
1412 @@ -4666,13 +4633,14 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
1413 * storage and we have allocated xattr already,
1414 * so need to remove it.
1415 */
1416 - ocfs2_xattr_bucket_remove_xs(inode, xs);
1417 + ocfs2_xattr_bucket_remove_xs(inode, ctxt->handle, xs);
1418 }
1419 goto out;
1420 }
1421
1422 set_value_outside:
1423 - ret = ocfs2_xattr_bucket_set_value_outside(inode, xs, val, value_len);
1424 + ret = ocfs2_xattr_bucket_set_value_outside(inode, ctxt->handle,
1425 + xs, val, value_len);
1426 out:
1427 return ret;
1428 }
1429 @@ -4785,7 +4753,8 @@ try_again:
1430 * name/value will be moved, the xe shouldn't be changed
1431 * in xs.
1432 */
1433 - ret = ocfs2_defrag_xattr_bucket(inode, xs->bucket);
1434 + ret = ocfs2_defrag_xattr_bucket(inode, ctxt->handle,
1435 + xs->bucket);
1436 if (ret) {
1437 mlog_errno(ret);
1438 goto out;
1439 @@ -4865,6 +4834,13 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
1440
1441 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
1442
1443 + ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
1444 + if (IS_ERR(ctxt.handle)) {
1445 + ret = PTR_ERR(ctxt.handle);
1446 + mlog_errno(ret);
1447 + goto out;
1448 + }
1449 +
1450 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
1451 xe = &xh->xh_entries[i];
1452 if (ocfs2_xattr_is_local(xe))
1453 @@ -4879,9 +4855,10 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
1454 }
1455 }
1456
1457 + ret = ocfs2_commit_trans(osb, ctxt.handle);
1458 ocfs2_schedule_truncate_log_flush(osb, 1);
1459 ocfs2_run_deallocs(osb, &ctxt.dealloc);
1460 -
1461 +out:
1462 return ret;
1463 }
1464
1465 --
1466 1.5.6
1467