diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
| -rw-r--r-- | fs/xfs/xfs_log.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index e8fba92d7cd9..2be019136287 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -745,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t *mp, | |||
| 745 | 745 | ||
| 746 | /* | 746 | /* |
| 747 | * Determine if we have a transaction that has gone to disk | 747 | * Determine if we have a transaction that has gone to disk |
| 748 | * that needs to be covered. Log activity needs to be idle (no AIL and | 748 | * that needs to be covered. To begin the transition to the idle state |
| 749 | * nothing in the iclogs). And, we need to be in the right state indicating | 749 | * firstly the log needs to be idle (no AIL and nothing in the iclogs). |
| 750 | * something has gone out. | 750 | * If we are then in a state where covering is needed, the caller is informed |
| 751 | * that dummy transactions are required to move the log into the idle state. | ||
| 752 | * | ||
| 753 | * Because this is called as part of the sync process, we should also indicate | ||
| 754 | * that dummy transactions should be issued in anything but the covered or | ||
| 755 | * idle states. This ensures that the log tail is accurately reflected in | ||
| 756 | * the log at the end of the sync, hence if a crash occurrs avoids replay | ||
| 757 | * of transactions where the metadata is already on disk. | ||
| 751 | */ | 758 | */ |
| 752 | int | 759 | int |
| 753 | xfs_log_need_covered(xfs_mount_t *mp) | 760 | xfs_log_need_covered(xfs_mount_t *mp) |
| @@ -759,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
| 759 | return 0; | 766 | return 0; |
| 760 | 767 | ||
| 761 | spin_lock(&log->l_icloglock); | 768 | spin_lock(&log->l_icloglock); |
| 762 | if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || | 769 | switch (log->l_covered_state) { |
| 763 | (log->l_covered_state == XLOG_STATE_COVER_NEED2)) | 770 | case XLOG_STATE_COVER_DONE: |
| 764 | && !xfs_trans_ail_tail(log->l_ailp) | 771 | case XLOG_STATE_COVER_DONE2: |
| 765 | && xlog_iclogs_empty(log)) { | 772 | case XLOG_STATE_COVER_IDLE: |
| 766 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) | 773 | break; |
| 767 | log->l_covered_state = XLOG_STATE_COVER_DONE; | 774 | case XLOG_STATE_COVER_NEED: |
| 768 | else { | 775 | case XLOG_STATE_COVER_NEED2: |
| 769 | ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2); | 776 | if (!xfs_trans_ail_tail(log->l_ailp) && |
| 770 | log->l_covered_state = XLOG_STATE_COVER_DONE2; | 777 | xlog_iclogs_empty(log)) { |
| 778 | if (log->l_covered_state == XLOG_STATE_COVER_NEED) | ||
| 779 | log->l_covered_state = XLOG_STATE_COVER_DONE; | ||
| 780 | else | ||
| 781 | log->l_covered_state = XLOG_STATE_COVER_DONE2; | ||
| 771 | } | 782 | } |
| 783 | /* FALLTHRU */ | ||
| 784 | default: | ||
| 772 | needed = 1; | 785 | needed = 1; |
| 786 | break; | ||
| 773 | } | 787 | } |
| 774 | spin_unlock(&log->l_icloglock); | 788 | spin_unlock(&log->l_icloglock); |
| 775 | return needed; | 789 | return needed; |
