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/uipc_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/uipc_syscalls.c')
-rw-r--r-- | sys/kern/uipc_syscalls.c | 25 |
1 files changed, 9 insertions, 16 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index f86e657..9adbbc6 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -122,23 +122,16 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp) int error; fp = NULL; - if (fdp == NULL) + if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL) { error = EBADF; - else { - FILEDESC_SLOCK(fdp); - fp = fget_locked(fdp, fd); - if (fp == NULL) - error = EBADF; - else if (fp->f_type != DTYPE_SOCKET) { - fp = NULL; - error = ENOTSOCK; - } else { - fhold(fp); - if (fflagp != NULL) - *fflagp = fp->f_flag; - error = 0; - } - FILEDESC_SUNLOCK(fdp); + } else if (fp->f_type != DTYPE_SOCKET) { + fdrop(fp, curthread); + fp = NULL; + error = ENOTSOCK; + } else { + if (fflagp != NULL) + *fflagp = fp->f_flag; + error = 0; } *fpp = fp; return (error); |