diff options
author | Luiz Otavio O Souza <luiz@netgate.com> | 2016-06-30 13:24:42 -0500 |
---|---|---|
committer | Luiz Otavio O Souza <luiz@netgate.com> | 2016-06-30 13:24:42 -0500 |
commit | 9d5ffb47ff56597309eb2939cc97b1df4d616797 (patch) | |
tree | b34fd92dce8092bb4cb58c875caabd93e1fece39 /sys/kern/vfs_mount.c | |
parent | 1fc6b0207cc2f3cce33817706603caa41a9de24d (diff) | |
parent | 13295f52fb5936b237a994e75311fe18612c73c4 (diff) | |
download | FreeBSD-src-9d5ffb47ff56597309eb2939cc97b1df4d616797.zip FreeBSD-src-9d5ffb47ff56597309eb2939cc97b1df4d616797.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r-- | sys/kern/vfs_mount.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 3ca995f..f5f522e 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -1222,7 +1222,6 @@ dounmount(struct mount *mp, int flags, struct thread *td) 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, struct thread *td) 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, struct thread *td) 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, struct thread *td) 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; |