summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty.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/tty.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/tty.c')
-rw-r--r--sys/kern/tty.c11
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);
}
OpenPOWER on IntegriCloud