From 1f9b3b64d417a714eb79d9a4cd4927ab304b0fc0 Mon Sep 17 00:00:00 2001 From: Lachlan McIlroy Date: Sat, 10 Feb 2007 18:35:33 +1100 Subject: [XFS] remove unused xflags parameter from sync routines SGI-PV: 959137 SGI-Modid: xfs-linux-melb:xfs-kern:27710a Signed-off-by: Lachlan McIlroy Signed-off-by: Eric Sandeen Signed-off-by: Tim Shimmin --- fs/xfs/xfs_vfsops.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'fs/xfs/xfs_vfsops.c') diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 62336a4cc5a4..aec4e8d9cba7 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -640,7 +640,7 @@ xfs_quiesce_fs( * we can write the unmount record. */ do { - xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL); + xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, NULL); pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); if (!pincount) { delay(50); @@ -886,24 +886,20 @@ xfs_sync( if (unlikely(flags == SYNC_QUIESCE)) return xfs_quiesce_fs(mp); else - return xfs_syncsub(mp, flags, 0, NULL); + return xfs_syncsub(mp, flags, NULL); } /* * xfs sync routine for internal use * * This routine supports all of the flags defined for the generic vfs_sync - * interface as explained above under xfs_sync. In the interests of not - * changing interfaces within the 6.5 family, additional internally- - * required functions are specified within a separate xflags parameter, - * only available by calling this routine. + * interface as explained above under xfs_sync. * */ int xfs_sync_inodes( xfs_mount_t *mp, int flags, - int xflags, int *bypassed) { xfs_inode_t *ip = NULL; @@ -1412,17 +1408,13 @@ xfs_sync_inodes( * xfs sync routine for internal use * * This routine supports all of the flags defined for the generic vfs_sync - * interface as explained above under xfs_sync. In the interests of not - * changing interfaces within the 6.5 family, additional internally- - * required functions are specified within a separate xflags parameter, - * only available by calling this routine. + * interface as explained above under xfs_sync. * */ int xfs_syncsub( xfs_mount_t *mp, int flags, - int xflags, int *bypassed) { int error = 0; @@ -1444,7 +1436,7 @@ xfs_syncsub( if (flags & SYNC_BDFLUSH) xfs_finish_reclaim_all(mp, 1); else - error = xfs_sync_inodes(mp, flags, xflags, bypassed); + error = xfs_sync_inodes(mp, flags, bypassed); } /* -- cgit v1.2.2 From dbcabad19aa91dc9bc7176fd2853fa74f724cd2f Mon Sep 17 00:00:00 2001 From: David Chinner Date: Sat, 10 Feb 2007 18:36:17 +1100 Subject: [XFS] Fix block reservation mechanism. The block reservation mechanism has been broken since the per-cpu superblock counters were introduced. Make the block reservation code work with the per-cpu counters by syncing the counters, snapshotting the amount of available space and then doing a modifcation of the counter state according to the result. Continue in a loop until we either have no space available or we reserve some space. SGI-PV: 956323 SGI-Modid: xfs-linux-melb:xfs-kern:27895a Signed-off-by: David Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Tim Shimmin --- fs/xfs/xfs_vfsops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/xfs/xfs_vfsops.c') diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index aec4e8d9cba7..f5ea74b999b6 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -806,7 +806,7 @@ xfs_statvfs( statp->f_type = XFS_SB_MAGIC; - xfs_icsb_sync_counters_lazy(mp); + xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT); s = XFS_SB_LOCK(mp); statp->f_bsize = sbp->sb_blocksize; lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0; -- cgit v1.2.2 From 2823945fda94e0636be573a037c45cb7b6495af2 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Sat, 10 Feb 2007 18:36:40 +1100 Subject: [XFS] Ensure a frozen filesystem has a clean log before writing the dummy record. The current Linux XFS freeze code is a mess. We flush the metadata buffers out while we are still allowing new transactions to start and then fail to flush the dirty buffers back out before writing the unmount and dummy records to the log. This leads to problems when the frozen filesystem is used for snapshots - we do log recovery on a readonly image and often it appears that the log image in the snapshot is not correct. Hence we end up with hangs, oops and mount failures when trying to mount a snapshot image that has been created when the filesystem has not been correctly frozen. To fix this, we need to move th metadata flush to after we wait for all current transactions to complete in teh second stage of the freeze. This means that when we write the final log records, the log should be clean and recovery should never occur on a snapshot image created from a frozen filesystem. SGI-PV: 959267 SGI-Modid: xfs-linux-melb:xfs-kern:28010a Signed-off-by: David Chinner Signed-off-by: Donald Douwsma Signed-off-by: Tim Shimmin --- fs/xfs/xfs_vfsops.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'fs/xfs/xfs_vfsops.c') 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( * this by simply making sure the log gets flushed * if SYNC_BDFLUSH is set, and by actually writing it * out otherwise. + * SYNC_DIO_WAIT - The caller wants us to wait for all direct I/Os + * as well to ensure all data I/O completes before we + * return. Forms the drain side of the write barrier needed + * to safely quiesce the filesystem. * */ /*ARGSUSED*/ @@ -883,10 +887,7 @@ xfs_sync( { xfs_mount_t *mp = XFS_BHVTOM(bdp); - if (unlikely(flags == SYNC_QUIESCE)) - return xfs_quiesce_fs(mp); - else - return xfs_syncsub(mp, flags, NULL); + return xfs_syncsub(mp, flags, NULL); } /* @@ -1172,6 +1173,12 @@ xfs_sync_inodes( } } + /* + * When freezing, we need to wait ensure direct I/O is complete + * as well to ensure all data modification is complete here + */ + if (flags & SYNC_DIO_WAIT) + vn_iowait(vp); if (flags & SYNC_BDFLUSH) { if ((flags & SYNC_ATTR) && @@ -1950,15 +1957,26 @@ xfs_showargs( return 0; } +/* + * Second stage of a freeze. The data is already frozen, now we have to take + * care of the metadata. New transactions are already blocked, so we need to + * wait for any remaining transactions to drain out before proceding. + */ STATIC void xfs_freeze( bhv_desc_t *bdp) { xfs_mount_t *mp = XFS_BHVTOM(bdp); + /* wait for all modifications to complete */ while (atomic_read(&mp->m_active_trans) > 0) delay(100); + /* flush inodes and push all remaining buffers out to disk */ + xfs_quiesce_fs(mp); + + BUG_ON(atomic_read(&mp->m_active_trans) > 0); + /* Push the superblock and write an unmount record */ xfs_log_unmount_write(mp); xfs_unmountfs_writesb(mp); -- cgit v1.2.2 From 3c0dc77b42cee99c71e913765073888620d442fa Mon Sep 17 00:00:00 2001 From: David Chinner Date: Sat, 10 Feb 2007 18:37:22 +1100 Subject: [XFS] Make freeze code a little cleaner. Fixes a few small issues (mostly cosmetic) that were picked up during the review cycle for the last set of freeze path changes. SGI-PV: 959267 SGI-Modid: xfs-linux-melb:xfs-kern:28035a Signed-off-by: David Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Tim Shimmin --- fs/xfs/xfs_vfsops.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'fs/xfs/xfs_vfsops.c') diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index c2a6eab7fa2d..29f72f613782 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -872,10 +872,10 @@ xfs_statvfs( * this by simply making sure the log gets flushed * if SYNC_BDFLUSH is set, and by actually writing it * out otherwise. - * SYNC_DIO_WAIT - The caller wants us to wait for all direct I/Os - * as well to ensure all data I/O completes before we - * return. Forms the drain side of the write barrier needed - * to safely quiesce the filesystem. + * SYNC_IOWAIT - The caller wants us to wait for all data I/O to complete + * before we return (including direct I/O). Forms the drain + * side of the write barrier needed to safely quiesce the + * filesystem. * */ /*ARGSUSED*/ @@ -1174,10 +1174,11 @@ xfs_sync_inodes( } /* - * When freezing, we need to wait ensure direct I/O is complete - * as well to ensure all data modification is complete here + * When freezing, we need to wait ensure all I/O (including direct + * I/O) is complete to ensure no further data modification can take + * place after this point */ - if (flags & SYNC_DIO_WAIT) + if (flags & SYNC_IOWAIT) vn_iowait(vp); if (flags & SYNC_BDFLUSH) { @@ -1975,7 +1976,7 @@ xfs_freeze( /* flush inodes and push all remaining buffers out to disk */ xfs_quiesce_fs(mp); - BUG_ON(atomic_read(&mp->m_active_trans) > 0); + ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); /* Push the superblock and write an unmount record */ xfs_log_unmount_write(mp); -- cgit v1.2.2