aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_sync.c
diff options
context:
space:
mode:
authorDavid Chinner <david@fromorbit.com>2008-10-30 02:16:21 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 02:16:21 -0400
commit76bf105cb16da6c847a13a3c77dc962ba1081713 (patch)
tree83c75b54f897589a6f13efe1ca42d1352d5fe060 /fs/xfs/linux-2.6/xfs_sync.c
parenta4e4c4f4a8f9376158f8181a75285091f52a79e3 (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.c55
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
360STATIC void
361xfs_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 */
390void
391xfs_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: