diff options
author | jeff <jeff@FreeBSD.org> | 2009-05-14 03:24:22 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2009-05-14 03:24:22 +0000 |
commit | 20397e643153b90263768cb71928b488cab2c91e (patch) | |
tree | 03247850c0c9db357665199f280535e6edca7d99 /sys/kern/vfs_syscalls.c | |
parent | dc1ac440de95721f8b696146577a51ef7a418f59 (diff) | |
download | FreeBSD-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.c | 19 |
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); |