diff options
author | Christoph Hellwig <hch@sgi.com> | 2005-06-21 15:40:48 +1000 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-06-21 15:40:48 +1000 |
commit | f898d6c09caa40d82203acd72e9fda3cd5aeae74 (patch) | |
tree | 4fc118dd4374cae5804e427e2703c2343d01a6a4 /fs/xfs/xfs_vfsops.c | |
parent | 48fab6bf5f8baf0d16b20a35e537719d14b66275 (diff) |
[XFS] quiesce the filesystem proper when freezing
SGI-PV: 936977
SGI-Modid: xfs-linux:xfs-kern:193840a
Signed-off-by: Christoph Hellwig <hch@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 10350049834..42bcc021520 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -612,7 +612,34 @@ out: return XFS_ERROR(error); } -#define REMOUNT_READONLY_FLAGS (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) +STATIC int +xfs_quiesce_fs( + xfs_mount_t *mp) +{ + int count = 0, pincount; + + xfs_refcache_purge_mp(mp); + xfs_flush_buftarg(mp->m_ddev_targp, 0); + xfs_finish_reclaim_all(mp, 0); + + /* This loop must run at least twice. + * The first instance of the loop will flush + * most meta data but that will generate more + * meta data (typically directory updates). + * Which then must be flushed and logged before + * we can write the unmount record. + */ + do { + xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL); + pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); + if (!pincount) { + delay(50); + count++; + } + } while (count < 2); + + return 0; +} STATIC int xfs_mntupdate( @@ -622,8 +649,7 @@ xfs_mntupdate( { struct vfs *vfsp = bhvtovfs(bdp); xfs_mount_t *mp = XFS_BHVTOM(bdp); - int pincount, error; - int count = 0; + int error; if (args->flags & XFSMNT_NOATIME) mp->m_flags |= XFS_MOUNT_NOATIME; @@ -635,25 +661,7 @@ xfs_mntupdate( } if (*flags & MS_RDONLY) { - xfs_refcache_purge_mp(mp); - xfs_flush_buftarg(mp->m_ddev_targp, 0); - xfs_finish_reclaim_all(mp, 0); - - /* This loop must run at least twice. - * The first instance of the loop will flush - * most meta data but that will generate more - * meta data (typically directory updates). - * Which then must be flushed and logged before - * we can write the unmount record. - */ - do { - VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error); - pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); - if (!pincount) { - delay(50); - count++; - } - } while (count < 2); + xfs_quiesce_fs(mp); /* Ok now write out an unmount record */ xfs_log_unmount_write(mp); @@ -869,10 +877,12 @@ xfs_sync( int flags, cred_t *credp) { - xfs_mount_t *mp; + xfs_mount_t *mp = XFS_BHVTOM(bdp); - mp = XFS_BHVTOM(bdp); - return (xfs_syncsub(mp, flags, 0, NULL)); + if (unlikely(flags == SYNC_QUIESCE)) + return xfs_quiesce_fs(mp); + else + return xfs_syncsub(mp, flags, 0, NULL); } /* |