aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/open.23
-rw-r--r--sys/kern/kern_descrip.c6
-rw-r--r--sys/kern/vfs_lookup.c2
-rw-r--r--sys/kern/vfs_syscalls.c11
4 files changed, 15 insertions, 7 deletions
diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
index f9c54bfc7581..06a877e34460 100644
--- a/lib/libc/sys/open.2
+++ b/lib/libc/sys/open.2
@@ -349,6 +349,9 @@ But operations like
and any other that operate on file and not on file descriptor (except
.Xr fstat 2 ),
are not allowed.
+File opened with the
+.Dv O_PATH
+flag does not prevent non-forced unmount of the volume it belongs to.
See also the description of
.Dv AT_EMPTY_PATH
flag for
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);