diff options
author | Christoph Hellwig <hch@sgi.com> | 2005-06-21 01:40:48 -0400 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-06-21 01:40:48 -0400 |
commit | f898d6c09caa40d82203acd72e9fda3cd5aeae74 (patch) | |
tree | 4fc118dd4374cae5804e427e2703c2343d01a6a4 | |
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>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 6 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vfs.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 60 |
3 files changed, 40 insertions, 27 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index d5f0340ddcd9..5fe9af38aa20 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -590,8 +590,10 @@ linvfs_sync_super( | |||
590 | int error; | 590 | int error; |
591 | int flags = SYNC_FSDATA; | 591 | int flags = SYNC_FSDATA; |
592 | 592 | ||
593 | if (wait) | 593 | if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) |
594 | flags |= SYNC_WAIT; | 594 | flags = SYNC_QUIESCE; |
595 | else | ||
596 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); | ||
595 | 597 | ||
596 | VFS_SYNC(vfsp, flags, NULL, error); | 598 | VFS_SYNC(vfsp, flags, NULL, error); |
597 | sb->s_dirt = 0; | 599 | sb->s_dirt = 0; |
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index 76493991578f..7ee1f714e9ba 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h | |||
@@ -107,6 +107,7 @@ typedef enum { | |||
107 | #define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ | 107 | #define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ |
108 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ | 108 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ |
109 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ | 109 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ |
110 | #define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ | ||
110 | 111 | ||
111 | typedef int (*vfs_mount_t)(bhv_desc_t *, | 112 | typedef int (*vfs_mount_t)(bhv_desc_t *, |
112 | struct xfs_mount_args *, struct cred *); | 113 | struct xfs_mount_args *, struct cred *); |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 103500498342..42bcc0215203 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -612,7 +612,34 @@ out: | |||
612 | return XFS_ERROR(error); | 612 | return XFS_ERROR(error); |
613 | } | 613 | } |
614 | 614 | ||
615 | #define REMOUNT_READONLY_FLAGS (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) | 615 | STATIC int |
616 | xfs_quiesce_fs( | ||
617 | xfs_mount_t *mp) | ||
618 | { | ||
619 | int count = 0, pincount; | ||
620 | |||
621 | xfs_refcache_purge_mp(mp); | ||
622 | xfs_flush_buftarg(mp->m_ddev_targp, 0); | ||
623 | xfs_finish_reclaim_all(mp, 0); | ||
624 | |||
625 | /* This loop must run at least twice. | ||
626 | * The first instance of the loop will flush | ||
627 | * most meta data but that will generate more | ||
628 | * meta data (typically directory updates). | ||
629 | * Which then must be flushed and logged before | ||
630 | * we can write the unmount record. | ||
631 | */ | ||
632 | do { | ||
633 | xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL); | ||
634 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); | ||
635 | if (!pincount) { | ||
636 | delay(50); | ||
637 | count++; | ||
638 | } | ||
639 | } while (count < 2); | ||
640 | |||
641 | return 0; | ||
642 | } | ||
616 | 643 | ||
617 | STATIC int | 644 | STATIC int |
618 | xfs_mntupdate( | 645 | xfs_mntupdate( |
@@ -622,8 +649,7 @@ xfs_mntupdate( | |||
622 | { | 649 | { |
623 | struct vfs *vfsp = bhvtovfs(bdp); | 650 | struct vfs *vfsp = bhvtovfs(bdp); |
624 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 651 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
625 | int pincount, error; | 652 | int error; |
626 | int count = 0; | ||
627 | 653 | ||
628 | if (args->flags & XFSMNT_NOATIME) | 654 | if (args->flags & XFSMNT_NOATIME) |
629 | mp->m_flags |= XFS_MOUNT_NOATIME; | 655 | mp->m_flags |= XFS_MOUNT_NOATIME; |
@@ -635,25 +661,7 @@ xfs_mntupdate( | |||
635 | } | 661 | } |
636 | 662 | ||
637 | if (*flags & MS_RDONLY) { | 663 | if (*flags & MS_RDONLY) { |
638 | xfs_refcache_purge_mp(mp); | 664 | xfs_quiesce_fs(mp); |
639 | xfs_flush_buftarg(mp->m_ddev_targp, 0); | ||
640 | xfs_finish_reclaim_all(mp, 0); | ||
641 | |||
642 | /* This loop must run at least twice. | ||
643 | * The first instance of the loop will flush | ||
644 | * most meta data but that will generate more | ||
645 | * meta data (typically directory updates). | ||
646 | * Which then must be flushed and logged before | ||
647 | * we can write the unmount record. | ||
648 | */ | ||
649 | do { | ||
650 | VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error); | ||
651 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); | ||
652 | if (!pincount) { | ||
653 | delay(50); | ||
654 | count++; | ||
655 | } | ||
656 | } while (count < 2); | ||
657 | 665 | ||
658 | /* Ok now write out an unmount record */ | 666 | /* Ok now write out an unmount record */ |
659 | xfs_log_unmount_write(mp); | 667 | xfs_log_unmount_write(mp); |
@@ -869,10 +877,12 @@ xfs_sync( | |||
869 | int flags, | 877 | int flags, |
870 | cred_t *credp) | 878 | cred_t *credp) |
871 | { | 879 | { |
872 | xfs_mount_t *mp; | 880 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
873 | 881 | ||
874 | mp = XFS_BHVTOM(bdp); | 882 | if (unlikely(flags == SYNC_QUIESCE)) |
875 | return (xfs_syncsub(mp, flags, 0, NULL)); | 883 | return xfs_quiesce_fs(mp); |
884 | else | ||
885 | return xfs_syncsub(mp, flags, 0, NULL); | ||
876 | } | 886 | } |
877 | 887 | ||
878 | /* | 888 | /* |