aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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