diff options
| author | Alfred Perlstein <alfred@FreeBSD.org> | 2002-01-13 11:58:06 +0000 |
|---|---|---|
| committer | Alfred Perlstein <alfred@FreeBSD.org> | 2002-01-13 11:58:06 +0000 |
| commit | 426da3bcfb40b0b0733f0be4dea9e7659f442368 (patch) | |
| tree | 598e20df363e602313c7ad93de8f8c4b4240d61d /sys/dev | |
| parent | 12076922ff2c1b5b1f22d92fa4a924ab2757e46d (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/aac/aac.c | 9 | ||||
| -rw-r--r-- | sys/dev/streams/streams.c | 26 | ||||
| -rw-r--r-- | sys/dev/tdfx/tdfx_pci.c | 6 |
3 files changed, 34 insertions, 7 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 42e3697901e9b..f456f3f39ae1d 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -2576,16 +2576,21 @@ aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) { struct file *fp; u_long cmd; + int error; debug_called(2); - fp = td->td_proc->p_fd->fd_ofiles[args->fd]; + fp = ffind_hold(td, args->fd); + if (fp == NULL) + return (EBADF); cmd = args->cmd; /* * Pass the ioctl off to our standard handler. */ - return(fo_ioctl(fp, cmd, (caddr_t)args->arg, td)); + error = (fo_ioctl(fp, cmd, (caddr_t)args->arg, td)); + fdrop(fp, td); + return (error); } #endif diff --git a/sys/dev/streams/streams.c b/sys/dev/streams/streams.c index 38d7fee29734a..a5c2b4df22544 100644 --- a/sys/dev/streams/streams.c +++ b/sys/dev/streams/streams.c @@ -266,15 +266,19 @@ streamsopen(dev_t dev, int oflags, int devtype, struct thread *td) if ((error = socreate(family, &so, type, protocol, td->td_proc->p_ucred, td)) != 0) { + FILEDESC_LOCK(p->p_fd); p->p_fd->fd_ofiles[fd] = 0; + FILEDESC_UNLOCK(p->p_fd); ffree(fp); return error; } + FILEDESC_LOCK(p->p_fd); fp->f_data = (caddr_t)so; fp->f_flag = FREAD|FWRITE; fp->f_ops = &svr4_netops; fp->f_type = DTYPE_SOCKET; + FILEDESC_UNLOCK(p->p_fd); (void)svr4_stream_get(fp); PROC_LOCK(p); @@ -355,8 +359,12 @@ svr4_stream_get(fp) so = (struct socket *) fp->f_data; - if (so->so_emuldata) + /* + * mpfixme: lock socketbuffer here + */ + if (so->so_emuldata) { return so->so_emuldata; + } /* Allocate a new one. */ st = malloc(sizeof(struct svr4_strm), M_TEMP, M_WAITOK); @@ -364,8 +372,19 @@ svr4_stream_get(fp) st->s_cmd = ~0; st->s_afd = -1; st->s_eventmask = 0; - so->so_emuldata = st; - fp->f_ops = &svr4_netops; + /* + * avoid a race where we loose due to concurrancy issues + * of two threads trying to allocate the so_emuldata. + */ + if (so->so_emuldata) { + /* lost the race, use the existing emuldata */ + FREE(st, M_TEMP); + st = so->so_emuldata; + } else { + /* we won, or there was no race, use our copy */ + so->so_emuldata = st; + fp->f_ops = &svr4_netops; + } return st; } @@ -406,5 +425,4 @@ svr4_soo_close(struct file *fp, struct thread *td) svr4_delete_socket(td->td_proc, fp); free(so->so_emuldata, M_TEMP); return soo_close(fp, td); - return (0); } diff --git a/sys/dev/tdfx/tdfx_pci.c b/sys/dev/tdfx/tdfx_pci.c index 5594a13630ebc..cfbfe18a08337 100644 --- a/sys/dev/tdfx/tdfx_pci.c +++ b/sys/dev/tdfx/tdfx_pci.c @@ -842,11 +842,15 @@ linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args) and one void*. */ char d_pio[2*sizeof(short) + sizeof(int) + sizeof(void*)]; - struct file *fp = td->td_proc->p_fd->fd_ofiles[args->fd]; + struct file *fp; + fp = ffind_hold(td, args->fd); + if (fp == NULL) + return (EBADF); /* We simply copy the data and send it right to ioctl */ copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio)); error = fo_ioctl(fp, cmd, (caddr_t)&d_pio, td); + fdrop(fp, td); return error; } #endif /* TDFX_LINUX */ |
