aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-10-08 06:56:08 -0400
committerBen Myers <bpm@sgi.com>2012-10-17 14:39:14 -0400
commitc75921a72a7c4bb73a5e09a697a672722e5543f1 (patch)
treeed46f37241cdc860ffc691f6d71159333c434a83
parentc7eea6f7adca4501d2c2db7f0f7c9dc88efac95e (diff)
xfs: xfs_quiesce_attr() should quiesce the log like unmount
xfs_quiesce_attr() is supposed to leave the log empty with an unmount record written. Right now it does not wait for the AIL to be emptied before writing the unmount record, not does it wait for metadata IO completion, either. Fix it to use the same method and code as xfs_log_unmount(). 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.c25
-rw-r--r--fs/xfs/xfs_log.h1
-rw-r--r--fs/xfs/xfs_super.c41
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)
855} /* xfs_log_unmount_write */ 855} /* xfs_log_unmount_write */
856 856
857/* 857/*
858 * Shut down and release the AIL and Log. 858 * Empty the log for unmount/freeze.
859 *
860 * During unmount, we need to ensure we flush all the dirty metadata objects
861 * from the AIL so that the log is empty before we write the unmount record to
862 * the log.
863 * 859 *
864 * To do this, we first need to shut down the background log work so it is not 860 * 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 861 * 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 862 * 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 863 * run the callbacks removing themselves from the AIL, we can write the unmount
868 * record, tear down the AIL and finally free the log. 864 * record.
869 */ 865 */
870void 866void
871xfs_log_unmount(xfs_mount_t *mp) 867xfs_log_quiesce(
868 struct xfs_mount *mp)
872{ 869{
873 cancel_delayed_work_sync(&mp->m_log->l_work); 870 cancel_delayed_work_sync(&mp->m_log->l_work);
874 xfs_log_force(mp, XFS_LOG_SYNC); 871 xfs_log_force(mp, XFS_LOG_SYNC);
@@ -886,6 +883,20 @@ xfs_log_unmount(xfs_mount_t *mp)
886 xfs_buf_unlock(mp->m_sb_bp); 883 xfs_buf_unlock(mp->m_sb_bp);
887 884
888 xfs_log_unmount_write(mp); 885 xfs_log_unmount_write(mp);
886}
887
888/*
889 * Shut down and release the AIL and Log.
890 *
891 * During unmount, we need to ensure we flush all the dirty metadata objects
892 * from the AIL so that the log is empty before we write the unmount record to
893 * the log. Once this is done, we can tear down the AIL and the log.
894 */
895void
896xfs_log_unmount(
897 struct xfs_mount *mp)
898{
899 xfs_log_quiesce(mp);
889 900
890 xfs_trans_ail_destroy(mp); 901 xfs_trans_ail_destroy(mp);
891 xlog_dealloc_log(mp->m_log); 902 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);
183 183
184void xfs_log_work_queue(struct xfs_mount *mp); 184void xfs_log_work_queue(struct xfs_mount *mp);
185void xfs_log_worker(struct work_struct *work); 185void xfs_log_worker(struct work_struct *work);
186void xfs_log_quiesce(struct xfs_mount *mp);
186 187
187#endif 188#endif
188#endif /* __XFS_LOG_H__ */ 189#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)
1153 * 1153 *
1154 * This ensures that the metadata is written to their location on disk rather 1154 * This ensures that the metadata is written to their location on disk rather
1155 * than just existing in transactions in the log. This means after a quiesce 1155 * than just existing in transactions in the log. This means after a quiesce
1156 * there is no log replay required to write the inodes to disk (this is the main 1156 * there is no log replay required to write the inodes to disk - this is the
1157 * difference between a sync and a quiesce). 1157 * primary difference between a sync and a quiesce.
1158 * 1158 *
1159 * This shoul deffectively mimic the code in xfs_unmountfs() and 1159 * Note: xfs_log_quiesce() stops background log work - the callers must ensure
1160 * xfs_log_umount() but without tearing down any structures. 1160 * it is started again when appropriate.
1161 * XXX: bug fixes needed!
1162 *
1163 * Note: this stops background log work - the callers must ensure it is started
1164 * again when appropriate.
1165 */ 1161 */
1166void 1162void
1167xfs_quiesce_attr( 1163xfs_quiesce_attr(
@@ -1180,39 +1176,18 @@ xfs_quiesce_attr(
1180 xfs_reclaim_inodes(mp, 0); 1176 xfs_reclaim_inodes(mp, 0);
1181 xfs_reclaim_inodes(mp, SYNC_WAIT); 1177 xfs_reclaim_inodes(mp, SYNC_WAIT);
1182 1178
1183 /* flush all pending changes from the AIL */
1184 xfs_ail_push_all_sync(mp->m_ail);
1185
1186 /* stop background log work */
1187 cancel_delayed_work_sync(&mp->m_log->l_work);
1188
1189 /*
1190 * Just warn here till VFS can correctly support
1191 * read-only remount without racing.
1192 */
1193 WARN_ON(atomic_read(&mp->m_active_trans) != 0);
1194
1195 /* Push the superblock and write an unmount record */ 1179 /* Push the superblock and write an unmount record */
1196 error = xfs_log_sbcount(mp); 1180 error = xfs_log_sbcount(mp);
1197 if (error) 1181 if (error)
1198 xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. " 1182 xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. "
1199 "Frozen image may not be consistent."); 1183 "Frozen image may not be consistent.");
1200 xfs_log_unmount_write(mp);
1201
1202 /* 1184 /*
1203 * At this point we might have modified the superblock again and thus 1185 * Just warn here till VFS can correctly support
1204 * added an item to the AIL, thus flush it again. 1186 * read-only remount without racing.
1205 */ 1187 */
1206 xfs_ail_push_all_sync(mp->m_ail); 1188 WARN_ON(atomic_read(&mp->m_active_trans) != 0);
1207 1189
1208 /* 1190 xfs_log_quiesce(mp);
1209 * The superblock buffer is uncached and xfsaild_push() will lock and
1210 * set the XBF_ASYNC flag on the buffer. We cannot do xfs_buf_iowait()
1211 * here but a lock on the superblock buffer will block until iodone()
1212 * has completed.
1213 */
1214 xfs_buf_lock(mp->m_sb_bp);
1215 xfs_buf_unlock(mp->m_sb_bp);
1216} 1191}
1217 1192
1218STATIC int 1193STATIC int