irda: Push BKL down into irda ioctl handlers
authorAlan Cox <alan@redhat.com>
Mon, 26 May 2008 06:43:11 +0000 (23:43 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 26 May 2008 06:43:11 +0000 (23:43 -0700)
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/irda/irnet/irnet_ppp.c
net/irda/irnet/irnet_ppp.h

index e0eab5927c4f434d6210711525ac9b14ba34599e..f6e54fa97f47286ad43e247909b15a4b22339db9 100644 (file)
@@ -628,8 +628,8 @@ dev_irnet_poll(struct file *        file,
  * This is the way pppd configure us and control us while the PPP
  * instance is active.
  */
-static int
-dev_irnet_ioctl(struct inode * inode,
+static long
+dev_irnet_ioctl(
                struct file *   file,
                unsigned int    cmd,
                unsigned long   arg)
@@ -660,6 +660,7 @@ dev_irnet_ioctl(struct inode *      inode,
        {
          DEBUG(FS_INFO, "Entering PPP discipline.\n");
          /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/
+         lock_kernel();
          err = ppp_register_channel(&ap->chan);
          if(err == 0)
            {
@@ -672,12 +673,14 @@ dev_irnet_ioctl(struct inode *    inode,
            }
          else
            DERROR(FS_ERROR, "Can't setup PPP channel...\n");
+          unlock_kernel();
        }
       else
        {
          /* In theory, should be N_TTY */
          DEBUG(FS_INFO, "Exiting PPP discipline.\n");
          /* Disconnect from the generic PPP layer */
+         lock_kernel();
          if(ap->ppp_open)
            {
              ap->ppp_open = 0;
@@ -686,24 +689,20 @@ dev_irnet_ioctl(struct inode *    inode,
          else
            DERROR(FS_ERROR, "Channel not registered !\n");
          err = 0;
+         unlock_kernel();
        }
       break;
 
       /* Query PPP channel and unit number */
     case PPPIOCGCHAN:
-      if(!ap->ppp_open)
-       break;
-      if(put_user(ppp_channel_index(&ap->chan), (int __user *)argp))
-       break;
-      DEBUG(FS_INFO, "Query channel.\n");
-      err = 0;
+      if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan),
+                                               (int __user *)argp))
+       err = 0;
       break;
     case PPPIOCGUNIT:
-      if(!ap->ppp_open)
-       break;
-      if(put_user(ppp_unit_number(&ap->chan), (int __user *)argp))
-       break;
-      DEBUG(FS_INFO, "Query unit number.\n");
+      lock_kernel();
+      if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan),
+                                               (int __user *)argp))
       err = 0;
       break;
 
@@ -723,34 +722,39 @@ dev_irnet_ioctl(struct inode *    inode,
       DEBUG(FS_INFO, "Standard PPP ioctl.\n");
       if(!capable(CAP_NET_ADMIN))
        err = -EPERM;
-      else
+      else {
+       lock_kernel();
        err = ppp_irnet_ioctl(&ap->chan, cmd, arg);
+       unlock_kernel();
+      }
       break;
 
       /* TTY IOCTLs : Pretend that we are a tty, to keep pppd happy */
       /* Get termios */
     case TCGETS:
       DEBUG(FS_INFO, "Get termios.\n");
+      lock_kernel();
 #ifndef TCGETS2
-      if(kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
-       break;
+      if(!kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios))
+       err = 0;
 #else
       if(kernel_termios_to_user_termios_1((struct termios __user *)argp, &ap->termios))
-       break;
+       err = 0;
 #endif
-      err = 0;
+      unlock_kernel();
       break;
       /* Set termios */
     case TCSETSF:
       DEBUG(FS_INFO, "Set termios.\n");
+      lock_kernel();
 #ifndef TCGETS2
-      if(user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
-       break;
+      if(!user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp))
+       err = 0;
 #else
-      if(user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp))
-       break;
+      if(!user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp))
+       err = 0;
 #endif
-      err = 0;
+      unlock_kernel();
       break;
 
       /* Set DTR/RTS */
@@ -773,7 +777,9 @@ dev_irnet_ioctl(struct inode *      inode,
        * We should also worry that we don't accept junk here and that
        * we get rid of our own buffers */
 #ifdef FLUSH_TO_PPP
+      lock_kernel();
       ppp_output_wakeup(&ap->chan);
+      unlock_kernel();
 #endif /* FLUSH_TO_PPP */
       err = 0;
       break;
@@ -788,7 +794,7 @@ dev_irnet_ioctl(struct inode *      inode,
 
     default:
       DERROR(FS_ERROR, "Unsupported ioctl (0x%X)\n", cmd);
-      err = -ENOIOCTLCMD;
+      err = -ENOTTY;
     }
 
   DEXIT(FS_TRACE, " - err = 0x%X\n", err);
index d2beb7df8f7fdd5d09176efd6b3ea8e4884b6b5a..d9f8bd4ebd05fcfb5040f527c5d8cb7eee5ac738 100644 (file)
@@ -76,9 +76,8 @@ static ssize_t
 static unsigned int
        dev_irnet_poll(struct file *,
                       poll_table *);
-static int
-       dev_irnet_ioctl(struct inode *,
-                       struct file *,
+static long
+       dev_irnet_ioctl(struct file *,
                        unsigned int,
                        unsigned long);
 /* ------------------------ PPP INTERFACE ------------------------ */
@@ -102,7 +101,7 @@ static struct file_operations irnet_device_fops =
        .read           = dev_irnet_read,
        .write          = dev_irnet_write,
        .poll           = dev_irnet_poll,
-       .ioctl          = dev_irnet_ioctl,
+       .unlocked_ioctl = dev_irnet_ioctl,
        .open           = dev_irnet_open,
        .release        = dev_irnet_close
   /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */