xfs: halt auto-reclamation activities while rebuilding rmap

Rebuilding the reverse-mapping tree requires us to quiesce all inodes in
the filesystem, so we must stop background reclamation of post-EOF and
CoW prealloc blocks.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Darrick J. Wong 2018-05-09 10:03:56 -07:00
parent 95eb308caa
commit d6b636ebb1
4 changed files with 31 additions and 12 deletions

View file

@ -1826,3 +1826,21 @@ xfs_inode_clear_cowblocks_tag(
return __xfs_inode_clear_blocks_tag(ip, return __xfs_inode_clear_blocks_tag(ip,
trace_xfs_perag_clear_cowblocks, XFS_ICI_COWBLOCKS_TAG); trace_xfs_perag_clear_cowblocks, XFS_ICI_COWBLOCKS_TAG);
} }
/* Disable post-EOF and CoW block auto-reclamation. */
void
xfs_icache_disable_reclaim(
struct xfs_mount *mp)
{
cancel_delayed_work_sync(&mp->m_eofblocks_work);
cancel_delayed_work_sync(&mp->m_cowblocks_work);
}
/* Enable post-EOF and CoW block auto-reclamation. */
void
xfs_icache_enable_reclaim(
struct xfs_mount *mp)
{
xfs_queue_eofblocks(mp);
xfs_queue_cowblocks(mp);
}

View file

@ -131,4 +131,7 @@ xfs_fs_eofblocks_from_user(
int xfs_icache_inode_is_allocated(struct xfs_mount *mp, struct xfs_trans *tp, int xfs_icache_inode_is_allocated(struct xfs_mount *mp, struct xfs_trans *tp,
xfs_ino_t ino, bool *inuse); xfs_ino_t ino, bool *inuse);
void xfs_icache_disable_reclaim(struct xfs_mount *mp);
void xfs_icache_enable_reclaim(struct xfs_mount *mp);
#endif #endif

View file

@ -1072,9 +1072,7 @@ xfs_unmountfs(
uint64_t resblks; uint64_t resblks;
int error; int error;
cancel_delayed_work_sync(&mp->m_eofblocks_work); xfs_icache_disable_reclaim(mp);
cancel_delayed_work_sync(&mp->m_cowblocks_work);
xfs_fs_unreserve_ag_blocks(mp); xfs_fs_unreserve_ag_blocks(mp);
xfs_qm_unmount_quotas(mp); xfs_qm_unmount_quotas(mp);
xfs_rtunmount_inodes(mp); xfs_rtunmount_inodes(mp);

View file

@ -1372,7 +1372,6 @@ xfs_fs_remount(
*/ */
xfs_restore_resvblks(mp); xfs_restore_resvblks(mp);
xfs_log_work_queue(mp); xfs_log_work_queue(mp);
xfs_queue_eofblocks(mp);
/* Recover any CoW blocks that never got remapped. */ /* Recover any CoW blocks that never got remapped. */
error = xfs_reflink_recover_cow(mp); error = xfs_reflink_recover_cow(mp);
@ -1382,7 +1381,7 @@ xfs_fs_remount(
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
return error; return error;
} }
xfs_queue_cowblocks(mp); xfs_icache_enable_reclaim(mp);
/* Create the per-AG metadata reservation pool .*/ /* Create the per-AG metadata reservation pool .*/
error = xfs_fs_reserve_ag_blocks(mp); error = xfs_fs_reserve_ag_blocks(mp);
@ -1392,8 +1391,13 @@ xfs_fs_remount(
/* rw -> ro */ /* rw -> ro */
if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) { if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & SB_RDONLY)) {
/*
* Cancel background eofb scanning so it cannot race with the
* final log force+buftarg wait and deadlock the remount.
*/
xfs_icache_disable_reclaim(mp);
/* Get rid of any leftover CoW reservations... */ /* Get rid of any leftover CoW reservations... */
cancel_delayed_work_sync(&mp->m_cowblocks_work);
error = xfs_icache_free_cowblocks(mp, NULL); error = xfs_icache_free_cowblocks(mp, NULL);
if (error) { if (error) {
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
@ -1416,12 +1420,6 @@ xfs_fs_remount(
*/ */
xfs_save_resvblks(mp); xfs_save_resvblks(mp);
/*
* Cancel background eofb scanning so it cannot race with the
* final log force+buftarg wait and deadlock the remount.
*/
cancel_delayed_work_sync(&mp->m_eofblocks_work);
xfs_quiesce_attr(mp); xfs_quiesce_attr(mp);
mp->m_flags |= XFS_MOUNT_RDONLY; mp->m_flags |= XFS_MOUNT_RDONLY;
} }
@ -1441,6 +1439,7 @@ xfs_fs_freeze(
{ {
struct xfs_mount *mp = XFS_M(sb); struct xfs_mount *mp = XFS_M(sb);
xfs_icache_disable_reclaim(mp);
xfs_save_resvblks(mp); xfs_save_resvblks(mp);
xfs_quiesce_attr(mp); xfs_quiesce_attr(mp);
return xfs_sync_sb(mp, true); return xfs_sync_sb(mp, true);
@ -1454,6 +1453,7 @@ xfs_fs_unfreeze(
xfs_restore_resvblks(mp); xfs_restore_resvblks(mp);
xfs_log_work_queue(mp); xfs_log_work_queue(mp);
xfs_icache_enable_reclaim(mp);
return 0; return 0;
} }