| Summary: | Linux kernel module (linux.ko) fails to load in -CURRENT | ||
|---|---|---|---|
| Product: | Base System | Reporter: | SAKIYAMA Nobuo <sakichan> |
| Component: | kern | Assignee: | Matt Dillon <dillon> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 5.0-CURRENT | ||
| Hardware: | Any | ||
| OS: | Any | ||
My patch was incomplete, because that lacks a lock.
Following patch will be correct.
--- sys/compat/linux/linux_socket.c 26 Oct 2001 23:10:08 -0000 1.30
+++ sys/compat/linux/linux_socket.c 17 Nov 2001 18:27:20 -0000
@@ -416,7 +416,7 @@
int namelen;
} */ bsd_args;
struct socket *so;
- struct file *fp;
+ unsigned int flag;
int error;
#ifdef __alpha__
@@ -438,17 +438,20 @@
* when on a non-blocking socket. Instead it returns the
* error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
*/
- error = holdsock(td->td_proc->p_fd, linux_args.s, &fp);
- if (error)
+ mtx_lock(&Giant);
+ error = fgetsock(td, linux_args.s, &so, &flag);
+ if (error) {
+ mtx_unlock(&Giant);
return (error);
+ }
error = EISCONN;
- if (fp->f_flag & FNONBLOCK) {
- so = (struct socket *)fp->f_data;
+ if (flag & FNONBLOCK) {
if (so->so_emuldata == 0)
error = so->so_error;
so->so_emuldata = (void *)1;
}
- fdrop(fp, td);
+ fputsock(so);
+ mtx_unlock(&Giant);
return (error);
}
Responsible Changed From-To: freebsd-bugs->dillon I think Matt may just have fixed this, but I'll asign it to him so he can look over the patch (it's a holdsock->fgetsock patch). State Changed From-To: open->closed This should be fixed now. We do not need to get Giant in this case because the linux system call definition in i386/linux/syscalls.master is not marked as being MP safe (i.e. it's STD instead of MSTD). So the syscall code gets Giant for us. |
src/sys/kern/uipc_syscalls.c:1.99 removes holdsock(), but src/sys/compat/linux-socket.c use that, so loading of linux kernel module fails. Fix: Following patch will be good. --- sys/compat/linux/linux_socket.c 26 Oct 2001 23:10:08 -0000 1.30 +++ sys/compat/linux/linux_socket.c 17 Nov 2001 15:35:56 -0000 @@ -416,7 +416,7 @@ int namelen; } */ bsd_args; struct socket *so; - struct file *fp; + unsigned int flag; int error; #ifdef __alpha__ @@ -438,17 +438,16 @@ * when on a non-blocking socket. Instead it returns the * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. */ - error = holdsock(td->td_proc->p_fd, linux_args.s, &fp); + error = fgetsock(td, linux_args.s, &so, &flag); if (error) return (error); error = EISCONN; - if (fp->f_flag & FNONBLOCK) { - so = (struct socket *)fp->f_data; + if (flag & FNONBLOCK) { if (so->so_emuldata == 0) error = so->so_error; so->so_emuldata = (void *)1; } - fdrop(fp, td); + fputsock(so); return (error); } How-To-Repeat: kldload linux.ko