xfs: shutdown xfs_sync_worker before the log

Revert commit 1307bbd, which uses the s_umount semaphore to provide
exclusion between xfs_sync_worker and unmount, in favor of shutting down
the sync worker before freeing the log in xfs_log_unmount.  This is a
cleaner way of resolving the race between xfs_sync_worker and unmount
than using s_umount.

Signed-off-by: Ben Myers <bpm@sgi.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Ben Myers 2012-05-25 15:45:36 -05:00
parent 59c84ed0dd
commit 8866fc6fa5
2 changed files with 16 additions and 15 deletions

View File

@ -810,6 +810,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
void void
xfs_log_unmount(xfs_mount_t *mp) xfs_log_unmount(xfs_mount_t *mp)
{ {
cancel_delayed_work_sync(&mp->m_sync_work);
xfs_trans_ail_destroy(mp); xfs_trans_ail_destroy(mp);
xlog_dealloc_log(mp->m_log); xlog_dealloc_log(mp->m_log);
} }

View File

@ -386,23 +386,23 @@ xfs_sync_worker(
* We shouldn't write/force the log if we are in the mount/unmount * We shouldn't write/force the log if we are in the mount/unmount
* process or on a read only filesystem. The workqueue still needs to be * process or on a read only filesystem. The workqueue still needs to be
* active in both cases, however, because it is used for inode reclaim * active in both cases, however, because it is used for inode reclaim
* during these times. Use the s_umount semaphore to provide exclusion * during these times. Use the MS_ACTIVE flag to avoid doing anything
* with unmount. * during mount. Doing work during unmount is avoided by calling
* cancel_delayed_work_sync on this work queue before tearing down
* the ail and the log in xfs_log_unmount.
*/ */
if (down_read_trylock(&mp->m_super->s_umount)) { if (!(mp->m_super->s_flags & MS_ACTIVE) &&
if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { !(mp->m_flags & XFS_MOUNT_RDONLY)) {
/* dgc: errors ignored here */ /* dgc: errors ignored here */
if (mp->m_super->s_frozen == SB_UNFROZEN && if (mp->m_super->s_frozen == SB_UNFROZEN &&
xfs_log_need_covered(mp)) xfs_log_need_covered(mp))
error = xfs_fs_log_dummy(mp); error = xfs_fs_log_dummy(mp);
else else
xfs_log_force(mp, 0); xfs_log_force(mp, 0);
/* start pushing all the metadata that is currently /* start pushing all the metadata that is currently
* dirty */ * dirty */
xfs_ail_push_all(mp->m_ail); xfs_ail_push_all(mp->m_ail);
}
up_read(&mp->m_super->s_umount);
} }
/* queue us up again */ /* queue us up again */