aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-06-18 02:50:48 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-07-14 01:35:58 -0400
commit516b2e7c2661615ba5d5ad9fb584f068363502d3 (patch)
tree984aed9e4dd27cb2acb547dd587525b5e4bf53d9 /fs
parent957d0ebed04239b734552c7da3fae9094b6f090c (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')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h14
-rw-r--r--fs/xfs/xfs_vfsops.c53
3 files changed, 46 insertions, 23 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 05f188ed1206..06894cf00b12 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -664,7 +664,7 @@ xfs_fs_sync_super(
664 * occur here so don't bother flushing the buftarg (i.e 664 * occur here so don't bother flushing the buftarg (i.e
665 * SYNC_QUIESCE) because it'll just get dirty again. 665 * SYNC_QUIESCE) because it'll just get dirty again.
666 */ 666 */
667 flags = SYNC_FSDATA | SYNC_DELWRI | SYNC_WAIT | SYNC_IOWAIT; 667 flags = SYNC_DATA_QUIESCE;
668 } else 668 } else
669 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); 669 flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
670 670
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index cb7b0d62fb96..dca3481aaafa 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -94,6 +94,20 @@ typedef enum {
94#define SYNC_IOWAIT 0x0100 /* wait for all I/O to complete */ 94#define SYNC_IOWAIT 0x0100 /* wait for all I/O to complete */
95#define SYNC_SUPER 0x0200 /* flush superblock to disk */ 95#define SYNC_SUPER 0x0200 /* flush superblock to disk */
96 96
97/*
98 * When remounting a filesystem read-only or freezing the filesystem,
99 * we have two phases to execute. This first phase is syncing the data
100 * before we quiesce the fielsystem, and the second is flushing all the
101 * inodes out after we've waited for all the transactions created by
102 * the first phase to complete. The second phase uses SYNC_INODE_QUIESCE
103 * to ensure that the inodes are written to their location on disk
104 * rather than just existing in transactions in the log. This means
105 * after a quiesce there is no log replay required to write the inodes
106 * to disk (this is the main difference between a sync and a quiesce).
107 */
108#define SYNC_DATA_QUIESCE (SYNC_DELWRI|SYNC_FSDATA|SYNC_WAIT|SYNC_IOWAIT)
109#define SYNC_INODE_QUIESCE (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT)
110
97#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ 111#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
98#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ 112#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
99#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */ 113#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
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 */
659STATIC void
660xfs_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
654STATIC int 678STATIC int
655xfs_mntupdate( 679xfs_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 */
1959STATIC void 1980STATIC void
1960xfs_freeze( 1981xfs_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