aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-11-11 19:27:00 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:34:19 -0500
commit78f30c314a74b9dc5d7368d96fe4be883d9a3a04 (patch)
tree07904e23f2d2c1287869daecc9f27052b71d67a5
parentc73f60f900ddf73ec4ea2a143829ab97242c4e8c (diff)
ocfs2/xattr: Reserve meta/data at the beginning of ocfs2_xattr_set.
In ocfs2 xattr set, we reserve metadata and clusters in any place they are needed. It is time-consuming and ineffective, so this patch try to reserve metadata and clusters at the beginning of ocfs2_xattr_set. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/alloc.h4
-rw-r--r--fs/ocfs2/xattr.c483
2 files changed, 361 insertions, 126 deletions
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index c301cf225f0b..3eb735eedae6 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -176,6 +176,10 @@ static inline void ocfs2_init_dealloc_ctxt(struct ocfs2_cached_dealloc_ctxt *c)
176} 176}
177int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, 177int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
178 u64 blkno, unsigned int bit); 178 u64 blkno, unsigned int bit);
179static inline int ocfs2_dealloc_has_cluster(struct ocfs2_cached_dealloc_ctxt *c)
180{
181 return c->c_global_allocator != NULL;
182}
179int ocfs2_run_deallocs(struct ocfs2_super *osb, 183int ocfs2_run_deallocs(struct ocfs2_super *osb,
180 struct ocfs2_cached_dealloc_ctxt *ctxt); 184 struct ocfs2_cached_dealloc_ctxt *ctxt);
181 185
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index f1da381a44f6..4fd201a54c72 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -71,6 +71,12 @@ struct ocfs2_xattr_bucket {
71 int bu_blocks; 71 int bu_blocks;
72}; 72};
73 73
74struct ocfs2_xattr_set_ctxt {
75 struct ocfs2_alloc_context *meta_ac;
76 struct ocfs2_alloc_context *data_ac;
77 struct ocfs2_cached_dealloc_ctxt dealloc;
78};
79
74#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) 80#define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root))
75#define OCFS2_XATTR_INLINE_SIZE 80 81#define OCFS2_XATTR_INLINE_SIZE 80
76 82
@@ -133,11 +139,13 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
133 size_t buffer_size); 139 size_t buffer_size);
134 140
135static int ocfs2_xattr_create_index_block(struct inode *inode, 141static int ocfs2_xattr_create_index_block(struct inode *inode,
136 struct ocfs2_xattr_search *xs); 142 struct ocfs2_xattr_search *xs,
143 struct ocfs2_xattr_set_ctxt *ctxt);
137 144
138static int ocfs2_xattr_set_entry_index_block(struct inode *inode, 145static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
139 struct ocfs2_xattr_info *xi, 146 struct ocfs2_xattr_info *xi,
140 struct ocfs2_xattr_search *xs); 147 struct ocfs2_xattr_search *xs,
148 struct ocfs2_xattr_set_ctxt *ctxt);
141 149
142static int ocfs2_delete_xattr_index_block(struct inode *inode, 150static int ocfs2_delete_xattr_index_block(struct inode *inode,
143 struct buffer_head *xb_bh); 151 struct buffer_head *xb_bh);
@@ -334,14 +342,13 @@ static void ocfs2_xattr_hash_entry(struct inode *inode,
334static int ocfs2_xattr_extend_allocation(struct inode *inode, 342static int ocfs2_xattr_extend_allocation(struct inode *inode,
335 u32 clusters_to_add, 343 u32 clusters_to_add,
336 struct buffer_head *xattr_bh, 344 struct buffer_head *xattr_bh,
337 struct ocfs2_xattr_value_root *xv) 345 struct ocfs2_xattr_value_root *xv,
346 struct ocfs2_xattr_set_ctxt *ctxt)
338{ 347{
339 int status = 0; 348 int status = 0;
340 int restart_func = 0; 349 int restart_func = 0;
341 int credits = 0; 350 int credits = 0;
342 handle_t *handle = NULL; 351 handle_t *handle = NULL;
343 struct ocfs2_alloc_context *data_ac = NULL;
344 struct ocfs2_alloc_context *meta_ac = NULL;
345 enum ocfs2_alloc_restarted why; 352 enum ocfs2_alloc_restarted why;
346 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 353 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
347 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters); 354 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters);
@@ -353,13 +360,6 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
353 360
354restart_all: 361restart_all:
355 362
356 status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
357 &data_ac, &meta_ac);
358 if (status) {
359 mlog_errno(status);
360 goto leave;
361 }
362
363 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el, 363 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
364 clusters_to_add); 364 clusters_to_add);
365 handle = ocfs2_start_trans(osb, credits); 365 handle = ocfs2_start_trans(osb, credits);
@@ -386,8 +386,8 @@ restarted_transaction:
386 0, 386 0,
387 &et, 387 &et,
388 handle, 388 handle,
389 data_ac, 389 ctxt->data_ac,
390 meta_ac, 390 ctxt->meta_ac,
391 &why); 391 &why);
392 if ((status < 0) && (status != -EAGAIN)) { 392 if ((status < 0) && (status != -EAGAIN)) {
393 if (status != -ENOSPC) 393 if (status != -ENOSPC)
@@ -432,14 +432,6 @@ leave:
432 ocfs2_commit_trans(osb, handle); 432 ocfs2_commit_trans(osb, handle);
433 handle = NULL; 433 handle = NULL;
434 } 434 }
435 if (data_ac) {
436 ocfs2_free_alloc_context(data_ac);
437 data_ac = NULL;
438 }
439 if (meta_ac) {
440 ocfs2_free_alloc_context(meta_ac);
441 meta_ac = NULL;
442 }
443 if ((!status) && restart_func) { 435 if ((!status) && restart_func) {
444 restart_func = 0; 436 restart_func = 0;
445 goto restart_all; 437 goto restart_all;
@@ -452,23 +444,16 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
452 struct buffer_head *root_bh, 444 struct buffer_head *root_bh,
453 struct ocfs2_xattr_value_root *xv, 445 struct ocfs2_xattr_value_root *xv,
454 u32 cpos, u32 phys_cpos, u32 len, 446 u32 cpos, u32 phys_cpos, u32 len,
455 struct ocfs2_cached_dealloc_ctxt *dealloc) 447 struct ocfs2_xattr_set_ctxt *ctxt)
456{ 448{
457 int ret; 449 int ret;
458 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); 450 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
459 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 451 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
460 handle_t *handle; 452 handle_t *handle;
461 struct ocfs2_alloc_context *meta_ac = NULL;
462 struct ocfs2_extent_tree et; 453 struct ocfs2_extent_tree et;
463 454
464 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv); 455 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv);
465 456
466 ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
467 if (ret) {
468 mlog_errno(ret);
469 return ret;
470 }
471
472 handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); 457 handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
473 if (IS_ERR(handle)) { 458 if (IS_ERR(handle)) {
474 ret = PTR_ERR(handle); 459 ret = PTR_ERR(handle);
@@ -483,8 +468,8 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
483 goto out_commit; 468 goto out_commit;
484 } 469 }
485 470
486 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac, 471 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac,
487 dealloc); 472 &ctxt->dealloc);
488 if (ret) { 473 if (ret) {
489 mlog_errno(ret); 474 mlog_errno(ret);
490 goto out_commit; 475 goto out_commit;
@@ -498,17 +483,13 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
498 goto out_commit; 483 goto out_commit;
499 } 484 }
500 485
501 ret = ocfs2_cache_cluster_dealloc(dealloc, phys_blkno, len); 486 ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len);
502 if (ret) 487 if (ret)
503 mlog_errno(ret); 488 mlog_errno(ret);
504 489
505out_commit: 490out_commit:
506 ocfs2_commit_trans(osb, handle); 491 ocfs2_commit_trans(osb, handle);
507out: 492out:
508
509 if (meta_ac)
510 ocfs2_free_alloc_context(meta_ac);
511
512 return ret; 493 return ret;
513} 494}
514 495
@@ -516,15 +497,12 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
516 u32 old_clusters, 497 u32 old_clusters,
517 u32 new_clusters, 498 u32 new_clusters,
518 struct buffer_head *root_bh, 499 struct buffer_head *root_bh,
519 struct ocfs2_xattr_value_root *xv) 500 struct ocfs2_xattr_value_root *xv,
501 struct ocfs2_xattr_set_ctxt *ctxt)
520{ 502{
521 int ret = 0; 503 int ret = 0;
522 u32 trunc_len, cpos, phys_cpos, alloc_size; 504 u32 trunc_len, cpos, phys_cpos, alloc_size;
523 u64 block; 505 u64 block;
524 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
525 struct ocfs2_cached_dealloc_ctxt dealloc;
526
527 ocfs2_init_dealloc_ctxt(&dealloc);
528 506
529 if (old_clusters <= new_clusters) 507 if (old_clusters <= new_clusters)
530 return 0; 508 return 0;
@@ -544,7 +522,7 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
544 522
545 ret = __ocfs2_remove_xattr_range(inode, root_bh, xv, cpos, 523 ret = __ocfs2_remove_xattr_range(inode, root_bh, xv, cpos,
546 phys_cpos, alloc_size, 524 phys_cpos, alloc_size,
547 &dealloc); 525 ctxt);
548 if (ret) { 526 if (ret) {
549 mlog_errno(ret); 527 mlog_errno(ret);
550 goto out; 528 goto out;
@@ -558,16 +536,14 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
558 } 536 }
559 537
560out: 538out:
561 ocfs2_schedule_truncate_log_flush(osb, 1);
562 ocfs2_run_deallocs(osb, &dealloc);
563
564 return ret; 539 return ret;
565} 540}
566 541
567static int ocfs2_xattr_value_truncate(struct inode *inode, 542static int ocfs2_xattr_value_truncate(struct inode *inode,
568 struct buffer_head *root_bh, 543 struct buffer_head *root_bh,
569 struct ocfs2_xattr_value_root *xv, 544 struct ocfs2_xattr_value_root *xv,
570 int len) 545 int len,
546 struct ocfs2_xattr_set_ctxt *ctxt)
571{ 547{
572 int ret; 548 int ret;
573 u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb, len); 549 u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb, len);
@@ -579,11 +555,11 @@ static int ocfs2_xattr_value_truncate(struct inode *inode,
579 if (new_clusters > old_clusters) 555 if (new_clusters > old_clusters)
580 ret = ocfs2_xattr_extend_allocation(inode, 556 ret = ocfs2_xattr_extend_allocation(inode,
581 new_clusters - old_clusters, 557 new_clusters - old_clusters,
582 root_bh, xv); 558 root_bh, xv, ctxt);
583 else 559 else
584 ret = ocfs2_xattr_shrink_size(inode, 560 ret = ocfs2_xattr_shrink_size(inode,
585 old_clusters, new_clusters, 561 old_clusters, new_clusters,
586 root_bh, xv); 562 root_bh, xv, ctxt);
587 563
588 return ret; 564 return ret;
589} 565}
@@ -1167,6 +1143,7 @@ out:
1167static int ocfs2_xattr_set_value_outside(struct inode *inode, 1143static int ocfs2_xattr_set_value_outside(struct inode *inode,
1168 struct ocfs2_xattr_info *xi, 1144 struct ocfs2_xattr_info *xi,
1169 struct ocfs2_xattr_search *xs, 1145 struct ocfs2_xattr_search *xs,
1146 struct ocfs2_xattr_set_ctxt *ctxt,
1170 size_t offs) 1147 size_t offs)
1171{ 1148{
1172 size_t name_len = strlen(xi->name); 1149 size_t name_len = strlen(xi->name);
@@ -1186,7 +1163,7 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode,
1186 xv->xr_list.l_next_free_rec = 0; 1163 xv->xr_list.l_next_free_rec = 0;
1187 1164
1188 ret = ocfs2_xattr_value_truncate(inode, xs->xattr_bh, xv, 1165 ret = ocfs2_xattr_value_truncate(inode, xs->xattr_bh, xv,
1189 xi->value_len); 1166 xi->value_len, ctxt);
1190 if (ret < 0) { 1167 if (ret < 0) {
1191 mlog_errno(ret); 1168 mlog_errno(ret);
1192 return ret; 1169 return ret;
@@ -1317,6 +1294,7 @@ static void ocfs2_xattr_set_entry_local(struct inode *inode,
1317static int ocfs2_xattr_set_entry(struct inode *inode, 1294static int ocfs2_xattr_set_entry(struct inode *inode,
1318 struct ocfs2_xattr_info *xi, 1295 struct ocfs2_xattr_info *xi,
1319 struct ocfs2_xattr_search *xs, 1296 struct ocfs2_xattr_search *xs,
1297 struct ocfs2_xattr_set_ctxt *ctxt,
1320 int flag) 1298 int flag)
1321{ 1299{
1322 struct ocfs2_xattr_entry *last; 1300 struct ocfs2_xattr_entry *last;
@@ -1387,7 +1365,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1387 if (ocfs2_xattr_is_local(xs->here) && size == size_l) { 1365 if (ocfs2_xattr_is_local(xs->here) && size == size_l) {
1388 /* Replace existing local xattr with tree root */ 1366 /* Replace existing local xattr with tree root */
1389 ret = ocfs2_xattr_set_value_outside(inode, xi, xs, 1367 ret = ocfs2_xattr_set_value_outside(inode, xi, xs,
1390 offs); 1368 ctxt, offs);
1391 if (ret < 0) 1369 if (ret < 0)
1392 mlog_errno(ret); 1370 mlog_errno(ret);
1393 goto out; 1371 goto out;
@@ -1406,7 +1384,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1406 ret = ocfs2_xattr_value_truncate(inode, 1384 ret = ocfs2_xattr_value_truncate(inode,
1407 xs->xattr_bh, 1385 xs->xattr_bh,
1408 xv, 1386 xv,
1409 xi->value_len); 1387 xi->value_len,
1388 ctxt);
1410 if (ret < 0) { 1389 if (ret < 0) {
1411 mlog_errno(ret); 1390 mlog_errno(ret);
1412 goto out; 1391 goto out;
@@ -1436,7 +1415,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1436 ret = ocfs2_xattr_value_truncate(inode, 1415 ret = ocfs2_xattr_value_truncate(inode,
1437 xs->xattr_bh, 1416 xs->xattr_bh,
1438 xv, 1417 xv,
1439 0); 1418 0,
1419 ctxt);
1440 if (ret < 0) 1420 if (ret < 0)
1441 mlog_errno(ret); 1421 mlog_errno(ret);
1442 } 1422 }
@@ -1531,7 +1511,7 @@ out_commit:
1531 * This is the second step for value size > INLINE_SIZE. 1511 * This is the second step for value size > INLINE_SIZE.
1532 */ 1512 */
1533 size_t offs = le16_to_cpu(xs->here->xe_name_offset); 1513 size_t offs = le16_to_cpu(xs->here->xe_name_offset);
1534 ret = ocfs2_xattr_set_value_outside(inode, xi, xs, offs); 1514 ret = ocfs2_xattr_set_value_outside(inode, xi, xs, ctxt, offs);
1535 if (ret < 0) { 1515 if (ret < 0) {
1536 int ret2; 1516 int ret2;
1537 1517
@@ -1555,6 +1535,10 @@ static int ocfs2_remove_value_outside(struct inode*inode,
1555 struct ocfs2_xattr_header *header) 1535 struct ocfs2_xattr_header *header)
1556{ 1536{
1557 int ret = 0, i; 1537 int ret = 0, i;
1538 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1539 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
1540
1541 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
1558 1542
1559 for (i = 0; i < le16_to_cpu(header->xh_count); i++) { 1543 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
1560 struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; 1544 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
@@ -1567,14 +1551,17 @@ static int ocfs2_remove_value_outside(struct inode*inode,
1567 le16_to_cpu(entry->xe_name_offset); 1551 le16_to_cpu(entry->xe_name_offset);
1568 xv = (struct ocfs2_xattr_value_root *) 1552 xv = (struct ocfs2_xattr_value_root *)
1569 (val + OCFS2_XATTR_SIZE(entry->xe_name_len)); 1553 (val + OCFS2_XATTR_SIZE(entry->xe_name_len));
1570 ret = ocfs2_xattr_value_truncate(inode, bh, xv, 0); 1554 ret = ocfs2_xattr_value_truncate(inode, bh, xv,
1555 0, &ctxt);
1571 if (ret < 0) { 1556 if (ret < 0) {
1572 mlog_errno(ret); 1557 mlog_errno(ret);
1573 return ret; 1558 break;
1574 } 1559 }
1575 } 1560 }
1576 } 1561 }
1577 1562
1563 ocfs2_schedule_truncate_log_flush(osb, 1);
1564 ocfs2_run_deallocs(osb, &ctxt.dealloc);
1578 return ret; 1565 return ret;
1579} 1566}
1580 1567
@@ -1836,7 +1823,8 @@ static int ocfs2_xattr_ibody_find(struct inode *inode,
1836 */ 1823 */
1837static int ocfs2_xattr_ibody_set(struct inode *inode, 1824static int ocfs2_xattr_ibody_set(struct inode *inode,
1838 struct ocfs2_xattr_info *xi, 1825 struct ocfs2_xattr_info *xi,
1839 struct ocfs2_xattr_search *xs) 1826 struct ocfs2_xattr_search *xs,
1827 struct ocfs2_xattr_set_ctxt *ctxt)
1840{ 1828{
1841 struct ocfs2_inode_info *oi = OCFS2_I(inode); 1829 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1842 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; 1830 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
@@ -1853,7 +1841,7 @@ static int ocfs2_xattr_ibody_set(struct inode *inode,
1853 } 1841 }
1854 } 1842 }
1855 1843
1856 ret = ocfs2_xattr_set_entry(inode, xi, xs, 1844 ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt,
1857 (OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL)); 1845 (OCFS2_INLINE_XATTR_FL | OCFS2_HAS_XATTR_FL));
1858out: 1846out:
1859 up_write(&oi->ip_alloc_sem); 1847 up_write(&oi->ip_alloc_sem);
@@ -1926,12 +1914,12 @@ cleanup:
1926 */ 1914 */
1927static int ocfs2_xattr_block_set(struct inode *inode, 1915static int ocfs2_xattr_block_set(struct inode *inode,
1928 struct ocfs2_xattr_info *xi, 1916 struct ocfs2_xattr_info *xi,
1929 struct ocfs2_xattr_search *xs) 1917 struct ocfs2_xattr_search *xs,
1918 struct ocfs2_xattr_set_ctxt *ctxt)
1930{ 1919{
1931 struct buffer_head *new_bh = NULL; 1920 struct buffer_head *new_bh = NULL;
1932 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1921 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1933 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; 1922 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1934 struct ocfs2_alloc_context *meta_ac = NULL;
1935 handle_t *handle = NULL; 1923 handle_t *handle = NULL;
1936 struct ocfs2_xattr_block *xblk = NULL; 1924 struct ocfs2_xattr_block *xblk = NULL;
1937 u16 suballoc_bit_start; 1925 u16 suballoc_bit_start;
@@ -1940,15 +1928,6 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1940 int ret; 1928 int ret;
1941 1929
1942 if (!xs->xattr_bh) { 1930 if (!xs->xattr_bh) {
1943 /*
1944 * Alloc one external block for extended attribute
1945 * outside of inode.
1946 */
1947 ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
1948 if (ret < 0) {
1949 mlog_errno(ret);
1950 goto out;
1951 }
1952 handle = ocfs2_start_trans(osb, 1931 handle = ocfs2_start_trans(osb,
1953 OCFS2_XATTR_BLOCK_CREATE_CREDITS); 1932 OCFS2_XATTR_BLOCK_CREATE_CREDITS);
1954 if (IS_ERR(handle)) { 1933 if (IS_ERR(handle)) {
@@ -1963,7 +1942,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1963 goto out_commit; 1942 goto out_commit;
1964 } 1943 }
1965 1944
1966 ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, 1945 ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1,
1967 &suballoc_bit_start, &num_got, 1946 &suballoc_bit_start, &num_got,
1968 &first_blkno); 1947 &first_blkno);
1969 if (ret < 0) { 1948 if (ret < 0) {
@@ -1996,7 +1975,6 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1996 xs->end = (void *)xblk + inode->i_sb->s_blocksize; 1975 xs->end = (void *)xblk + inode->i_sb->s_blocksize;
1997 xs->here = xs->header->xh_entries; 1976 xs->here = xs->header->xh_entries;
1998 1977
1999
2000 ret = ocfs2_journal_dirty(handle, new_bh); 1978 ret = ocfs2_journal_dirty(handle, new_bh);
2001 if (ret < 0) { 1979 if (ret < 0) {
2002 mlog_errno(ret); 1980 mlog_errno(ret);
@@ -2009,8 +1987,6 @@ static int ocfs2_xattr_block_set(struct inode *inode,
2009out_commit: 1987out_commit:
2010 ocfs2_commit_trans(osb, handle); 1988 ocfs2_commit_trans(osb, handle);
2011out: 1989out:
2012 if (meta_ac)
2013 ocfs2_free_alloc_context(meta_ac);
2014 if (ret < 0) 1990 if (ret < 0)
2015 return ret; 1991 return ret;
2016 } else 1992 } else
@@ -2018,22 +1994,266 @@ out:
2018 1994
2019 if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) { 1995 if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) {
2020 /* Set extended attribute into external block */ 1996 /* Set extended attribute into external block */
2021 ret = ocfs2_xattr_set_entry(inode, xi, xs, OCFS2_HAS_XATTR_FL); 1997 ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt,
1998 OCFS2_HAS_XATTR_FL);
2022 if (!ret || ret != -ENOSPC) 1999 if (!ret || ret != -ENOSPC)
2023 goto end; 2000 goto end;
2024 2001
2025 ret = ocfs2_xattr_create_index_block(inode, xs); 2002 ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
2026 if (ret) 2003 if (ret)
2027 goto end; 2004 goto end;
2028 } 2005 }
2029 2006
2030 ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs); 2007 ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt);
2031 2008
2032end: 2009end:
2033 2010
2034 return ret; 2011 return ret;
2035} 2012}
2036 2013
2014/* Check whether the new xattr can be inserted into the inode. */
2015static int ocfs2_xattr_can_be_in_inode(struct inode *inode,
2016 struct ocfs2_xattr_info *xi,
2017 struct ocfs2_xattr_search *xs)
2018{
2019 u64 value_size;
2020 struct ocfs2_xattr_entry *last;
2021 int free, i;
2022 size_t min_offs = xs->end - xs->base;
2023
2024 if (!xs->header)
2025 return 0;
2026
2027 last = xs->header->xh_entries;
2028
2029 for (i = 0; i < le16_to_cpu(xs->header->xh_count); i++) {
2030 size_t offs = le16_to_cpu(last->xe_name_offset);
2031 if (offs < min_offs)
2032 min_offs = offs;
2033 last += 1;
2034 }
2035
2036 free = min_offs - ((void *)last - xs->base) - sizeof(__u32);
2037 if (free < 0)
2038 return 0;
2039
2040 BUG_ON(!xs->not_found);
2041
2042 if (xi->value_len > OCFS2_XATTR_INLINE_SIZE)
2043 value_size = OCFS2_XATTR_ROOT_SIZE;
2044 else
2045 value_size = OCFS2_XATTR_SIZE(xi->value_len);
2046
2047 if (free >= sizeof(struct ocfs2_xattr_entry) +
2048 OCFS2_XATTR_SIZE(strlen(xi->name)) + value_size)
2049 return 1;
2050
2051 return 0;
2052}
2053
2054static int ocfs2_calc_xattr_set_need(struct inode *inode,
2055 struct ocfs2_dinode *di,
2056 struct ocfs2_xattr_info *xi,
2057 struct ocfs2_xattr_search *xis,
2058 struct ocfs2_xattr_search *xbs,
2059 int *clusters_need,
2060 int *meta_need)
2061{
2062 int ret = 0, old_in_xb = 0;
2063 int clusters_add = 0, meta_add = 0;
2064 struct buffer_head *bh = NULL;
2065 struct ocfs2_xattr_block *xb = NULL;
2066 struct ocfs2_xattr_entry *xe = NULL;
2067 struct ocfs2_xattr_value_root *xv = NULL;
2068 char *base = NULL;
2069 int name_offset, name_len = 0;
2070 u32 new_clusters = ocfs2_clusters_for_bytes(inode->i_sb,
2071 xi->value_len);
2072 u64 value_size;
2073
2074 /*
2075 * delete a xattr doesn't need metadata and cluster allocation.
2076 * so return.
2077 */
2078 if (!xi->value)
2079 goto out;
2080
2081 if (xis->not_found && xbs->not_found) {
2082 if (xi->value_len > OCFS2_XATTR_INLINE_SIZE)
2083 clusters_add += new_clusters;
2084
2085 goto meta_guess;
2086 }
2087
2088 if (!xis->not_found) {
2089 xe = xis->here;
2090 name_offset = le16_to_cpu(xe->xe_name_offset);
2091 name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
2092 base = xis->base;
2093 } else {
2094 int i, block_off;
2095 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
2096 xe = xbs->here;
2097 name_offset = le16_to_cpu(xe->xe_name_offset);
2098 name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
2099 i = xbs->here - xbs->header->xh_entries;
2100 old_in_xb = 1;
2101
2102 if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
2103 ret = ocfs2_xattr_bucket_get_name_value(inode,
2104 bucket_xh(xbs->bucket),
2105 i, &block_off,
2106 &name_offset);
2107 base = bucket_block(xbs->bucket, block_off);
2108 } else
2109 base = xbs->base;
2110 }
2111
2112 /* do cluster allocation guess first. */
2113 value_size = le64_to_cpu(xe->xe_value_size);
2114
2115 if (old_in_xb) {
2116 /*
2117 * In xattr set, we always try to set the xe in inode first,
2118 * so if it can be inserted into inode successfully, the old
2119 * one will be removed from the xattr block, and this xattr
2120 * will be inserted into inode as a new xattr in inode.
2121 */
2122 if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) {
2123 clusters_add += new_clusters;
2124 goto out;
2125 }
2126 }
2127
2128 if (xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
2129 /* the new values will be stored outside. */
2130 u32 old_clusters = 0;
2131
2132 if (!ocfs2_xattr_is_local(xe)) {
2133 old_clusters = ocfs2_clusters_for_bytes(inode->i_sb,
2134 value_size);
2135 xv = (struct ocfs2_xattr_value_root *)
2136 (base + name_offset + name_len);
2137 } else
2138 xv = &def_xv.xv;
2139
2140 if (old_clusters >= new_clusters)
2141 goto out;
2142 else {
2143 meta_add += ocfs2_extend_meta_needed(&xv->xr_list);
2144 clusters_add += new_clusters - old_clusters;
2145 goto out;
2146 }
2147 } else {
2148 /*
2149 * Now the new value will be stored inside. So if the new
2150 * value is smaller than the size of value root or the old
2151 * value, we don't need any allocation, otherwise we have
2152 * to guess metadata allocation.
2153 */
2154 if ((ocfs2_xattr_is_local(xe) && value_size >= xi->value_len) ||
2155 (!ocfs2_xattr_is_local(xe) &&
2156 OCFS2_XATTR_ROOT_SIZE >= xi->value_len))
2157 goto out;
2158 }
2159
2160meta_guess:
2161 /* calculate metadata allocation. */
2162 if (di->i_xattr_loc) {
2163 if (!xbs->xattr_bh) {
2164 ret = ocfs2_read_block(inode,
2165 le64_to_cpu(di->i_xattr_loc),
2166 &bh);
2167 if (ret) {
2168 mlog_errno(ret);
2169 goto out;
2170 }
2171
2172 xb = (struct ocfs2_xattr_block *)bh->b_data;
2173 } else
2174 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
2175
2176 if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
2177 struct ocfs2_extent_list *el =
2178 &xb->xb_attrs.xb_root.xt_list;
2179 meta_add += ocfs2_extend_meta_needed(el);
2180 }
2181
2182 /*
2183 * This cluster will be used either for new bucket or for
2184 * new xattr block.
2185 * If the cluster size is the same as the bucket size, one
2186 * more is needed since we may need to extend the bucket
2187 * also.
2188 */
2189 clusters_add += 1;
2190 if (OCFS2_XATTR_BUCKET_SIZE ==
2191 OCFS2_SB(inode->i_sb)->s_clustersize)
2192 clusters_add += 1;
2193 } else
2194 meta_add += 1;
2195out:
2196 if (clusters_need)
2197 *clusters_need = clusters_add;
2198 if (meta_need)
2199 *meta_need = meta_add;
2200 brelse(bh);
2201 return ret;
2202}
2203
2204static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
2205 struct ocfs2_dinode *di,
2206 struct ocfs2_xattr_info *xi,
2207 struct ocfs2_xattr_search *xis,
2208 struct ocfs2_xattr_search *xbs,
2209 struct ocfs2_xattr_set_ctxt *ctxt)
2210{
2211 int clusters_add, meta_add, ret;
2212 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2213
2214 memset(ctxt, 0, sizeof(struct ocfs2_xattr_set_ctxt));
2215
2216 ocfs2_init_dealloc_ctxt(&ctxt->dealloc);
2217
2218 ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs,
2219 &clusters_add, &meta_add);
2220 if (ret) {
2221 mlog_errno(ret);
2222 return ret;
2223 }
2224
2225 mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d\n",
2226 xi->name, meta_add, clusters_add);
2227
2228 if (meta_add) {
2229 ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
2230 &ctxt->meta_ac);
2231 if (ret) {
2232 mlog_errno(ret);
2233 goto out;
2234 }
2235 }
2236
2237 if (clusters_add) {
2238 ret = ocfs2_reserve_clusters(osb, clusters_add, &ctxt->data_ac);
2239 if (ret)
2240 mlog_errno(ret);
2241 }
2242out:
2243 if (ret) {
2244 if (ctxt->meta_ac) {
2245 ocfs2_free_alloc_context(ctxt->meta_ac);
2246 ctxt->meta_ac = NULL;
2247 }
2248
2249 /*
2250 * We cannot have an error and a non null ctxt->data_ac.
2251 */
2252 }
2253
2254 return ret;
2255}
2256
2037/* 2257/*
2038 * ocfs2_xattr_set() 2258 * ocfs2_xattr_set()
2039 * 2259 *
@@ -2051,6 +2271,8 @@ int ocfs2_xattr_set(struct inode *inode,
2051 struct buffer_head *di_bh = NULL; 2271 struct buffer_head *di_bh = NULL;
2052 struct ocfs2_dinode *di; 2272 struct ocfs2_dinode *di;
2053 int ret; 2273 int ret;
2274 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2275 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
2054 2276
2055 struct ocfs2_xattr_info xi = { 2277 struct ocfs2_xattr_info xi = {
2056 .name_index = name_index, 2278 .name_index = name_index,
@@ -2115,15 +2337,21 @@ int ocfs2_xattr_set(struct inode *inode,
2115 goto cleanup; 2337 goto cleanup;
2116 } 2338 }
2117 2339
2340 ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, &xbs, &ctxt);
2341 if (ret) {
2342 mlog_errno(ret);
2343 goto cleanup;
2344 }
2345
2118 if (!value) { 2346 if (!value) {
2119 /* Remove existing extended attribute */ 2347 /* Remove existing extended attribute */
2120 if (!xis.not_found) 2348 if (!xis.not_found)
2121 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis); 2349 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
2122 else if (!xbs.not_found) 2350 else if (!xbs.not_found)
2123 ret = ocfs2_xattr_block_set(inode, &xi, &xbs); 2351 ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
2124 } else { 2352 } else {
2125 /* We always try to set extended attribute into inode first*/ 2353 /* We always try to set extended attribute into inode first*/
2126 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis); 2354 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
2127 if (!ret && !xbs.not_found) { 2355 if (!ret && !xbs.not_found) {
2128 /* 2356 /*
2129 * If succeed and that extended attribute existing in 2357 * If succeed and that extended attribute existing in
@@ -2131,7 +2359,7 @@ int ocfs2_xattr_set(struct inode *inode,
2131 */ 2359 */
2132 xi.value = NULL; 2360 xi.value = NULL;
2133 xi.value_len = 0; 2361 xi.value_len = 0;
2134 ret = ocfs2_xattr_block_set(inode, &xi, &xbs); 2362 ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
2135 } else if (ret == -ENOSPC) { 2363 } else if (ret == -ENOSPC) {
2136 if (di->i_xattr_loc && !xbs.xattr_bh) { 2364 if (di->i_xattr_loc && !xbs.xattr_bh) {
2137 ret = ocfs2_xattr_block_find(inode, name_index, 2365 ret = ocfs2_xattr_block_find(inode, name_index,
@@ -2143,9 +2371,9 @@ int ocfs2_xattr_set(struct inode *inode,
2143 * If no space in inode, we will set extended attribute 2371 * If no space in inode, we will set extended attribute
2144 * into external block. 2372 * into external block.
2145 */ 2373 */
2146 ret = ocfs2_xattr_block_set(inode, &xi, &xbs); 2374 ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
2147 if (ret) 2375 if (ret)
2148 goto cleanup; 2376 goto free;
2149 if (!xis.not_found) { 2377 if (!xis.not_found) {
2150 /* 2378 /*
2151 * If succeed and that extended attribute 2379 * If succeed and that extended attribute
@@ -2153,10 +2381,19 @@ int ocfs2_xattr_set(struct inode *inode,
2153 */ 2381 */
2154 xi.value = NULL; 2382 xi.value = NULL;
2155 xi.value_len = 0; 2383 xi.value_len = 0;
2156 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis); 2384 ret = ocfs2_xattr_ibody_set(inode, &xi,
2385 &xis, &ctxt);
2157 } 2386 }
2158 } 2387 }
2159 } 2388 }
2389free:
2390 if (ctxt.data_ac)
2391 ocfs2_free_alloc_context(ctxt.data_ac);
2392 if (ctxt.meta_ac)
2393 ocfs2_free_alloc_context(ctxt.meta_ac);
2394 if (ocfs2_dealloc_has_cluster(&ctxt.dealloc))
2395 ocfs2_schedule_truncate_log_flush(osb, 1);
2396 ocfs2_run_deallocs(osb, &ctxt.dealloc);
2160cleanup: 2397cleanup:
2161 up_write(&OCFS2_I(inode)->ip_xattr_sem); 2398 up_write(&OCFS2_I(inode)->ip_xattr_sem);
2162 ocfs2_inode_unlock(inode, 1); 2399 ocfs2_inode_unlock(inode, 1);
@@ -2734,7 +2971,8 @@ static void ocfs2_xattr_update_xattr_search(struct inode *inode,
2734} 2971}
2735 2972
2736static int ocfs2_xattr_create_index_block(struct inode *inode, 2973static int ocfs2_xattr_create_index_block(struct inode *inode,
2737 struct ocfs2_xattr_search *xs) 2974 struct ocfs2_xattr_search *xs,
2975 struct ocfs2_xattr_set_ctxt *ctxt)
2738{ 2976{
2739 int ret, credits = OCFS2_SUBALLOC_ALLOC; 2977 int ret, credits = OCFS2_SUBALLOC_ALLOC;
2740 u32 bit_off, len; 2978 u32 bit_off, len;
@@ -2742,7 +2980,6 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
2742 handle_t *handle; 2980 handle_t *handle;
2743 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 2981 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2744 struct ocfs2_inode_info *oi = OCFS2_I(inode); 2982 struct ocfs2_inode_info *oi = OCFS2_I(inode);
2745 struct ocfs2_alloc_context *data_ac;
2746 struct buffer_head *xb_bh = xs->xattr_bh; 2983 struct buffer_head *xb_bh = xs->xattr_bh;
2747 struct ocfs2_xattr_block *xb = 2984 struct ocfs2_xattr_block *xb =
2748 (struct ocfs2_xattr_block *)xb_bh->b_data; 2985 (struct ocfs2_xattr_block *)xb_bh->b_data;
@@ -2755,12 +2992,6 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
2755 BUG_ON(xb_flags & OCFS2_XATTR_INDEXED); 2992 BUG_ON(xb_flags & OCFS2_XATTR_INDEXED);
2756 BUG_ON(!xs->bucket); 2993 BUG_ON(!xs->bucket);
2757 2994
2758 ret = ocfs2_reserve_clusters(osb, 1, &data_ac);
2759 if (ret) {
2760 mlog_errno(ret);
2761 goto out;
2762 }
2763
2764 /* 2995 /*
2765 * XXX: 2996 * XXX:
2766 * We can use this lock for now, and maybe move to a dedicated mutex 2997 * We can use this lock for now, and maybe move to a dedicated mutex
@@ -2787,7 +3018,8 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
2787 goto out_commit; 3018 goto out_commit;
2788 } 3019 }
2789 3020
2790 ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, &len); 3021 ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac,
3022 1, 1, &bit_off, &len);
2791 if (ret) { 3023 if (ret) {
2792 mlog_errno(ret); 3024 mlog_errno(ret);
2793 goto out_commit; 3025 goto out_commit;
@@ -2850,10 +3082,6 @@ out_commit:
2850out_sem: 3082out_sem:
2851 up_write(&oi->ip_alloc_sem); 3083 up_write(&oi->ip_alloc_sem);
2852 3084
2853out:
2854 if (data_ac)
2855 ocfs2_free_alloc_context(data_ac);
2856
2857 return ret; 3085 return ret;
2858} 3086}
2859 3087
@@ -3614,7 +3842,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3614 u32 *num_clusters, 3842 u32 *num_clusters,
3615 u32 prev_cpos, 3843 u32 prev_cpos,
3616 u64 prev_blkno, 3844 u64 prev_blkno,
3617 int *extend) 3845 int *extend,
3846 struct ocfs2_xattr_set_ctxt *ctxt)
3618{ 3847{
3619 int ret, credits; 3848 int ret, credits;
3620 u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1); 3849 u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
@@ -3622,8 +3851,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3622 u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0; 3851 u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0;
3623 u64 block; 3852 u64 block;
3624 handle_t *handle = NULL; 3853 handle_t *handle = NULL;
3625 struct ocfs2_alloc_context *data_ac = NULL;
3626 struct ocfs2_alloc_context *meta_ac = NULL;
3627 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3854 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3628 struct ocfs2_extent_tree et; 3855 struct ocfs2_extent_tree et;
3629 3856
@@ -3634,13 +3861,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3634 3861
3635 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); 3862 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
3636 3863
3637 ret = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
3638 &data_ac, &meta_ac);
3639 if (ret) {
3640 mlog_errno(ret);
3641 goto leave;
3642 }
3643
3644 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el, 3864 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
3645 clusters_to_add); 3865 clusters_to_add);
3646 handle = ocfs2_start_trans(osb, credits); 3866 handle = ocfs2_start_trans(osb, credits);
@@ -3658,7 +3878,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3658 goto leave; 3878 goto leave;
3659 } 3879 }
3660 3880
3661 ret = __ocfs2_claim_clusters(osb, handle, data_ac, 1, 3881 ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac, 1,
3662 clusters_to_add, &bit_off, &num_bits); 3882 clusters_to_add, &bit_off, &num_bits);
3663 if (ret < 0) { 3883 if (ret < 0) {
3664 if (ret != -ENOSPC) 3884 if (ret != -ENOSPC)
@@ -3719,7 +3939,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3719 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", 3939 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
3720 num_bits, (unsigned long long)block, v_start); 3940 num_bits, (unsigned long long)block, v_start);
3721 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block, 3941 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block,
3722 num_bits, 0, meta_ac); 3942 num_bits, 0, ctxt->meta_ac);
3723 if (ret < 0) { 3943 if (ret < 0) {
3724 mlog_errno(ret); 3944 mlog_errno(ret);
3725 goto leave; 3945 goto leave;
@@ -3734,10 +3954,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3734leave: 3954leave:
3735 if (handle) 3955 if (handle)
3736 ocfs2_commit_trans(osb, handle); 3956 ocfs2_commit_trans(osb, handle);
3737 if (data_ac)
3738 ocfs2_free_alloc_context(data_ac);
3739 if (meta_ac)
3740 ocfs2_free_alloc_context(meta_ac);
3741 3957
3742 return ret; 3958 return ret;
3743} 3959}
@@ -3821,7 +4037,8 @@ out:
3821 */ 4037 */
3822static int ocfs2_add_new_xattr_bucket(struct inode *inode, 4038static int ocfs2_add_new_xattr_bucket(struct inode *inode,
3823 struct buffer_head *xb_bh, 4039 struct buffer_head *xb_bh,
3824 struct buffer_head *header_bh) 4040 struct buffer_head *header_bh,
4041 struct ocfs2_xattr_set_ctxt *ctxt)
3825{ 4042{
3826 struct ocfs2_xattr_header *first_xh = NULL; 4043 struct ocfs2_xattr_header *first_xh = NULL;
3827 struct buffer_head *first_bh = NULL; 4044 struct buffer_head *first_bh = NULL;
@@ -3872,7 +4089,8 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
3872 &num_clusters, 4089 &num_clusters,
3873 e_cpos, 4090 e_cpos,
3874 p_blkno, 4091 p_blkno,
3875 &extend); 4092 &extend,
4093 ctxt);
3876 if (ret) { 4094 if (ret) {
3877 mlog_errno(ret); 4095 mlog_errno(ret);
3878 goto out; 4096 goto out;
@@ -4147,7 +4365,8 @@ out:
4147static int ocfs2_xattr_bucket_value_truncate(struct inode *inode, 4365static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4148 struct buffer_head *header_bh, 4366 struct buffer_head *header_bh,
4149 int xe_off, 4367 int xe_off,
4150 int len) 4368 int len,
4369 struct ocfs2_xattr_set_ctxt *ctxt)
4151{ 4370{
4152 int ret, offset; 4371 int ret, offset;
4153 u64 value_blk; 4372 u64 value_blk;
@@ -4182,7 +4401,7 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4182 4401
4183 mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n", 4402 mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n",
4184 xe_off, (unsigned long long)header_bh->b_blocknr, len); 4403 xe_off, (unsigned long long)header_bh->b_blocknr, len);
4185 ret = ocfs2_xattr_value_truncate(inode, value_bh, xv, len); 4404 ret = ocfs2_xattr_value_truncate(inode, value_bh, xv, len, ctxt);
4186 if (ret) { 4405 if (ret) {
4187 mlog_errno(ret); 4406 mlog_errno(ret);
4188 goto out; 4407 goto out;
@@ -4200,8 +4419,9 @@ out:
4200} 4419}
4201 4420
4202static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode, 4421static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
4203 struct ocfs2_xattr_search *xs, 4422 struct ocfs2_xattr_search *xs,
4204 int len) 4423 int len,
4424 struct ocfs2_xattr_set_ctxt *ctxt)
4205{ 4425{
4206 int ret, offset; 4426 int ret, offset;
4207 struct ocfs2_xattr_entry *xe = xs->here; 4427 struct ocfs2_xattr_entry *xe = xs->here;
@@ -4211,7 +4431,7 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
4211 4431
4212 offset = xe - xh->xh_entries; 4432 offset = xe - xh->xh_entries;
4213 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket->bu_bhs[0], 4433 ret = ocfs2_xattr_bucket_value_truncate(inode, xs->bucket->bu_bhs[0],
4214 offset, len); 4434 offset, len, ctxt);
4215 if (ret) 4435 if (ret)
4216 mlog_errno(ret); 4436 mlog_errno(ret);
4217 4437
@@ -4375,7 +4595,8 @@ out_commit:
4375 */ 4595 */
4376static int ocfs2_xattr_set_in_bucket(struct inode *inode, 4596static int ocfs2_xattr_set_in_bucket(struct inode *inode,
4377 struct ocfs2_xattr_info *xi, 4597 struct ocfs2_xattr_info *xi,
4378 struct ocfs2_xattr_search *xs) 4598 struct ocfs2_xattr_search *xs,
4599 struct ocfs2_xattr_set_ctxt *ctxt)
4379{ 4600{
4380 int ret, local = 1; 4601 int ret, local = 1;
4381 size_t value_len; 4602 size_t value_len;
@@ -4403,7 +4624,8 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
4403 value_len = 0; 4624 value_len = 0;
4404 4625
4405 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs, 4626 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
4406 value_len); 4627 value_len,
4628 ctxt);
4407 if (ret) 4629 if (ret)
4408 goto out; 4630 goto out;
4409 4631
@@ -4434,7 +4656,7 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
4434 4656
4435 /* allocate the space now for the outside block storage. */ 4657 /* allocate the space now for the outside block storage. */
4436 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs, 4658 ret = ocfs2_xattr_bucket_value_truncate_xs(inode, xs,
4437 value_len); 4659 value_len, ctxt);
4438 if (ret) { 4660 if (ret) {
4439 mlog_errno(ret); 4661 mlog_errno(ret);
4440 4662
@@ -4485,7 +4707,8 @@ static int ocfs2_check_xattr_bucket_collision(struct inode *inode,
4485 4707
4486static int ocfs2_xattr_set_entry_index_block(struct inode *inode, 4708static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
4487 struct ocfs2_xattr_info *xi, 4709 struct ocfs2_xattr_info *xi,
4488 struct ocfs2_xattr_search *xs) 4710 struct ocfs2_xattr_search *xs,
4711 struct ocfs2_xattr_set_ctxt *ctxt)
4489{ 4712{
4490 struct ocfs2_xattr_header *xh; 4713 struct ocfs2_xattr_header *xh;
4491 struct ocfs2_xattr_entry *xe; 4714 struct ocfs2_xattr_entry *xe;
@@ -4603,7 +4826,8 @@ try_again:
4603 4826
4604 ret = ocfs2_add_new_xattr_bucket(inode, 4827 ret = ocfs2_add_new_xattr_bucket(inode,
4605 xs->xattr_bh, 4828 xs->xattr_bh,
4606 xs->bucket->bu_bhs[0]); 4829 xs->bucket->bu_bhs[0],
4830 ctxt);
4607 if (ret) { 4831 if (ret) {
4608 mlog_errno(ret); 4832 mlog_errno(ret);
4609 goto out; 4833 goto out;
@@ -4622,7 +4846,7 @@ try_again:
4622 } 4846 }
4623 4847
4624xattr_set: 4848xattr_set:
4625 ret = ocfs2_xattr_set_in_bucket(inode, xi, xs); 4849 ret = ocfs2_xattr_set_in_bucket(inode, xi, xs, ctxt);
4626out: 4850out:
4627 mlog_exit(ret); 4851 mlog_exit(ret);
4628 return ret; 4852 return ret;
@@ -4636,6 +4860,10 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
4636 struct ocfs2_xattr_header *xh = bucket_xh(bucket); 4860 struct ocfs2_xattr_header *xh = bucket_xh(bucket);
4637 u16 i; 4861 u16 i;
4638 struct ocfs2_xattr_entry *xe; 4862 struct ocfs2_xattr_entry *xe;
4863 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4864 struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,};
4865
4866 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
4639 4867
4640 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { 4868 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
4641 xe = &xh->xh_entries[i]; 4869 xe = &xh->xh_entries[i];
@@ -4644,13 +4872,16 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
4644 4872
4645 ret = ocfs2_xattr_bucket_value_truncate(inode, 4873 ret = ocfs2_xattr_bucket_value_truncate(inode,
4646 bucket->bu_bhs[0], 4874 bucket->bu_bhs[0],
4647 i, 0); 4875 i, 0, &ctxt);
4648 if (ret) { 4876 if (ret) {
4649 mlog_errno(ret); 4877 mlog_errno(ret);
4650 break; 4878 break;
4651 } 4879 }
4652 } 4880 }
4653 4881
4882 ocfs2_schedule_truncate_log_flush(osb, 1);
4883 ocfs2_run_deallocs(osb, &ctxt.dealloc);
4884
4654 return ret; 4885 return ret;
4655} 4886}
4656 4887