svn commit: r248562 - head/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Wed Mar 20 21:07:50 UTC 2013
Author: kib
Date: Wed Mar 20 21:07:49 2013
New Revision: 248562
URL: http://svnweb.freebsd.org/changeset/base/248562
Log:
When the journaled FFS volume is suspended due to the journal space
becoming too low, the softdep flush thread processes the workitems,
which frees the space in journal, and then unsuspends the fs. The
softdep_flush() and other workitem processing functions busy the
filesystem before iterating over the worklist, to prevent the parallel
unmount from freeing the mount data. The vfs_busy() is called with
MBF_NOWAIT flag.
Now, if the unmount is already started and the filesystem is suspended
due to low journal space, the journal is never flushed and filesystem
is never unsuspended, because vfs_busy(MBF_NOWAIT) call cannot succeed
for the unmounting fs, and softdep_flush() does not process the
workitems. Unmount needs to write metadata, where it hangs in the
"suspfs" state.
Move the vn_start_write() call in the dounmount() before setting the
MNTK_UNMOUNT flag. This practically ensures that softdep_flush()
processed the pending journal writes by making dounmount() wait for
the lift of the suspension.
Sponsored by: The FreeBSD Foundation
Reported and tested by: pho
MFC after: 2 weeks
Modified:
head/sys/kern/vfs_mount.c
Modified: head/sys/kern/vfs_mount.c
==============================================================================
--- head/sys/kern/vfs_mount.c Wed Mar 20 17:57:00 2013 (r248561)
+++ head/sys/kern/vfs_mount.c Wed Mar 20 21:07:49 2013 (r248562)
@@ -1256,12 +1256,14 @@ dounmount(mp, flags, td)
return (error);
}
+ vn_start_write(NULL, &mp, V_WAIT);
MNT_ILOCK(mp);
if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
!TAILQ_EMPTY(&mp->mnt_uppers)) {
MNT_IUNLOCK(mp);
if (coveredvp)
VOP_UNLOCK(coveredvp, 0);
+ vn_finished_write(mp);
return (EBUSY);
}
mp->mnt_kern_flag |= MNTK_UNMOUNT | MNTK_NOINSMNTQ;
@@ -1281,7 +1283,6 @@ dounmount(mp, flags, td)
KASSERT(error == 0,
("%s: invalid return value for msleep in the drain path @ %s:%d",
__func__, __FILE__, __LINE__));
- vn_start_write(NULL, &mp, V_WAIT);
if (mp->mnt_flag & MNT_EXPUBLIC)
vfs_setpublicfs(NULL, NULL, NULL);
More information about the svn-src-head
mailing list