svn commit: r302079 - stable/10/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Wed Jun 22 09:10:54 UTC 2016
Author: kib
Date: Wed Jun 22 09:10:52 2016
New Revision: 302079
URL: https://svnweb.freebsd.org/changeset/base/302079
Log:
MFC r301929:
Do not assume that we own the use reference on the covered vnode until
we set MNTK_UNMOUNT flag on the mp.
Modified:
stable/10/sys/kern/vfs_mount.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/kern/vfs_mount.c
==============================================================================
--- stable/10/sys/kern/vfs_mount.c Wed Jun 22 09:08:18 2016 (r302078)
+++ stable/10/sys/kern/vfs_mount.c Wed Jun 22 09:10:52 2016 (r302079)
@@ -1222,7 +1222,6 @@ dounmount(struct mount *mp, int flags, s
VI_LOCK(coveredvp);
vholdl(coveredvp);
vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY);
- vdrop(coveredvp);
/*
* Check for mp being unmounted while waiting for the
* covered vnode lock.
@@ -1230,18 +1229,22 @@ dounmount(struct mount *mp, int flags, s
if (coveredvp->v_mountedhere != mp ||
coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) {
VOP_UNLOCK(coveredvp, 0);
+ vdrop(coveredvp);
vfs_rel(mp);
return (EBUSY);
}
}
+
/*
* Only privileged root, or (if MNT_USER is set) the user that did the
* original mount is permitted to unmount this filesystem.
*/
error = vfs_suser(mp, td);
if (error != 0) {
- if (coveredvp)
+ if (coveredvp != NULL) {
VOP_UNLOCK(coveredvp, 0);
+ vdrop(coveredvp);
+ }
vfs_rel(mp);
return (error);
}
@@ -1251,8 +1254,10 @@ dounmount(struct mount *mp, int flags, s
if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0 ||
!TAILQ_EMPTY(&mp->mnt_uppers)) {
MNT_IUNLOCK(mp);
- if (coveredvp)
+ if (coveredvp != NULL) {
VOP_UNLOCK(coveredvp, 0);
+ vdrop(coveredvp);
+ }
vn_finished_write(mp);
return (EBUSY);
}
@@ -1285,6 +1290,16 @@ dounmount(struct mount *mp, int flags, s
if (mp->mnt_flag & MNT_EXPUBLIC)
vfs_setpublicfs(NULL, NULL, NULL);
+ /*
+ * From now, we can claim that the use reference on the
+ * coveredvp is ours, and the ref can be released only by
+ * successfull unmount by us, or left for later unmount
+ * attempt. The previously acquired hold reference is no
+ * longer needed to protect the vnode from reuse.
+ */
+ if (coveredvp != NULL)
+ vdrop(coveredvp);
+
vfs_msync(mp, MNT_WAIT);
MNT_ILOCK(mp);
async_flag = mp->mnt_flag & MNT_ASYNC;
More information about the svn-src-stable-10
mailing list