diff options
author | David Chinner <david@fromorbit.com> | 2008-10-30 02:16:21 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 02:16:21 -0400 |
commit | 76bf105cb16da6c847a13a3c77dc962ba1081713 (patch) | |
tree | 83c75b54f897589a6f13efe1ca42d1352d5fe060 /fs/xfs/linux-2.6/xfs_sync.c | |
parent | a4e4c4f4a8f9376158f8181a75285091f52a79e3 (diff) |
[XFS] Move remaining quiesce code.
With all the other filesystem sync code it in xfs_sync.c including the
data quiesce code, it makes sense to move the remaining quiesce code to
the same place.
SGI-PV: 988140
SGI-Modid: xfs-linux-melb:xfs-kern:32312a
Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_sync.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index ed24435af651..b2b708254ae6 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -357,6 +357,61 @@ xfs_quiesce_data( | |||
357 | return error; | 357 | return error; |
358 | } | 358 | } |
359 | 359 | ||
360 | STATIC void | ||
361 | xfs_quiesce_fs( | ||
362 | struct xfs_mount *mp) | ||
363 | { | ||
364 | int count = 0, pincount; | ||
365 | |||
366 | xfs_flush_buftarg(mp->m_ddev_targp, 0); | ||
367 | xfs_finish_reclaim_all(mp, 0, XFS_IFLUSH_DELWRI_ELSE_ASYNC); | ||
368 | |||
369 | /* | ||
370 | * This loop must run at least twice. The first instance of the loop | ||
371 | * will flush most meta data but that will generate more meta data | ||
372 | * (typically directory updates). Which then must be flushed and | ||
373 | * logged before we can write the unmount record. | ||
374 | */ | ||
375 | do { | ||
376 | xfs_sync_inodes(mp, SYNC_ATTR|SYNC_WAIT); | ||
377 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); | ||
378 | if (!pincount) { | ||
379 | delay(50); | ||
380 | count++; | ||
381 | } | ||
382 | } while (count < 2); | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * Second stage of a quiesce. The data is already synced, now we have to take | ||
387 | * care of the metadata. New transactions are already blocked, so we need to | ||
388 | * wait for any remaining transactions to drain out before proceding. | ||
389 | */ | ||
390 | void | ||
391 | xfs_quiesce_attr( | ||
392 | struct xfs_mount *mp) | ||
393 | { | ||
394 | int error = 0; | ||
395 | |||
396 | /* wait for all modifications to complete */ | ||
397 | while (atomic_read(&mp->m_active_trans) > 0) | ||
398 | delay(100); | ||
399 | |||
400 | /* flush inodes and push all remaining buffers out to disk */ | ||
401 | xfs_quiesce_fs(mp); | ||
402 | |||
403 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
404 | |||
405 | /* Push the superblock and write an unmount record */ | ||
406 | error = xfs_log_sbcount(mp, 1); | ||
407 | if (error) | ||
408 | xfs_fs_cmn_err(CE_WARN, mp, | ||
409 | "xfs_attr_quiesce: failed to log sb changes. " | ||
410 | "Frozen image may not be consistent."); | ||
411 | xfs_log_unmount_write(mp); | ||
412 | xfs_unmountfs_writesb(mp); | ||
413 | } | ||
414 | |||
360 | /* | 415 | /* |
361 | * Enqueue a work item to be picked up by the vfs xfssyncd thread. | 416 | * Enqueue a work item to be picked up by the vfs xfssyncd thread. |
362 | * Doing this has two advantages: | 417 | * Doing this has two advantages: |