aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2018-08-01 10:20:33 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2018-08-03 02:05:14 -0400
commit9b1f4e9831df29776031e86e112e68784f1fc079 (patch)
tree02cd52f1c6fe6851354ecb33cf6850173e618f46 /fs/xfs
parent60f31a609ed3d28791acb2bc24188cb7e2259176 (diff)
xfs: cancel dfops on xfs_defer_finish() error
The current semantics of xfs_defer_finish() require the caller to call xfs_defer_cancel() on error. This is slightly inconsistent with transaction commit error handling where a failed commit cleans up the transaction before returning. More significantly, the only requirement for exposure of ->dop_pending outside of xfs_defer_finish() is so that xfs_defer_cancel() can drain it on error. Since the only recourse of xfs_defer_finish() errors is cancellation, mirror the transaction logic and cancel remaining dfops before returning from xfs_defer_finish() with an error. Beside simplifying xfs_defer_finish() semantics, this ensures that xfs_defer_finish() always returns with an empty ->dop_pending and thus facilitates removal of the list from xfs_defer_ops. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_attr.c16
-rw-r--r--fs/xfs/libxfs/xfs_attr_remote.c4
-rw-r--r--fs/xfs/libxfs/xfs_defer.c11
-rw-r--r--fs/xfs/xfs_bmap_util.c2
-rw-r--r--fs/xfs/xfs_dquot.c2
-rw-r--r--fs/xfs/xfs_inode.c2
-rw-r--r--fs/xfs/xfs_reflink.c4
-rw-r--r--fs/xfs/xfs_trans.c4
8 files changed, 21 insertions, 24 deletions
diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 3190dfc21b60..1e671d4eb6fa 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -590,7 +590,7 @@ xfs_attr_leaf_addname(
590 goto out_defer_cancel; 590 goto out_defer_cancel;
591 error = xfs_defer_finish(&args->trans); 591 error = xfs_defer_finish(&args->trans);
592 if (error) 592 if (error)
593 goto out_defer_cancel; 593 return error;
594 594
595 /* 595 /*
596 * Commit the current trans (including the inode) and start 596 * Commit the current trans (including the inode) and start
@@ -678,7 +678,7 @@ xfs_attr_leaf_addname(
678 goto out_defer_cancel; 678 goto out_defer_cancel;
679 error = xfs_defer_finish(&args->trans); 679 error = xfs_defer_finish(&args->trans);
680 if (error) 680 if (error)
681 goto out_defer_cancel; 681 return error;
682 } 682 }
683 683
684 /* 684 /*
@@ -741,7 +741,7 @@ xfs_attr_leaf_removename(
741 goto out_defer_cancel; 741 goto out_defer_cancel;
742 error = xfs_defer_finish(&args->trans); 742 error = xfs_defer_finish(&args->trans);
743 if (error) 743 if (error)
744 goto out_defer_cancel; 744 return error;
745 } 745 }
746 return 0; 746 return 0;
747out_defer_cancel: 747out_defer_cancel:
@@ -867,7 +867,7 @@ restart:
867 goto out_defer_cancel; 867 goto out_defer_cancel;
868 error = xfs_defer_finish(&args->trans); 868 error = xfs_defer_finish(&args->trans);
869 if (error) 869 if (error)
870 goto out_defer_cancel; 870 goto out;
871 871
872 /* 872 /*
873 * Commit the node conversion and start the next 873 * Commit the node conversion and start the next
@@ -891,7 +891,7 @@ restart:
891 goto out_defer_cancel; 891 goto out_defer_cancel;
892 error = xfs_defer_finish(&args->trans); 892 error = xfs_defer_finish(&args->trans);
893 if (error) 893 if (error)
894 goto out_defer_cancel; 894 goto out;
895 } else { 895 } else {
896 /* 896 /*
897 * Addition succeeded, update Btree hashvals. 897 * Addition succeeded, update Btree hashvals.
@@ -987,7 +987,7 @@ restart:
987 goto out_defer_cancel; 987 goto out_defer_cancel;
988 error = xfs_defer_finish(&args->trans); 988 error = xfs_defer_finish(&args->trans);
989 if (error) 989 if (error)
990 goto out_defer_cancel; 990 goto out;
991 } 991 }
992 992
993 /* 993 /*
@@ -1110,7 +1110,7 @@ xfs_attr_node_removename(
1110 goto out_defer_cancel; 1110 goto out_defer_cancel;
1111 error = xfs_defer_finish(&args->trans); 1111 error = xfs_defer_finish(&args->trans);
1112 if (error) 1112 if (error)
1113 goto out_defer_cancel; 1113 goto out;
1114 /* 1114 /*
1115 * Commit the Btree join operation and start a new trans. 1115 * Commit the Btree join operation and start a new trans.
1116 */ 1116 */
@@ -1141,7 +1141,7 @@ xfs_attr_node_removename(
1141 goto out_defer_cancel; 1141 goto out_defer_cancel;
1142 error = xfs_defer_finish(&args->trans); 1142 error = xfs_defer_finish(&args->trans);
1143 if (error) 1143 if (error)
1144 goto out_defer_cancel; 1144 goto out;
1145 } else 1145 } else
1146 xfs_trans_brelse(args->trans, bp); 1146 xfs_trans_brelse(args->trans, bp);
1147 } 1147 }
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index f52552313773..af094063e402 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -488,7 +488,7 @@ xfs_attr_rmtval_set(
488 goto out_defer_cancel; 488 goto out_defer_cancel;
489 error = xfs_defer_finish(&args->trans); 489 error = xfs_defer_finish(&args->trans);
490 if (error) 490 if (error)
491 goto out_defer_cancel; 491 return error;
492 492
493 ASSERT(nmap == 1); 493 ASSERT(nmap == 1);
494 ASSERT((map.br_startblock != DELAYSTARTBLOCK) && 494 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
@@ -628,7 +628,7 @@ xfs_attr_rmtval_remove(
628 goto out_defer_cancel; 628 goto out_defer_cancel;
629 error = xfs_defer_finish(&args->trans); 629 error = xfs_defer_finish(&args->trans);
630 if (error) 630 if (error)
631 goto out_defer_cancel; 631 return error;
632 632
633 /* 633 /*
634 * Close out trans and start the next one in the chain. 634 * Close out trans and start the next one in the chain.
diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c
index 7079f534c735..b656a399cd71 100644
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -416,14 +416,15 @@ xfs_defer_finish_noroll(
416 } 416 }
417 417
418out: 418out:
419 if (error) 419 if (error) {
420 trace_xfs_defer_finish_error((*tp)->t_mountp, (*tp)->t_dfops, 420 trace_xfs_defer_finish_error((*tp)->t_mountp, (*tp)->t_dfops,
421 error); 421 error);
422 else 422 xfs_defer_cancel(*tp);
423 trace_xfs_defer_finish_done((*tp)->t_mountp, (*tp)->t_dfops, 423 return error;
424 _RET_IP_); 424 }
425 425
426 return error; 426 trace_xfs_defer_finish_done((*tp)->t_mountp, (*tp)->t_dfops, _RET_IP_);
427 return 0;
427} 428}
428 429
429int 430int
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 30ac1300dc49..d9dad399440a 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1624,7 +1624,7 @@ xfs_swap_extent_rmap(
1624 error = xfs_defer_finish(tpp); 1624 error = xfs_defer_finish(tpp);
1625 tp = *tpp; 1625 tp = *tpp;
1626 if (error) 1626 if (error)
1627 goto out_defer; 1627 goto out;
1628 1628
1629 tirec.br_startoff += rlen; 1629 tirec.br_startoff += rlen;
1630 if (tirec.br_startblock != HOLESTARTBLOCK && 1630 if (tirec.br_startblock != HOLESTARTBLOCK &&
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index e1196854dbcd..70a76ac41f01 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -371,7 +371,7 @@ xfs_dquot_disk_alloc(
371 tp = *tpp; 371 tp = *tpp;
372 if (error) { 372 if (error) {
373 xfs_buf_relse(bp); 373 xfs_buf_relse(bp);
374 goto error1; 374 goto error0;
375 } 375 }
376 *bpp = bp; 376 *bpp = bp;
377 return 0; 377 return 0;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 7bb46a0eecfc..d957a46dc1cb 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1571,7 +1571,7 @@ xfs_itruncate_extents_flags(
1571 */ 1571 */
1572 error = xfs_defer_finish(&tp); 1572 error = xfs_defer_finish(&tp);
1573 if (error) 1573 if (error)
1574 goto out_bmap_cancel; 1574 goto out;
1575 1575
1576 error = xfs_trans_roll_inode(&tp, ip); 1576 error = xfs_trans_roll_inode(&tp, ip);
1577 if (error) 1577 if (error)
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index dce8ba8ab681..2ec562d75494 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -518,10 +518,8 @@ xfs_reflink_cancel_cow_blocks(
518 518
519 /* Roll the transaction */ 519 /* Roll the transaction */
520 error = xfs_defer_finish(tpp); 520 error = xfs_defer_finish(tpp);
521 if (error) { 521 if (error)
522 xfs_defer_cancel(*tpp);
523 break; 522 break;
524 }
525 523
526 /* Remove the mapping from the CoW fork. */ 524 /* Remove the mapping from the CoW fork. */
527 xfs_bmap_del_extent_cow(ip, &icur, &got, &del); 525 xfs_bmap_del_extent_cow(ip, &icur, &got, &del);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index b0130b21f4de..b050663c2a70 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -933,10 +933,8 @@ __xfs_trans_commit(
933 !(tp->t_flags & XFS_TRANS_PERM_LOG_RES)); 933 !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
934 if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) { 934 if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) {
935 error = xfs_defer_finish_noroll(&tp); 935 error = xfs_defer_finish_noroll(&tp);
936 if (error) { 936 if (error)
937 xfs_defer_cancel(tp);
938 goto out_unreserve; 937 goto out_unreserve;
939 }
940 } 938 }
941 939
942 /* 940 /*