diff options
author | Dave Chinner <dchinner@redhat.com> | 2012-10-08 06:56:00 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-10-17 12:25:06 -0400 |
commit | 7e18530bef6a18a5479690ae7e8256319ecf1300 (patch) | |
tree | 01b336aed89889bf654327346742956abe0a5d45 /fs | |
parent | 33c7a2bc48a81fa714572f8ce29f29bc17e6faf0 (diff) |
xfs: rationalise xfs_mount_wq users
Instead of starting and stopping background work on the xfs_mount_wq
all at the same time, separate them to where they really are needed
to start and stop.
The xfs_sync_worker, only needs to be started after all the mount
processing has completed successfully, while it needs to be stopped
before the log is unmounted.
The xfs_reclaim_worker is started on demand, and can be
stopped before the unmount process does it's own inode reclaim pass.
The xfs_flush_inodes work is run on demand, and so we really only
need to ensure that it has stopped running before we start
processing an unmount, freeze or remount,ro.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_mount.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 34 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.c | 21 |
3 files changed, 23 insertions, 38 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b2bd3a0e6376..d9a31c6a0c53 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1450,9 +1450,11 @@ xfs_unmountfs( | |||
1450 | 1450 | ||
1451 | /* | 1451 | /* |
1452 | * And reclaim all inodes. At this point there should be no dirty | 1452 | * And reclaim all inodes. At this point there should be no dirty |
1453 | * inode, and none should be pinned or locked, but use synchronous | 1453 | * inodes and none should be pinned or locked, but use synchronous |
1454 | * reclaim just to be sure. | 1454 | * reclaim just to be sure. We can stop background inode reclaim |
1455 | * here as well if it is still running. | ||
1455 | */ | 1456 | */ |
1457 | cancel_delayed_work_sync(&mp->m_reclaim_work); | ||
1456 | xfs_reclaim_inodes(mp, SYNC_WAIT); | 1458 | xfs_reclaim_inodes(mp, SYNC_WAIT); |
1457 | 1459 | ||
1458 | xfs_qm_unmount(mp); | 1460 | xfs_qm_unmount(mp); |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 37d1bbce047d..9805cac81fc9 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1005,14 +1005,12 @@ xfs_fs_put_super( | |||
1005 | { | 1005 | { |
1006 | struct xfs_mount *mp = XFS_M(sb); | 1006 | struct xfs_mount *mp = XFS_M(sb); |
1007 | 1007 | ||
1008 | xfs_filestream_unmount(mp); | ||
1009 | cancel_delayed_work_sync(&mp->m_sync_work); | ||
1010 | xfs_unmountfs(mp); | ||
1011 | |||
1012 | cancel_delayed_work_sync(&mp->m_sync_work); | 1008 | cancel_delayed_work_sync(&mp->m_sync_work); |
1013 | cancel_delayed_work_sync(&mp->m_reclaim_work); | ||
1014 | cancel_work_sync(&mp->m_flush_work); | 1009 | cancel_work_sync(&mp->m_flush_work); |
1015 | 1010 | ||
1011 | xfs_filestream_unmount(mp); | ||
1012 | xfs_unmountfs(mp); | ||
1013 | |||
1016 | xfs_freesb(mp); | 1014 | xfs_freesb(mp); |
1017 | xfs_icsb_destroy_counters(mp); | 1015 | xfs_icsb_destroy_counters(mp); |
1018 | xfs_destroy_mount_workqueues(mp); | 1016 | xfs_destroy_mount_workqueues(mp); |
@@ -1325,6 +1323,9 @@ xfs_fs_fill_super( | |||
1325 | spin_lock_init(&mp->m_sb_lock); | 1323 | spin_lock_init(&mp->m_sb_lock); |
1326 | mutex_init(&mp->m_growlock); | 1324 | mutex_init(&mp->m_growlock); |
1327 | atomic_set(&mp->m_active_trans, 0); | 1325 | atomic_set(&mp->m_active_trans, 0); |
1326 | INIT_WORK(&mp->m_flush_work, xfs_flush_worker); | ||
1327 | INIT_DELAYED_WORK(&mp->m_sync_work, xfs_sync_worker); | ||
1328 | INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); | ||
1328 | 1329 | ||
1329 | mp->m_super = sb; | 1330 | mp->m_super = sb; |
1330 | sb->s_fs_info = mp; | 1331 | sb->s_fs_info = mp; |
@@ -1388,15 +1389,9 @@ xfs_fs_fill_super( | |||
1388 | sb->s_time_gran = 1; | 1389 | sb->s_time_gran = 1; |
1389 | set_posix_acl_flag(sb); | 1390 | set_posix_acl_flag(sb); |
1390 | 1391 | ||
1391 | INIT_WORK(&mp->m_flush_work, xfs_flush_worker); | ||
1392 | INIT_DELAYED_WORK(&mp->m_sync_work, xfs_sync_worker); | ||
1393 | INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); | ||
1394 | |||
1395 | xfs_syncd_queue_sync(mp); | ||
1396 | |||
1397 | error = xfs_mountfs(mp); | 1392 | error = xfs_mountfs(mp); |
1398 | if (error) | 1393 | if (error) |
1399 | goto out_syncd_stop; | 1394 | goto out_filestream_unmount; |
1400 | 1395 | ||
1401 | root = igrab(VFS_I(mp->m_rootip)); | 1396 | root = igrab(VFS_I(mp->m_rootip)); |
1402 | if (!root) { | 1397 | if (!root) { |
@@ -1413,12 +1408,15 @@ xfs_fs_fill_super( | |||
1413 | goto out_unmount; | 1408 | goto out_unmount; |
1414 | } | 1409 | } |
1415 | 1410 | ||
1411 | /* | ||
1412 | * The filesystem is successfully mounted, so we can start background | ||
1413 | * sync work now. | ||
1414 | */ | ||
1415 | xfs_syncd_queue_sync(mp); | ||
1416 | |||
1416 | return 0; | 1417 | return 0; |
1417 | out_syncd_stop: | ||
1418 | cancel_delayed_work_sync(&mp->m_sync_work); | ||
1419 | cancel_delayed_work_sync(&mp->m_reclaim_work); | ||
1420 | cancel_work_sync(&mp->m_flush_work); | ||
1421 | 1418 | ||
1419 | out_filestream_unmount: | ||
1422 | xfs_filestream_unmount(mp); | 1420 | xfs_filestream_unmount(mp); |
1423 | out_free_sb: | 1421 | out_free_sb: |
1424 | xfs_freesb(mp); | 1422 | xfs_freesb(mp); |
@@ -1437,10 +1435,6 @@ out_destroy_workqueues: | |||
1437 | out_unmount: | 1435 | out_unmount: |
1438 | xfs_filestream_unmount(mp); | 1436 | xfs_filestream_unmount(mp); |
1439 | xfs_unmountfs(mp); | 1437 | xfs_unmountfs(mp); |
1440 | |||
1441 | cancel_delayed_work_sync(&mp->m_sync_work); | ||
1442 | cancel_delayed_work_sync(&mp->m_reclaim_work); | ||
1443 | cancel_work_sync(&mp->m_flush_work); | ||
1444 | goto out_free_sb; | 1438 | goto out_free_sb; |
1445 | } | 1439 | } |
1446 | 1440 | ||
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index 7502f0621fb9..a68761696ab5 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c | |||
@@ -379,9 +379,9 @@ xfs_syncd_queue_sync( | |||
379 | } | 379 | } |
380 | 380 | ||
381 | /* | 381 | /* |
382 | * Every sync period we need to unpin all items, reclaim inodes and sync | 382 | * Every sync period we need to unpin all items in the AIL and push them to |
383 | * disk quotas. We might need to cover the log to indicate that the | 383 | * disk. If there is nothing dirty, then we might need to cover the log to |
384 | * filesystem is idle and not frozen. | 384 | * indicate that the filesystem is idle and not frozen. |
385 | */ | 385 | */ |
386 | void | 386 | void |
387 | xfs_sync_worker( | 387 | xfs_sync_worker( |
@@ -391,17 +391,7 @@ xfs_sync_worker( | |||
391 | struct xfs_mount, m_sync_work); | 391 | struct xfs_mount, m_sync_work); |
392 | int error; | 392 | int error; |
393 | 393 | ||
394 | /* | 394 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { |
395 | * We shouldn't write/force the log if we are in the mount/unmount | ||
396 | * process or on a read only filesystem. The workqueue still needs to be | ||
397 | * active in both cases, however, because it is used for inode reclaim | ||
398 | * during these times. Use the MS_ACTIVE flag to avoid doing anything | ||
399 | * during mount. Doing work during unmount is avoided by calling | ||
400 | * cancel_delayed_work_sync on this work queue before tearing down | ||
401 | * the ail and the log in xfs_log_unmount. | ||
402 | */ | ||
403 | if (!(mp->m_super->s_flags & MS_ACTIVE) && | ||
404 | !(mp->m_flags & XFS_MOUNT_RDONLY)) { | ||
405 | /* dgc: errors ignored here */ | 395 | /* dgc: errors ignored here */ |
406 | if (mp->m_super->s_writers.frozen == SB_UNFROZEN && | 396 | if (mp->m_super->s_writers.frozen == SB_UNFROZEN && |
407 | xfs_log_need_covered(mp)) | 397 | xfs_log_need_covered(mp)) |
@@ -409,8 +399,7 @@ xfs_sync_worker( | |||
409 | else | 399 | else |
410 | xfs_log_force(mp, 0); | 400 | xfs_log_force(mp, 0); |
411 | 401 | ||
412 | /* start pushing all the metadata that is currently | 402 | /* start pushing all the metadata that is currently dirty */ |
413 | * dirty */ | ||
414 | xfs_ail_push_all(mp->m_ail); | 403 | xfs_ail_push_all(mp->m_ail); |
415 | } | 404 | } |
416 | 405 | ||