diff options
-rw-r--r-- | fs/xfs/xfs_log.c | 25 | ||||
-rw-r--r-- | fs/xfs/xfs_log.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 41 |
3 files changed, 27 insertions, 40 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index b6ce4d4b6def..d2d59692739f 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -855,20 +855,17 @@ xfs_log_unmount_write(xfs_mount_t *mp) } /* xfs_log_unmount_write */ /* - * Shut down and release the AIL and 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. + * Empty the log for unmount/freeze. * * 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. + * record. */ void -xfs_log_unmount(xfs_mount_t *mp) +xfs_log_quiesce( + struct xfs_mount *mp) { cancel_delayed_work_sync(&mp->m_log->l_work); xfs_log_force(mp, XFS_LOG_SYNC); @@ -886,6 +883,20 @@ xfs_log_unmount(xfs_mount_t *mp) xfs_buf_unlock(mp->m_sb_bp); xfs_log_unmount_write(mp); +} + +/* + * Shut down and release the AIL and 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. Once this is done, we can tear down the AIL and the log. + */ +void +xfs_log_unmount( + struct xfs_mount *mp) +{ + xfs_log_quiesce(mp); xfs_trans_ail_destroy(mp); xlog_dealloc_log(mp->m_log); diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 26ed7de352d7..5caee96059df 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -183,6 +183,7 @@ bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); void xfs_log_work_queue(struct xfs_mount *mp); void xfs_log_worker(struct work_struct *work); +void xfs_log_quiesce(struct xfs_mount *mp); #endif #endif /* __XFS_LOG_H__ */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 3bafe66227fb..fdedf2cabae3 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1153,15 +1153,11 @@ xfs_restore_resvblks(struct xfs_mount *mp) * * This ensures that the metadata is written to their location on disk rather * than just existing in transactions in the log. This means after a quiesce - * there is no log replay required to write the inodes to disk (this is the main - * difference between a sync and a quiesce). + * there is no log replay required to write the inodes to disk - this is the + * primary difference between a sync and a quiesce. * - * This shoul deffectively mimic the code in xfs_unmountfs() and - * xfs_log_umount() but without tearing down any structures. - * XXX: bug fixes needed! - * - * Note: this stops background log work - the callers must ensure it is started - * again when appropriate. + * Note: xfs_log_quiesce() stops background log work - the callers must ensure + * it is started again when appropriate. */ void xfs_quiesce_attr( @@ -1180,39 +1176,18 @@ xfs_quiesce_attr( xfs_reclaim_inodes(mp, 0); xfs_reclaim_inodes(mp, SYNC_WAIT); - /* flush all pending changes from the AIL */ - xfs_ail_push_all_sync(mp->m_ail); - - /* stop background log work */ - cancel_delayed_work_sync(&mp->m_log->l_work); - - /* - * Just warn here till VFS can correctly support - * read-only remount without racing. - */ - WARN_ON(atomic_read(&mp->m_active_trans) != 0); - /* Push the superblock and write an unmount record */ error = xfs_log_sbcount(mp); if (error) xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. " "Frozen image may not be consistent."); - xfs_log_unmount_write(mp); - /* - * At this point we might have modified the superblock again and thus - * added an item to the AIL, thus flush it again. + * Just warn here till VFS can correctly support + * read-only remount without racing. */ - xfs_ail_push_all_sync(mp->m_ail); + WARN_ON(atomic_read(&mp->m_active_trans) != 0); - /* - * 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_quiesce(mp); } STATIC int |