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:
parent
bcf62ab64d
commit
11159a0500
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,11 +386,13 @@ 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))
|
||||||
|
@ -402,8 +404,6 @@ xfs_sync_worker(
|
||||||
* 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 */
|
||||||
xfs_syncd_queue_sync(mp);
|
xfs_syncd_queue_sync(mp);
|
||||||
|
|
Loading…
Reference in a new issue