Commit 81e5b50a authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent c7cc296d
Loading
Loading
Loading
Loading
+31 −45
Original line number Diff line number Diff line
@@ -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;