diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2021-04-03 18:55:11 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2021-04-15 09:48:27 +0000 |
commit | a5970a529c2d952714f20e4bc6e529c74fd2b3b5 (patch) | |
tree | 3e02def33d5dab3f36911337f39f3930316015e1 /sys | |
parent | 8d9ed174f3afba5f114742447e622fc1173d4774 (diff) | |
download | src-a5970a529c2d952714f20e4bc6e529c74fd2b3b5.tar.gz src-a5970a529c2d952714f20e4bc6e529c74fd2b3b5.zip |
Make files opened with O_PATH to not block non-forced unmount
by only keeping hold count on the vnode, instead of the use count.
Reviewed by: markj
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D29323
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_descrip.c | 6 | ||||
-rw-r--r-- | sys/kern/vfs_lookup.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 11 |
3 files changed, 12 insertions, 7 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 81af58fbddd1..a28e94634326 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -3430,7 +3430,7 @@ _fgetvp(struct thread *td, int fd, int flags, cap_rights_t *needrightsp, error = EINVAL; } else { *vpp = fp->f_vnode; - vrefact(*vpp); + vref(*vpp); } fdrop(fp, td); @@ -3466,7 +3466,7 @@ fgetvp_rights(struct thread *td, int fd, cap_rights_t *needrightsp, *havecaps = caps; *vpp = fp->f_vnode; - vrefact(*vpp); + vref(*vpp); fdrop(fp, td); return (0); @@ -4978,7 +4978,7 @@ path_close(struct file *fp, struct thread *td) { MPASS(fp->f_type == DTYPE_VNODE); fp->f_ops = &badfileops; - vrele(fp->f_vnode); + vdrop(fp->f_vnode); return (0); } diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index f979676f4c7d..3050275c1b6f 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -380,7 +380,7 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) error = ENOTDIR; } else { *dpp = dfp->f_vnode; - vrefact(*dpp); + vref(*dpp); if ((dfp->f_flag & FSEARCH) != 0) cnp->cn_flags |= NOEXECCHECK; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 5a1efcdec467..9130843f6761 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -896,7 +896,7 @@ sys_fchdir(struct thread *td, struct fchdir_args *uap) if (error != 0) return (error); vp = fp->f_vnode; - vrefact(vp); + vref(vp); fdrop(fp, td); vn_lock(vp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(vp); @@ -1191,8 +1191,13 @@ kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, if (fp->f_ops == &badfileops) { KASSERT(vp->v_type != VFIFO || (flags & O_PATH) != 0, ("Unexpected fifo fp %p vp %p", fp, vp)); - finit_vnode(fp, flags, NULL, (flags & O_PATH) != 0 ? - &path_fileops : &vnops); + if ((flags & O_PATH) != 0) { + finit_vnode(fp, flags, NULL, &path_fileops); + vhold(vp); + vunref(vp); + } else { + finit_vnode(fp, flags, NULL, &vnops); + } } VOP_UNLOCK(vp); |