diff options
author | Brian Foster <bfoster@redhat.com> | 2018-08-01 10:20:33 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-08-03 02:05:14 -0400 |
commit | 9b1f4e9831df29776031e86e112e68784f1fc079 (patch) | |
tree | 02cd52f1c6fe6851354ecb33cf6850173e618f46 /fs/xfs | |
parent | 60f31a609ed3d28791acb2bc24188cb7e2259176 (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.c | 16 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_attr_remote.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_defer.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_reflink.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 4 |
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; |
747 | out_defer_cancel: | 747 | out_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 | ||
418 | out: | 418 | out: |
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 | ||
429 | int | 430 | int |
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 | /* |