diff options
author | pjd <pjd@FreeBSD.org> | 2012-06-13 21:32:35 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2012-06-13 21:32:35 +0000 |
commit | f695b590b4c9789422bbd4036eb6bc2792dcfbac (patch) | |
tree | e00e28ee04040eddb61f3564b1a68eebe20ca4cd /sys/kern/vfs_syscalls.c | |
parent | f7e18321ef9850591a2250b2f534c3d87ffe87fc (diff) | |
download | FreeBSD-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.c | 18 |
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 |