diff options
| -rw-r--r-- | fs/xfs/xfs_log_cil.c | 14 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.c | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans_priv.h | 3 |
3 files changed, 17 insertions, 5 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 31e4ea2d19ac..ef8e7d9f445d 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
| @@ -377,9 +377,23 @@ xfs_log_commit_cil( | |||
| 377 | xfs_log_done(mp, tp->t_ticket, NULL, log_flags); | 377 | xfs_log_done(mp, tp->t_ticket, NULL, log_flags); |
| 378 | xfs_trans_unreserve_and_mod_sb(tp); | 378 | xfs_trans_unreserve_and_mod_sb(tp); |
| 379 | 379 | ||
| 380 | /* | ||
| 381 | * Once all the items of the transaction have been copied to the CIL, | ||
| 382 | * the items can be unlocked and freed. | ||
| 383 | * | ||
| 384 | * This needs to be done before we drop the CIL context lock because we | ||
| 385 | * have to update state in the log items and unlock them before they go | ||
| 386 | * to disk. If we don't, then the CIL checkpoint can race with us and | ||
| 387 | * we can run checkpoint completion before we've updated and unlocked | ||
| 388 | * the log items. This affects (at least) processing of stale buffers, | ||
| 389 | * inodes and EFIs. | ||
| 390 | */ | ||
| 391 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
| 392 | |||
| 380 | /* check for background commit before unlock */ | 393 | /* check for background commit before unlock */ |
| 381 | if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log)) | 394 | if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log)) |
| 382 | push = 1; | 395 | push = 1; |
| 396 | |||
| 383 | up_read(&log->l_cilp->xc_ctx_lock); | 397 | up_read(&log->l_cilp->xc_ctx_lock); |
| 384 | 398 | ||
| 385 | /* | 399 | /* |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index fdca7416c754..1c47edaea0d2 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
| @@ -1167,7 +1167,7 @@ xfs_trans_del_item( | |||
| 1167 | * Unlock all of the items of a transaction and free all the descriptors | 1167 | * Unlock all of the items of a transaction and free all the descriptors |
| 1168 | * of that transaction. | 1168 | * of that transaction. |
| 1169 | */ | 1169 | */ |
| 1170 | STATIC void | 1170 | void |
| 1171 | xfs_trans_free_items( | 1171 | xfs_trans_free_items( |
| 1172 | struct xfs_trans *tp, | 1172 | struct xfs_trans *tp, |
| 1173 | xfs_lsn_t commit_lsn, | 1173 | xfs_lsn_t commit_lsn, |
| @@ -1653,9 +1653,6 @@ xfs_trans_commit_cil( | |||
| 1653 | return error; | 1653 | return error; |
| 1654 | 1654 | ||
| 1655 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1655 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
| 1656 | |||
| 1657 | /* xfs_trans_free_items() unlocks them first */ | ||
| 1658 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
| 1659 | xfs_trans_free(tp); | 1656 | xfs_trans_free(tp); |
| 1660 | return 0; | 1657 | return 0; |
| 1661 | } | 1658 | } |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index e2d93d8ead7b..62da86c90de5 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
| @@ -25,7 +25,8 @@ struct xfs_trans; | |||
| 25 | 25 | ||
| 26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); | 26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); |
| 27 | void xfs_trans_del_item(struct xfs_log_item *); | 27 | void xfs_trans_del_item(struct xfs_log_item *); |
| 28 | 28 | void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn, | |
| 29 | int flags); | ||
| 29 | void xfs_trans_item_committed(struct xfs_log_item *lip, | 30 | void xfs_trans_item_committed(struct xfs_log_item *lip, |
| 30 | xfs_lsn_t commit_lsn, int aborted); | 31 | xfs_lsn_t commit_lsn, int aborted); |
| 31 | void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); | 32 | void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); |
