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.
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.
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.
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.
27 Signed-off-by: Tao Ma <tao.ma@oracle.com>
28 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
30 fs/ocfs2/xattr.c | 673 ++++++++++++++++++++++++++----------------------------
31 1 files changed, 325 insertions(+), 348 deletions(-)
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 {
40 struct ocfs2_xattr_set_ctxt {
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)
49 - int restart_func = 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,
58 ocfs2_init_xattr_value_extent_tree(&et, inode, xattr_bh, xv);
62 - credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
64 - handle = ocfs2_start_trans(osb, credits);
65 - if (IS_ERR(handle)) {
66 - status = PTR_ERR(handle);
72 -restarted_transaction:
73 status = ocfs2_journal_access(handle, inode, xattr_bh,
74 OCFS2_JOURNAL_ACCESS_WRITE);
76 @@ -389,9 +375,8 @@ restarted_transaction:
80 - if ((status < 0) && (status != -EAGAIN)) {
81 - if (status != -ENOSPC)
88 @@ -403,39 +388,13 @@ restarted_transaction:
90 clusters_to_add -= le32_to_cpu(xv->xr_clusters) - prev_clusters;
92 - if (why != RESTART_NONE && clusters_to_add) {
93 - if (why == RESTART_META) {
94 - mlog(0, "restarting function.\n");
97 - BUG_ON(why != RESTART_TRANS);
99 - mlog(0, "restarting transaction.\n");
100 - /* TODO: This can be more intelligent. */
101 - credits = ocfs2_calc_extend_credits(osb->sb,
104 - status = ocfs2_extend_trans(handle, credits);
106 - /* handle still has to be committed at
109 - mlog_errno(status);
112 - goto restarted_transaction;
116 + * We should have already allocated enough space before the transaction,
117 + * so no need to restart.
119 + BUG_ON(why != RESTART_NONE || clusters_to_add);
123 - ocfs2_commit_trans(osb, handle);
126 - if ((!status) && restart_func) {
133 @@ -448,31 +407,23 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
136 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
137 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
139 + handle_t *handle = ctxt->handle;
140 struct ocfs2_extent_tree et;
142 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv);
144 - handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
145 - if (IS_ERR(handle)) {
146 - ret = PTR_ERR(handle);
151 ret = ocfs2_journal_access(handle, inode, root_bh,
152 OCFS2_JOURNAL_ACCESS_WRITE);
159 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac,
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);
176 ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len);
181 - ocfs2_commit_trans(osb, handle);
185 @@ -975,6 +924,7 @@ static int ocfs2_xattr_get(struct inode *inode,
188 static int __ocfs2_xattr_set_value_outside(struct inode *inode,
190 struct ocfs2_xattr_value_root *xv,
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);
196 struct buffer_head *bh = NULL;
199 BUG_ON(clusters > le32_to_cpu(xv->xr_clusters));
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.
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);
215 @@ -1003,7 +956,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
216 &num_clusters, &xv->xr_list);
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);
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);
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);
251 @@ -1049,8 +1002,6 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
253 cpos += num_clusters;
256 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
260 @@ -1058,28 +1009,21 @@ out:
263 static int ocfs2_xattr_cleanup(struct inode *inode,
265 struct ocfs2_xattr_info *xi,
266 struct ocfs2_xattr_search *xs,
269 - handle_t *handle = NULL;
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;
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);
282 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
283 OCFS2_JOURNAL_ACCESS_WRITE);
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);
296 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
301 static int ocfs2_xattr_update_entry(struct inode *inode,
303 struct ocfs2_xattr_info *xi,
304 struct ocfs2_xattr_search *xs,
307 - handle_t *handle = NULL;
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);
318 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
319 OCFS2_JOURNAL_ACCESS_WRITE);
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);
332 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
336 @@ -1168,13 +1101,13 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode,
340 - ret = __ocfs2_xattr_set_value_outside(inode, xv, xi->value,
342 + ret = ocfs2_xattr_update_entry(inode, ctxt->handle, xi, xs, offs);
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);
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);
357 - handle_t *handle = NULL;
358 + handle_t *handle = ctxt->handle;
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,
366 - ret = __ocfs2_xattr_set_value_outside(inode,
370 + ret = ocfs2_xattr_update_entry(inode,
380 - ret = ocfs2_xattr_update_entry(inode,
384 + ret = __ocfs2_xattr_set_value_outside(inode,
392 @@ -1413,45 +1348,29 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
393 * just trucate old value to zero.
395 ret = ocfs2_xattr_value_truncate(inode,
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);
418 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
419 OCFS2_JOURNAL_ACCESS_WRITE);
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);
435 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
436 OCFS2_JOURNAL_ACCESS_WRITE);
444 @@ -1465,7 +1384,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
445 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
453 @@ -1502,9 +1421,6 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
458 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
460 if (!ret && xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
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.
467 - ret2 = ocfs2_xattr_cleanup(inode, xi, xs, offs);
468 + ret2 = ocfs2_xattr_cleanup(inode, ctxt->handle,
479 static int ocfs2_remove_value_outside(struct inode*inode,
480 @@ -1540,6 +1456,13 @@ static int ocfs2_remove_value_outside(struct inode*inode,
482 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
484 + ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
485 + if (IS_ERR(ctxt.handle)) {
486 + ret = PTR_ERR(ctxt.handle);
491 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
492 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
494 @@ -1560,8 +1483,10 @@ static int ocfs2_remove_value_outside(struct inode*inode,
498 + ocfs2_commit_trans(osb, ctxt.handle);
499 ocfs2_schedule_truncate_log_flush(osb, 1);
500 ocfs2_run_deallocs(osb, &ctxt.dealloc);
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;
514 @@ -1928,18 +1853,11 @@ static int ocfs2_xattr_block_set(struct inode *inode,
518 - handle = ocfs2_start_trans(osb,
519 - OCFS2_XATTR_BLOCK_CREATE_CREDITS);
520 - if (IS_ERR(handle)) {
521 - ret = PTR_ERR(handle);
525 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
526 OCFS2_JOURNAL_ACCESS_CREATE);
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,
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);
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);
559 di->i_xattr_loc = cpu_to_le64(first_blkno);
560 - ret = ocfs2_journal_dirty(handle, xs->inode_bh);
564 - ocfs2_commit_trans(osb, handle);
568 + ocfs2_journal_dirty(handle, xs->inode_bh);
570 xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
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,
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,
591 - * delete a xattr doesn't need metadata and cluster allocation.
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);
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,
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);
614 + credits += OCFS2_INODE_UPDATE_CREDITS;
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,
621 base = bucket_block(xbs->bucket, block_off);
623 + credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
626 + credits += OCFS2_XATTR_BLOCK_UPDATE_CREDITS;
631 + * delete a xattr doesn't need metadata and cluster allocation.
632 + * so just calculate the credits and return.
634 + * The credits for removing the value tree will be extended
635 + * by ocfs2_remove_extent itself.
638 + if (!ocfs2_xattr_is_local(xe))
639 + credits += OCFS2_REMOVE_EXTENT_CREDITS;
644 /* do cluster allocation guess first. */
645 @@ -2121,6 +2050,13 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
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(
654 + &def_xv.xv.xr_list,
659 @@ -2137,11 +2073,16 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
663 - if (old_clusters >= new_clusters)
664 + if (old_clusters >= new_clusters) {
665 + credits += OCFS2_REMOVE_EXTENT_CREDITS;
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,
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,
687 @@ -2187,16 +2130,23 @@ meta_guess:
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);
701 + credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
705 *clusters_need = clusters_add;
707 *meta_need = meta_add;
709 + *credits_need = credits;
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,
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);
726 ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs,
727 - &clusters_add, &meta_add);
728 + &clusters_add, &meta_add, credits);
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);
740 ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
741 @@ -2254,6 +2205,126 @@ out:
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)
752 + int ret = 0, credits;
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);
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) {
765 + * If succeed and that extended attribute existing in
766 + * external block, then we will remove it.
771 + xis->not_found = -ENODATA;
772 + ret = ocfs2_calc_xattr_set_need(inode,
785 + ret = ocfs2_extend_trans(ctxt->handle, credits +
786 + ctxt->handle->h_buffer_credits);
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,
800 + xis->not_found = -ENODATA;
801 + ret = ocfs2_calc_xattr_set_need(inode,
814 + ret = ocfs2_extend_trans(ctxt->handle, credits +
815 + ctxt->handle->h_buffer_credits);
822 + * If no space in inode, we will set extended attribute
823 + * into external block.
825 + ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
828 + if (!xis->not_found) {
830 + * If succeed and that extended attribute
831 + * existing in inode, we will remove it.
835 + xbs->not_found = -ENODATA;
836 + ret = ocfs2_calc_xattr_set_need(inode,
849 + ret = ocfs2_extend_trans(ctxt->handle, credits +
850 + ctxt->handle->h_buffer_credits);
855 + ret = ocfs2_xattr_ibody_set(inode, xi,
868 @@ -2270,8 +2341,9 @@ int ocfs2_xattr_set(struct inode *inode,
870 struct buffer_head *di_bh = NULL;
871 struct ocfs2_dinode *di;
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, };
878 struct ocfs2_xattr_info xi = {
879 @@ -2337,56 +2409,37 @@ int ocfs2_xattr_set(struct inode *inode,
883 - ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, &xbs, &ctxt);
885 + mutex_lock(&tl_inode->i_mutex);
887 + if (ocfs2_truncate_log_needs_flush(osb)) {
888 + ret = __ocfs2_flush_truncate_log(osb);
890 + mutex_unlock(&tl_inode->i_mutex);
895 + mutex_unlock(&tl_inode->i_mutex);
897 + ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis,
898 + &xbs, &ctxt, &credits);
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);
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) {
915 - * If succeed and that extended attribute existing in
916 - * external block, then we will remove it.
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,
929 - * If no space in inode, we will set extended attribute
930 - * into external block.
932 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
935 - if (!xis.not_found) {
937 - * If succeed and that extended attribute
938 - * existing in inode, we will remove it.
942 - ret = ocfs2_xattr_ibody_set(inode, &xi,
946 + ctxt.handle = ocfs2_start_trans(osb, credits);
947 + if (IS_ERR(ctxt.handle)) {
948 + ret = PTR_ERR(ctxt.handle);
954 + ret = __ocfs2_xattr_set_handle(inode, di, &xi, &xis, &xbs, &ctxt);
956 + ocfs2_commit_trans(osb, ctxt.handle);
959 ocfs2_free_alloc_context(ctxt.data_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)
965 - int ret, credits = OCFS2_SUBALLOC_ALLOC;
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,
976 down_write(&oi->ip_alloc_sem);
979 - * We need more credits. One for the xattr block update and one
980 - * for each block of the new xattr bucket.
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);
990 ret = ocfs2_journal_access(handle, inode, xb_bh,
991 OCFS2_JOURNAL_ACCESS_WRITE);
998 ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac,
999 1, 1, &bit_off, &len);
1007 @@ -3038,14 +3079,14 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
1008 ret = ocfs2_init_xattr_bucket(xs->bucket, blkno);
1015 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
1016 OCFS2_JOURNAL_ACCESS_CREATE);
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,
1026 xb->xb_flags = cpu_to_le16(xb_flags | OCFS2_XATTR_INDEXED);
1028 - ret = ocfs2_journal_dirty(handle, xb_bh);
1033 + ocfs2_journal_dirty(handle, xb_bh);
1036 - ocfs2_commit_trans(osb, handle);
1040 up_write(&oi->ip_alloc_sem);
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.
1046 static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1048 struct ocfs2_xattr_bucket *bucket)
1051 @@ -3114,7 +3149,6 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
1052 u64 blkno = bucket_blkno(bucket);
1054 size_t blocksize = inode->i_sb->s_blocksize;
1056 struct ocfs2_xattr_entry *xe;
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);
1063 - handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)), bucket->bu_blocks);
1064 - if (IS_ERR(handle)) {
1065 - ret = PTR_ERR(handle);
1071 ret = ocfs2_xattr_bucket_journal_access(handle, bucket,
1072 OCFS2_JOURNAL_ACCESS_WRITE);
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);
1083 if (xh_free_start == end)
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);
1094 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
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
1102 - credits = bpc / 2 + 1;
1103 + credits = bpc / 2 + 1 + handle->h_buffer_credits;
1104 ret = ocfs2_extend_trans(handle, credits);
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.
1111 - credits = bpc + 1;
1112 + credits = bpc + 1 + handle->h_buffer_credits;
1113 ret = ocfs2_extend_trans(handle, credits);
1116 @@ -3732,7 +3756,7 @@ static int ocfs2_divide_xattr_cluster(struct inode *inode,
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;
1123 BUG_ON(OCFS2_XATTR_BUCKET_SIZE < OCFS2_SB(inode->i_sb)->s_clustersize);
1125 @@ -3845,12 +3869,12 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1127 struct ocfs2_xattr_set_ctxt *ctxt)
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;
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;
1140 @@ -3861,16 +3885,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1142 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
1144 - credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
1146 - handle = ocfs2_start_trans(osb, credits);
1147 - if (IS_ERR(handle)) {
1148 - ret = PTR_ERR(handle);
1154 ret = ocfs2_journal_access(handle, inode, root_bh,
1155 OCFS2_JOURNAL_ACCESS_WRITE);
1157 @@ -3924,18 +3938,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
1161 - if (handle->h_buffer_credits < credits) {
1163 - * The journal has been restarted before, and don't
1164 - * have enough space for the insertion, so extend it
1167 - ret = ocfs2_extend_trans(handle, credits);
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,
1179 ret = ocfs2_journal_dirty(handle, root_bh);
1188 - ocfs2_commit_trans(osb, handle);
1193 @@ -3963,6 +3960,7 @@ leave:
1194 * We meet with start_bh. Only move half of the xattrs to the bucket after it.
1196 static int ocfs2_extend_xattr_bucket(struct inode *inode,
1198 struct buffer_head *first_bh,
1199 struct buffer_head *start_bh,
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);
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.
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);
1218 + credits = end_blk - start_blk + 3 * blk_per_bucket + 1 +
1219 + handle->h_buffer_credits;
1220 + ret = ocfs2_extend_trans(handle, credits);
1225 @@ -4002,14 +3998,14 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
1226 OCFS2_JOURNAL_ACCESS_WRITE);
1233 while (end_blk != start_blk) {
1234 ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk,
1235 end_blk + blk_per_bucket, 0);
1239 end_blk -= blk_per_bucket;
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);
1247 - ocfs2_commit_trans(osb, handle);
1251 @@ -4099,6 +4093,7 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
1254 ret = ocfs2_extend_xattr_bucket(inode,
1259 @@ -4272,14 +4267,13 @@ set_new_name_value:
1260 * space for the xattr insertion.
1262 static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
1264 struct ocfs2_xattr_info *xi,
1265 struct ocfs2_xattr_search *xs,
1270 - handle_t *handle = NULL;
1271 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
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,
1279 - handle = ocfs2_start_trans(osb, xs->bucket->bu_blocks);
1280 - if (IS_ERR(handle)) {
1281 - ret = PTR_ERR(handle);
1287 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
1288 OCFS2_JOURNAL_ACCESS_WRITE);
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);
1294 - ocfs2_commit_trans(osb, handle);
1299 static int ocfs2_xattr_value_update_size(struct inode *inode,
1301 struct buffer_head *xe_bh,
1302 struct ocfs2_xattr_entry *xe,
1306 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1307 - handle_t *handle = NULL;
1309 - handle = ocfs2_start_trans(osb, 1);
1310 - if (IS_ERR(handle)) {
1316 ret = ocfs2_journal_access(handle, inode, xe_bh,
1317 OCFS2_JOURNAL_ACCESS_WRITE);
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,
1330 - ocfs2_commit_trans(osb, handle);
1334 @@ -4407,7 +4381,8 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
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);
1344 @@ -4439,6 +4414,7 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
1347 static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
1349 struct ocfs2_xattr_search *xs,
1352 @@ -4454,7 +4430,8 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
1354 xv = (struct ocfs2_xattr_value_root *)(xs->base + offset);
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);
1361 static int ocfs2_rm_xattr_cluster(struct inode *inode,
1362 @@ -4547,27 +4524,19 @@ out:
1365 static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
1367 struct ocfs2_xattr_search *xs)
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];
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);
1383 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
1384 OCFS2_JOURNAL_ACCESS_WRITE);
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);
1395 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
1398 - ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1402 @@ -4645,7 +4611,8 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
1403 xi->value_len = OCFS2_XATTR_ROOT_SIZE;
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);
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.
1416 - ocfs2_xattr_bucket_remove_xs(inode, xs);
1417 + ocfs2_xattr_bucket_remove_xs(inode, ctxt->handle, xs);
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);
1429 @@ -4785,7 +4753,8 @@ try_again:
1430 * name/value will be moved, the xe shouldn't be changed
1433 - ret = ocfs2_defrag_xattr_bucket(inode, xs->bucket);
1434 + ret = ocfs2_defrag_xattr_bucket(inode, ctxt->handle,
1439 @@ -4865,6 +4834,13 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
1441 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
1443 + ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
1444 + if (IS_ERR(ctxt.handle)) {
1445 + ret = PTR_ERR(ctxt.handle);
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,
1457 + ret = ocfs2_commit_trans(osb, ctxt.handle);
1458 ocfs2_schedule_truncate_log_flush(osb, 1);
1459 ocfs2_run_deallocs(osb, &ctxt.dealloc);