summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2009-05-14 03:24:22 +0000
committerjeff <jeff@FreeBSD.org>2009-05-14 03:24:22 +0000
commit20397e643153b90263768cb71928b488cab2c91e (patch)
tree03247850c0c9db357665199f280535e6edca7d99 /sys/kern/vfs_syscalls.c
parentdc1ac440de95721f8b696146577a51ef7a418f59 (diff)
downloadFreeBSD-src-20397e643153b90263768cb71928b488cab2c91e.zip
FreeBSD-src-20397e643153b90263768cb71928b488cab2c91e.tar.gz
- Implement a lockless file descriptor lookup algorithm in
fget_unlocked(). - Save old file descriptor tables created on expansion until the entire descriptor table is freed so that pointers may be followed without regard for expanders. - Mark the file zone as NOFREE so we may attempt to reference potentially freed files. - Convert several fget_locked() users to fget_unlocked(). This requires us to manage reference counts explicitly but reduces locking overhead in the common case.
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 64ca316..ae3904d 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -4235,22 +4235,13 @@ getvnode(fdp, fd, fpp)
int error;
struct file *fp;
+ error = 0;
fp = NULL;
- if (fdp == NULL)
+ if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL)
error = EBADF;
- else {
- FILEDESC_SLOCK(fdp);
- if ((u_int)fd >= fdp->fd_nfiles ||
- (fp = fdp->fd_ofiles[fd]) == NULL)
- error = EBADF;
- else if (fp->f_vnode == NULL) {
- fp = NULL;
- error = EINVAL;
- } else {
- fhold(fp);
- error = 0;
- }
- FILEDESC_SUNLOCK(fdp);
+ else if (fp->f_vnode == NULL) {
+ error = EINVAL;
+ fdrop(fp, curthread);
}
*fpp = fp;
return (error);
OpenPOWER on IntegriCloud