diff options
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 26 |
1 files changed, 22 insertions, 4 deletions
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); |