xfs: remove periodic superblock writeback
All modifications to the superblock are done transactional through xfs_trans_log_buf, so there is no reason to initiate periodic asynchronous writeback. This only removes the superblock from the delwri list and will lead to sub-optimal I/O scheduling. Cut down xfs_sync_fsdata now that it's only used for synchronous superblock writes and move the log coverage checks into the two callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
parent
f983710758
commit
df308bcfec
@ -356,68 +356,24 @@ xfs_commit_dummy_trans(
|
|||||||
|
|
||||||
STATIC int
|
STATIC int
|
||||||
xfs_sync_fsdata(
|
xfs_sync_fsdata(
|
||||||
struct xfs_mount *mp,
|
struct xfs_mount *mp)
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
struct xfs_buf *bp;
|
struct xfs_buf *bp;
|
||||||
struct xfs_buf_log_item *bip;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this is xfssyncd() then only sync the superblock if we can
|
* If the buffer is pinned then push on the log so we won't get stuck
|
||||||
* lock it without sleeping and it is not pinned.
|
* waiting in the write for someone, maybe ourselves, to flush the log.
|
||||||
|
*
|
||||||
|
* Even though we just pushed the log above, we did not have the
|
||||||
|
* superblock buffer locked at that point so it can become pinned in
|
||||||
|
* between there and here.
|
||||||
*/
|
*/
|
||||||
if (flags & SYNC_TRYLOCK) {
|
bp = xfs_getsb(mp, 0);
|
||||||
ASSERT(!(flags & SYNC_WAIT));
|
if (XFS_BUF_ISPINNED(bp))
|
||||||
|
xfs_log_force(mp, 0);
|
||||||
|
|
||||||
bp = xfs_getsb(mp, XBF_TRYLOCK);
|
XFS_BUF_UNASYNC(bp);
|
||||||
if (!bp)
|
return xfs_bwrite(mp, bp);
|
||||||
goto out;
|
|
||||||
|
|
||||||
bip = XFS_BUF_FSPRIVATE(bp, struct xfs_buf_log_item *);
|
|
||||||
if (!bip || !xfs_buf_item_dirty(bip) || XFS_BUF_ISPINNED(bp))
|
|
||||||
goto out_brelse;
|
|
||||||
} else {
|
|
||||||
bp = xfs_getsb(mp, 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the buffer is pinned then push on the log so we won't
|
|
||||||
* get stuck waiting in the write for someone, maybe
|
|
||||||
* ourselves, to flush the log.
|
|
||||||
*
|
|
||||||
* Even though we just pushed the log above, we did not have
|
|
||||||
* the superblock buffer locked at that point so it can
|
|
||||||
* become pinned in between there and here.
|
|
||||||
*/
|
|
||||||
if (XFS_BUF_ISPINNED(bp))
|
|
||||||
xfs_log_force(mp, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (flags & SYNC_WAIT)
|
|
||||||
XFS_BUF_UNASYNC(bp);
|
|
||||||
else
|
|
||||||
XFS_BUF_ASYNC(bp);
|
|
||||||
|
|
||||||
error = xfs_bwrite(mp, bp);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this is a data integrity sync make sure all pending buffers
|
|
||||||
* are flushed out for the log coverage check below.
|
|
||||||
*/
|
|
||||||
if (flags & SYNC_WAIT)
|
|
||||||
xfs_flush_buftarg(mp->m_ddev_targp, 1);
|
|
||||||
|
|
||||||
if (xfs_log_need_covered(mp))
|
|
||||||
error = xfs_commit_dummy_trans(mp, flags);
|
|
||||||
return error;
|
|
||||||
|
|
||||||
out_brelse:
|
|
||||||
xfs_buf_relse(bp);
|
|
||||||
out:
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -441,7 +397,7 @@ int
|
|||||||
xfs_quiesce_data(
|
xfs_quiesce_data(
|
||||||
struct xfs_mount *mp)
|
struct xfs_mount *mp)
|
||||||
{
|
{
|
||||||
int error;
|
int error, error2 = 0;
|
||||||
|
|
||||||
/* push non-blocking */
|
/* push non-blocking */
|
||||||
xfs_sync_data(mp, 0);
|
xfs_sync_data(mp, 0);
|
||||||
@ -452,13 +408,20 @@ xfs_quiesce_data(
|
|||||||
xfs_qm_sync(mp, SYNC_WAIT);
|
xfs_qm_sync(mp, SYNC_WAIT);
|
||||||
|
|
||||||
/* write superblock and hoover up shutdown errors */
|
/* write superblock and hoover up shutdown errors */
|
||||||
error = xfs_sync_fsdata(mp, SYNC_WAIT);
|
error = xfs_sync_fsdata(mp);
|
||||||
|
|
||||||
|
/* make sure all delwri buffers are written out */
|
||||||
|
xfs_flush_buftarg(mp->m_ddev_targp, 1);
|
||||||
|
|
||||||
|
/* mark the log as covered if needed */
|
||||||
|
if (xfs_log_need_covered(mp))
|
||||||
|
error2 = xfs_commit_dummy_trans(mp, SYNC_WAIT);
|
||||||
|
|
||||||
/* flush data-only devices */
|
/* flush data-only devices */
|
||||||
if (mp->m_rtdev_targp)
|
if (mp->m_rtdev_targp)
|
||||||
XFS_bflush(mp->m_rtdev_targp);
|
XFS_bflush(mp->m_rtdev_targp);
|
||||||
|
|
||||||
return error;
|
return error ? error : error2;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void
|
STATIC void
|
||||||
@ -581,9 +544,9 @@ xfs_flush_inodes(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Every sync period we need to unpin all items, reclaim inodes, sync
|
* Every sync period we need to unpin all items, reclaim inodes and sync
|
||||||
* quota and write out the superblock. We might need to cover the log
|
* disk quotas. We might need to cover the log to indicate that the
|
||||||
* to indicate it is idle.
|
* filesystem is idle.
|
||||||
*/
|
*/
|
||||||
STATIC void
|
STATIC void
|
||||||
xfs_sync_worker(
|
xfs_sync_worker(
|
||||||
@ -597,7 +560,8 @@ xfs_sync_worker(
|
|||||||
xfs_reclaim_inodes(mp, 0);
|
xfs_reclaim_inodes(mp, 0);
|
||||||
/* dgc: errors ignored here */
|
/* dgc: errors ignored here */
|
||||||
error = xfs_qm_sync(mp, SYNC_TRYLOCK);
|
error = xfs_qm_sync(mp, SYNC_TRYLOCK);
|
||||||
error = xfs_sync_fsdata(mp, SYNC_TRYLOCK);
|
if (xfs_log_need_covered(mp))
|
||||||
|
error = xfs_commit_dummy_trans(mp, 0);
|
||||||
}
|
}
|
||||||
mp->m_sync_seq++;
|
mp->m_sync_seq++;
|
||||||
wake_up(&mp->m_wait_single_sync_task);
|
wake_up(&mp->m_wait_single_sync_task);
|
||||||
|
Loading…
Reference in New Issue
Block a user