diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 42 |
1 files changed, 41 insertions, 1 deletions
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 |