From ec947125fcb7cb1aded3ab608b9a9255a433d256 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 8 Oct 2012 21:56:03 +1100 Subject: [PATCH] --- yaml --- r: 339375 b: refs/heads/master c: cf2931db2d189ce0583be7ae880d7e3f8c15f623 h: refs/heads/master i: 339373: 6f29acfd4abbba3ea597e64c95de193b60126641 339371: 97d398bb3f9eae853dd0b6d341685e73bbf65393 339367: 742b4cf7c0159a60de75527568a8955bef5ddb64 339359: 674ebc62930dd5fbb99935ce9185f33e17ca220e v: v3 --- [refs] | 2 +- trunk/fs/xfs/xfs_log.c | 29 ++++++++++++++++++++++++++--- trunk/fs/xfs/xfs_mount.c | 24 ------------------------ 3 files changed, 27 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index a16d454074c5..ddd18973f97e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f661f1e0bf5002bdcc8b5810ad0a184a1841537f +refs/heads/master: cf2931db2d189ce0583be7ae880d7e3f8c15f623 diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index efea12bfbd6b..e788f39721e3 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -855,15 +855,38 @@ xfs_log_unmount_write(xfs_mount_t *mp) } /* xfs_log_unmount_write */ /* - * Deallocate log structures for unmount/relocation. + * Shut down and release the AIL and Log. * - * We need to stop the aild from running before we destroy - * and deallocate the log as the aild references the log. + * During unmount, we need to ensure we flush all the dirty metadata objects + * from the AIL so that the log is empty before we write the unmount record to + * the log. + * + * To do this, we first need to shut down the background log work so it is not + * trying to cover the log as we clean up. We then need to unpin all objects in + * the log so we can then flush them out. Once they have completed their IO and + * run the callbacks removing themselves from the AIL, we can write the unmount + * record, tear down the AIL and finally free the log. */ void xfs_log_unmount(xfs_mount_t *mp) { cancel_delayed_work_sync(&mp->m_log->l_work); + xfs_log_force(mp, XFS_LOG_SYNC); + + /* + * The superblock buffer is uncached and while xfs_ail_push_all_sync() + * will push it, xfs_wait_buftarg() will not wait for it. Further, + * xfs_buf_iowait() cannot be used because it was pushed with the + * XBF_ASYNC flag set, so we need to use a lock/unlock pair to wait for + * the IO to complete. + */ + xfs_ail_push_all_sync(mp->m_ail); + xfs_wait_buftarg(mp->m_ddev_targp); + xfs_buf_lock(mp->m_sb_bp); + xfs_buf_unlock(mp->m_sb_bp); + + xfs_log_unmount_write(mp); + xfs_trans_ail_destroy(mp); xlog_dealloc_log(mp->m_log); } diff --git a/trunk/fs/xfs/xfs_mount.c b/trunk/fs/xfs/xfs_mount.c index d9a31c6a0c53..c195ec85c725 100644 --- a/trunk/fs/xfs/xfs_mount.c +++ b/trunk/fs/xfs/xfs_mount.c @@ -1459,13 +1459,6 @@ xfs_unmountfs( xfs_qm_unmount(mp); - /* - * Flush out the log synchronously so that we know for sure - * that nothing is pinned. This is important because bflush() - * will skip pinned buffers. - */ - xfs_log_force(mp, XFS_LOG_SYNC); - /* * Unreserve any blocks we have so that when we unmount we don't account * the reserved free space as used. This is really only necessary for @@ -1491,23 +1484,6 @@ xfs_unmountfs( xfs_warn(mp, "Unable to update superblock counters. " "Freespace may not be correct on next mount."); - /* - * At this point we might have modified the superblock again and thus - * added an item to the AIL, thus flush it again. - */ - xfs_ail_push_all_sync(mp->m_ail); - xfs_wait_buftarg(mp->m_ddev_targp); - - /* - * The superblock buffer is uncached and xfsaild_push() will lock and - * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait() - * here but a lock on the superblock buffer will block until iodone() - * has completed. - */ - xfs_buf_lock(mp->m_sb_bp); - xfs_buf_unlock(mp->m_sb_bp); - - xfs_log_unmount_write(mp); xfs_log_unmount(mp); xfs_uuid_unmount(mp);