Page MenuHomeFreeBSD

D30131.diff
No OneTemporary

D30131.diff

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
@@ -190,8 +190,11 @@
fd->fd_type = ftype;
fd->fd_fd = fd_fd;
fd->fd_ix = ix;
- if (ftype == Fdesc && fmp->flags & FMNT_LINRDLNKF)
- vp->v_vflag |= VV_READLINK;
+ if (ftype == Fdesc) {
+ if ((fmp->flags & FMNT_LINRDLNKF) != 0)
+ vp->v_vflag |= VV_READLINK;
+ vn_irflag_set(vp, VIRF_FDESCFS);
+ }
error = insmntque1(vp, mp);
if (error != 0) {
vgone(vp);
@@ -380,11 +383,18 @@
static int
fdesc_open(struct vop_open_args *ap)
{
- struct vnode *vp = ap->a_vp;
+ struct vnode *vp;
+ struct file *fp;
+ struct thread *td;
+ int error, fd, locked;
+
+ vp = ap->a_vp;
if (VTOFDESC(vp)->fd_type == Froot)
return (0);
+ fd = VTOFDESC(vp)->fd_fd;
+
/*
* XXX Kludge: set td->td_proc->p_dupfd to contain the value of the file
* descriptor being sought for duplication. The error return ensures
@@ -393,8 +403,25 @@
* Other callers of vn_open or VOP_OPEN will simply report the
* error.
*/
- ap->a_td->td_dupfd = VTOFDESC(vp)->fd_fd; /* XXX */
- return (ENODEV);
+ ap->a_td->td_dupfd = fd;
+
+ if ((ap->a_mode & O_DIRECTORY) != 0) {
+ locked = VOP_ISLOCKED(vp);
+ VOP_UNLOCK(vp);
+ td = curthread;
+ error = fget_unlocked(td, fd, &cap_no_rights, &fp);
+ if (error == 0) {
+ if (fp->f_type != DTYPE_VNODE ||
+ fp->f_vnode->v_type != VDIR)
+ error = ENOTDIR;
+ fdrop(fp, td);
+ }
+ vn_lock(vp, locked | LK_RETRY);
+ } else {
+ error = 0;
+ }
+
+ return (error == 0 ? ENODEV : error);
}
static int
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -401,7 +401,8 @@
if ((fmode & O_PATH) == 0 || (fmode & FEXEC) != 0)
return (EMLINK);
}
- if (vp->v_type != VDIR && fmode & O_DIRECTORY)
+ if (vp->v_type != VDIR && (fmode & O_DIRECTORY) != 0 &&
+ (vn_irflag_read(vp) & VIRF_FDESCFS) == 0)
return (ENOTDIR);
accmode = 0;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -229,6 +229,7 @@
#define VIRF_MOUNTPOINT 0x0004 /* This vnode is mounted on */
#define VIRF_TEXT_REF 0x0008 /* Executable mappings ref the vnode */
#define VIRF_CROSSMP 0x0010 /* Cross-mp vnode, no locking */
+#define VIRF_FDESCFS 0x0020 /* Fdescfs, special handling on open */
#define VI_UNUSED0 0x0001 /* unused */
#define VI_MOUNT 0x0002 /* Mount in progress */

File Metadata

Mime Type
text/plain
Expires
Sat, Jul 4, 6:43 PM (4 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34679943
Default Alt Text
D30131.diff (2 KB)

Event Timeline