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) | |||
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 | */ |
870 | void | 866 | void |
871 | xfs_log_unmount(xfs_mount_t *mp) | 867 | xfs_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 | */ | ||
895 | void | ||
896 | xfs_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 | ||
184 | void xfs_log_work_queue(struct xfs_mount *mp); | 184 | void xfs_log_work_queue(struct xfs_mount *mp); |
185 | void xfs_log_worker(struct work_struct *work); | 185 | void xfs_log_worker(struct work_struct *work); |
186 | void 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 | */ |
1166 | void | 1162 | void |
1167 | xfs_quiesce_attr( | 1163 | xfs_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 | ||
1218 | STATIC int | 1193 | STATIC int |