Commit 80f6c29d authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

xfs: replace barriers with explicit flush / FUA usage



Switch to the WRITE_FLUSH_FUA flag for log writes and remove the EOPNOTSUPP
detection for barriers.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Signed-off-by: default avatarJens Axboe <jaxboe@fusionio.com>
parent 2cf6d26a
Loading
Loading
Loading
Loading
+2 −14
Original line number Diff line number Diff line
@@ -929,19 +929,7 @@ xfs_buf_iodone_work(
	xfs_buf_t		*bp =
		container_of(work, xfs_buf_t, b_iodone_work);

	/*
	 * We can get an EOPNOTSUPP to ordered writes.  Here we clear the
	 * ordered flag and reissue them.  Because we can't tell the higher
	 * layers directly that they should not issue ordered I/O anymore, they
	 * need to check if the _XFS_BARRIER_FAILED flag was set during I/O completion.
	 */
	if ((bp->b_error == EOPNOTSUPP) &&
	    (bp->b_flags & (XBF_ORDERED|XBF_ASYNC)) == (XBF_ORDERED|XBF_ASYNC)) {
		trace_xfs_buf_ordered_retry(bp, _RET_IP_);
		bp->b_flags &= ~XBF_ORDERED;
		bp->b_flags |= _XFS_BARRIER_FAILED;
		xfs_buf_iorequest(bp);
	} else if (bp->b_iodone)
	if (bp->b_iodone)
		(*(bp->b_iodone))(bp);
	else if (bp->b_flags & XBF_ASYNC)
		xfs_buf_relse(bp);
@@ -1200,7 +1188,7 @@ _xfs_buf_ioapply(

	if (bp->b_flags & XBF_ORDERED) {
		ASSERT(!(bp->b_flags & XBF_READ));
		rw = WRITE_BARRIER;
		rw = WRITE_FLUSH_FUA;
	} else if (bp->b_flags & XBF_LOG_BUFFER) {
		ASSERT(!(bp->b_flags & XBF_READ_AHEAD));
		bp->b_flags &= ~_XBF_RUN_QUEUES;
+1 −10
Original line number Diff line number Diff line
@@ -86,14 +86,6 @@ typedef enum {
 */
#define _XBF_PAGE_LOCKED	(1 << 22)

/*
 * If we try a barrier write, but it fails we have to communicate
 * this to the upper layers.  Unfortunately b_error gets overwritten
 * when the buffer is re-issued so we have to add another flag to
 * keep this information.
 */
#define _XFS_BARRIER_FAILED	(1 << 23)

typedef unsigned int xfs_buf_flags_t;

#define XFS_BUF_FLAGS \
@@ -114,8 +106,7 @@ typedef unsigned int xfs_buf_flags_t;
	{ _XBF_PAGES,		"PAGES" }, \
	{ _XBF_RUN_QUEUES,	"RUN_QUEUES" }, \
	{ _XBF_DELWRI_Q,	"DELWRI_Q" }, \
	{ _XBF_PAGE_LOCKED,	"PAGE_LOCKED" }, \
	{ _XFS_BARRIER_FAILED,	"BARRIER_FAILED" }
	{ _XBF_PAGE_LOCKED,	"PAGE_LOCKED" }


typedef enum {
+0 −1
Original line number Diff line number Diff line
@@ -325,7 +325,6 @@ DEFINE_BUF_EVENT(xfs_buf_lock);
DEFINE_BUF_EVENT(xfs_buf_lock_done);
DEFINE_BUF_EVENT(xfs_buf_cond_lock);
DEFINE_BUF_EVENT(xfs_buf_unlock);
DEFINE_BUF_EVENT(xfs_buf_ordered_retry);
DEFINE_BUF_EVENT(xfs_buf_iowait);
DEFINE_BUF_EVENT(xfs_buf_iowait_done);
DEFINE_BUF_EVENT(xfs_buf_delwri_queue);
+0 −13
Original line number Diff line number Diff line
@@ -916,19 +916,6 @@ xlog_iodone(xfs_buf_t *bp)
	aborted = 0;
	l = iclog->ic_log;

	/*
	 * If the _XFS_BARRIER_FAILED flag was set by a lower
	 * layer, it means the underlying device no longer supports
	 * barrier I/O. Warn loudly and turn off barriers.
	 */
	if (bp->b_flags & _XFS_BARRIER_FAILED) {
		bp->b_flags &= ~_XFS_BARRIER_FAILED;
		l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
		xfs_fs_cmn_err(CE_WARN, l->l_mp,
				"xlog_iodone: Barriers are no longer supported"
				" by device. Disabling barriers\n");
	}

	/*
	 * Race to shutdown the filesystem if we see an error.
	 */