1 From: Tao Ma <tao.ma@oracle.com>
2 Date: Wed, 12 Nov 2008 08:27:00 +0800
3 Subject: ocfs2/xattr: Reserve meta/data at the beginning of ocfs2_xattr_set.
6 In ocfs2 xattr set, we reserve metadata and clusters in any place
7 they are needed. It is time-consuming and ineffective, so this
8 patch try to reserve metadata and clusters at the beginning of
11 Signed-off-by: Tao Ma <tao.ma@oracle.com>
12 Signed-off-by: Mark Fasheh <mfasheh@suse.com>
14 fs/ocfs2/alloc.h | 4 +
15 fs/ocfs2/xattr.c | 483 ++++++++++++++++++++++++++++++++++++++++--------------
16 2 files changed, 361 insertions(+), 126 deletions(-)
18 diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
19 index c301cf2..3eb735e 100644
20 --- a/fs/ocfs2/alloc.h
21 +++ b/fs/ocfs2/alloc.h
22 @@ -176,6 +176,10 @@ static inline void ocfs2_init_dealloc_ctxt(struct ocfs2_cached_dealloc_ctxt *c)
24 int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
25 u64 blkno, unsigned int bit);
26 +static inline int ocfs2_dealloc_has_cluster(struct ocfs2_cached_dealloc_ctxt *c)
28 + return c->c_global_allocator != NULL;
30 int ocfs2_run_deallocs(struct ocfs2_super *osb,
31 struct ocfs2_cached_dealloc_ctxt *ctxt);
33 diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
34 index f1da381..4fd201a 100644
35 --- a/fs/ocfs2/xattr.c
36 +++ b/fs/ocfs2/xattr.c
37 @@ -71,6 +71,12 @@ struct ocfs2_xattr_bucket {
41 +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;
47 #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
48 #define OCFS2_XATTR_INLINE_SIZE 80
50 @@ -133,11 +139,13 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
53 static int ocfs2_xattr_create_index_block(struct inode *inode,
54 - struct ocfs2_xattr_search *xs);
55 + struct ocfs2_xattr_search *xs,
56 + struct ocfs2_xattr_set_ctxt *ctxt);
58 static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
59 struct ocfs2_xattr_info *xi,
60 - struct ocfs2_xattr_search *xs);
61 + struct ocfs2_xattr_search *xs,
62 + struct ocfs2_xattr_set_ctxt *ctxt);
64 static int ocfs2_delete_xattr_index_block(struct inode *inode,
65 struct buffer_head *xb_bh);
66 @@ -334,14 +342,13 @@ static void ocfs2_xattr_hash_entry(struct inode *inode,
67 static int ocfs2_xattr_extend_allocation(struct inode *inode,
69 struct buffer_head *xattr_bh,
70 - struct ocfs2_xattr_value_root *xv)
71 + struct ocfs2_xattr_value_root *xv,
72 + struct ocfs2_xattr_set_ctxt *ctxt)
77 handle_t *handle = NULL;
78 - struct ocfs2_alloc_context *data_ac = NULL;
79 - struct ocfs2_alloc_context *meta_ac = NULL;
80 enum ocfs2_alloc_restarted why;
81 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
82 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters);
83 @@ -353,13 +360,6 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
87 - status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
88 - &data_ac, &meta_ac);
94 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
96 handle = ocfs2_start_trans(osb, credits);
97 @@ -386,8 +386,8 @@ restarted_transaction:
106 if ((status < 0) && (status != -EAGAIN)) {
107 if (status != -ENOSPC)
108 @@ -432,14 +432,6 @@ leave:
109 ocfs2_commit_trans(osb, handle);
113 - ocfs2_free_alloc_context(data_ac);
117 - ocfs2_free_alloc_context(meta_ac);
120 if ((!status) && restart_func) {
123 @@ -452,23 +444,16 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
124 struct buffer_head *root_bh,
125 struct ocfs2_xattr_value_root *xv,
126 u32 cpos, u32 phys_cpos, u32 len,
127 - struct ocfs2_cached_dealloc_ctxt *dealloc)
128 + struct ocfs2_xattr_set_ctxt *ctxt)
131 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
132 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
134 - struct ocfs2_alloc_context *meta_ac = NULL;
135 struct ocfs2_extent_tree et;
137 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv);
139 - ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
145 handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
146 if (IS_ERR(handle)) {
147 ret = PTR_ERR(handle);
148 @@ -483,8 +468,8 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
152 - ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac,
154 + ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac,
159 @@ -498,17 +483,13 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
163 - ret = ocfs2_cache_cluster_dealloc(dealloc, phys_blkno, len);
164 + ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len);
169 ocfs2_commit_trans(osb, handle);
173 - ocfs2_free_alloc_context(meta_ac);
178 @@ -516,15 +497,12 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
181 struct buffer_head *root_bh,
182 - struct ocfs2_xattr_value_root *xv)
183 + struct ocfs2_xattr_value_root *xv,
184 + struct ocfs2_xattr_set_ctxt *ctxt)
187 u32 trunc_len, cpos, phys_cpos, alloc_size;
189 - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
190 - struct ocfs2_cached_dealloc_ctxt dealloc;
192 - ocfs2_init_dealloc_ctxt(&dealloc);
194 if (old_clusters <= new_clusters)
196 @@ -544,7 +522,7 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
198 ret = __ocfs2_remove_xattr_range(inode, root_bh, xv, cpos,
199 phys_cpos, alloc_size,
205 @@ -558,16 +536,14 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
209 - ocfs2_schedule_truncate_log_flush(osb, 1);
210 - ocfs2_run_deallocs(osb, &dealloc);
215 static int ocfs2_xattr_value_truncate(struct inode *inode,
216 struct buffer_head *root_bh,
217 struct ocfs2_xattr_value_root *xv,
220 + struct ocfs2_xattr_set_ctxt *ctxt)
223 u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb, len);
224 @@ -579,11 +555,11 @@ static int ocfs2_xattr_value_truncate(struct inode *inode,
225 if (new_clusters > old_clusters)
226 ret = ocfs2_xattr_extend_allocation(inode,
227 new_clusters - old_clusters,
229 + root_bh, xv, ctxt);
231 ret = ocfs2_xattr_shrink_size(inode,
232 old_clusters, new_clusters,
234 + root_bh, xv, ctxt);
238 @@ -1167,6 +1143,7 @@ out:
239 static int ocfs2_xattr_set_value_outside(struct inode *inode,
240 struct ocfs2_xattr_info *xi,
241 struct ocfs2_xattr_search *xs,
242 + struct ocfs2_xattr_set_ctxt *ctxt,
245 size_t name_len = strlen(xi->name);
246 @@ -1186,7 +1163,7 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode,
247 xv->xr_list.l_next_free_rec = 0;
249 ret = ocfs2_xattr_value_truncate(inode, xs->xattr_bh, xv,
251 + xi->value_len, ctxt);
255 @@ -1317,6 +1294,7 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode,
256 static int ocfs2_xattr_set_entry(struct inode *inode,
257 struct ocfs2_xattr_info *xi,
258 struct ocfs2_xattr_search *xs,
259 + struct ocfs2_xattr_set_ctxt *ctxt,
262 struct ocfs2_xattr_entry *last;
263 @@ -1387,7 +1365,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
264 if (ocfs2_xattr_is_local(xs->here) && size == size_l) {
265 /* Replace existing local xattr with tree root */
266 ret = ocfs2_xattr_set_value_outside(inode, xi, xs,
272 @@ -1406,7 +1384,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
273 ret = ocfs2_xattr_value_truncate(inode,
282 @@ -1436,7 +1415,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
283 ret = ocfs2_xattr_value_truncate(inode,
292 @@ -1531,7 +1511,7 @@ out_commit:
293 * This is the second step for value size > INLINE_SIZE.
295 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
296 - ret = ocfs2_xattr_set_value_outside(inode, xi, xs, offs);
297 + ret = ocfs2_xattr_set_value_outside(inode, xi, xs, ctxt, offs);
301 @@ -1555,6 +1535,10 @@ static int ocfs2_remove_value_outside(struct inode*inode,
302 struct ocfs2_xattr_header *header)
305 + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
306 + struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
308 + ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
310 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
311 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
312 @@ -1567,14 +1551,17 @@ static int ocfs2_remove_value_outside(struct inode*inode,
313 le16_to_cpu(entry->xe_name_offset);
314 xv = (struct ocfs2_xattr_value_root *)
315 (val + OCFS2_XATTR_SIZE(entry->xe_name_len));
316 - ret = ocfs2_xattr_value_truncate(inode, bh, xv, 0);
317 + ret = ocfs2_xattr_value_truncate(inode, bh, xv,
327 + ocfs2_schedule_truncate_log_flush(osb, 1);
328 + ocfs2_run_deallocs(osb, &ctxt.dealloc);
332 @@ -1836,7 +1823,8 @@ static int ocfs2_xattr_ibody_find(struct inode *inode,
334 static int ocfs2_xattr_ibody_set(struct inode *inode,
335 struct ocfs2_xattr_info *xi,
336 - struct ocfs2_xattr_search *xs)
337 + struct ocfs2_xattr_search *xs,
338 + struct ocfs2_xattr_set_ctxt *ctxt)
340 struct ocfs2_inode_info *oi = OCFS2_I(inode);
341 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
342 @@ -1853,7 +1841,7 @@ static int ocfs2_xattr_ibody_set(struct inode *inode,
346 - ret = ocfs2_xattr_set_entry(inode, xi, xs,
347 + ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt,
348 (OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL));
350 up_write(&oi->ip_alloc_sem);
351 @@ -1926,12 +1914,12 @@ cleanup:
353 static int ocfs2_xattr_block_set(struct inode *inode,
354 struct ocfs2_xattr_info *xi,
355 - struct ocfs2_xattr_search *xs)
356 + struct ocfs2_xattr_search *xs,
357 + struct ocfs2_xattr_set_ctxt *ctxt)
359 struct buffer_head *new_bh = NULL;
360 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
361 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
362 - struct ocfs2_alloc_context *meta_ac = NULL;
363 handle_t *handle = NULL;
364 struct ocfs2_xattr_block *xblk = NULL;
365 u16 suballoc_bit_start;
366 @@ -1940,15 +1928,6 @@ static int ocfs2_xattr_block_set(struct inode *inode,
371 - * Alloc one external block for extended attribute
372 - * outside of inode.
374 - ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
379 handle = ocfs2_start_trans(osb,
380 OCFS2_XATTR_BLOCK_CREATE_CREDITS);
381 if (IS_ERR(handle)) {
382 @@ -1963,7 +1942,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
386 - ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1,
387 + ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1,
388 &suballoc_bit_start, &num_got,
391 @@ -1996,7 +1975,6 @@ static int ocfs2_xattr_block_set(struct inode *inode,
392 xs->end = (void *)xblk + inode->i_sb->s_blocksize;
393 xs->here = xs->header->xh_entries;
396 ret = ocfs2_journal_dirty(handle, new_bh);
399 @@ -2009,8 +1987,6 @@ static int ocfs2_xattr_block_set(struct inode *inode,
401 ocfs2_commit_trans(osb, handle);
404 - ocfs2_free_alloc_context(meta_ac);
408 @@ -2018,22 +1994,266 @@ out:
410 if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) {
411 /* Set extended attribute into external block */
412 - ret = ocfs2_xattr_set_entry(inode, xi, xs, OCFS2_HAS_XATTR_FL);
413 + ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt,
414 + OCFS2_HAS_XATTR_FL);
415 if (!ret || ret != -ENOSPC)
418 - ret = ocfs2_xattr_create_index_block(inode, xs);
419 + ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
424 - ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs);
425 + ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt);
432 +/* Check whether the new xattr can be inserted into the inode. */
433 +static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
434 + struct ocfs2_xattr_info *xi,
435 + struct ocfs2_xattr_search *xs)
438 + struct ocfs2_xattr_entry *last;
440 + size_t min_offs = xs->end - xs->base;
445 + last = xs->header->xh_entries;
447 + for (i = 0; i < le16_to_cpu(xs->header->xh_count); i++) {
448 + size_t offs = le16_to_cpu(last->xe_name_offset);
449 + if (offs < min_offs)
454 + free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
458 + BUG_ON(!xs->not_found);
460 + if (xi->value_len > OCFS2_XATTR_INLINE_SIZE)
461 + value_size = OCFS2_XATTR_ROOT_SIZE;
463 + value_size = OCFS2_XATTR_SIZE(xi->value_len);
465 + if (free >= sizeof(struct ocfs2_xattr_entry) +
466 + OCFS2_XATTR_SIZE(strlen(xi->name)) + value_size)
472 +static int ocfs2_calc_xattr_set_need(struct inode *inode,
473 + struct ocfs2_dinode *di,
474 + struct ocfs2_xattr_info *xi,
475 + struct ocfs2_xattr_search *xis,
476 + struct ocfs2_xattr_search *xbs,
477 + int *clusters_need,
480 + int ret = 0, old_in_xb = 0;
481 + int clusters_add = 0, meta_add = 0;
482 + struct buffer_head *bh = NULL;
483 + struct ocfs2_xattr_block *xb = NULL;
484 + struct ocfs2_xattr_entry *xe = NULL;
485 + struct ocfs2_xattr_value_root *xv = NULL;
487 + int name_offset, name_len = 0;
488 + u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb,
493 + * delete a xattr doesn't need metadata and cluster allocation.
499 + if (xis->not_found && xbs->not_found) {
500 + if (xi->value_len > OCFS2_XATTR_INLINE_SIZE)
501 + clusters_add += new_clusters;
506 + if (!xis->not_found) {
508 + name_offset = le16_to_cpu(xe->xe_name_offset);
509 + name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
513 + xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
515 + name_offset = le16_to_cpu(xe->xe_name_offset);
516 + name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
517 + i = xbs->here - xbs->header->xh_entries;
520 + if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
521 + ret = ocfs2_xattr_bucket_get_name_value(inode,
522 + bucket_xh(xbs->bucket),
525 + base = bucket_block(xbs->bucket, block_off);
530 + /* do cluster allocation guess first. */
531 + value_size = le64_to_cpu(xe->xe_value_size);
535 + * In xattr set, we always try to set the xe in inode first,
536 + * so if it can be inserted into inode successfully, the old
537 + * one will be removed from the xattr block, and this xattr
538 + * will be inserted into inode as a new xattr in inode.
540 + if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) {
541 + clusters_add += new_clusters;
546 + if (xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
547 + /* the new values will be stored outside. */
548 + u32 old_clusters = 0;
550 + if (!ocfs2_xattr_is_local(xe)) {
551 + old_clusters = ocfs2_clusters_for_bytes(inode->i_sb,
553 + xv = (struct ocfs2_xattr_value_root *)
554 + (base + name_offset + name_len);
558 + if (old_clusters >= new_clusters)
561 + meta_add += ocfs2_extend_meta_needed(&xv->xr_list);
562 + clusters_add += new_clusters - old_clusters;
567 + * Now the new value will be stored inside. So if the new
568 + * value is smaller than the size of value root or the old
569 + * value, we don't need any allocation, otherwise we have
570 + * to guess metadata allocation.
572 + if ((ocfs2_xattr_is_local(xe) && value_size >= xi->value_len) ||
573 + (!ocfs2_xattr_is_local(xe) &&
574 + OCFS2_XATTR_ROOT_SIZE >= xi->value_len))
579 + /* calculate metadata allocation. */
580 + if (di->i_xattr_loc) {
581 + if (!xbs->xattr_bh) {
582 + ret = ocfs2_read_block(inode,
583 + le64_to_cpu(di->i_xattr_loc),
590 + xb = (struct ocfs2_xattr_block *)bh->b_data;
592 + xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
594 + if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
595 + struct ocfs2_extent_list *el =
596 + &xb->xb_attrs.xb_root.xt_list;
597 + meta_add += ocfs2_extend_meta_needed(el);
601 + * This cluster will be used either for new bucket or for
603 + * If the cluster size is the same as the bucket size, one
604 + * more is needed since we may need to extend the bucket
608 + if (OCFS2_XATTR_BUCKET_SIZE ==
609 + OCFS2_SB(inode->i_sb)->s_clustersize)
615 + *clusters_need = clusters_add;
617 + *meta_need = meta_add;
622 +static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
623 + struct ocfs2_dinode *di,
624 + struct ocfs2_xattr_info *xi,
625 + struct ocfs2_xattr_search *xis,
626 + struct ocfs2_xattr_search *xbs,
627 + struct ocfs2_xattr_set_ctxt *ctxt)
629 + int clusters_add, meta_add, ret;
630 + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
632 + memset(ctxt, 0, sizeof(struct ocfs2_xattr_set_ctxt));
634 + ocfs2_init_dealloc_ctxt(&ctxt->dealloc);
636 + ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs,
637 + &clusters_add, &meta_add);
643 + mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d\n",
644 + xi->name, meta_add, clusters_add);
647 + ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
655 + if (clusters_add) {
656 + ret = ocfs2_reserve_clusters(osb, clusters_add, &ctxt->data_ac);
662 + if (ctxt->meta_ac) {
663 + ocfs2_free_alloc_context(ctxt->meta_ac);
664 + ctxt->meta_ac = NULL;
668 + * We cannot have an error and a non null ctxt->data_ac.
678 @@ -2051,6 +2271,8 @@ int ocfs2_xattr_set(struct inode *inode,
679 struct buffer_head *di_bh = NULL;
680 struct ocfs2_dinode *di;
682 + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
683 + struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
685 struct ocfs2_xattr_info xi = {
686 .name_index = name_index,
687 @@ -2115,15 +2337,21 @@ int ocfs2_xattr_set(struct inode *inode,
691 + ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, &xbs, &ctxt);
698 /* Remove existing extended attribute */
700 - ret = ocfs2_xattr_ibody_set(inode, &xi, &xis);
701 + ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
702 else if (!xbs.not_found)
703 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs);
704 + ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
706 /* We always try to set extended attribute into inode first*/
707 - ret = ocfs2_xattr_ibody_set(inode, &xi, &xis);
708 + ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
709 if (!ret && !xbs.not_found) {
711 * If succeed and that extended attribute existing in
712 @@ -2131,7 +2359,7 @@ int ocfs2_xattr_set(struct inode *inode,
716 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs);
717 + ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
718 } else if (ret == -ENOSPC) {
719 if (di->i_xattr_loc && !xbs.xattr_bh) {
720 ret = ocfs2_xattr_block_find(inode, name_index,
721 @@ -2143,9 +2371,9 @@ int ocfs2_xattr_set(struct inode *inode,
722 * If no space in inode, we will set extended attribute
723 * into external block.
725 - ret = ocfs2_xattr_block_set(inode, &xi, &xbs);
726 + ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
730 if (!xis.not_found) {
732 * If succeed and that extended attribute
733 @@ -2153,10 +2381,19 @@ int ocfs2_xattr_set(struct inode *inode,
737 - ret = ocfs2_xattr_ibody_set(inode, &xi, &xis);
738 + ret = ocfs2_xattr_ibody_set(inode, &xi,
745 + ocfs2_free_alloc_context(ctxt.data_ac);
747 + ocfs2_free_alloc_context(ctxt.meta_ac);
748 + if (ocfs2_dealloc_has_cluster(&ctxt.dealloc))
749 + ocfs2_schedule_truncate_log_flush(osb, 1);
750 + ocfs2_run_deallocs(osb, &ctxt.dealloc);
752 up_write(&OCFS2_I(inode)->ip_xattr_sem);
753 ocfs2_inode_unlock(inode, 1);
754 @@ -2734,7 +2971,8 @@ static void ocfs2_xattr_update_xattr_search(struct inode *inode,
757 static int ocfs2_xattr_create_index_block(struct inode *inode,
758 - struct ocfs2_xattr_search *xs)
759 + struct ocfs2_xattr_search *xs,
760 + struct ocfs2_xattr_set_ctxt *ctxt)
762 int ret, credits = OCFS2_SUBALLOC_ALLOC;
764 @@ -2742,7 +2980,6 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
766 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
767 struct ocfs2_inode_info *oi = OCFS2_I(inode);
768 - struct ocfs2_alloc_context *data_ac;
769 struct buffer_head *xb_bh = xs->xattr_bh;
770 struct ocfs2_xattr_block *xb =
771 (struct ocfs2_xattr_block *)xb_bh->b_data;
772 @@ -2755,12 +2992,6 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
773 BUG_ON(xb_flags & OCFS2_XATTR_INDEXED);
776 - ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
784 * We can use this lock for now, and maybe move to a dedicated mutex
785 @@ -2787,7 +3018,8 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
789 - ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, &len);
790 + ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac,
791 + 1, 1, &bit_off, &len);
795 @@ -2850,10 +3082,6 @@ out_commit:
797 up_write(&oi->ip_alloc_sem);
801 - ocfs2_free_alloc_context(data_ac);
806 @@ -3614,7 +3842,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
812 + struct ocfs2_xattr_set_ctxt *ctxt)
815 u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
816 @@ -3622,8 +3851,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
817 u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0;
819 handle_t *handle = NULL;
820 - struct ocfs2_alloc_context *data_ac = NULL;
821 - struct ocfs2_alloc_context *meta_ac = NULL;
822 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
823 struct ocfs2_extent_tree et;
825 @@ -3634,13 +3861,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
827 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
829 - ret = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
830 - &data_ac, &meta_ac);
836 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
838 handle = ocfs2_start_trans(osb, credits);
839 @@ -3658,7 +3878,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
843 - ret = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
844 + ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac, 1,
845 clusters_to_add, &bit_off, &num_bits);
848 @@ -3719,7 +3939,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
849 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
850 num_bits, (unsigned long long)block, v_start);
851 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block,
852 - num_bits, 0, meta_ac);
853 + num_bits, 0, ctxt->meta_ac);
857 @@ -3734,10 +3954,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
860 ocfs2_commit_trans(osb, handle);
862 - ocfs2_free_alloc_context(data_ac);
864 - ocfs2_free_alloc_context(meta_ac);
868 @@ -3821,7 +4037,8 @@ out:
870 static int ocfs2_add_new_xattr_bucket(struct inode *inode,
871 struct buffer_head *xb_bh,
872 - struct buffer_head *header_bh)
873 + struct buffer_head *header_bh,
874 + struct ocfs2_xattr_set_ctxt *ctxt)
876 struct ocfs2_xattr_header *first_xh = NULL;
877 struct buffer_head *first_bh = NULL;
878 @@ -3872,7 +4089,8 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
888 @@ -4147,7 +4365,8 @@ out:
889 static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
890 struct buffer_head *header_bh,
894 + struct ocfs2_xattr_set_ctxt *ctxt)
898 @@ -4182,7 +4401,7 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
900 mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n",
901 xe_off, (unsigned long long)header_bh->b_blocknr, len);
902 - ret = ocfs2_xattr_value_truncate(inode, value_bh, xv, len);
903 + ret = ocfs2_xattr_value_truncate(inode, value_bh, xv, len, ctxt);
907 @@ -4200,8 +4419,9 @@ out:
910 static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
911 - struct ocfs2_xattr_search *xs,
913 + struct ocfs2_xattr_search *xs,
915 + struct ocfs2_xattr_set_ctxt *ctxt)
918 struct ocfs2_xattr_entry *xe = xs->here;
919 @@ -4211,7 +4431,7 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
921 offset = xe - xh->xh_entries;
922 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket->bu_bhs[0],
924 + offset, len, ctxt);
928 @@ -4375,7 +4595,8 @@ out_commit:
930 static int ocfs2_xattr_set_in_bucket(struct inode *inode,
931 struct ocfs2_xattr_info *xi,
932 - struct ocfs2_xattr_search *xs)
933 + struct ocfs2_xattr_search *xs,
934 + struct ocfs2_xattr_set_ctxt *ctxt)
938 @@ -4403,7 +4624,8 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
941 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
948 @@ -4434,7 +4656,7 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
950 /* allocate the space now for the outside block storage. */
951 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
957 @@ -4485,7 +4707,8 @@ static int ocfs2_check_xattr_bucket_collision(struct inode *inode,
959 static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
960 struct ocfs2_xattr_info *xi,
961 - struct ocfs2_xattr_search *xs)
962 + struct ocfs2_xattr_search *xs,
963 + struct ocfs2_xattr_set_ctxt *ctxt)
965 struct ocfs2_xattr_header *xh;
966 struct ocfs2_xattr_entry *xe;
967 @@ -4603,7 +4826,8 @@ try_again:
969 ret = ocfs2_add_new_xattr_bucket(inode,
971 - xs->bucket->bu_bhs[0]);
972 + xs->bucket->bu_bhs[0],
977 @@ -4622,7 +4846,7 @@ try_again:
981 - ret = ocfs2_xattr_set_in_bucket(inode, xi, xs);
982 + ret = ocfs2_xattr_set_in_bucket(inode, xi, xs, ctxt);
986 @@ -4636,6 +4860,10 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
987 struct ocfs2_xattr_header *xh = bucket_xh(bucket);
989 struct ocfs2_xattr_entry *xe;
990 + struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
991 + struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,};
993 + ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
995 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
996 xe = &xh->xh_entries[i];
997 @@ -4644,13 +4872,16 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
999 ret = ocfs2_xattr_bucket_value_truncate(inode,
1009 + ocfs2_schedule_truncate_log_flush(osb, 1);
1010 + ocfs2_run_deallocs(osb, &ctxt.dealloc);