aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2011-01-03 23:49:29 -0500
committerAlex Elder <aelder@sgi.com>2011-01-11 21:28:17 -0500
commitc58efdb442bb49dea1d148f207560c41918c1bf4 (patch)
treed6e117ae65ff7ff921600ef936a7bbb4e3130010 /fs/xfs
parenteda77982729b7170bdc9e8855f0682edf322d277 (diff)
xfs: ensure log covering transactions are synchronous
To ensure the log is covered and the filesystem idles correctly, we need to ensure that dummy transactions hit the disk and do not stay pinned in memory. If the superblock is pinned in memory, it can't be flushed so the log covering cannot make progress. The result is dependent on timing - more oftent han not we continue to issues a log covering transaction every 36s rather than idling after ~90s. Fix this by making the log covering transaction synchronous. To avoid additional log force from xfssyncd, make the log covering transaction take the place of the existing log force in the xfssyncd background sync process. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c11
-rw-r--r--fs/xfs/xfs_fsops.c10
-rw-r--r--fs/xfs/xfs_fsops.h2
4 files changed, 13 insertions, 12 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index c51faaa5e291..af32f375ca96 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1413,7 +1413,7 @@ xfs_fs_freeze(
1413 1413
1414 xfs_save_resvblks(mp); 1414 xfs_save_resvblks(mp);
1415 xfs_quiesce_attr(mp); 1415 xfs_quiesce_attr(mp);
1416 return -xfs_fs_log_dummy(mp, SYNC_WAIT); 1416 return -xfs_fs_log_dummy(mp);
1417} 1417}
1418 1418
1419STATIC int 1419STATIC int
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index a02480de9759..e22f0057d21f 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -362,7 +362,7 @@ xfs_quiesce_data(
362 362
363 /* mark the log as covered if needed */ 363 /* mark the log as covered if needed */
364 if (xfs_log_need_covered(mp)) 364 if (xfs_log_need_covered(mp))
365 error2 = xfs_fs_log_dummy(mp, SYNC_WAIT); 365 error2 = xfs_fs_log_dummy(mp);
366 366
367 /* flush data-only devices */ 367 /* flush data-only devices */
368 if (mp->m_rtdev_targp) 368 if (mp->m_rtdev_targp)
@@ -503,13 +503,14 @@ xfs_sync_worker(
503 int error; 503 int error;
504 504
505 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { 505 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
506 xfs_log_force(mp, 0);
507 xfs_reclaim_inodes(mp, 0);
508 /* dgc: errors ignored here */ 506 /* dgc: errors ignored here */
509 error = xfs_qm_sync(mp, SYNC_TRYLOCK);
510 if (mp->m_super->s_frozen == SB_UNFROZEN && 507 if (mp->m_super->s_frozen == SB_UNFROZEN &&
511 xfs_log_need_covered(mp)) 508 xfs_log_need_covered(mp))
512 error = xfs_fs_log_dummy(mp, 0); 509 error = xfs_fs_log_dummy(mp);
510 else
511 xfs_log_force(mp, 0);
512 xfs_reclaim_inodes(mp, 0);
513 error = xfs_qm_sync(mp, SYNC_TRYLOCK);
513 } 514 }
514 mp->m_sync_seq++; 515 mp->m_sync_seq++;
515 wake_up(&mp->m_wait_single_sync_task); 516 wake_up(&mp->m_wait_single_sync_task);
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index f56d30e8040c..cec89dd5d7d2 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -612,12 +612,13 @@ out:
612 * 612 *
613 * We cannot use an inode here for this - that will push dirty state back up 613 * We cannot use an inode here for this - that will push dirty state back up
614 * into the VFS and then periodic inode flushing will prevent log covering from 614 * into the VFS and then periodic inode flushing will prevent log covering from
615 * making progress. Hence we log a field in the superblock instead. 615 * making progress. Hence we log a field in the superblock instead and use a
616 * synchronous transaction to ensure the superblock is immediately unpinned
617 * and can be written back.
616 */ 618 */
617int 619int
618xfs_fs_log_dummy( 620xfs_fs_log_dummy(
619 xfs_mount_t *mp, 621 xfs_mount_t *mp)
620 int flags)
621{ 622{
622 xfs_trans_t *tp; 623 xfs_trans_t *tp;
623 int error; 624 int error;
@@ -632,8 +633,7 @@ xfs_fs_log_dummy(
632 633
633 /* log the UUID because it is an unchanging field */ 634 /* log the UUID because it is an unchanging field */
634 xfs_mod_sb(tp, XFS_SB_UUID); 635 xfs_mod_sb(tp, XFS_SB_UUID);
635 if (flags & SYNC_WAIT) 636 xfs_trans_set_sync(tp);
636 xfs_trans_set_sync(tp);
637 return xfs_trans_commit(tp, 0); 637 return xfs_trans_commit(tp, 0);
638} 638}
639 639
diff --git a/fs/xfs/xfs_fsops.h b/fs/xfs/xfs_fsops.h
index a786c5212c1e..1b6a98b66886 100644
--- a/fs/xfs/xfs_fsops.h
+++ b/fs/xfs/xfs_fsops.h
@@ -25,6 +25,6 @@ extern int xfs_fs_counts(xfs_mount_t *mp, xfs_fsop_counts_t *cnt);
25extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval, 25extern int xfs_reserve_blocks(xfs_mount_t *mp, __uint64_t *inval,
26 xfs_fsop_resblks_t *outval); 26 xfs_fsop_resblks_t *outval);
27extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags); 27extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
28extern int xfs_fs_log_dummy(xfs_mount_t *mp, int flags); 28extern int xfs_fs_log_dummy(struct xfs_mount *mp);
29 29
30#endif /* __XFS_FSOPS_H__ */ 30#endif /* __XFS_FSOPS_H__ */