xfs: factor out a xlog_wait_on_iclog helper

Factor out the shared code to wait for a log force into a new helper.
This helper uses the XLOG_FORCED_SHUTDOWN check previous only used
by the unmount code over the equivalent iclog ioerror state used by
the other two functions.

There is a slight behavior change in that the force of the unmount
record is now accounted in the log force statistics.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
Christoph Hellwig 2020-03-20 08:49:18 -07:00 committed by Darrick J. Wong
parent c7cc296ddd
commit 81e5b50a8f

View File

@ -859,6 +859,31 @@ xfs_log_mount_cancel(
xfs_log_unmount(mp);
}
/*
* Wait for the iclog to be written disk, or return an error if the log has been
* shut down.
*/
static int
xlog_wait_on_iclog(
struct xlog_in_core *iclog)
__releases(iclog->ic_log->l_icloglock)
{
struct xlog *log = iclog->ic_log;
if (!XLOG_FORCED_SHUTDOWN(log) &&
iclog->ic_state != XLOG_STATE_ACTIVE &&
iclog->ic_state != XLOG_STATE_DIRTY) {
XFS_STATS_INC(log->l_mp, xs_log_force_sleep);
xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
} else {
spin_unlock(&log->l_icloglock);
}
if (XLOG_FORCED_SHUTDOWN(log))
return -EIO;
return 0;
}
/*
* Final log writes as part of unmount.
*
@ -926,18 +951,7 @@ out_err:
atomic_inc(&iclog->ic_refcnt);
xlog_state_want_sync(log, iclog);
error = xlog_state_release_iclog(log, iclog);
switch (iclog->ic_state) {
default:
if (!XLOG_FORCED_SHUTDOWN(log)) {
xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
break;
}
/* fall through */
case XLOG_STATE_ACTIVE:
case XLOG_STATE_DIRTY:
spin_unlock(&log->l_icloglock);
break;
}
xlog_wait_on_iclog(iclog);
if (tic) {
trace_xfs_log_umount_write(log, tic);
@ -3230,9 +3244,6 @@ xfs_log_force(
* previous iclog and go to sleep.
*/
iclog = iclog->ic_prev;
if (iclog->ic_state == XLOG_STATE_ACTIVE ||
iclog->ic_state == XLOG_STATE_DIRTY)
goto out_unlock;
} else if (iclog->ic_state == XLOG_STATE_ACTIVE) {
if (atomic_read(&iclog->ic_refcnt) == 0) {
/*
@ -3248,8 +3259,7 @@ xfs_log_force(
if (xlog_state_release_iclog(log, iclog))
goto out_error;
if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn ||
iclog->ic_state == XLOG_STATE_DIRTY)
if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn)
goto out_unlock;
} else {
/*
@ -3269,17 +3279,8 @@ xfs_log_force(
;
}
if (!(flags & XFS_LOG_SYNC))
goto out_unlock;
if (iclog->ic_state == XLOG_STATE_IOERROR)
goto out_error;
XFS_STATS_INC(mp, xs_log_force_sleep);
xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
if (iclog->ic_state == XLOG_STATE_IOERROR)
return -EIO;
return 0;
if (flags & XFS_LOG_SYNC)
return xlog_wait_on_iclog(iclog);
out_unlock:
spin_unlock(&log->l_icloglock);
return 0;
@ -3310,9 +3311,6 @@ __xfs_log_force_lsn(
goto out_unlock;
}
if (iclog->ic_state == XLOG_STATE_DIRTY)
goto out_unlock;
if (iclog->ic_state == XLOG_STATE_ACTIVE) {
/*
* We sleep here if we haven't already slept (e.g. this is the
@ -3346,20 +3344,8 @@ __xfs_log_force_lsn(
*log_flushed = 1;
}
if (!(flags & XFS_LOG_SYNC) ||
(iclog->ic_state == XLOG_STATE_ACTIVE ||
iclog->ic_state == XLOG_STATE_DIRTY))
goto out_unlock;
if (iclog->ic_state == XLOG_STATE_IOERROR)
goto out_error;
XFS_STATS_INC(mp, xs_log_force_sleep);
xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
if (iclog->ic_state == XLOG_STATE_IOERROR)
return -EIO;
return 0;
if (flags & XFS_LOG_SYNC)
return xlog_wait_on_iclog(iclog);
out_unlock:
spin_unlock(&log->l_icloglock);
return 0;