diff options
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r-- | fs/xfs/xfs_log_cil.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 7e5455391176..039c873e6fb2 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c | |||
@@ -385,7 +385,15 @@ xlog_cil_committed( | |||
385 | xfs_extent_busy_clear(mp, &ctx->busy_extents, | 385 | xfs_extent_busy_clear(mp, &ctx->busy_extents, |
386 | (mp->m_flags & XFS_MOUNT_DISCARD) && !abort); | 386 | (mp->m_flags & XFS_MOUNT_DISCARD) && !abort); |
387 | 387 | ||
388 | /* | ||
389 | * If we are aborting the commit, wake up anyone waiting on the | ||
390 | * committing list. If we don't, then a shutdown we can leave processes | ||
391 | * waiting in xlog_cil_force_lsn() waiting on a sequence commit that | ||
392 | * will never happen because we aborted it. | ||
393 | */ | ||
388 | spin_lock(&ctx->cil->xc_push_lock); | 394 | spin_lock(&ctx->cil->xc_push_lock); |
395 | if (abort) | ||
396 | wake_up_all(&ctx->cil->xc_commit_wait); | ||
389 | list_del(&ctx->committing); | 397 | list_del(&ctx->committing); |
390 | spin_unlock(&ctx->cil->xc_push_lock); | 398 | spin_unlock(&ctx->cil->xc_push_lock); |
391 | 399 | ||
@@ -564,8 +572,18 @@ restart: | |||
564 | spin_lock(&cil->xc_push_lock); | 572 | spin_lock(&cil->xc_push_lock); |
565 | list_for_each_entry(new_ctx, &cil->xc_committing, committing) { | 573 | list_for_each_entry(new_ctx, &cil->xc_committing, committing) { |
566 | /* | 574 | /* |
575 | * Avoid getting stuck in this loop because we were woken by the | ||
576 | * shutdown, but then went back to sleep once already in the | ||
577 | * shutdown state. | ||
578 | */ | ||
579 | if (XLOG_FORCED_SHUTDOWN(log)) { | ||
580 | spin_unlock(&cil->xc_push_lock); | ||
581 | goto out_abort_free_ticket; | ||
582 | } | ||
583 | |||
584 | /* | ||
567 | * Higher sequences will wait for this one so skip them. | 585 | * Higher sequences will wait for this one so skip them. |
568 | * Don't wait for own own sequence, either. | 586 | * Don't wait for our own sequence, either. |
569 | */ | 587 | */ |
570 | if (new_ctx->sequence >= ctx->sequence) | 588 | if (new_ctx->sequence >= ctx->sequence) |
571 | continue; | 589 | continue; |
@@ -810,6 +828,13 @@ restart: | |||
810 | */ | 828 | */ |
811 | spin_lock(&cil->xc_push_lock); | 829 | spin_lock(&cil->xc_push_lock); |
812 | list_for_each_entry(ctx, &cil->xc_committing, committing) { | 830 | list_for_each_entry(ctx, &cil->xc_committing, committing) { |
831 | /* | ||
832 | * Avoid getting stuck in this loop because we were woken by the | ||
833 | * shutdown, but then went back to sleep once already in the | ||
834 | * shutdown state. | ||
835 | */ | ||
836 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
837 | goto out_shutdown; | ||
813 | if (ctx->sequence > sequence) | 838 | if (ctx->sequence > sequence) |
814 | continue; | 839 | continue; |
815 | if (!ctx->commit_lsn) { | 840 | if (!ctx->commit_lsn) { |
@@ -833,14 +858,12 @@ restart: | |||
833 | * push sequence after the above wait loop and the CIL still contains | 858 | * push sequence after the above wait loop and the CIL still contains |
834 | * dirty objects. | 859 | * dirty objects. |
835 | * | 860 | * |
836 | * When the push occurs, it will empty the CIL and | 861 | * When the push occurs, it will empty the CIL and atomically increment |
837 | * atomically increment the currect sequence past the push sequence and | 862 | * the currect sequence past the push sequence and move it into the |
838 | * move it into the committing list. Of course, if the CIL is clean at | 863 | * committing list. Of course, if the CIL is clean at the time of the |
839 | * the time of the push, it won't have pushed the CIL at all, so in that | 864 | * push, it won't have pushed the CIL at all, so in that case we should |
840 | * case we should try the push for this sequence again from the start | 865 | * try the push for this sequence again from the start just in case. |
841 | * just in case. | ||
842 | */ | 866 | */ |
843 | |||
844 | if (sequence == cil->xc_current_sequence && | 867 | if (sequence == cil->xc_current_sequence && |
845 | !list_empty(&cil->xc_cil)) { | 868 | !list_empty(&cil->xc_cil)) { |
846 | spin_unlock(&cil->xc_push_lock); | 869 | spin_unlock(&cil->xc_push_lock); |
@@ -849,6 +872,17 @@ restart: | |||
849 | 872 | ||
850 | spin_unlock(&cil->xc_push_lock); | 873 | spin_unlock(&cil->xc_push_lock); |
851 | return commit_lsn; | 874 | return commit_lsn; |
875 | |||
876 | /* | ||
877 | * We detected a shutdown in progress. We need to trigger the log force | ||
878 | * to pass through it's iclog state machine error handling, even though | ||
879 | * we are already in a shutdown state. Hence we can't return | ||
880 | * NULLCOMMITLSN here as that has special meaning to log forces (i.e. | ||
881 | * LSN is already stable), so we return a zero LSN instead. | ||
882 | */ | ||
883 | out_shutdown: | ||
884 | spin_unlock(&cil->xc_push_lock); | ||
885 | return 0; | ||
852 | } | 886 | } |
853 | 887 | ||
854 | /* | 888 | /* |