diff options
author | David Chinner <dgc@sgi.com> | 2007-06-18 02:50:48 -0400 |
---|---|---|
committer | Tim Shimmin <tes@chook.melbourne.sgi.com> | 2007-07-14 01:35:58 -0400 |
commit | 516b2e7c2661615ba5d5ad9fb584f068363502d3 (patch) | |
tree | 984aed9e4dd27cb2acb547dd587525b5e4bf53d9 /fs/xfs/xfs_vfsops.c | |
parent | 957d0ebed04239b734552c7da3fae9094b6f090c (diff) |
[XFS] Fix remount,readonly path to flush everything correctly.
The remount readonly path can fail to writeback properly because we still
have active transactions after calling xfs_quiesce_fs(). Further
investigation shows that this path is broken in the same ways that the xfs
freeze path was broken so fix it the same way.
SGI-PV: 964464
SGI-Modid: xfs-linux-melb:xfs-kern:28869a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 3a647339f40e..c343fde10ef9 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, NULL); | 643 | xfs_syncsub(mp, SYNC_INODE_QUIESCE, 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); |
@@ -651,6 +651,30 @@ xfs_quiesce_fs( | |||
651 | return 0; | 651 | return 0; |
652 | } | 652 | } |
653 | 653 | ||
654 | /* | ||
655 | * Second stage of a quiesce. The data is already synced, now we have to take | ||
656 | * care of the metadata. New transactions are already blocked, so we need to | ||
657 | * wait for any remaining transactions to drain out before proceding. | ||
658 | */ | ||
659 | STATIC void | ||
660 | xfs_attr_quiesce( | ||
661 | xfs_mount_t *mp) | ||
662 | { | ||
663 | /* wait for all modifications to complete */ | ||
664 | while (atomic_read(&mp->m_active_trans) > 0) | ||
665 | delay(100); | ||
666 | |||
667 | /* flush inodes and push all remaining buffers out to disk */ | ||
668 | xfs_quiesce_fs(mp); | ||
669 | |||
670 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
671 | |||
672 | /* Push the superblock and write an unmount record */ | ||
673 | xfs_log_sbcount(mp, 1); | ||
674 | xfs_log_unmount_write(mp); | ||
675 | xfs_unmountfs_writesb(mp); | ||
676 | } | ||
677 | |||
654 | STATIC int | 678 | STATIC int |
655 | xfs_mntupdate( | 679 | xfs_mntupdate( |
656 | bhv_desc_t *bdp, | 680 | bhv_desc_t *bdp, |
@@ -670,11 +694,8 @@ xfs_mntupdate( | |||
670 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 694 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
671 | } | 695 | } |
672 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ | 696 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ |
673 | bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL); | 697 | bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL); |
674 | xfs_quiesce_fs(mp); | 698 | xfs_attr_quiesce(mp); |
675 | xfs_log_sbcount(mp, 1); | ||
676 | xfs_log_unmount_write(mp); | ||
677 | xfs_unmountfs_writesb(mp); | ||
678 | vfsp->vfs_flag |= VFS_RDONLY; | 699 | vfsp->vfs_flag |= VFS_RDONLY; |
679 | } | 700 | } |
680 | return 0; | 701 | return 0; |
@@ -1952,9 +1973,9 @@ xfs_showargs( | |||
1952 | } | 1973 | } |
1953 | 1974 | ||
1954 | /* | 1975 | /* |
1955 | * Second stage of a freeze. The data is already frozen, now we have to take | 1976 | * Second stage of a freeze. The data is already frozen so we only |
1956 | * care of the metadata. New transactions are already blocked, so we need to | 1977 | * need to take care of themetadata. Once that's done write a dummy |
1957 | * wait for any remaining transactions to drain out before proceding. | 1978 | * record to dirty the log in case of a crash while frozen. |
1958 | */ | 1979 | */ |
1959 | STATIC void | 1980 | STATIC void |
1960 | xfs_freeze( | 1981 | xfs_freeze( |
@@ -1962,19 +1983,7 @@ xfs_freeze( | |||
1962 | { | 1983 | { |
1963 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 1984 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
1964 | 1985 | ||
1965 | /* wait for all modifications to complete */ | 1986 | xfs_attr_quiesce(mp); |
1966 | while (atomic_read(&mp->m_active_trans) > 0) | ||
1967 | delay(100); | ||
1968 | |||
1969 | /* flush inodes and push all remaining buffers out to disk */ | ||
1970 | xfs_quiesce_fs(mp); | ||
1971 | |||
1972 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
1973 | |||
1974 | /* Push the superblock and write an unmount record */ | ||
1975 | xfs_log_sbcount(mp, 1); | ||
1976 | xfs_log_unmount_write(mp); | ||
1977 | xfs_unmountfs_writesb(mp); | ||
1978 | xfs_fs_log_dummy(mp); | 1987 | xfs_fs_log_dummy(mp); |
1979 | } | 1988 | } |
1980 | 1989 | ||