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 | |
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')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 6 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 55 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.h | 1 |
3 files changed, 59 insertions, 3 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 60ecf47b9f05..15fb262ef868 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1212,7 +1212,7 @@ xfs_fs_remount( | |||
1212 | /* rw -> ro */ | 1212 | /* rw -> ro */ |
1213 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { | 1213 | if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) { |
1214 | xfs_quiesce_data(mp); | 1214 | xfs_quiesce_data(mp); |
1215 | xfs_attr_quiesce(mp); | 1215 | xfs_quiesce_attr(mp); |
1216 | mp->m_flags |= XFS_MOUNT_RDONLY; | 1216 | mp->m_flags |= XFS_MOUNT_RDONLY; |
1217 | } | 1217 | } |
1218 | 1218 | ||
@@ -1221,7 +1221,7 @@ xfs_fs_remount( | |||
1221 | 1221 | ||
1222 | /* | 1222 | /* |
1223 | * Second stage of a freeze. The data is already frozen so we only | 1223 | * Second stage of a freeze. The data is already frozen so we only |
1224 | * need to take care of themetadata. Once that's done write a dummy | 1224 | * need to take care of the metadata. Once that's done write a dummy |
1225 | * record to dirty the log in case of a crash while frozen. | 1225 | * record to dirty the log in case of a crash while frozen. |
1226 | */ | 1226 | */ |
1227 | STATIC void | 1227 | STATIC void |
@@ -1230,7 +1230,7 @@ xfs_fs_lockfs( | |||
1230 | { | 1230 | { |
1231 | struct xfs_mount *mp = XFS_M(sb); | 1231 | struct xfs_mount *mp = XFS_M(sb); |
1232 | 1232 | ||
1233 | xfs_attr_quiesce(mp); | 1233 | xfs_quiesce_attr(mp); |
1234 | xfs_fs_log_dummy(mp); | 1234 | xfs_fs_log_dummy(mp); |
1235 | } | 1235 | } |
1236 | 1236 | ||
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: |
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h index 4591dc0c7880..3b49aa3bb5fc 100644 --- a/fs/xfs/linux-2.6/xfs_sync.h +++ b/fs/xfs/linux-2.6/xfs_sync.h | |||
@@ -40,6 +40,7 @@ int xfs_sync_inodes(struct xfs_mount *mp, int flags); | |||
40 | int xfs_sync_fsdata(struct xfs_mount *mp, int flags); | 40 | int xfs_sync_fsdata(struct xfs_mount *mp, int flags); |
41 | 41 | ||
42 | int xfs_quiesce_data(struct xfs_mount *mp); | 42 | int xfs_quiesce_data(struct xfs_mount *mp); |
43 | void xfs_quiesce_attr(struct xfs_mount *mp); | ||
43 | 44 | ||
44 | void xfs_flush_inode(struct xfs_inode *ip); | 45 | void xfs_flush_inode(struct xfs_inode *ip); |
45 | void xfs_flush_device(struct xfs_inode *ip); | 46 | void xfs_flush_device(struct xfs_inode *ip); |