Bug 32059

Summary: Linux kernel module (linux.ko) fails to load in -CURRENT
Product: Base System Reporter: SAKIYAMA Nobuo <sakichan>
Component: kernAssignee: Matt Dillon <dillon>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 5.0-CURRENT   
Hardware: Any   
OS: Any   

Description SAKIYAMA Nobuo 2001-11-17 16:20:01 UTC
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
Comment 1 SAKIYAMA Nobuo 2001-11-17 18:37:24 UTC
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);
 }
Comment 2 dwmalone freebsd_committer freebsd_triage 2001-11-18 11:42:10 UTC
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).
Comment 3 Matt Dillon freebsd_committer freebsd_triage 2001-11-18 18:55:34 UTC
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.