aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2008-11-11 19:27:01 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:34:19 -0500
commit85db90e77806d48a19fda77dabe8897d369a1710 (patch)
treedaaceb3943214b83b7784e8f4170c5321d69ea5f
parent78f30c314a74b9dc5d7368d96fe4be883d9a3a04 (diff)
ocfs2/xattr: Merge xattr set transaction.
In current ocfs2/xattr, the whole xattr set is divided into many steps are many transaction are used, this make the xattr set process isn't like a real transaction, so this patch try to merge all the transaction into one. Another benefit is that acl can use it easily now. I don't merge the transaction of deleting xattr when we remove an inode. The reason is that if we have a large number of xattrs and every xattrs has large values(large enough for outside storage), the whole transaction will be very huge and it looks like jbd can't handle it(I meet with a jbd complain once). And the old inode removal is also divided into many steps, so I'd like to leave as it is. Note: In xattr set, I try to avoid ocfs2_extend_trans since if the credits aren't enough for the extension, it will commit all the dirty blocks and create a new transaction which may lead to inconsistency in metadata. All ocfs2_extend_trans remained are safe now. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r--fs/ocfs2/xattr.c673
1 files changed, 325 insertions, 348 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 4fd201a54c72..7a9089255a87 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -72,6 +72,7 @@ struct ocfs2_xattr_bucket {
72}; 72};
73 73
74struct ocfs2_xattr_set_ctxt { 74struct ocfs2_xattr_set_ctxt {
75 handle_t *handle;
75 struct ocfs2_alloc_context *meta_ac; 76 struct ocfs2_alloc_context *meta_ac;
76 struct ocfs2_alloc_context *data_ac; 77 struct ocfs2_alloc_context *data_ac;
77 struct ocfs2_cached_dealloc_ctxt dealloc; 78 struct ocfs2_cached_dealloc_ctxt dealloc;
@@ -346,9 +347,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
346 struct ocfs2_xattr_set_ctxt *ctxt) 347 struct ocfs2_xattr_set_ctxt *ctxt)
347{ 348{
348 int status = 0; 349 int status = 0;
349 int restart_func = 0; 350 handle_t *handle = ctxt->handle;
350 int credits = 0;
351 handle_t *handle = NULL;
352 enum ocfs2_alloc_restarted why; 351 enum ocfs2_alloc_restarted why;
353 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 352 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
354 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters); 353 u32 prev_clusters, logical_start = le32_to_cpu(xv->xr_clusters);
@@ -358,19 +357,6 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
358 357
359 ocfs2_init_xattr_value_extent_tree(&et, inode, xattr_bh, xv); 358 ocfs2_init_xattr_value_extent_tree(&et, inode, xattr_bh, xv);
360 359
361restart_all:
362
363 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
364 clusters_to_add);
365 handle = ocfs2_start_trans(osb, credits);
366 if (IS_ERR(handle)) {
367 status = PTR_ERR(handle);
368 handle = NULL;
369 mlog_errno(status);
370 goto leave;
371 }
372
373restarted_transaction:
374 status = ocfs2_journal_access(handle, inode, xattr_bh, 360 status = ocfs2_journal_access(handle, inode, xattr_bh,
375 OCFS2_JOURNAL_ACCESS_WRITE); 361 OCFS2_JOURNAL_ACCESS_WRITE);
376 if (status < 0) { 362 if (status < 0) {
@@ -389,9 +375,8 @@ restarted_transaction:
389 ctxt->data_ac, 375 ctxt->data_ac,
390 ctxt->meta_ac, 376 ctxt->meta_ac,
391 &why); 377 &why);
392 if ((status < 0) && (status != -EAGAIN)) { 378 if (status < 0) {
393 if (status != -ENOSPC) 379 mlog_errno(status);
394 mlog_errno(status);
395 goto leave; 380 goto leave;
396 } 381 }
397 382
@@ -403,39 +388,13 @@ restarted_transaction:
403 388
404 clusters_to_add -= le32_to_cpu(xv->xr_clusters) - prev_clusters; 389 clusters_to_add -= le32_to_cpu(xv->xr_clusters) - prev_clusters;
405 390
406 if (why != RESTART_NONE && clusters_to_add) { 391 /*
407 if (why == RESTART_META) { 392 * We should have already allocated enough space before the transaction,
408 mlog(0, "restarting function.\n"); 393 * so no need to restart.
409 restart_func = 1; 394 */
410 } else { 395 BUG_ON(why != RESTART_NONE || clusters_to_add);
411 BUG_ON(why != RESTART_TRANS);
412
413 mlog(0, "restarting transaction.\n");
414 /* TODO: This can be more intelligent. */
415 credits = ocfs2_calc_extend_credits(osb->sb,
416 et.et_root_el,
417 clusters_to_add);
418 status = ocfs2_extend_trans(handle, credits);
419 if (status < 0) {
420 /* handle still has to be committed at
421 * this point. */
422 status = -ENOMEM;
423 mlog_errno(status);
424 goto leave;
425 }
426 goto restarted_transaction;
427 }
428 }
429 396
430leave: 397leave:
431 if (handle) {
432 ocfs2_commit_trans(osb, handle);
433 handle = NULL;
434 }
435 if ((!status) && restart_func) {
436 restart_func = 0;
437 goto restart_all;
438 }
439 398
440 return status; 399 return status;
441} 400}
@@ -448,31 +407,23 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
448{ 407{
449 int ret; 408 int ret;
450 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); 409 u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
451 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 410 handle_t *handle = ctxt->handle;
452 handle_t *handle;
453 struct ocfs2_extent_tree et; 411 struct ocfs2_extent_tree et;
454 412
455 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv); 413 ocfs2_init_xattr_value_extent_tree(&et, inode, root_bh, xv);
456 414
457 handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
458 if (IS_ERR(handle)) {
459 ret = PTR_ERR(handle);
460 mlog_errno(ret);
461 goto out;
462 }
463
464 ret = ocfs2_journal_access(handle, inode, root_bh, 415 ret = ocfs2_journal_access(handle, inode, root_bh,
465 OCFS2_JOURNAL_ACCESS_WRITE); 416 OCFS2_JOURNAL_ACCESS_WRITE);
466 if (ret) { 417 if (ret) {
467 mlog_errno(ret); 418 mlog_errno(ret);
468 goto out_commit; 419 goto out;
469 } 420 }
470 421
471 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac, 422 ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac,
472 &ctxt->dealloc); 423 &ctxt->dealloc);
473 if (ret) { 424 if (ret) {
474 mlog_errno(ret); 425 mlog_errno(ret);
475 goto out_commit; 426 goto out;
476 } 427 }
477 428
478 le32_add_cpu(&xv->xr_clusters, -len); 429 le32_add_cpu(&xv->xr_clusters, -len);
@@ -480,15 +431,13 @@ static int __ocfs2_remove_xattr_range(struct inode *inode,
480 ret = ocfs2_journal_dirty(handle, root_bh); 431 ret = ocfs2_journal_dirty(handle, root_bh);
481 if (ret) { 432 if (ret) {
482 mlog_errno(ret); 433 mlog_errno(ret);
483 goto out_commit; 434 goto out;
484 } 435 }
485 436
486 ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len); 437 ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len);
487 if (ret) 438 if (ret)
488 mlog_errno(ret); 439 mlog_errno(ret);
489 440
490out_commit:
491 ocfs2_commit_trans(osb, handle);
492out: 441out:
493 return ret; 442 return ret;
494} 443}
@@ -975,6 +924,7 @@ static int ocfs2_xattr_get(struct inode *inode,
975} 924}
976 925
977static int __ocfs2_xattr_set_value_outside(struct inode *inode, 926static int __ocfs2_xattr_set_value_outside(struct inode *inode,
927 handle_t *handle,
978 struct ocfs2_xattr_value_root *xv, 928 struct ocfs2_xattr_value_root *xv,
979 const void *value, 929 const void *value,
980 int value_len) 930 int value_len)
@@ -986,14 +936,17 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
986 u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len); 936 u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len);
987 u64 blkno; 937 u64 blkno;
988 struct buffer_head *bh = NULL; 938 struct buffer_head *bh = NULL;
989 handle_t *handle;
990 939
991 BUG_ON(clusters > le32_to_cpu(xv->xr_clusters)); 940 BUG_ON(clusters > le32_to_cpu(xv->xr_clusters));
992 941
942 /*
943 * In __ocfs2_xattr_set_value_outside has already been dirtied,
944 * so we don't need to worry about whether ocfs2_extend_trans
945 * will create a new transactio for us or not.
946 */
993 credits = clusters * bpc; 947 credits = clusters * bpc;
994 handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb), credits); 948 ret = ocfs2_extend_trans(handle, credits);
995 if (IS_ERR(handle)) { 949 if (ret) {
996 ret = PTR_ERR(handle);
997 mlog_errno(ret); 950 mlog_errno(ret);
998 goto out; 951 goto out;
999 } 952 }
@@ -1003,7 +956,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
1003 &num_clusters, &xv->xr_list); 956 &num_clusters, &xv->xr_list);
1004 if (ret) { 957 if (ret) {
1005 mlog_errno(ret); 958 mlog_errno(ret);
1006 goto out_commit; 959 goto out;
1007 } 960 }
1008 961
1009 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); 962 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
@@ -1012,7 +965,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
1012 ret = ocfs2_read_block(inode, blkno, &bh); 965 ret = ocfs2_read_block(inode, blkno, &bh);
1013 if (ret) { 966 if (ret) {
1014 mlog_errno(ret); 967 mlog_errno(ret);
1015 goto out_commit; 968 goto out;
1016 } 969 }
1017 970
1018 ret = ocfs2_journal_access(handle, 971 ret = ocfs2_journal_access(handle,
@@ -1021,7 +974,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
1021 OCFS2_JOURNAL_ACCESS_WRITE); 974 OCFS2_JOURNAL_ACCESS_WRITE);
1022 if (ret < 0) { 975 if (ret < 0) {
1023 mlog_errno(ret); 976 mlog_errno(ret);
1024 goto out_commit; 977 goto out;
1025 } 978 }
1026 979
1027 cp_len = value_len > blocksize ? blocksize : value_len; 980 cp_len = value_len > blocksize ? blocksize : value_len;
@@ -1035,7 +988,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
1035 ret = ocfs2_journal_dirty(handle, bh); 988 ret = ocfs2_journal_dirty(handle, bh);
1036 if (ret < 0) { 989 if (ret < 0) {
1037 mlog_errno(ret); 990 mlog_errno(ret);
1038 goto out_commit; 991 goto out;
1039 } 992 }
1040 brelse(bh); 993 brelse(bh);
1041 bh = NULL; 994 bh = NULL;
@@ -1049,8 +1002,6 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
1049 } 1002 }
1050 cpos += num_clusters; 1003 cpos += num_clusters;
1051 } 1004 }
1052out_commit:
1053 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1054out: 1005out:
1055 brelse(bh); 1006 brelse(bh);
1056 1007
@@ -1058,28 +1009,21 @@ out:
1058} 1009}
1059 1010
1060static int ocfs2_xattr_cleanup(struct inode *inode, 1011static int ocfs2_xattr_cleanup(struct inode *inode,
1012 handle_t *handle,
1061 struct ocfs2_xattr_info *xi, 1013 struct ocfs2_xattr_info *xi,
1062 struct ocfs2_xattr_search *xs, 1014 struct ocfs2_xattr_search *xs,
1063 size_t offs) 1015 size_t offs)
1064{ 1016{
1065 handle_t *handle = NULL;
1066 int ret = 0; 1017 int ret = 0;
1067 size_t name_len = strlen(xi->name); 1018 size_t name_len = strlen(xi->name);
1068 void *val = xs->base + offs; 1019 void *val = xs->base + offs;
1069 size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE; 1020 size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE;
1070 1021
1071 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
1072 OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
1073 if (IS_ERR(handle)) {
1074 ret = PTR_ERR(handle);
1075 mlog_errno(ret);
1076 goto out;
1077 }
1078 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh, 1022 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
1079 OCFS2_JOURNAL_ACCESS_WRITE); 1023 OCFS2_JOURNAL_ACCESS_WRITE);
1080 if (ret) { 1024 if (ret) {
1081 mlog_errno(ret); 1025 mlog_errno(ret);
1082 goto out_commit; 1026 goto out;
1083 } 1027 }
1084 /* Decrease xattr count */ 1028 /* Decrease xattr count */
1085 le16_add_cpu(&xs->header->xh_count, -1); 1029 le16_add_cpu(&xs->header->xh_count, -1);
@@ -1090,32 +1034,23 @@ static int ocfs2_xattr_cleanup(struct inode *inode,
1090 ret = ocfs2_journal_dirty(handle, xs->xattr_bh); 1034 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
1091 if (ret < 0) 1035 if (ret < 0)
1092 mlog_errno(ret); 1036 mlog_errno(ret);
1093out_commit:
1094 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1095out: 1037out:
1096 return ret; 1038 return ret;
1097} 1039}
1098 1040
1099static int ocfs2_xattr_update_entry(struct inode *inode, 1041static int ocfs2_xattr_update_entry(struct inode *inode,
1042 handle_t *handle,
1100 struct ocfs2_xattr_info *xi, 1043 struct ocfs2_xattr_info *xi,
1101 struct ocfs2_xattr_search *xs, 1044 struct ocfs2_xattr_search *xs,
1102 size_t offs) 1045 size_t offs)
1103{ 1046{
1104 handle_t *handle = NULL; 1047 int ret;
1105 int ret = 0;
1106 1048
1107 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
1108 OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
1109 if (IS_ERR(handle)) {
1110 ret = PTR_ERR(handle);
1111 mlog_errno(ret);
1112 goto out;
1113 }
1114 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh, 1049 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
1115 OCFS2_JOURNAL_ACCESS_WRITE); 1050 OCFS2_JOURNAL_ACCESS_WRITE);
1116 if (ret) { 1051 if (ret) {
1117 mlog_errno(ret); 1052 mlog_errno(ret);
1118 goto out_commit; 1053 goto out;
1119 } 1054 }
1120 1055
1121 xs->here->xe_name_offset = cpu_to_le16(offs); 1056 xs->here->xe_name_offset = cpu_to_le16(offs);
@@ -1129,8 +1064,6 @@ static int ocfs2_xattr_update_entry(struct inode *inode,
1129 ret = ocfs2_journal_dirty(handle, xs->xattr_bh); 1064 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
1130 if (ret < 0) 1065 if (ret < 0)
1131 mlog_errno(ret); 1066 mlog_errno(ret);
1132out_commit:
1133 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1134out: 1067out:
1135 return ret; 1068 return ret;
1136} 1069}
@@ -1168,13 +1101,13 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode,
1168 mlog_errno(ret); 1101 mlog_errno(ret);
1169 return ret; 1102 return ret;
1170 } 1103 }
1171 ret = __ocfs2_xattr_set_value_outside(inode, xv, xi->value, 1104 ret = ocfs2_xattr_update_entry(inode, ctxt->handle, xi, xs, offs);
1172 xi->value_len);
1173 if (ret < 0) { 1105 if (ret < 0) {
1174 mlog_errno(ret); 1106 mlog_errno(ret);
1175 return ret; 1107 return ret;
1176 } 1108 }
1177 ret = ocfs2_xattr_update_entry(inode, xi, xs, offs); 1109 ret = __ocfs2_xattr_set_value_outside(inode, ctxt->handle, xv,
1110 xi->value, xi->value_len);
1178 if (ret < 0) 1111 if (ret < 0)
1179 mlog_errno(ret); 1112 mlog_errno(ret);
1180 1113
@@ -1302,7 +1235,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1302 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; 1235 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1303 size_t min_offs = xs->end - xs->base, name_len = strlen(xi->name); 1236 size_t min_offs = xs->end - xs->base, name_len = strlen(xi->name);
1304 size_t size_l = 0; 1237 size_t size_l = 0;
1305 handle_t *handle = NULL; 1238 handle_t *handle = ctxt->handle;
1306 int free, i, ret; 1239 int free, i, ret;
1307 struct ocfs2_xattr_info xi_l = { 1240 struct ocfs2_xattr_info xi_l = {
1308 .name_index = xi->name_index, 1241 .name_index = xi->name_index,
@@ -1391,19 +1324,21 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1391 goto out; 1324 goto out;
1392 } 1325 }
1393 1326
1394 ret = __ocfs2_xattr_set_value_outside(inode, 1327 ret = ocfs2_xattr_update_entry(inode,
1395 xv, 1328 handle,
1396 xi->value, 1329 xi,
1397 xi->value_len); 1330 xs,
1331 offs);
1398 if (ret < 0) { 1332 if (ret < 0) {
1399 mlog_errno(ret); 1333 mlog_errno(ret);
1400 goto out; 1334 goto out;
1401 } 1335 }
1402 1336
1403 ret = ocfs2_xattr_update_entry(inode, 1337 ret = __ocfs2_xattr_set_value_outside(inode,
1404 xi, 1338 handle,
1405 xs, 1339 xv,
1406 offs); 1340 xi->value,
1341 xi->value_len);
1407 if (ret < 0) 1342 if (ret < 0)
1408 mlog_errno(ret); 1343 mlog_errno(ret);
1409 goto out; 1344 goto out;
@@ -1413,45 +1348,29 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1413 * just trucate old value to zero. 1348 * just trucate old value to zero.
1414 */ 1349 */
1415 ret = ocfs2_xattr_value_truncate(inode, 1350 ret = ocfs2_xattr_value_truncate(inode,
1416 xs->xattr_bh, 1351 xs->xattr_bh,
1417 xv, 1352 xv,
1418 0, 1353 0,
1419 ctxt); 1354 ctxt);
1420 if (ret < 0) 1355 if (ret < 0)
1421 mlog_errno(ret); 1356 mlog_errno(ret);
1422 } 1357 }
1423 } 1358 }
1424 } 1359 }
1425 1360
1426 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
1427 OCFS2_INODE_UPDATE_CREDITS);
1428 if (IS_ERR(handle)) {
1429 ret = PTR_ERR(handle);
1430 mlog_errno(ret);
1431 goto out;
1432 }
1433
1434 ret = ocfs2_journal_access(handle, inode, xs->inode_bh, 1361 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
1435 OCFS2_JOURNAL_ACCESS_WRITE); 1362 OCFS2_JOURNAL_ACCESS_WRITE);
1436 if (ret) { 1363 if (ret) {
1437 mlog_errno(ret); 1364 mlog_errno(ret);
1438 goto out_commit; 1365 goto out;
1439 } 1366 }
1440 1367
1441 if (!(flag & OCFS2_INLINE_XATTR_FL)) { 1368 if (!(flag & OCFS2_INLINE_XATTR_FL)) {
1442 /* set extended attribute in external block. */
1443 ret = ocfs2_extend_trans(handle,
1444 OCFS2_INODE_UPDATE_CREDITS +
1445 OCFS2_XATTR_BLOCK_UPDATE_CREDITS);
1446 if (ret) {
1447 mlog_errno(ret);
1448 goto out_commit;
1449 }
1450 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh, 1369 ret = ocfs2_journal_access(handle, inode, xs->xattr_bh,
1451 OCFS2_JOURNAL_ACCESS_WRITE); 1370 OCFS2_JOURNAL_ACCESS_WRITE);
1452 if (ret) { 1371 if (ret) {
1453 mlog_errno(ret); 1372 mlog_errno(ret);
1454 goto out_commit; 1373 goto out;
1455 } 1374 }
1456 } 1375 }
1457 1376
@@ -1465,7 +1384,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1465 ret = ocfs2_journal_dirty(handle, xs->xattr_bh); 1384 ret = ocfs2_journal_dirty(handle, xs->xattr_bh);
1466 if (ret < 0) { 1385 if (ret < 0) {
1467 mlog_errno(ret); 1386 mlog_errno(ret);
1468 goto out_commit; 1387 goto out;
1469 } 1388 }
1470 } 1389 }
1471 1390
@@ -1502,9 +1421,6 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
1502 if (ret < 0) 1421 if (ret < 0)
1503 mlog_errno(ret); 1422 mlog_errno(ret);
1504 1423
1505out_commit:
1506 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
1507
1508 if (!ret && xi->value_len > OCFS2_XATTR_INLINE_SIZE) { 1424 if (!ret && xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
1509 /* 1425 /*
1510 * Set value outside in B tree. 1426 * Set value outside in B tree.
@@ -1520,14 +1436,14 @@ out_commit:
1520 * If set value outside failed, we have to clean 1436 * If set value outside failed, we have to clean
1521 * the junk tree root we have already set in local. 1437 * the junk tree root we have already set in local.
1522 */ 1438 */
1523 ret2 = ocfs2_xattr_cleanup(inode, xi, xs, offs); 1439 ret2 = ocfs2_xattr_cleanup(inode, ctxt->handle,
1440 xi, xs, offs);
1524 if (ret2 < 0) 1441 if (ret2 < 0)
1525 mlog_errno(ret2); 1442 mlog_errno(ret2);
1526 } 1443 }
1527 } 1444 }
1528out: 1445out:
1529 return ret; 1446 return ret;
1530
1531} 1447}
1532 1448
1533static int ocfs2_remove_value_outside(struct inode*inode, 1449static int ocfs2_remove_value_outside(struct inode*inode,
@@ -1540,6 +1456,13 @@ static int ocfs2_remove_value_outside(struct inode*inode,
1540 1456
1541 ocfs2_init_dealloc_ctxt(&ctxt.dealloc); 1457 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
1542 1458
1459 ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
1460 if (IS_ERR(ctxt.handle)) {
1461 ret = PTR_ERR(ctxt.handle);
1462 mlog_errno(ret);
1463 goto out;
1464 }
1465
1543 for (i = 0; i < le16_to_cpu(header->xh_count); i++) { 1466 for (i = 0; i < le16_to_cpu(header->xh_count); i++) {
1544 struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; 1467 struct ocfs2_xattr_entry *entry = &header->xh_entries[i];
1545 1468
@@ -1560,8 +1483,10 @@ static int ocfs2_remove_value_outside(struct inode*inode,
1560 } 1483 }
1561 } 1484 }
1562 1485
1486 ocfs2_commit_trans(osb, ctxt.handle);
1563 ocfs2_schedule_truncate_log_flush(osb, 1); 1487 ocfs2_schedule_truncate_log_flush(osb, 1);
1564 ocfs2_run_deallocs(osb, &ctxt.dealloc); 1488 ocfs2_run_deallocs(osb, &ctxt.dealloc);
1489out:
1565 return ret; 1490 return ret;
1566} 1491}
1567 1492
@@ -1920,7 +1845,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1920 struct buffer_head *new_bh = NULL; 1845 struct buffer_head *new_bh = NULL;
1921 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1846 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1922 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; 1847 struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data;
1923 handle_t *handle = NULL; 1848 handle_t *handle = ctxt->handle;
1924 struct ocfs2_xattr_block *xblk = NULL; 1849 struct ocfs2_xattr_block *xblk = NULL;
1925 u16 suballoc_bit_start; 1850 u16 suballoc_bit_start;
1926 u32 num_got; 1851 u32 num_got;
@@ -1928,18 +1853,11 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1928 int ret; 1853 int ret;
1929 1854
1930 if (!xs->xattr_bh) { 1855 if (!xs->xattr_bh) {
1931 handle = ocfs2_start_trans(osb,
1932 OCFS2_XATTR_BLOCK_CREATE_CREDITS);
1933 if (IS_ERR(handle)) {
1934 ret = PTR_ERR(handle);
1935 mlog_errno(ret);
1936 goto out;
1937 }
1938 ret = ocfs2_journal_access(handle, inode, xs->inode_bh, 1856 ret = ocfs2_journal_access(handle, inode, xs->inode_bh,
1939 OCFS2_JOURNAL_ACCESS_CREATE); 1857 OCFS2_JOURNAL_ACCESS_CREATE);
1940 if (ret < 0) { 1858 if (ret < 0) {
1941 mlog_errno(ret); 1859 mlog_errno(ret);
1942 goto out_commit; 1860 goto end;
1943 } 1861 }
1944 1862
1945 ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1, 1863 ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1,
@@ -1947,7 +1865,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1947 &first_blkno); 1865 &first_blkno);
1948 if (ret < 0) { 1866 if (ret < 0) {
1949 mlog_errno(ret); 1867 mlog_errno(ret);
1950 goto out_commit; 1868 goto end;
1951 } 1869 }
1952 1870
1953 new_bh = sb_getblk(inode->i_sb, first_blkno); 1871 new_bh = sb_getblk(inode->i_sb, first_blkno);
@@ -1957,7 +1875,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1957 OCFS2_JOURNAL_ACCESS_CREATE); 1875 OCFS2_JOURNAL_ACCESS_CREATE);
1958 if (ret < 0) { 1876 if (ret < 0) {
1959 mlog_errno(ret); 1877 mlog_errno(ret);
1960 goto out_commit; 1878 goto end;
1961 } 1879 }
1962 1880
1963 /* Initialize ocfs2_xattr_block */ 1881 /* Initialize ocfs2_xattr_block */
@@ -1978,17 +1896,10 @@ static int ocfs2_xattr_block_set(struct inode *inode,
1978 ret = ocfs2_journal_dirty(handle, new_bh); 1896 ret = ocfs2_journal_dirty(handle, new_bh);
1979 if (ret < 0) { 1897 if (ret < 0) {
1980 mlog_errno(ret); 1898 mlog_errno(ret);
1981 goto out_commit; 1899 goto end;
1982 } 1900 }
1983 di->i_xattr_loc = cpu_to_le64(first_blkno); 1901 di->i_xattr_loc = cpu_to_le64(first_blkno);
1984 ret = ocfs2_journal_dirty(handle, xs->inode_bh); 1902 ocfs2_journal_dirty(handle, xs->inode_bh);
1985 if (ret < 0)
1986 mlog_errno(ret);
1987out_commit:
1988 ocfs2_commit_trans(osb, handle);
1989out:
1990 if (ret < 0)
1991 return ret;
1992 } else 1903 } else
1993 xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; 1904 xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
1994 1905
@@ -2057,10 +1968,11 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2057 struct ocfs2_xattr_search *xis, 1968 struct ocfs2_xattr_search *xis,
2058 struct ocfs2_xattr_search *xbs, 1969 struct ocfs2_xattr_search *xbs,
2059 int *clusters_need, 1970 int *clusters_need,
2060 int *meta_need) 1971 int *meta_need,
1972 int *credits_need)
2061{ 1973{
2062 int ret = 0, old_in_xb = 0; 1974 int ret = 0, old_in_xb = 0;
2063 int clusters_add = 0, meta_add = 0; 1975 int clusters_add = 0, meta_add = 0, credits = 0;
2064 struct buffer_head *bh = NULL; 1976 struct buffer_head *bh = NULL;
2065 struct ocfs2_xattr_block *xb = NULL; 1977 struct ocfs2_xattr_block *xb = NULL;
2066 struct ocfs2_xattr_entry *xe = NULL; 1978 struct ocfs2_xattr_entry *xe = NULL;
@@ -2071,16 +1983,15 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2071 xi->value_len); 1983 xi->value_len);
2072 u64 value_size; 1984 u64 value_size;
2073 1985
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) { 1986 if (xis->not_found && xbs->not_found) {
2082 if (xi->value_len > OCFS2_XATTR_INLINE_SIZE) 1987 credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
1988
1989 if (xi->value_len > OCFS2_XATTR_INLINE_SIZE) {
2083 clusters_add += new_clusters; 1990 clusters_add += new_clusters;
1991 credits += ocfs2_calc_extend_credits(inode->i_sb,
1992 &def_xv.xv.xr_list,
1993 new_clusters);
1994 }
2084 1995
2085 goto meta_guess; 1996 goto meta_guess;
2086 } 1997 }
@@ -2090,6 +2001,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2090 name_offset = le16_to_cpu(xe->xe_name_offset); 2001 name_offset = le16_to_cpu(xe->xe_name_offset);
2091 name_len = OCFS2_XATTR_SIZE(xe->xe_name_len); 2002 name_len = OCFS2_XATTR_SIZE(xe->xe_name_len);
2092 base = xis->base; 2003 base = xis->base;
2004 credits += OCFS2_INODE_UPDATE_CREDITS;
2093 } else { 2005 } else {
2094 int i, block_off; 2006 int i, block_off;
2095 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data; 2007 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
@@ -2105,8 +2017,25 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2105 i, &block_off, 2017 i, &block_off,
2106 &name_offset); 2018 &name_offset);
2107 base = bucket_block(xbs->bucket, block_off); 2019 base = bucket_block(xbs->bucket, block_off);
2108 } else 2020 credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2021 } else {
2109 base = xbs->base; 2022 base = xbs->base;
2023 credits += OCFS2_XATTR_BLOCK_UPDATE_CREDITS;
2024 }
2025 }
2026
2027 /*
2028 * delete a xattr doesn't need metadata and cluster allocation.
2029 * so just calculate the credits and return.
2030 *
2031 * The credits for removing the value tree will be extended
2032 * by ocfs2_remove_extent itself.
2033 */
2034 if (!xi->value) {
2035 if (!ocfs2_xattr_is_local(xe))
2036 credits += OCFS2_REMOVE_EXTENT_CREDITS;
2037
2038 goto out;
2110 } 2039 }
2111 2040
2112 /* do cluster allocation guess first. */ 2041 /* do cluster allocation guess first. */
@@ -2121,6 +2050,13 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2121 */ 2050 */
2122 if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) { 2051 if (ocfs2_xattr_can_be_in_inode(inode, xi, xis)) {
2123 clusters_add += new_clusters; 2052 clusters_add += new_clusters;
2053 credits += OCFS2_REMOVE_EXTENT_CREDITS +
2054 OCFS2_INODE_UPDATE_CREDITS;
2055 if (!ocfs2_xattr_is_local(xe))
2056 credits += ocfs2_calc_extend_credits(
2057 inode->i_sb,
2058 &def_xv.xv.xr_list,
2059 new_clusters);
2124 goto out; 2060 goto out;
2125 } 2061 }
2126 } 2062 }
@@ -2137,11 +2073,16 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2137 } else 2073 } else
2138 xv = &def_xv.xv; 2074 xv = &def_xv.xv;
2139 2075
2140 if (old_clusters >= new_clusters) 2076 if (old_clusters >= new_clusters) {
2077 credits += OCFS2_REMOVE_EXTENT_CREDITS;
2141 goto out; 2078 goto out;
2142 else { 2079 } else {
2143 meta_add += ocfs2_extend_meta_needed(&xv->xr_list); 2080 meta_add += ocfs2_extend_meta_needed(&xv->xr_list);
2144 clusters_add += new_clusters - old_clusters; 2081 clusters_add += new_clusters - old_clusters;
2082 credits += ocfs2_calc_extend_credits(inode->i_sb,
2083 &xv->xr_list,
2084 new_clusters -
2085 old_clusters);
2145 goto out; 2086 goto out;
2146 } 2087 }
2147 } else { 2088 } else {
@@ -2177,6 +2118,8 @@ meta_guess:
2177 struct ocfs2_extent_list *el = 2118 struct ocfs2_extent_list *el =
2178 &xb->xb_attrs.xb_root.xt_list; 2119 &xb->xb_attrs.xb_root.xt_list;
2179 meta_add += ocfs2_extend_meta_needed(el); 2120 meta_add += ocfs2_extend_meta_needed(el);
2121 credits += ocfs2_calc_extend_credits(inode->i_sb,
2122 el, 1);
2180 } 2123 }
2181 2124
2182 /* 2125 /*
@@ -2187,16 +2130,23 @@ meta_guess:
2187 * also. 2130 * also.
2188 */ 2131 */
2189 clusters_add += 1; 2132 clusters_add += 1;
2133 credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2190 if (OCFS2_XATTR_BUCKET_SIZE == 2134 if (OCFS2_XATTR_BUCKET_SIZE ==
2191 OCFS2_SB(inode->i_sb)->s_clustersize) 2135 OCFS2_SB(inode->i_sb)->s_clustersize) {
2136 credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
2192 clusters_add += 1; 2137 clusters_add += 1;
2193 } else 2138 }
2139 } else {
2194 meta_add += 1; 2140 meta_add += 1;
2141 credits += OCFS2_XATTR_BLOCK_CREATE_CREDITS;
2142 }
2195out: 2143out:
2196 if (clusters_need) 2144 if (clusters_need)
2197 *clusters_need = clusters_add; 2145 *clusters_need = clusters_add;
2198 if (meta_need) 2146 if (meta_need)
2199 *meta_need = meta_add; 2147 *meta_need = meta_add;
2148 if (credits_need)
2149 *credits_need = credits;
2200 brelse(bh); 2150 brelse(bh);
2201 return ret; 2151 return ret;
2202} 2152}
@@ -2206,7 +2156,8 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
2206 struct ocfs2_xattr_info *xi, 2156 struct ocfs2_xattr_info *xi,
2207 struct ocfs2_xattr_search *xis, 2157 struct ocfs2_xattr_search *xis,
2208 struct ocfs2_xattr_search *xbs, 2158 struct ocfs2_xattr_search *xbs,
2209 struct ocfs2_xattr_set_ctxt *ctxt) 2159 struct ocfs2_xattr_set_ctxt *ctxt,
2160 int *credits)
2210{ 2161{
2211 int clusters_add, meta_add, ret; 2162 int clusters_add, meta_add, ret;
2212 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 2163 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
@@ -2216,14 +2167,14 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
2216 ocfs2_init_dealloc_ctxt(&ctxt->dealloc); 2167 ocfs2_init_dealloc_ctxt(&ctxt->dealloc);
2217 2168
2218 ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs, 2169 ret = ocfs2_calc_xattr_set_need(inode, di, xi, xis, xbs,
2219 &clusters_add, &meta_add); 2170 &clusters_add, &meta_add, credits);
2220 if (ret) { 2171 if (ret) {
2221 mlog_errno(ret); 2172 mlog_errno(ret);
2222 return ret; 2173 return ret;
2223 } 2174 }
2224 2175
2225 mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d\n", 2176 mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d, "
2226 xi->name, meta_add, clusters_add); 2177 "credits = %d\n", xi->name, meta_add, clusters_add, *credits);
2227 2178
2228 if (meta_add) { 2179 if (meta_add) {
2229 ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add, 2180 ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
@@ -2254,6 +2205,126 @@ out:
2254 return ret; 2205 return ret;
2255} 2206}
2256 2207
2208static int __ocfs2_xattr_set_handle(struct inode *inode,
2209 struct ocfs2_dinode *di,
2210 struct ocfs2_xattr_info *xi,
2211 struct ocfs2_xattr_search *xis,
2212 struct ocfs2_xattr_search *xbs,
2213 struct ocfs2_xattr_set_ctxt *ctxt)
2214{
2215 int ret = 0, credits;
2216
2217 if (!xi->value) {
2218 /* Remove existing extended attribute */
2219 if (!xis->not_found)
2220 ret = ocfs2_xattr_ibody_set(inode, xi, xis, ctxt);
2221 else if (!xbs->not_found)
2222 ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
2223 } else {
2224 /* We always try to set extended attribute into inode first*/
2225 ret = ocfs2_xattr_ibody_set(inode, xi, xis, ctxt);
2226 if (!ret && !xbs->not_found) {
2227 /*
2228 * If succeed and that extended attribute existing in
2229 * external block, then we will remove it.
2230 */
2231 xi->value = NULL;
2232 xi->value_len = 0;
2233
2234 xis->not_found = -ENODATA;
2235 ret = ocfs2_calc_xattr_set_need(inode,
2236 di,
2237 xi,
2238 xis,
2239 xbs,
2240 NULL,
2241 NULL,
2242 &credits);
2243 if (ret) {
2244 mlog_errno(ret);
2245 goto out;
2246 }
2247
2248 ret = ocfs2_extend_trans(ctxt->handle, credits +
2249 ctxt->handle->h_buffer_credits);
2250 if (ret) {
2251 mlog_errno(ret);
2252 goto out;
2253 }
2254 ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
2255 } else if (ret == -ENOSPC) {
2256 if (di->i_xattr_loc && !xbs->xattr_bh) {
2257 ret = ocfs2_xattr_block_find(inode,
2258 xi->name_index,
2259 xi->name, xbs);
2260 if (ret)
2261 goto out;
2262
2263 xis->not_found = -ENODATA;
2264 ret = ocfs2_calc_xattr_set_need(inode,
2265 di,
2266 xi,
2267 xis,
2268 xbs,
2269 NULL,
2270 NULL,
2271 &credits);
2272 if (ret) {
2273 mlog_errno(ret);
2274 goto out;
2275 }
2276
2277 ret = ocfs2_extend_trans(ctxt->handle, credits +
2278 ctxt->handle->h_buffer_credits);
2279 if (ret) {
2280 mlog_errno(ret);
2281 goto out;
2282 }
2283 }
2284 /*
2285 * If no space in inode, we will set extended attribute
2286 * into external block.
2287 */
2288 ret = ocfs2_xattr_block_set(inode, xi, xbs, ctxt);
2289 if (ret)
2290 goto out;
2291 if (!xis->not_found) {
2292 /*
2293 * If succeed and that extended attribute
2294 * existing in inode, we will remove it.
2295 */
2296 xi->value = NULL;
2297 xi->value_len = 0;
2298 xbs->not_found = -ENODATA;
2299 ret = ocfs2_calc_xattr_set_need(inode,
2300 di,
2301 xi,
2302 xis,
2303 xbs,
2304 NULL,
2305 NULL,
2306 &credits);
2307 if (ret) {
2308 mlog_errno(ret);
2309 goto out;
2310 }
2311
2312 ret = ocfs2_extend_trans(ctxt->handle, credits +
2313 ctxt->handle->h_buffer_credits);
2314 if (ret) {
2315 mlog_errno(ret);
2316 goto out;
2317 }
2318 ret = ocfs2_xattr_ibody_set(inode, xi,
2319 xis, ctxt);
2320 }
2321 }
2322 }
2323
2324out:
2325 return ret;
2326}
2327
2257/* 2328/*
2258 * ocfs2_xattr_set() 2329 * ocfs2_xattr_set()
2259 * 2330 *
@@ -2270,8 +2341,9 @@ int ocfs2_xattr_set(struct inode *inode,
2270{ 2341{
2271 struct buffer_head *di_bh = NULL; 2342 struct buffer_head *di_bh = NULL;
2272 struct ocfs2_dinode *di; 2343 struct ocfs2_dinode *di;
2273 int ret; 2344 int ret, credits;
2274 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 2345 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2346 struct inode *tl_inode = osb->osb_tl_inode;
2275 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, }; 2347 struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, };
2276 2348
2277 struct ocfs2_xattr_info xi = { 2349 struct ocfs2_xattr_info xi = {
@@ -2337,56 +2409,37 @@ int ocfs2_xattr_set(struct inode *inode,
2337 goto cleanup; 2409 goto cleanup;
2338 } 2410 }
2339 2411
2340 ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, &xbs, &ctxt); 2412
2413 mutex_lock(&tl_inode->i_mutex);
2414
2415 if (ocfs2_truncate_log_needs_flush(osb)) {
2416 ret = __ocfs2_flush_truncate_log(osb);
2417 if (ret < 0) {
2418 mutex_unlock(&tl_inode->i_mutex);
2419 mlog_errno(ret);
2420 goto cleanup;
2421 }
2422 }
2423 mutex_unlock(&tl_inode->i_mutex);
2424
2425 ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis,
2426 &xbs, &ctxt, &credits);
2341 if (ret) { 2427 if (ret) {
2342 mlog_errno(ret); 2428 mlog_errno(ret);
2343 goto cleanup; 2429 goto cleanup;
2344 } 2430 }
2345 2431
2346 if (!value) { 2432 ctxt.handle = ocfs2_start_trans(osb, credits);
2347 /* Remove existing extended attribute */ 2433 if (IS_ERR(ctxt.handle)) {
2348 if (!xis.not_found) 2434 ret = PTR_ERR(ctxt.handle);
2349 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt); 2435 mlog_errno(ret);
2350 else if (!xbs.not_found) 2436 goto cleanup;
2351 ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
2352 } else {
2353 /* We always try to set extended attribute into inode first*/
2354 ret = ocfs2_xattr_ibody_set(inode, &xi, &xis, &ctxt);
2355 if (!ret && !xbs.not_found) {
2356 /*
2357 * If succeed and that extended attribute existing in
2358 * external block, then we will remove it.
2359 */
2360 xi.value = NULL;
2361 xi.value_len = 0;
2362 ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
2363 } else if (ret == -ENOSPC) {
2364 if (di->i_xattr_loc && !xbs.xattr_bh) {
2365 ret = ocfs2_xattr_block_find(inode, name_index,
2366 name, &xbs);
2367 if (ret)
2368 goto cleanup;
2369 }
2370 /*
2371 * If no space in inode, we will set extended attribute
2372 * into external block.
2373 */
2374 ret = ocfs2_xattr_block_set(inode, &xi, &xbs, &ctxt);
2375 if (ret)
2376 goto free;
2377 if (!xis.not_found) {
2378 /*
2379 * If succeed and that extended attribute
2380 * existing in inode, we will remove it.
2381 */
2382 xi.value = NULL;
2383 xi.value_len = 0;
2384 ret = ocfs2_xattr_ibody_set(inode, &xi,
2385 &xis, &ctxt);
2386 }
2387 }
2388 } 2437 }
2389free: 2438
2439 ret = __ocfs2_xattr_set_handle(inode, di, &xi, &xis, &xbs, &ctxt);
2440
2441 ocfs2_commit_trans(osb, ctxt.handle);
2442
2390 if (ctxt.data_ac) 2443 if (ctxt.data_ac)
2391 ocfs2_free_alloc_context(ctxt.data_ac); 2444 ocfs2_free_alloc_context(ctxt.data_ac);
2392 if (ctxt.meta_ac) 2445 if (ctxt.meta_ac)
@@ -2974,10 +3027,10 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
2974 struct ocfs2_xattr_search *xs, 3027 struct ocfs2_xattr_search *xs,
2975 struct ocfs2_xattr_set_ctxt *ctxt) 3028 struct ocfs2_xattr_set_ctxt *ctxt)
2976{ 3029{
2977 int ret, credits = OCFS2_SUBALLOC_ALLOC; 3030 int ret;
2978 u32 bit_off, len; 3031 u32 bit_off, len;
2979 u64 blkno; 3032 u64 blkno;
2980 handle_t *handle; 3033 handle_t *handle = ctxt->handle;
2981 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3034 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
2982 struct ocfs2_inode_info *oi = OCFS2_I(inode); 3035 struct ocfs2_inode_info *oi = OCFS2_I(inode);
2983 struct buffer_head *xb_bh = xs->xattr_bh; 3036 struct buffer_head *xb_bh = xs->xattr_bh;
@@ -2999,30 +3052,18 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
2999 */ 3052 */
3000 down_write(&oi->ip_alloc_sem); 3053 down_write(&oi->ip_alloc_sem);
3001 3054
3002 /*
3003 * We need more credits. One for the xattr block update and one
3004 * for each block of the new xattr bucket.
3005 */
3006 credits += 1 + ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3007 handle = ocfs2_start_trans(osb, credits);
3008 if (IS_ERR(handle)) {
3009 ret = PTR_ERR(handle);
3010 mlog_errno(ret);
3011 goto out_sem;
3012 }
3013
3014 ret = ocfs2_journal_access(handle, inode, xb_bh, 3055 ret = ocfs2_journal_access(handle, inode, xb_bh,
3015 OCFS2_JOURNAL_ACCESS_WRITE); 3056 OCFS2_JOURNAL_ACCESS_WRITE);
3016 if (ret) { 3057 if (ret) {
3017 mlog_errno(ret); 3058 mlog_errno(ret);
3018 goto out_commit; 3059 goto out;
3019 } 3060 }
3020 3061
3021 ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac, 3062 ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac,
3022 1, 1, &bit_off, &len); 3063 1, 1, &bit_off, &len);
3023 if (ret) { 3064 if (ret) {
3024 mlog_errno(ret); 3065 mlog_errno(ret);
3025 goto out_commit; 3066 goto out;
3026 } 3067 }
3027 3068
3028 /* 3069 /*
@@ -3038,14 +3079,14 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
3038 ret = ocfs2_init_xattr_bucket(xs->bucket, blkno); 3079 ret = ocfs2_init_xattr_bucket(xs->bucket, blkno);
3039 if (ret) { 3080 if (ret) {
3040 mlog_errno(ret); 3081 mlog_errno(ret);
3041 goto out_commit; 3082 goto out;
3042 } 3083 }
3043 3084
3044 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, 3085 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
3045 OCFS2_JOURNAL_ACCESS_CREATE); 3086 OCFS2_JOURNAL_ACCESS_CREATE);
3046 if (ret) { 3087 if (ret) {
3047 mlog_errno(ret); 3088 mlog_errno(ret);
3048 goto out_commit; 3089 goto out;
3049 } 3090 }
3050 3091
3051 ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket); 3092 ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket);
@@ -3070,16 +3111,9 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
3070 3111
3071 xb->xb_flags = cpu_to_le16(xb_flags | OCFS2_XATTR_INDEXED); 3112 xb->xb_flags = cpu_to_le16(xb_flags | OCFS2_XATTR_INDEXED);
3072 3113
3073 ret = ocfs2_journal_dirty(handle, xb_bh); 3114 ocfs2_journal_dirty(handle, xb_bh);
3074 if (ret) {
3075 mlog_errno(ret);
3076 goto out_commit;
3077 }
3078 3115
3079out_commit: 3116out:
3080 ocfs2_commit_trans(osb, handle);
3081
3082out_sem:
3083 up_write(&oi->ip_alloc_sem); 3117 up_write(&oi->ip_alloc_sem);
3084 3118
3085 return ret; 3119 return ret;
@@ -3105,6 +3139,7 @@ static int cmp_xe_offset(const void *a, const void *b)
3105 * so that we can spare some space for insertion. 3139 * so that we can spare some space for insertion.
3106 */ 3140 */
3107static int ocfs2_defrag_xattr_bucket(struct inode *inode, 3141static int ocfs2_defrag_xattr_bucket(struct inode *inode,
3142 handle_t *handle,
3108 struct ocfs2_xattr_bucket *bucket) 3143 struct ocfs2_xattr_bucket *bucket)
3109{ 3144{
3110 int ret, i; 3145 int ret, i;
@@ -3114,7 +3149,6 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
3114 u64 blkno = bucket_blkno(bucket); 3149 u64 blkno = bucket_blkno(bucket);
3115 u16 xh_free_start; 3150 u16 xh_free_start;
3116 size_t blocksize = inode->i_sb->s_blocksize; 3151 size_t blocksize = inode->i_sb->s_blocksize;
3117 handle_t *handle;
3118 struct ocfs2_xattr_entry *xe; 3152 struct ocfs2_xattr_entry *xe;
3119 3153
3120 /* 3154 /*
@@ -3133,19 +3167,11 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
3133 for (i = 0; i < bucket->bu_blocks; i++, buf += blocksize) 3167 for (i = 0; i < bucket->bu_blocks; i++, buf += blocksize)
3134 memcpy(buf, bucket_block(bucket, i), blocksize); 3168 memcpy(buf, bucket_block(bucket, i), blocksize);
3135 3169
3136 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)), bucket->bu_blocks);
3137 if (IS_ERR(handle)) {
3138 ret = PTR_ERR(handle);
3139 handle = NULL;
3140 mlog_errno(ret);
3141 goto out;
3142 }
3143
3144 ret = ocfs2_xattr_bucket_journal_access(handle, bucket, 3170 ret = ocfs2_xattr_bucket_journal_access(handle, bucket,
3145 OCFS2_JOURNAL_ACCESS_WRITE); 3171 OCFS2_JOURNAL_ACCESS_WRITE);
3146 if (ret < 0) { 3172 if (ret < 0) {
3147 mlog_errno(ret); 3173 mlog_errno(ret);
3148 goto commit; 3174 goto out;
3149 } 3175 }
3150 3176
3151 xh = (struct ocfs2_xattr_header *)bucket_buf; 3177 xh = (struct ocfs2_xattr_header *)bucket_buf;
@@ -3203,7 +3229,7 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
3203 "bucket %llu\n", (unsigned long long)blkno); 3229 "bucket %llu\n", (unsigned long long)blkno);
3204 3230
3205 if (xh_free_start == end) 3231 if (xh_free_start == end)
3206 goto commit; 3232 goto out;
3207 3233
3208 memset(bucket_buf + xh_free_start, 0, end - xh_free_start); 3234 memset(bucket_buf + xh_free_start, 0, end - xh_free_start);
3209 xh->xh_free_start = cpu_to_le16(end); 3235 xh->xh_free_start = cpu_to_le16(end);
@@ -3218,8 +3244,6 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
3218 memcpy(bucket_block(bucket, i), buf, blocksize); 3244 memcpy(bucket_block(bucket, i), buf, blocksize);
3219 ocfs2_xattr_bucket_journal_dirty(handle, bucket); 3245 ocfs2_xattr_bucket_journal_dirty(handle, bucket);
3220 3246
3221commit:
3222 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
3223out: 3247out:
3224 kfree(bucket_buf); 3248 kfree(bucket_buf);
3225 return ret; 3249 return ret;
@@ -3270,7 +3294,7 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
3270 * 1 more for the update of the 1st bucket of the previous 3294 * 1 more for the update of the 1st bucket of the previous
3271 * extent record. 3295 * extent record.
3272 */ 3296 */
3273 credits = bpc / 2 + 1; 3297 credits = bpc / 2 + 1 + handle->h_buffer_credits;
3274 ret = ocfs2_extend_trans(handle, credits); 3298 ret = ocfs2_extend_trans(handle, credits);
3275 if (ret) { 3299 if (ret) {
3276 mlog_errno(ret); 3300 mlog_errno(ret);
@@ -3662,7 +3686,7 @@ static int ocfs2_cp_xattr_cluster(struct inode *inode,
3662 * We need to update the new cluster and 1 more for the update of 3686 * We need to update the new cluster and 1 more for the update of
3663 * the 1st bucket of the previous extent rec. 3687 * the 1st bucket of the previous extent rec.
3664 */ 3688 */
3665 credits = bpc + 1; 3689 credits = bpc + 1 + handle->h_buffer_credits;
3666 ret = ocfs2_extend_trans(handle, credits); 3690 ret = ocfs2_extend_trans(handle, credits);
3667 if (ret) { 3691 if (ret) {
3668 mlog_errno(ret); 3692 mlog_errno(ret);
@@ -3732,7 +3756,7 @@ static int ocfs2_divide_xattr_cluster(struct inode *inode,
3732 u32 *first_hash) 3756 u32 *first_hash)
3733{ 3757{
3734 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 3758 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3735 int ret, credits = 2 * blk_per_bucket; 3759 int ret, credits = 2 * blk_per_bucket + handle->h_buffer_credits;
3736 3760
3737 BUG_ON(OCFS2_XATTR_BUCKET_SIZE < OCFS2_SB(inode->i_sb)->s_clustersize); 3761 BUG_ON(OCFS2_XATTR_BUCKET_SIZE < OCFS2_SB(inode->i_sb)->s_clustersize);
3738 3762
@@ -3845,12 +3869,12 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3845 int *extend, 3869 int *extend,
3846 struct ocfs2_xattr_set_ctxt *ctxt) 3870 struct ocfs2_xattr_set_ctxt *ctxt)
3847{ 3871{
3848 int ret, credits; 3872 int ret;
3849 u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1); 3873 u16 bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
3850 u32 prev_clusters = *num_clusters; 3874 u32 prev_clusters = *num_clusters;
3851 u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0; 3875 u32 clusters_to_add = 1, bit_off, num_bits, v_start = 0;
3852 u64 block; 3876 u64 block;
3853 handle_t *handle = NULL; 3877 handle_t *handle = ctxt->handle;
3854 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3878 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3855 struct ocfs2_extent_tree et; 3879 struct ocfs2_extent_tree et;
3856 3880
@@ -3861,16 +3885,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3861 3885
3862 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); 3886 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
3863 3887
3864 credits = ocfs2_calc_extend_credits(osb->sb, et.et_root_el,
3865 clusters_to_add);
3866 handle = ocfs2_start_trans(osb, credits);
3867 if (IS_ERR(handle)) {
3868 ret = PTR_ERR(handle);
3869 handle = NULL;
3870 mlog_errno(ret);
3871 goto leave;
3872 }
3873
3874 ret = ocfs2_journal_access(handle, inode, root_bh, 3888 ret = ocfs2_journal_access(handle, inode, root_bh,
3875 OCFS2_JOURNAL_ACCESS_WRITE); 3889 OCFS2_JOURNAL_ACCESS_WRITE);
3876 if (ret < 0) { 3890 if (ret < 0) {
@@ -3924,18 +3938,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3924 } 3938 }
3925 } 3939 }
3926 3940
3927 if (handle->h_buffer_credits < credits) {
3928 /*
3929 * The journal has been restarted before, and don't
3930 * have enough space for the insertion, so extend it
3931 * here.
3932 */
3933 ret = ocfs2_extend_trans(handle, credits);
3934 if (ret) {
3935 mlog_errno(ret);
3936 goto leave;
3937 }
3938 }
3939 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", 3941 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
3940 num_bits, (unsigned long long)block, v_start); 3942 num_bits, (unsigned long long)block, v_start);
3941 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block, 3943 ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block,
@@ -3946,15 +3948,10 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
3946 } 3948 }
3947 3949
3948 ret = ocfs2_journal_dirty(handle, root_bh); 3950 ret = ocfs2_journal_dirty(handle, root_bh);
3949 if (ret < 0) { 3951 if (ret < 0)
3950 mlog_errno(ret); 3952 mlog_errno(ret);
3951 goto leave;
3952 }
3953 3953
3954leave: 3954leave:
3955 if (handle)
3956 ocfs2_commit_trans(osb, handle);
3957
3958 return ret; 3955 return ret;
3959} 3956}
3960 3957
@@ -3963,6 +3960,7 @@ leave:
3963 * We meet with start_bh. Only move half of the xattrs to the bucket after it. 3960 * We meet with start_bh. Only move half of the xattrs to the bucket after it.
3964 */ 3961 */
3965static int ocfs2_extend_xattr_bucket(struct inode *inode, 3962static int ocfs2_extend_xattr_bucket(struct inode *inode,
3963 handle_t *handle,
3966 struct buffer_head *first_bh, 3964 struct buffer_head *first_bh,
3967 struct buffer_head *start_bh, 3965 struct buffer_head *start_bh,
3968 u32 num_clusters) 3966 u32 num_clusters)
@@ -3972,7 +3970,6 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
3972 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 3970 u16 blk_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3973 u64 start_blk = start_bh->b_blocknr, end_blk; 3971 u64 start_blk = start_bh->b_blocknr, end_blk;
3974 u32 num_buckets = num_clusters * ocfs2_xattr_buckets_per_cluster(osb); 3972 u32 num_buckets = num_clusters * ocfs2_xattr_buckets_per_cluster(osb);
3975 handle_t *handle;
3976 struct ocfs2_xattr_header *first_xh = 3973 struct ocfs2_xattr_header *first_xh =
3977 (struct ocfs2_xattr_header *)first_bh->b_data; 3974 (struct ocfs2_xattr_header *)first_bh->b_data;
3978 u16 bucket = le16_to_cpu(first_xh->xh_num_buckets); 3975 u16 bucket = le16_to_cpu(first_xh->xh_num_buckets);
@@ -3989,11 +3986,10 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
3989 * We will touch all the buckets after the start_bh(include it). 3986 * We will touch all the buckets after the start_bh(include it).
3990 * Then we add one more bucket. 3987 * Then we add one more bucket.
3991 */ 3988 */
3992 credits = end_blk - start_blk + 3 * blk_per_bucket + 1; 3989 credits = end_blk - start_blk + 3 * blk_per_bucket + 1 +
3993 handle = ocfs2_start_trans(osb, credits); 3990 handle->h_buffer_credits;
3994 if (IS_ERR(handle)) { 3991 ret = ocfs2_extend_trans(handle, credits);
3995 ret = PTR_ERR(handle); 3992 if (ret) {
3996 handle = NULL;
3997 mlog_errno(ret); 3993 mlog_errno(ret);
3998 goto out; 3994 goto out;
3999 } 3995 }
@@ -4002,14 +3998,14 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
4002 OCFS2_JOURNAL_ACCESS_WRITE); 3998 OCFS2_JOURNAL_ACCESS_WRITE);
4003 if (ret) { 3999 if (ret) {
4004 mlog_errno(ret); 4000 mlog_errno(ret);
4005 goto commit; 4001 goto out;
4006 } 4002 }
4007 4003
4008 while (end_blk != start_blk) { 4004 while (end_blk != start_blk) {
4009 ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk, 4005 ret = ocfs2_cp_xattr_bucket(inode, handle, end_blk,
4010 end_blk + blk_per_bucket, 0); 4006 end_blk + blk_per_bucket, 0);
4011 if (ret) 4007 if (ret)
4012 goto commit; 4008 goto out;
4013 end_blk -= blk_per_bucket; 4009 end_blk -= blk_per_bucket;
4014 } 4010 }
4015 4011
@@ -4020,8 +4016,6 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
4020 le16_add_cpu(&first_xh->xh_num_buckets, 1); 4016 le16_add_cpu(&first_xh->xh_num_buckets, 1);
4021 ocfs2_journal_dirty(handle, first_bh); 4017 ocfs2_journal_dirty(handle, first_bh);
4022 4018
4023commit:
4024 ocfs2_commit_trans(osb, handle);
4025out: 4019out:
4026 return ret; 4020 return ret;
4027} 4021}
@@ -4099,6 +4093,7 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4099 4093
4100 if (extend) 4094 if (extend)
4101 ret = ocfs2_extend_xattr_bucket(inode, 4095 ret = ocfs2_extend_xattr_bucket(inode,
4096 ctxt->handle,
4102 first_bh, 4097 first_bh,
4103 header_bh, 4098 header_bh,
4104 num_clusters); 4099 num_clusters);
@@ -4272,14 +4267,13 @@ set_new_name_value:
4272 * space for the xattr insertion. 4267 * space for the xattr insertion.
4273 */ 4268 */
4274static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode, 4269static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4270 handle_t *handle,
4275 struct ocfs2_xattr_info *xi, 4271 struct ocfs2_xattr_info *xi,
4276 struct ocfs2_xattr_search *xs, 4272 struct ocfs2_xattr_search *xs,
4277 u32 name_hash, 4273 u32 name_hash,
4278 int local) 4274 int local)
4279{ 4275{
4280 int ret; 4276 int ret;
4281 handle_t *handle = NULL;
4282 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4283 u64 blkno; 4277 u64 blkno;
4284 4278
4285 mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n", 4279 mlog(0, "Set xattr entry len = %lu index = %d in bucket %llu\n",
@@ -4296,14 +4290,6 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4296 } 4290 }
4297 } 4291 }
4298 4292
4299 handle = ocfs2_start_trans(osb, xs->bucket->bu_blocks);
4300 if (IS_ERR(handle)) {
4301 ret = PTR_ERR(handle);
4302 handle = NULL;
4303 mlog_errno(ret);
4304 goto out;
4305 }
4306
4307 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, 4293 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
4308 OCFS2_JOURNAL_ACCESS_WRITE); 4294 OCFS2_JOURNAL_ACCESS_WRITE);
4309 if (ret < 0) { 4295 if (ret < 0) {
@@ -4315,32 +4301,22 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode,
4315 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket); 4301 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
4316 4302
4317out: 4303out:
4318 ocfs2_commit_trans(osb, handle);
4319
4320 return ret; 4304 return ret;
4321} 4305}
4322 4306
4323static int ocfs2_xattr_value_update_size(struct inode *inode, 4307static int ocfs2_xattr_value_update_size(struct inode *inode,
4308 handle_t *handle,
4324 struct buffer_head *xe_bh, 4309 struct buffer_head *xe_bh,
4325 struct ocfs2_xattr_entry *xe, 4310 struct ocfs2_xattr_entry *xe,
4326 u64 new_size) 4311 u64 new_size)
4327{ 4312{
4328 int ret; 4313 int ret;
4329 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4330 handle_t *handle = NULL;
4331
4332 handle = ocfs2_start_trans(osb, 1);
4333 if (IS_ERR(handle)) {
4334 ret = -ENOMEM;
4335 mlog_errno(ret);
4336 goto out;
4337 }
4338 4314
4339 ret = ocfs2_journal_access(handle, inode, xe_bh, 4315 ret = ocfs2_journal_access(handle, inode, xe_bh,
4340 OCFS2_JOURNAL_ACCESS_WRITE); 4316 OCFS2_JOURNAL_ACCESS_WRITE);
4341 if (ret < 0) { 4317 if (ret < 0) {
4342 mlog_errno(ret); 4318 mlog_errno(ret);
4343 goto out_commit; 4319 goto out;
4344 } 4320 }
4345 4321
4346 xe->xe_value_size = cpu_to_le64(new_size); 4322 xe->xe_value_size = cpu_to_le64(new_size);
@@ -4349,8 +4325,6 @@ static int ocfs2_xattr_value_update_size(struct inode *inode,
4349 if (ret < 0) 4325 if (ret < 0)
4350 mlog_errno(ret); 4326 mlog_errno(ret);
4351 4327
4352out_commit:
4353 ocfs2_commit_trans(osb, handle);
4354out: 4328out:
4355 return ret; 4329 return ret;
4356} 4330}
@@ -4407,7 +4381,8 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4407 goto out; 4381 goto out;
4408 } 4382 }
4409 4383
4410 ret = ocfs2_xattr_value_update_size(inode, header_bh, xe, len); 4384 ret = ocfs2_xattr_value_update_size(inode, ctxt->handle,
4385 header_bh, xe, len);
4411 if (ret) { 4386 if (ret) {
4412 mlog_errno(ret); 4387 mlog_errno(ret);
4413 goto out; 4388 goto out;
@@ -4439,6 +4414,7 @@ static int ocfs2_xattr_bucket_value_truncate_xs(struct inode *inode,
4439} 4414}
4440 4415
4441static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, 4416static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
4417 handle_t *handle,
4442 struct ocfs2_xattr_search *xs, 4418 struct ocfs2_xattr_search *xs,
4443 char *val, 4419 char *val,
4444 int value_len) 4420 int value_len)
@@ -4454,7 +4430,8 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode,
4454 4430
4455 xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); 4431 xv = (struct ocfs2_xattr_value_root *)(xs->base + offset);
4456 4432
4457 return __ocfs2_xattr_set_value_outside(inode, xv, val, value_len); 4433 return __ocfs2_xattr_set_value_outside(inode, handle,
4434 xv, val, value_len);
4458} 4435}
4459 4436
4460static int ocfs2_rm_xattr_cluster(struct inode *inode, 4437static int ocfs2_rm_xattr_cluster(struct inode *inode,
@@ -4547,27 +4524,19 @@ out:
4547} 4524}
4548 4525
4549static void ocfs2_xattr_bucket_remove_xs(struct inode *inode, 4526static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4527 handle_t *handle,
4550 struct ocfs2_xattr_search *xs) 4528 struct ocfs2_xattr_search *xs)
4551{ 4529{
4552 handle_t *handle = NULL;
4553 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); 4530 struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket);
4554 struct ocfs2_xattr_entry *last = &xh->xh_entries[ 4531 struct ocfs2_xattr_entry *last = &xh->xh_entries[
4555 le16_to_cpu(xh->xh_count) - 1]; 4532 le16_to_cpu(xh->xh_count) - 1];
4556 int ret = 0; 4533 int ret = 0;
4557 4534
4558 handle = ocfs2_start_trans((OCFS2_SB(inode->i_sb)),
4559 ocfs2_blocks_per_xattr_bucket(inode->i_sb));
4560 if (IS_ERR(handle)) {
4561 ret = PTR_ERR(handle);
4562 mlog_errno(ret);
4563 return;
4564 }
4565
4566 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, 4535 ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket,
4567 OCFS2_JOURNAL_ACCESS_WRITE); 4536 OCFS2_JOURNAL_ACCESS_WRITE);
4568 if (ret) { 4537 if (ret) {
4569 mlog_errno(ret); 4538 mlog_errno(ret);
4570 goto out_commit; 4539 return;
4571 } 4540 }
4572 4541
4573 /* Remove the old entry. */ 4542 /* Remove the old entry. */
@@ -4577,9 +4546,6 @@ static void ocfs2_xattr_bucket_remove_xs(struct inode *inode,
4577 le16_add_cpu(&xh->xh_count, -1); 4546 le16_add_cpu(&xh->xh_count, -1);
4578 4547
4579 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket); 4548 ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
4580
4581out_commit:
4582 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
4583} 4549}
4584 4550
4585/* 4551/*
@@ -4645,7 +4611,8 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
4645 xi->value_len = OCFS2_XATTR_ROOT_SIZE; 4611 xi->value_len = OCFS2_XATTR_ROOT_SIZE;
4646 } 4612 }
4647 4613
4648 ret = ocfs2_xattr_set_entry_in_bucket(inode, xi, xs, name_hash, local); 4614 ret = ocfs2_xattr_set_entry_in_bucket(inode, ctxt->handle, xi, xs,
4615 name_hash, local);
4649 if (ret) { 4616 if (ret) {
4650 mlog_errno(ret); 4617 mlog_errno(ret);
4651 goto out; 4618 goto out;
@@ -4666,13 +4633,14 @@ static int ocfs2_xattr_set_in_bucket(struct inode *inode,
4666 * storage and we have allocated xattr already, 4633 * storage and we have allocated xattr already,
4667 * so need to remove it. 4634 * so need to remove it.
4668 */ 4635 */
4669 ocfs2_xattr_bucket_remove_xs(inode, xs); 4636 ocfs2_xattr_bucket_remove_xs(inode, ctxt->handle, xs);
4670 } 4637 }
4671 goto out; 4638 goto out;
4672 } 4639 }
4673 4640
4674set_value_outside: 4641set_value_outside:
4675 ret = ocfs2_xattr_bucket_set_value_outside(inode, xs, val, value_len); 4642 ret = ocfs2_xattr_bucket_set_value_outside(inode, ctxt->handle,
4643 xs, val, value_len);
4676out: 4644out:
4677 return ret; 4645 return ret;
4678} 4646}
@@ -4785,7 +4753,8 @@ try_again:
4785 * name/value will be moved, the xe shouldn't be changed 4753 * name/value will be moved, the xe shouldn't be changed
4786 * in xs. 4754 * in xs.
4787 */ 4755 */
4788 ret = ocfs2_defrag_xattr_bucket(inode, xs->bucket); 4756 ret = ocfs2_defrag_xattr_bucket(inode, ctxt->handle,
4757 xs->bucket);
4789 if (ret) { 4758 if (ret) {
4790 mlog_errno(ret); 4759 mlog_errno(ret);
4791 goto out; 4760 goto out;
@@ -4865,6 +4834,13 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
4865 4834
4866 ocfs2_init_dealloc_ctxt(&ctxt.dealloc); 4835 ocfs2_init_dealloc_ctxt(&ctxt.dealloc);
4867 4836
4837 ctxt.handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
4838 if (IS_ERR(ctxt.handle)) {
4839 ret = PTR_ERR(ctxt.handle);
4840 mlog_errno(ret);
4841 goto out;
4842 }
4843
4868 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { 4844 for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
4869 xe = &xh->xh_entries[i]; 4845 xe = &xh->xh_entries[i];
4870 if (ocfs2_xattr_is_local(xe)) 4846 if (ocfs2_xattr_is_local(xe))
@@ -4879,9 +4855,10 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode,
4879 } 4855 }
4880 } 4856 }
4881 4857
4858 ret = ocfs2_commit_trans(osb, ctxt.handle);
4882 ocfs2_schedule_truncate_log_flush(osb, 1); 4859 ocfs2_schedule_truncate_log_flush(osb, 1);
4883 ocfs2_run_deallocs(osb, &ctxt.dealloc); 4860 ocfs2_run_deallocs(osb, &ctxt.dealloc);
4884 4861out:
4885 return ret; 4862 return ret;
4886} 4863}
4887 4864