xfs: halt auto-reclamation activities while rebuilding rmap
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 9 May 2018 17:03:56 +0000 (10:03 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 16 May 2018 00:57:05 +0000 (17:57 -0700)
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>
fs/xfs/xfs_icache.c
fs/xfs/xfs_icache.h
fs/xfs/xfs_mount.c
fs/xfs/xfs_super.c

index 9deff13..164350d 100644 (file)
@@ -1826,3 +1826,21 @@ xfs_inode_clear_cowblocks_tag(
        return __xfs_inode_clear_blocks_tag(ip,
                        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);
+}
index d4a7758..d69a0f5 100644 (file)
@@ -131,4 +131,7 @@ xfs_fs_eofblocks_from_user(
 int xfs_icache_inode_is_allocated(struct xfs_mount *mp, struct xfs_trans *tp,
                                  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
index a901b86..73ed8fe 100644 (file)
@@ -1072,9 +1072,7 @@ xfs_unmountfs(
        uint64_t                resblks;
        int                     error;
 
-       cancel_delayed_work_sync(&mp->m_eofblocks_work);
-       cancel_delayed_work_sync(&mp->m_cowblocks_work);
-
+       xfs_icache_disable_reclaim(mp);
        xfs_fs_unreserve_ag_blocks(mp);
        xfs_qm_unmount_quotas(mp);
        xfs_rtunmount_inodes(mp);
index 5726ef4..84aefc8 100644 (file)
@@ -1372,7 +1372,6 @@ xfs_fs_remount(
                 */
                xfs_restore_resvblks(mp);
                xfs_log_work_queue(mp);
-               xfs_queue_eofblocks(mp);
 
                /* Recover any CoW blocks that never got remapped. */
                error = xfs_reflink_recover_cow(mp);
@@ -1382,7 +1381,7 @@ xfs_fs_remount(
                        xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
                        return error;
                }
-               xfs_queue_cowblocks(mp);
+               xfs_icache_enable_reclaim(mp);
 
                /* Create the per-AG metadata reservation pool .*/
                error = xfs_fs_reserve_ag_blocks(mp);
@@ -1392,8 +1391,13 @@ xfs_fs_remount(
 
        /* rw -> ro */
        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... */
-               cancel_delayed_work_sync(&mp->m_cowblocks_work);
                error = xfs_icache_free_cowblocks(mp, NULL);
                if (error) {
                        xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
@@ -1416,12 +1420,6 @@ xfs_fs_remount(
                 */
                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);
                mp->m_flags |= XFS_MOUNT_RDONLY;
        }
@@ -1441,6 +1439,7 @@ xfs_fs_freeze(
 {
        struct xfs_mount        *mp = XFS_M(sb);
 
+       xfs_icache_disable_reclaim(mp);
        xfs_save_resvblks(mp);
        xfs_quiesce_attr(mp);
        return xfs_sync_sb(mp, true);
@@ -1454,6 +1453,7 @@ xfs_fs_unfreeze(
 
        xfs_restore_resvblks(mp);
        xfs_log_work_queue(mp);
+       xfs_icache_enable_reclaim(mp);
        return 0;
 }