diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-03-14 21:52:49 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-05-19 10:58:08 -0400 |
commit | a3ccd2ca43d5cdfe0b256be02957dc5f47ec4c39 (patch) | |
tree | 08b6a0b911c5f1ba45ce9e61754f1db8331a0f72 /fs/xfs/xfs_trans.c | |
parent | 0924378a689ccb05f6d60875742dc28f69bf0129 (diff) |
xfs: clean up xfs_trans_commit logic even more
> +shut_us_down:
> + shutdown = XFS_FORCED_SHUTDOWN(mp) ? EIO : 0;
> + if (!(tp->t_flags & XFS_TRANS_DIRTY) || shutdown) {
> + xfs_trans_unreserve_and_mod_sb(tp);
> + /*
This whole area in _xfs_trans_commit is still a complete mess.
So while touching this code, unravel this mess as well to make the
whole flow of the function simpler and clearer.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r-- | fs/xfs/xfs_trans.c | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index e07b3290b3bf..2bff22995127 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1020,19 +1020,17 @@ xfs_trans_commit_iclog( | |||
1020 | * have already been unlocked as if the commit had succeeded. | 1020 | * have already been unlocked as if the commit had succeeded. |
1021 | * Do not reference the transaction structure after this call. | 1021 | * Do not reference the transaction structure after this call. |
1022 | */ | 1022 | */ |
1023 | /*ARGSUSED*/ | ||
1024 | int | 1023 | int |
1025 | _xfs_trans_commit( | 1024 | _xfs_trans_commit( |
1026 | xfs_trans_t *tp, | 1025 | struct xfs_trans *tp, |
1027 | uint flags, | 1026 | uint flags, |
1028 | int *log_flushed) | 1027 | int *log_flushed) |
1029 | { | 1028 | { |
1030 | xfs_mount_t *mp = tp->t_mountp; | 1029 | struct xfs_mount *mp = tp->t_mountp; |
1031 | xfs_lsn_t commit_lsn = -1; | 1030 | xfs_lsn_t commit_lsn = -1; |
1032 | int error; | 1031 | int error = 0; |
1033 | int log_flags = 0; | 1032 | int log_flags = 0; |
1034 | int sync = tp->t_flags & XFS_TRANS_SYNC; | 1033 | int sync = tp->t_flags & XFS_TRANS_SYNC; |
1035 | int shutdown; | ||
1036 | 1034 | ||
1037 | /* | 1035 | /* |
1038 | * Determine whether this commit is releasing a permanent | 1036 | * Determine whether this commit is releasing a permanent |
@@ -1050,30 +1048,14 @@ _xfs_trans_commit( | |||
1050 | * Also make sure to return any reserved blocks to | 1048 | * Also make sure to return any reserved blocks to |
1051 | * the free pool. | 1049 | * the free pool. |
1052 | */ | 1050 | */ |
1053 | shut_us_down: | 1051 | if (!(tp->t_flags & XFS_TRANS_DIRTY)) |
1054 | shutdown = XFS_FORCED_SHUTDOWN(mp) ? EIO : 0; | 1052 | goto out_unreserve; |
1055 | if (!(tp->t_flags & XFS_TRANS_DIRTY) || shutdown) { | 1053 | |
1056 | xfs_trans_unreserve_and_mod_sb(tp); | 1054 | if (XFS_FORCED_SHUTDOWN(mp)) { |
1057 | /* | 1055 | error = XFS_ERROR(EIO); |
1058 | * It is indeed possible for the transaction to be | 1056 | goto out_unreserve; |
1059 | * not dirty but the dqinfo portion to be. All that | ||
1060 | * means is that we have some (non-persistent) quota | ||
1061 | * reservations that need to be unreserved. | ||
1062 | */ | ||
1063 | xfs_trans_unreserve_and_mod_dquots(tp); | ||
1064 | if (tp->t_ticket) { | ||
1065 | commit_lsn = xfs_log_done(mp, tp->t_ticket, | ||
1066 | NULL, log_flags); | ||
1067 | if (commit_lsn == -1 && !shutdown) | ||
1068 | shutdown = XFS_ERROR(EIO); | ||
1069 | } | ||
1070 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | ||
1071 | xfs_trans_free_items(tp, shutdown? XFS_TRANS_ABORT : 0); | ||
1072 | xfs_trans_free_busy(tp); | ||
1073 | xfs_trans_free(tp); | ||
1074 | XFS_STATS_INC(xs_trans_empty); | ||
1075 | return (shutdown); | ||
1076 | } | 1057 | } |
1058 | |||
1077 | ASSERT(tp->t_ticket != NULL); | 1059 | ASSERT(tp->t_ticket != NULL); |
1078 | 1060 | ||
1079 | /* | 1061 | /* |
@@ -1086,7 +1068,8 @@ shut_us_down: | |||
1086 | error = xfs_trans_commit_iclog(mp, tp, &commit_lsn, flags); | 1068 | error = xfs_trans_commit_iclog(mp, tp, &commit_lsn, flags); |
1087 | if (error == ENOMEM) { | 1069 | if (error == ENOMEM) { |
1088 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); | 1070 | xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); |
1089 | goto shut_us_down; | 1071 | error = XFS_ERROR(EIO); |
1072 | goto out_unreserve; | ||
1090 | } | 1073 | } |
1091 | 1074 | ||
1092 | /* | 1075 | /* |
@@ -1103,7 +1086,29 @@ shut_us_down: | |||
1103 | XFS_STATS_INC(xs_trans_async); | 1086 | XFS_STATS_INC(xs_trans_async); |
1104 | } | 1087 | } |
1105 | 1088 | ||
1106 | return (error); | 1089 | return error; |
1090 | |||
1091 | out_unreserve: | ||
1092 | xfs_trans_unreserve_and_mod_sb(tp); | ||
1093 | |||
1094 | /* | ||
1095 | * It is indeed possible for the transaction to be not dirty but | ||
1096 | * the dqinfo portion to be. All that means is that we have some | ||
1097 | * (non-persistent) quota reservations that need to be unreserved. | ||
1098 | */ | ||
1099 | xfs_trans_unreserve_and_mod_dquots(tp); | ||
1100 | if (tp->t_ticket) { | ||
1101 | commit_lsn = xfs_log_done(mp, tp->t_ticket, NULL, log_flags); | ||
1102 | if (commit_lsn == -1 && !error) | ||
1103 | error = XFS_ERROR(EIO); | ||
1104 | } | ||
1105 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | ||
1106 | xfs_trans_free_items(tp, error ? XFS_TRANS_ABORT : 0); | ||
1107 | xfs_trans_free_busy(tp); | ||
1108 | xfs_trans_free(tp); | ||
1109 | |||
1110 | XFS_STATS_INC(xs_trans_empty); | ||
1111 | return error; | ||
1107 | } | 1112 | } |
1108 | 1113 | ||
1109 | /* | 1114 | /* |