Skip to content

Commit

Permalink
[XFS] quiesce the filesystem proper when freezing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Nathan Scott committed Jun 21, 2005
1 parent 48fab6b commit f898d6c
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 27 deletions.
6 changes: 4 additions & 2 deletions fs/xfs/linux-2.6/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,8 +590,10 @@ linvfs_sync_super(
int error;
int flags = SYNC_FSDATA;

if (wait)
flags |= SYNC_WAIT;
if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
flags = SYNC_QUIESCE;
else
flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);

VFS_SYNC(vfsp, flags, NULL, error);
sb->s_dirt = 0;
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/linux-2.6/xfs_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ typedef enum {
#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */

typedef int (*vfs_mount_t)(bhv_desc_t *,
struct xfs_mount_args *, struct cred *);
Expand Down
60 changes: 35 additions & 25 deletions fs/xfs/xfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,34 @@ xfs_unmount(
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(
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

/*
Expand Down

0 comments on commit f898d6c

Please sign in to comment.