aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-10-08 06:56:03 -0400
committerBen Myers <bpm@sgi.com>2012-10-17 12:57:10 -0400
commitcf2931db2d189ce0583be7ae880d7e3f8c15f623 (patch)
treec775754810bd0657fe770f6fedb429f0cc6dc586
parentf661f1e0bf5002bdcc8b5810ad0a184a1841537f (diff)
xfs: Bring some sanity to log unmounting
When unmounting the filesystem, there are lots of operations that need to be done in a specific order, and they are spread across across a couple of functions. We have to drain the AIL before we write the unmount record, and we have to shut down the background log work before we do either of them. But this is all split haphazardly across xfs_unmountfs() and xfs_log_unmount(). Move all the AIL flushing and log manipulations to xfs_log_unmount() so that the responisbilities of each function is clear and the operations they perform obvious. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r--fs/xfs/xfs_log.c29
-rw-r--r--fs/xfs/xfs_mount.c24
2 files changed, 26 insertions, 27 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index efea12bfbd6b..e788f39721e3 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -855,15 +855,38 @@ xfs_log_unmount_write(xfs_mount_t *mp)
855} /* xfs_log_unmount_write */ 855} /* xfs_log_unmount_write */
856 856
857/* 857/*
858 * Deallocate log structures for unmount/relocation. 858 * Shut down and release the AIL and Log.
859 * 859 *
860 * We need to stop the aild from running before we destroy 860 * During unmount, we need to ensure we flush all the dirty metadata objects
861 * and deallocate the log as the aild references the log. 861 * from the AIL so that the log is empty before we write the unmount record to
862 * the log.
863 *
864 * To do this, we first need to shut down the background log work so it is not
865 * trying to cover the log as we clean up. We then need to unpin all objects in
866 * the log so we can then flush them out. Once they have completed their IO and
867 * run the callbacks removing themselves from the AIL, we can write the unmount
868 * record, tear down the AIL and finally free the log.
862 */ 869 */
863void 870void
864xfs_log_unmount(xfs_mount_t *mp) 871xfs_log_unmount(xfs_mount_t *mp)
865{ 872{
866 cancel_delayed_work_sync(&mp->m_log->l_work); 873 cancel_delayed_work_sync(&mp->m_log->l_work);
874 xfs_log_force(mp, XFS_LOG_SYNC);
875
876 /*
877 * The superblock buffer is uncached and while xfs_ail_push_all_sync()
878 * will push it, xfs_wait_buftarg() will not wait for it. Further,
879 * xfs_buf_iowait() cannot be used because it was pushed with the
880 * XBF_ASYNC flag set, so we need to use a lock/unlock pair to wait for
881 * the IO to complete.
882 */
883 xfs_ail_push_all_sync(mp->m_ail);
884 xfs_wait_buftarg(mp->m_ddev_targp);
885 xfs_buf_lock(mp->m_sb_bp);
886 xfs_buf_unlock(mp->m_sb_bp);
887
888 xfs_log_unmount_write(mp);
889
867 xfs_trans_ail_destroy(mp); 890 xfs_trans_ail_destroy(mp);
868 xlog_dealloc_log(mp->m_log); 891 xlog_dealloc_log(mp->m_log);
869} 892}
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index d9a31c6a0c53..c195ec85c725 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1460,13 +1460,6 @@ xfs_unmountfs(
1460 xfs_qm_unmount(mp); 1460 xfs_qm_unmount(mp);
1461 1461
1462 /* 1462 /*
1463 * Flush out the log synchronously so that we know for sure
1464 * that nothing is pinned. This is important because bflush()
1465 * will skip pinned buffers.
1466 */
1467 xfs_log_force(mp, XFS_LOG_SYNC);
1468
1469 /*
1470 * Unreserve any blocks we have so that when we unmount we don't account 1463 * Unreserve any blocks we have so that when we unmount we don't account
1471 * the reserved free space as used. This is really only necessary for 1464 * the reserved free space as used. This is really only necessary for
1472 * lazy superblock counting because it trusts the incore superblock 1465 * lazy superblock counting because it trusts the incore superblock
@@ -1491,23 +1484,6 @@ xfs_unmountfs(
1491 xfs_warn(mp, "Unable to update superblock counters. " 1484 xfs_warn(mp, "Unable to update superblock counters. "
1492 "Freespace may not be correct on next mount."); 1485 "Freespace may not be correct on next mount.");
1493 1486
1494 /*
1495 * At this point we might have modified the superblock again and thus
1496 * added an item to the AIL, thus flush it again.
1497 */
1498 xfs_ail_push_all_sync(mp->m_ail);
1499 xfs_wait_buftarg(mp->m_ddev_targp);
1500
1501 /*
1502 * The superblock buffer is uncached and xfsaild_push() will lock and
1503 * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
1504 * here but a lock on the superblock buffer will block until iodone()
1505 * has completed.
1506 */
1507 xfs_buf_lock(mp->m_sb_bp);
1508 xfs_buf_unlock(mp->m_sb_bp);
1509
1510 xfs_log_unmount_write(mp);
1511 xfs_log_unmount(mp); 1487 xfs_log_unmount(mp);
1512 xfs_uuid_unmount(mp); 1488 xfs_uuid_unmount(mp);
1513 1489