diff options
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 62336a4cc5a4..29f72f613782 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -640,7 +640,7 @@ xfs_quiesce_fs( | |||
640 | * we can write the unmount record. | 640 | * we can write the unmount record. |
641 | */ | 641 | */ |
642 | do { | 642 | do { |
643 | xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL); | 643 | xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, NULL); |
644 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); | 644 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); |
645 | if (!pincount) { | 645 | if (!pincount) { |
646 | delay(50); | 646 | delay(50); |
@@ -806,7 +806,7 @@ xfs_statvfs( | |||
806 | 806 | ||
807 | statp->f_type = XFS_SB_MAGIC; | 807 | statp->f_type = XFS_SB_MAGIC; |
808 | 808 | ||
809 | xfs_icsb_sync_counters_lazy(mp); | 809 | xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); |
810 | s = XFS_SB_LOCK(mp); | 810 | s = XFS_SB_LOCK(mp); |
811 | statp->f_bsize = sbp->sb_blocksize; | 811 | statp->f_bsize = sbp->sb_blocksize; |
812 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; | 812 | lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; |
@@ -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_IOWAIT - The caller wants us to wait for all data I/O to complete | ||
876 | * before we return (including direct I/O). Forms the drain | ||
877 | * side of the write barrier needed to safely quiesce the | ||
878 | * filesystem. | ||
875 | * | 879 | * |
876 | */ | 880 | */ |
877 | /*ARGSUSED*/ | 881 | /*ARGSUSED*/ |
@@ -883,27 +887,20 @@ 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, 0, NULL); | ||
890 | } | 891 | } |
891 | 892 | ||
892 | /* | 893 | /* |
893 | * xfs sync routine for internal use | 894 | * xfs sync routine for internal use |
894 | * | 895 | * |
895 | * This routine supports all of the flags defined for the generic vfs_sync | 896 | * This routine supports all of the flags defined for the generic vfs_sync |
896 | * interface as explained above under xfs_sync. In the interests of not | 897 | * interface as explained above under xfs_sync. |
897 | * changing interfaces within the 6.5 family, additional internally- | ||
898 | * required functions are specified within a separate xflags parameter, | ||
899 | * only available by calling this routine. | ||
900 | * | 898 | * |
901 | */ | 899 | */ |
902 | int | 900 | int |
903 | xfs_sync_inodes( | 901 | xfs_sync_inodes( |
904 | xfs_mount_t *mp, | 902 | xfs_mount_t *mp, |
905 | int flags, | 903 | int flags, |
906 | int xflags, | ||
907 | int *bypassed) | 904 | int *bypassed) |
908 | { | 905 | { |
909 | xfs_inode_t *ip = NULL; | 906 | xfs_inode_t *ip = NULL; |
@@ -1176,6 +1173,13 @@ xfs_sync_inodes( | |||
1176 | } | 1173 | } |
1177 | 1174 | ||
1178 | } | 1175 | } |
1176 | /* | ||
1177 | * When freezing, we need to wait ensure all I/O (including direct | ||
1178 | * I/O) is complete to ensure no further data modification can take | ||
1179 | * place after this point | ||
1180 | */ | ||
1181 | if (flags & SYNC_IOWAIT) | ||
1182 | vn_iowait(vp); | ||
1179 | 1183 | ||
1180 | if (flags & SYNC_BDFLUSH) { | 1184 | if (flags & SYNC_BDFLUSH) { |
1181 | if ((flags & SYNC_ATTR) && | 1185 | if ((flags & SYNC_ATTR) && |
@@ -1412,17 +1416,13 @@ xfs_sync_inodes( | |||
1412 | * xfs sync routine for internal use | 1416 | * xfs sync routine for internal use |
1413 | * | 1417 | * |
1414 | * This routine supports all of the flags defined for the generic vfs_sync | 1418 | * This routine supports all of the flags defined for the generic vfs_sync |
1415 | * interface as explained above under xfs_sync. In the interests of not | 1419 | * interface as explained above under xfs_sync. |
1416 | * changing interfaces within the 6.5 family, additional internally- | ||
1417 | * required functions are specified within a separate xflags parameter, | ||
1418 | * only available by calling this routine. | ||
1419 | * | 1420 | * |
1420 | */ | 1421 | */ |
1421 | int | 1422 | int |
1422 | xfs_syncsub( | 1423 | xfs_syncsub( |
1423 | xfs_mount_t *mp, | 1424 | xfs_mount_t *mp, |
1424 | int flags, | 1425 | int flags, |
1425 | int xflags, | ||
1426 | int *bypassed) | 1426 | int *bypassed) |
1427 | { | 1427 | { |
1428 | int error = 0; | 1428 | int error = 0; |
@@ -1444,7 +1444,7 @@ xfs_syncsub( | |||
1444 | if (flags & SYNC_BDFLUSH) | 1444 | if (flags & SYNC_BDFLUSH) |
1445 | xfs_finish_reclaim_all(mp, 1); | 1445 | xfs_finish_reclaim_all(mp, 1); |
1446 | else | 1446 | else |
1447 | error = xfs_sync_inodes(mp, flags, xflags, bypassed); | 1447 | error = xfs_sync_inodes(mp, flags, bypassed); |
1448 | } | 1448 | } |
1449 | 1449 | ||
1450 | /* | 1450 | /* |
@@ -1958,15 +1958,26 @@ xfs_showargs( | |||
1958 | return 0; | 1958 | return 0; |
1959 | } | 1959 | } |
1960 | 1960 | ||
1961 | /* | ||
1962 | * Second stage of a freeze. The data is already frozen, now we have to take | ||
1963 | * care of the metadata. New transactions are already blocked, so we need to | ||
1964 | * wait for any remaining transactions to drain out before proceding. | ||
1965 | */ | ||
1961 | STATIC void | 1966 | STATIC void |
1962 | xfs_freeze( | 1967 | xfs_freeze( |
1963 | bhv_desc_t *bdp) | 1968 | bhv_desc_t *bdp) |
1964 | { | 1969 | { |
1965 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 1970 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
1966 | 1971 | ||
1972 | /* wait for all modifications to complete */ | ||
1967 | while (atomic_read(&mp->m_active_trans) > 0) | 1973 | while (atomic_read(&mp->m_active_trans) > 0) |
1968 | delay(100); | 1974 | delay(100); |
1969 | 1975 | ||
1976 | /* flush inodes and push all remaining buffers out to disk */ | ||
1977 | xfs_quiesce_fs(mp); | ||
1978 | |||
1979 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
1980 | |||
1970 | /* Push the superblock and write an unmount record */ | 1981 | /* Push the superblock and write an unmount record */ |
1971 | xfs_log_unmount_write(mp); | 1982 | xfs_log_unmount_write(mp); |
1972 | xfs_unmountfs_writesb(mp); | 1983 | xfs_unmountfs_writesb(mp); |