summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2012-06-13 21:32:35 +0000
committerpjd <pjd@FreeBSD.org>2012-06-13 21:32:35 +0000
commitf695b590b4c9789422bbd4036eb6bc2792dcfbac (patch)
treee00e28ee04040eddb61f3564b1a68eebe20ca4cd /sys/kern/vfs_syscalls.c
parentf7e18321ef9850591a2250b2f534c3d87ffe87fc (diff)
downloadFreeBSD-src-f695b590b4c9789422bbd4036eb6bc2792dcfbac.zip
FreeBSD-src-f695b590b4c9789422bbd4036eb6bc2792dcfbac.tar.gz
Allocate descriptor number in dupfdopen() itself instead of depending on
the caller using finstall(). This saves us the filedesc lock/unlock cycle, fhold()/fdrop() cycle and closes a race between finstall() and dupfdopen(). MFC after: 1 month
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9598a16..9d3d4eb 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1093,7 +1093,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
struct file *fp;
struct vnode *vp;
int cmode;
- int type, indx = -1, error, error_open;
+ int type, indx = -1, error;
struct flock lf;
struct nameidata nd;
int vfslocked;
@@ -1143,9 +1143,7 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
goto success;
/*
- * Handle special fdopen() case. bleh. dupfdopen() is
- * responsible for dropping the old contents of ofiles[indx]
- * if it succeeds.
+ * Handle special fdopen() case. bleh.
*
* Don't do this for relative (capability) lookups; we don't
* understand exactly what would happen, and we don't think
@@ -1154,14 +1152,12 @@ kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
if (nd.ni_strictrelative == 0 &&
(error == ENODEV || error == ENXIO) &&
td->td_dupfd >= 0) {
- /* XXX from fdopen */
- error_open = error;
- if ((error = finstall(td, fp, &indx, flags)) != 0)
- goto bad_unlocked;
- if ((error = dupfdopen(td, fdp, indx, td->td_dupfd,
- flags, error_open)) == 0)
+ error = dupfdopen(td, fdp, td->td_dupfd, flags, error,
+ &indx);
+ if (error == 0)
goto success;
}
+
if (error == ERESTART)
error = EINTR;
goto bad_unlocked;
@@ -4514,11 +4510,11 @@ sys_fhopen(td, uap)
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
-
/*
* An extra reference on `fp' has been held for us by
* falloc_noinstall().
*/
+
#ifdef INVARIANTS
td->td_dupfd = -1;
#endif
OpenPOWER on IntegriCloud