diff options
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 25 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 42 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 3 |
3 files changed, 50 insertions, 20 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 38d380a7ca23..376f32d92475 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -998,7 +998,6 @@ xfs_fs_put_super( | |||
998 | int error; | 998 | int error; |
999 | 999 | ||
1000 | xfs_syncd_stop(mp); | 1000 | xfs_syncd_stop(mp); |
1001 | xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
1002 | xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI); | 1001 | xfs_sync_inodes(mp, SYNC_ATTR|SYNC_DELWRI); |
1003 | 1002 | ||
1004 | #ifdef HAVE_DMAPI | 1003 | #ifdef HAVE_DMAPI |
@@ -1057,7 +1056,7 @@ xfs_fs_write_super( | |||
1057 | struct super_block *sb) | 1056 | struct super_block *sb) |
1058 | { | 1057 | { |
1059 | if (!(sb->s_flags & MS_RDONLY)) | 1058 | if (!(sb->s_flags & MS_RDONLY)) |
1060 | xfs_sync(XFS_M(sb), SYNC_FSDATA); | 1059 | xfs_sync_fsdata(XFS_M(sb), 0); |
1061 | sb->s_dirt = 0; | 1060 | sb->s_dirt = 0; |
1062 | } | 1061 | } |
1063 | 1062 | ||
@@ -1068,7 +1067,6 @@ xfs_fs_sync_super( | |||
1068 | { | 1067 | { |
1069 | struct xfs_mount *mp = XFS_M(sb); | 1068 | struct xfs_mount *mp = XFS_M(sb); |
1070 | int error; | 1069 | int error; |
1071 | int flags; | ||
1072 | 1070 | ||
1073 | /* | 1071 | /* |
1074 | * Treat a sync operation like a freeze. This is to work | 1072 | * Treat a sync operation like a freeze. This is to work |
@@ -1082,20 +1080,10 @@ xfs_fs_sync_super( | |||
1082 | * dirty the Linux inode until after the transaction I/O | 1080 | * dirty the Linux inode until after the transaction I/O |
1083 | * completes. | 1081 | * completes. |
1084 | */ | 1082 | */ |
1085 | if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { | 1083 | if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) |
1086 | /* | 1084 | error = xfs_quiesce_data(mp); |
1087 | * First stage of freeze - no more writers will make progress | 1085 | else |
1088 | * now we are here, so we flush delwri and delalloc buffers | 1086 | error = xfs_sync_fsdata(mp, 0); |
1089 | * here, then wait for all I/O to complete. Data is frozen at | ||
1090 | * that point. Metadata is not frozen, transactions can still | ||
1091 | * occur here so don't bother flushing the buftarg (i.e | ||
1092 | * SYNC_QUIESCE) because it'll just get dirty again. | ||
1093 | */ | ||
1094 | flags = SYNC_DATA_QUIESCE; | ||
1095 | } else | ||
1096 | flags = SYNC_FSDATA; | ||
1097 | |||
1098 | error = xfs_sync(mp, flags); | ||
1099 | sb->s_dirt = 0; | 1087 | sb->s_dirt = 0; |
1100 | 1088 | ||
1101 | if (unlikely(laptop_mode)) { | 1089 | if (unlikely(laptop_mode)) { |
@@ -1233,8 +1221,7 @@ xfs_fs_remount( | |||
1233 | 1221 | ||
1234 | /* rw -> ro */ | 1222 | /* rw -> ro */ |
1235 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { | 1223 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { |
1236 | xfs_filestream_flush(mp); | 1224 | xfs_quiesce_data(mp); |
1237 | xfs_sync(mp, SYNC_DATA_QUIESCE); | ||
1238 | xfs_attr_quiesce(mp); | 1225 | xfs_attr_quiesce(mp); |
1239 | mp->m_flags |= XFS_MOUNT_RDONLY; | 1226 | mp->m_flags |= XFS_MOUNT_RDONLY; |
1240 | } | 1227 | } |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index 002ccb6f0cbe..838070ce7249 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -217,12 +217,16 @@ xfs_sync_inodes( | |||
217 | int error; | 217 | int error; |
218 | int last_error; | 218 | int last_error; |
219 | int i; | 219 | int i; |
220 | int lflags = XFS_LOG_FORCE; | ||
220 | 221 | ||
221 | if (mp->m_flags & XFS_MOUNT_RDONLY) | 222 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
222 | return 0; | 223 | return 0; |
223 | error = 0; | 224 | error = 0; |
224 | last_error = 0; | 225 | last_error = 0; |
225 | 226 | ||
227 | if (flags & SYNC_WAIT) | ||
228 | lflags |= XFS_LOG_SYNC; | ||
229 | |||
226 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { | 230 | for (i = 0; i < mp->m_sb.sb_agcount; i++) { |
227 | if (!mp->m_perag[i].pag_ici_init) | 231 | if (!mp->m_perag[i].pag_ici_init) |
228 | continue; | 232 | continue; |
@@ -232,6 +236,9 @@ xfs_sync_inodes( | |||
232 | if (error == EFSCORRUPTED) | 236 | if (error == EFSCORRUPTED) |
233 | break; | 237 | break; |
234 | } | 238 | } |
239 | if (flags & SYNC_DELWRI) | ||
240 | xfs_log_force(mp, 0, lflags); | ||
241 | |||
235 | return XFS_ERROR(last_error); | 242 | return XFS_ERROR(last_error); |
236 | } | 243 | } |
237 | 244 | ||
@@ -269,7 +276,7 @@ xfs_commit_dummy_trans( | |||
269 | return 0; | 276 | return 0; |
270 | } | 277 | } |
271 | 278 | ||
272 | STATIC int | 279 | int |
273 | xfs_sync_fsdata( | 280 | xfs_sync_fsdata( |
274 | struct xfs_mount *mp, | 281 | struct xfs_mount *mp, |
275 | int flags) | 282 | int flags) |
@@ -323,6 +330,39 @@ xfs_sync_fsdata( | |||
323 | } | 330 | } |
324 | 331 | ||
325 | /* | 332 | /* |
333 | * First stage of freeze - no more writers will make progress now we are here, | ||
334 | * so we flush delwri and delalloc buffers here, then wait for all I/O to | ||
335 | * complete. Data is frozen at that point. Metadata is not frozen, | ||
336 | * transactions can still occur here so don't bother flushing the buftarg (i.e | ||
337 | * SYNC_QUIESCE) because it'll just get dirty again. | ||
338 | */ | ||
339 | int | ||
340 | xfs_quiesce_data( | ||
341 | struct xfs_mount *mp) | ||
342 | { | ||
343 | int error; | ||
344 | |||
345 | /* push non-blocking */ | ||
346 | xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_BDFLUSH); | ||
347 | XFS_QM_DQSYNC(mp, SYNC_BDFLUSH); | ||
348 | xfs_filestream_flush(mp); | ||
349 | |||
350 | /* push and block */ | ||
351 | xfs_sync_inodes(mp, SYNC_DELWRI|SYNC_WAIT|SYNC_IOWAIT); | ||
352 | XFS_QM_DQSYNC(mp, SYNC_WAIT); | ||
353 | |||
354 | /* write superblock and hoover shutdown errors */ | ||
355 | error = xfs_sync_fsdata(mp, 0); | ||
356 | |||
357 | /* flush devices */ | ||
358 | XFS_bflush(mp->m_ddev_targp); | ||
359 | if (mp->m_rtdev_targp) | ||
360 | XFS_bflush(mp->m_rtdev_targp); | ||
361 | |||
362 | return error; | ||
363 | } | ||
364 | |||
365 | /* | ||
326 | * xfs_sync flushes any pending I/O to file system vfsp. | 366 | * xfs_sync flushes any pending I/O to file system vfsp. |
327 | * | 367 | * |
328 | * This routine is called by vfs_sync() to make sure that things make it | 368 | * This routine is called by vfs_sync() to make sure that things make it |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 5316915c0834..fcd4040c9ad1 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -55,6 +55,9 @@ void xfs_syncd_stop(struct xfs_mount *mp); | |||
55 | 55 | ||
56 | int xfs_sync(struct xfs_mount *mp, int flags); | 56 | int xfs_sync(struct xfs_mount *mp, int flags); |
57 | int xfs_sync_inodes(struct xfs_mount *mp, int flags); | 57 | int xfs_sync_inodes(struct xfs_mount *mp, int flags); |
58 | int xfs_sync_fsdata(struct xfs_mount *mp, int flags); | ||
59 | |||
60 | int xfs_quiesce_data(struct xfs_mount *mp); | ||
58 | 61 | ||
59 | void xfs_flush_inode(struct xfs_inode *ip); | 62 | void xfs_flush_inode(struct xfs_inode *ip); |
60 | void xfs_flush_device(struct xfs_inode *ip); | 63 | void xfs_flush_device(struct xfs_inode *ip); |