diff options
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 14 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vfs.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 26 |
3 files changed, 34 insertions, 7 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index dab5d3802374..003e5f29d684 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -659,9 +659,17 @@ xfs_fs_sync_super( | |||
659 | int error; | 659 | int error; |
660 | int flags; | 660 | int flags; |
661 | 661 | ||
662 | if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) | 662 | if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) { |
663 | flags = SYNC_QUIESCE; | 663 | /* |
664 | else | 664 | * First stage of freeze - no more writers will make progress |
665 | * now we are here, so we flush delwri and delalloc buffers | ||
666 | * here, then wait for all I/O to complete. Data is frozen at | ||
667 | * that point. Metadata is not frozen, transactions can still | ||
668 | * occur here so don't bother flushing the buftarg (i.e | ||
669 | * SYNC_QUIESCE) because it'll just get dirty again. | ||
670 | */ | ||
671 | flags = SYNC_FSDATA | SYNC_DELWRI | SYNC_WAIT | SYNC_DIO_WAIT; | ||
672 | } else | ||
665 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); | 673 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); |
666 | 674 | ||
667 | error = bhv_vfs_sync(vfsp, flags, NULL); | 675 | error = bhv_vfs_sync(vfsp, flags, NULL); |
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index da255bdf5260..558823a83065 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h | |||
@@ -92,6 +92,7 @@ typedef enum { | |||
92 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ | 92 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ |
93 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ | 93 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ |
94 | #define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ | 94 | #define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ |
95 | #define SYNC_DIO_WAIT 0x0200 /* wait for direct I/O to complete */ | ||
95 | 96 | ||
96 | #define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ | 97 | #define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ |
97 | #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ | 98 | #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index f5ea74b999b6..c2a6eab7fa2d 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -872,6 +872,10 @@ xfs_statvfs( | |||
872 | * this by simply making sure the log gets flushed | 872 | * this by simply making sure the log gets flushed |
873 | * if SYNC_BDFLUSH is set, and by actually writing it | 873 | * if SYNC_BDFLUSH is set, and by actually writing it |
874 | * out otherwise. | 874 | * out otherwise. |
875 | * SYNC_DIO_WAIT - The caller wants us to wait for all direct I/Os | ||
876 | * as well to ensure all data I/O completes before we | ||
877 | * return. Forms the drain side of the write barrier needed | ||
878 | * to safely quiesce the filesystem. | ||
875 | * | 879 | * |
876 | */ | 880 | */ |
877 | /*ARGSUSED*/ | 881 | /*ARGSUSED*/ |
@@ -883,10 +887,7 @@ xfs_sync( | |||
883 | { | 887 | { |
884 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 888 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
885 | 889 | ||
886 | if (unlikely(flags == SYNC_QUIESCE)) | 890 | return xfs_syncsub(mp, flags, NULL); |
887 | return xfs_quiesce_fs(mp); | ||
888 | else | ||
889 | return xfs_syncsub(mp, flags, NULL); | ||
890 | } | 891 | } |
891 | 892 | ||
892 | /* | 893 | /* |
@@ -1172,6 +1173,12 @@ xfs_sync_inodes( | |||
1172 | } | 1173 | } |
1173 | 1174 | ||
1174 | } | 1175 | } |
1176 | /* | ||
1177 | * When freezing, we need to wait ensure direct I/O is complete | ||
1178 | * as well to ensure all data modification is complete here | ||
1179 | */ | ||
1180 | if (flags & SYNC_DIO_WAIT) | ||
1181 | vn_iowait(vp); | ||
1175 | 1182 | ||
1176 | if (flags & SYNC_BDFLUSH) { | 1183 | if (flags & SYNC_BDFLUSH) { |
1177 | if ((flags & SYNC_ATTR) && | 1184 | if ((flags & SYNC_ATTR) && |
@@ -1950,15 +1957,26 @@ xfs_showargs( | |||
1950 | return 0; | 1957 | return 0; |
1951 | } | 1958 | } |
1952 | 1959 | ||
1960 | /* | ||
1961 | * Second stage of a freeze. The data is already frozen, now we have to take | ||
1962 | * care of the metadata. New transactions are already blocked, so we need to | ||
1963 | * wait for any remaining transactions to drain out before proceding. | ||
1964 | */ | ||
1953 | STATIC void | 1965 | STATIC void |
1954 | xfs_freeze( | 1966 | xfs_freeze( |
1955 | bhv_desc_t *bdp) | 1967 | bhv_desc_t *bdp) |
1956 | { | 1968 | { |
1957 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 1969 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
1958 | 1970 | ||
1971 | /* wait for all modifications to complete */ | ||
1959 | while (atomic_read(&mp->m_active_trans) > 0) | 1972 | while (atomic_read(&mp->m_active_trans) > 0) |
1960 | delay(100); | 1973 | delay(100); |
1961 | 1974 | ||
1975 | /* flush inodes and push all remaining buffers out to disk */ | ||
1976 | xfs_quiesce_fs(mp); | ||
1977 | |||
1978 | BUG_ON(atomic_read(&mp->m_active_trans) > 0); | ||
1979 | |||
1962 | /* Push the superblock and write an unmount record */ | 1980 | /* Push the superblock and write an unmount record */ |
1963 | xfs_log_unmount_write(mp); | 1981 | xfs_log_unmount_write(mp); |
1964 | xfs_unmountfs_writesb(mp); | 1982 | xfs_unmountfs_writesb(mp); |