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/tty.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/tty.c')
-rw-r--r-- | sys/kern/tty.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c index d6ffdd7..2468e88 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1720,10 +1720,13 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, /* Validate the file descriptor. */ if ((fdp = p->p_fd) == NULL) return (EBADF); - FILEDESC_SLOCK(fdp); - if ((fp = fget_locked(fdp, fd)) == NULL || fp->f_ops == &badfileops) { - FILEDESC_SUNLOCK(fdp); + + fp = fget_unlocked(fdp, fd); + if (fp == NULL) return (EBADF); + if (fp->f_ops == &badfileops) { + error = EBADF; + goto done1; } /* Make sure the vnode is bound to a character device. */ @@ -1763,7 +1766,7 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, done3: tty_unlock(tp); done2: dev_relthread(dev); -done1: FILEDESC_SUNLOCK(fdp); +done1: fdrop(fp, curthread); return (error); } |