mirror of
https://github.com/torvalds/linux.git
synced 2025-01-01 07:42:07 +00:00
xfs: Always flush caches when integrity is required
There is no reason anymore for not issuing device integrity operations when teh filesystem requires ordering or data integrity guarantees. We should always issue cache flushes and FUA writes where necessary and let the underlying storage optimise them as necessary for correct integrity operation. Signed-Off-By: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
2e1d23370e
commit
2291dab2c9
@ -1711,8 +1711,7 @@ xfs_free_buftarg(
|
|||||||
percpu_counter_destroy(&btp->bt_io_count);
|
percpu_counter_destroy(&btp->bt_io_count);
|
||||||
list_lru_destroy(&btp->bt_lru);
|
list_lru_destroy(&btp->bt_lru);
|
||||||
|
|
||||||
if (mp->m_flags & XFS_MOUNT_BARRIER)
|
xfs_blkdev_issue_flush(btp);
|
||||||
xfs_blkdev_issue_flush(btp);
|
|
||||||
|
|
||||||
kmem_free(btp);
|
kmem_free(btp);
|
||||||
}
|
}
|
||||||
|
@ -149,19 +149,16 @@ xfs_file_fsync(
|
|||||||
|
|
||||||
xfs_iflags_clear(ip, XFS_ITRUNCATED);
|
xfs_iflags_clear(ip, XFS_ITRUNCATED);
|
||||||
|
|
||||||
if (mp->m_flags & XFS_MOUNT_BARRIER) {
|
/*
|
||||||
/*
|
* If we have an RT and/or log subvolume we need to make sure to flush
|
||||||
* If we have an RT and/or log subvolume we need to make sure
|
* the write cache the device used for file data first. This is to
|
||||||
* to flush the write cache the device used for file data
|
* ensure newly written file data make it to disk before logging the new
|
||||||
* first. This is to ensure newly written file data make
|
* inode size in case of an extending write.
|
||||||
* it to disk before logging the new inode size in case of
|
*/
|
||||||
* an extending write.
|
if (XFS_IS_REALTIME_INODE(ip))
|
||||||
*/
|
xfs_blkdev_issue_flush(mp->m_rtdev_targp);
|
||||||
if (XFS_IS_REALTIME_INODE(ip))
|
else if (mp->m_logdev_targp != mp->m_ddev_targp)
|
||||||
xfs_blkdev_issue_flush(mp->m_rtdev_targp);
|
xfs_blkdev_issue_flush(mp->m_ddev_targp);
|
||||||
else if (mp->m_logdev_targp != mp->m_ddev_targp)
|
|
||||||
xfs_blkdev_issue_flush(mp->m_ddev_targp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All metadata updates are logged, which means that we just have to
|
* All metadata updates are logged, which means that we just have to
|
||||||
@ -196,10 +193,8 @@ xfs_file_fsync(
|
|||||||
* an already allocated file and thus do not have any metadata to
|
* an already allocated file and thus do not have any metadata to
|
||||||
* commit.
|
* commit.
|
||||||
*/
|
*/
|
||||||
if ((mp->m_flags & XFS_MOUNT_BARRIER) &&
|
if (!log_flushed && !XFS_IS_REALTIME_INODE(ip) &&
|
||||||
mp->m_logdev_targp == mp->m_ddev_targp &&
|
mp->m_logdev_targp == mp->m_ddev_targp)
|
||||||
!XFS_IS_REALTIME_INODE(ip) &&
|
|
||||||
!log_flushed)
|
|
||||||
xfs_blkdev_issue_flush(mp->m_ddev_targp);
|
xfs_blkdev_issue_flush(mp->m_ddev_targp);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -1862,26 +1862,21 @@ xlog_sync(
|
|||||||
|
|
||||||
bp->b_io_length = BTOBB(count);
|
bp->b_io_length = BTOBB(count);
|
||||||
bp->b_fspriv = iclog;
|
bp->b_fspriv = iclog;
|
||||||
bp->b_flags &= ~(XBF_FUA | XBF_FLUSH);
|
bp->b_flags &= ~XBF_FLUSH;
|
||||||
bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE);
|
bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE | XBF_FUA);
|
||||||
|
|
||||||
if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
|
/*
|
||||||
bp->b_flags |= XBF_FUA;
|
* Flush the data device before flushing the log to make sure all meta
|
||||||
|
* data written back from the AIL actually made it to disk before
|
||||||
/*
|
* stamping the new log tail LSN into the log buffer. For an external
|
||||||
* Flush the data device before flushing the log to make
|
* log we need to issue the flush explicitly, and unfortunately
|
||||||
* sure all meta data written back from the AIL actually made
|
* synchronously here; for an internal log we can simply use the block
|
||||||
* it to disk before stamping the new log tail LSN into the
|
* layer state machine for preflushes.
|
||||||
* log buffer. For an external log we need to issue the
|
*/
|
||||||
* flush explicitly, and unfortunately synchronously here;
|
if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp)
|
||||||
* for an internal log we can simply use the block layer
|
xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp);
|
||||||
* state machine for preflushes.
|
else
|
||||||
*/
|
bp->b_flags |= XBF_FLUSH;
|
||||||
if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp)
|
|
||||||
xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp);
|
|
||||||
else
|
|
||||||
bp->b_flags |= XBF_FLUSH;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
|
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
|
||||||
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
|
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
|
||||||
@ -1906,10 +1901,8 @@ xlog_sync(
|
|||||||
xfs_buf_associate_memory(bp,
|
xfs_buf_associate_memory(bp,
|
||||||
(char *)&iclog->ic_header + count, split);
|
(char *)&iclog->ic_header + count, split);
|
||||||
bp->b_fspriv = iclog;
|
bp->b_fspriv = iclog;
|
||||||
bp->b_flags &= ~(XBF_FUA | XBF_FLUSH);
|
bp->b_flags &= ~XBF_FLUSH;
|
||||||
bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE);
|
bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE | XBF_FUA);
|
||||||
if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
|
|
||||||
bp->b_flags |= XBF_FUA;
|
|
||||||
|
|
||||||
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
|
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
|
||||||
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
|
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
|
||||||
|
Loading…
Reference in New Issue
Block a user