[XFS] quiesce the filesystem proper when freezing
authorChristoph Hellwig <hch@sgi.com>
Tue, 21 Jun 2005 05:40:48 +0000 (15:40 +1000)
committerNathan Scott <nathans@sgi.com>
Tue, 21 Jun 2005 05:40:48 +0000 (15:40 +1000)
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>
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_vfs.h
fs/xfs/xfs_vfsops.c

index d5f0340ddcd969efa90000686580dd6dafb24cc0..5fe9af38aa2063ac56c23ef7faa39a539b4161d1 100644 (file)
@@ -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;
index 76493991578ffe30f039094f640f0578a50ac23d..7ee1f714e9babfcefe02864f9a785fcb4ab52973 100644 (file)
@@ -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 *);
index 103500498342ddb4afdf81a951b6977796aa73c5..42bcc0215203b16f19e71c844a395a2b3398fb72 100644 (file)
@@ -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);
 }
 
 /*