diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -255,6 +255,7 @@ fdntype ftype; unsigned fd_fd; int ix; + bool use_real_vp; struct file *fp; struct thread *td; }; @@ -264,10 +265,18 @@ struct vnode **rvp) { struct fdesc_get_ino_args *a; + struct vnode *vp; int error; a = arg; - error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp); + if (a->use_real_vp && a->fp->f_type == DTYPE_VNODE) { + vp = a->fp->f_vnode; + vget(vp, lkflags | LK_RETRY); + *rvp = vp; + error = 0; + } else { + error = fdesc_allocvp(a->ftype, a->fd_fd, a->ix, mp, rvp); + } fdrop(a->fp, a->td); return (error); } @@ -361,6 +370,8 @@ arg.ftype = Fdesc; arg.fd_fd = fd; arg.ix = FD_DESC + fd; + arg.use_real_vp = cnp->cn_nameiop == LOOKUP && + (cnp->cn_flags & ISOPEN) == 0; arg.fp = fp; arg.td = td; error = vn_vget_ino_gen(dvp, fdesc_get_ino_alloc, &arg,