]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] 2.5.4-pre1: further llseek cleanup (3/3)
authorRobert Love <rml@tech9.net>
Wed, 6 Feb 2002 02:46:45 +0000 (18:46 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Wed, 6 Feb 2002 02:46:45 +0000 (18:46 -0800)
The previous patch did not provide protection for device lseek methods
(drivers/* stuff).  This patch pushes the BKL into each of the remaining
lseek methods -- without them we have a race.

I'd much prefer to have a a better lock to push down than the BKL, but
that will have to wait.

Before you balk at the size, remember patch #2 in this series which
removed much code ;-)

Thanks to Al for assistance, especially a listing of affected files.

Robert Love

22 files changed:
arch/cris/drivers/eeprom.c
arch/i386/kernel/cpuid.c
arch/i386/kernel/msr.c
arch/ppc/kernel/ppc_htab.c
drivers/char/mem.c
drivers/char/nvram.c
drivers/char/nwflash.c
drivers/char/vc_screen.c
drivers/ieee1394/pcilynx.c
drivers/macintosh/nvram.c
drivers/mtd/mtdchar.c
drivers/pci/proc.c
drivers/pnp/isapnp_proc.c
drivers/sbus/char/flash.c
drivers/sbus/char/jsflash.c
drivers/usb/devices.c
drivers/usb/devio.c
drivers/usb/drivers.c
drivers/usb/inode.c
drivers/usb/uhci-debug.h
drivers/zorro/proc.c
fs/driverfs/inode.c

index cb39cf10319a4188ffd05f93e32a214739c9e3e2..4766f649cb4e62d9e3defc7deb6f2cde32b5f2f6 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include "i2c.h"
 
@@ -448,36 +449,39 @@ static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
  *  orig 1: relative from current position
  *  orig 2: position from last eeprom address
  */
-  
+  loff_t ret;
+
+  lock_kernel();
   switch (orig)
   {
    case 0:
-     file->f_pos = offset;
+     ret = file->f_pos = offset;
      break;
    case 1:
-     file->f_pos += offset;
+     ret = file->f_pos += offset;
      break;
    case 2:
-     file->f_pos = eeprom.size - offset;
+     ret = file->f_pos = eeprom.size - offset;
      break;
    default:
-     return -EINVAL;
+     ret = -EINVAL;
   }
 
   /* truncate position */
   if (file->f_pos < 0)
   {
     file->f_pos = 0;    
-    return(-EOVERFLOW);
+    unlock_kernel();
+    ret = -EOVERFLOW;
   }
   
   if (file->f_pos >= eeprom.size)
   {
     file->f_pos = eeprom.size - 1;
-    return(-EOVERFLOW);
+    ret = -EOVERFLOW;
   }
 
-  return ( file->f_pos );
+  return ( ret );
 }
 
 /* Reads data from eeprom. */
index 2686bc9bcfd9e4784f3df9dea98b8420c4ab7d0b..0e8e46d76b34d552b535bd8e0b94c7b11563628c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/poll.h>
 #include <linux/smp.h>
 #include <linux/major.h>
+#include <linux/smp_lock.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -82,16 +83,24 @@ static inline void do_cpuid(int cpu, u32 reg, u32 *data)
 
 static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
 {
+  loff_t ret;
+
+  lock_kernel();
+
   switch (orig) {
   case 0:
     file->f_pos = offset;
-    return file->f_pos;
+    ret = file->f_pos;
+    break;
   case 1:
     file->f_pos += offset;
-    return file->f_pos;
+    ret = file->f_pos;
   default:
-    return -EINVAL;    /* SEEK_END not supported */
+    ret = -EINVAL;
   }
+
+  unlock_kernel();
+  return ret;
 }
 
 static ssize_t cpuid_read(struct file * file, char * buf,
index 5445ca5ac47b51986f8ef61e79eac7b2357b7a9e..18560356a40a7bde5ae984a66ac46bede653cef8 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp.h>
+#include <linux/smp_lock.h>
 #include <linux/major.h>
 
 #include <asm/processor.h>
@@ -162,16 +163,19 @@ static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
 
 static loff_t msr_seek(struct file *file, loff_t offset, int orig)
 {
+  loff_t ret = -EINVAL;
+  lock_kernel();
   switch (orig) {
   case 0:
     file->f_pos = offset;
-    return file->f_pos;
+    ret = file->f_pos;
+    break;
   case 1:
     file->f_pos += offset;
-    return file->f_pos;
-  default:
-    return -EINVAL;    /* SEEK_END not supported */
+    ret = file->f_pos;
   }
+  unlock_kernel();
+  return ret;
 }
 
 static ssize_t msr_read(struct file * file, char * buf,
index 8f054ff4c33cc376ef17a40365b232a5fc6544f3..99661be1e5672ed47fd279553b4f16ada079fb18 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sysctl.h>
 #include <linux/ctype.h>
 #include <linux/threads.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -430,18 +431,20 @@ static ssize_t ppc_htab_write(struct file * file, const char * buffer,
 static long long
 ppc_htab_lseek(struct file * file, loff_t offset, int orig)
 {
+    long long ret = -EINVAL;
+
+    lock_kernel();
     switch (orig) {
     case 0:
        file->f_pos = offset;
-       return(file->f_pos);
+       ret = file->f_pos;
+       break;
     case 1:
        file->f_pos += offset;
-       return(file->f_pos);
-    case 2:
-       return(-EINVAL);
-    default:
-       return(-EINVAL);
+       ret = file->f_pos;
     }
+    unlock_kernel();
+    return ret;
 }
 
 int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
index 90e1e9956054cd13de1ccb6e9694d6583142a674..9df1b5af4d43ccb04e8ada7cc5282554df590b5e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/raw.h>
 #include <linux/tty.h>
 #include <linux/capability.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -466,16 +467,23 @@ static loff_t null_lseek(struct file * file, loff_t offset, int orig)
  */
 static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
 {
+       int ret;
+
+       lock_kernel();
        switch (orig) {
                case 0:
                        file->f_pos = offset;
-                       return file->f_pos;
+                       ret = file->f_pos;
+                       break;
                case 1:
                        file->f_pos += offset;
-                       return file->f_pos;
+                       ret = file->f_pos;
+                       break;
                default:
-                       return -EINVAL;
+                       ret = -EINVAL;
        }
+       unlock_kernel();
+       return ret;
 }
 
 static int open_port(struct inode * inode, struct file * filp)
index fae1d0e9490effdc269c670e795eac46ba1f78db..e8377d0358c784cbc7f0e49935837d1c78ab7091 100644 (file)
@@ -216,6 +216,7 @@ void nvram_set_checksum( void )
 
 static long long nvram_llseek(struct file *file,loff_t offset, int origin )
 {
+       lock_kernel();
        switch( origin ) {
          case 0:
                /* nothing to do */
@@ -227,6 +228,7 @@ static long long nvram_llseek(struct file *file,loff_t offset, int origin )
                offset += NVRAM_BYTES;
                break;
        }
+       unlock_kernel();
        return( (offset >= 0) ? (file->f_pos = offset) : -EINVAL );
 }
 
index 58660979a036c583fa4693d5af6a4cf9d25564d9..5c343f2da4bb82f7fb4518e0859d7caffa8b13d3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 
 #include <asm/hardware/dec21285.h>
 #include <asm/io.h>
@@ -301,30 +302,45 @@ static ssize_t flash_write(struct file *file, const char *buf, size_t size, loff
  */
 static long long flash_llseek(struct file *file, long long offset, int orig)
 {
+       long long ret;
+
+       lock_kernel();
        if (flashdebug)
                printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n",
                       (unsigned int) offset, orig);
 
        switch (orig) {
        case 0:
-               if (offset < 0)
-                       return -EINVAL;
+               if (offset < 0) {
+                       ret = -EINVAL;
+                       break;
+               }
 
-               if ((unsigned int) offset > gbFlashSize)
-                       return -EINVAL;
+               if ((unsigned int) offset > gbFlashSize) {
+                       ret = -EINVAL;
+                       break;
+               }
 
                file->f_pos = (unsigned int) offset;
-               return file->f_pos;
+               ret = file->f_pos;
+               break;
        case 1:
-               if ((file->f_pos + offset) > gbFlashSize)
-                       return -EINVAL;
-               if ((file->f_pos + offset) < 0)
-                       return -EINVAL;
+               if ((file->f_pos + offset) > gbFlashSize) {
+                       ret = -EINVAL;
+                       break;
+               }
+               if ((file->f_pos + offset) < 0) {
+                       ret = -EINVAL;
+                       break;
+               }
                file->f_pos += offset;
-               return file->f_pos;
+               ret = file->f_pos;
+               break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
+       unlock_kernel();
+       return ret;
 }
 
 
index 157ac042486f60d19732122952cacbd301d4d1c2..ce001b8437cd5bbdced0b90d50169a601b06831e 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/selection.h>
 #include <linux/kbd_kern.h>
 #include <linux/console.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
@@ -67,10 +68,13 @@ vcs_size(struct inode *inode)
 
 static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 {
-       int size = vcs_size(file->f_dentry->d_inode);
+       int size;
 
+       lock_kernel();
+       size = vcs_size(file->f_dentry->d_inode);
        switch (orig) {
                default:
+                       unlock_kernel();
                        return -EINVAL;
                case 2:
                        offset += size;
@@ -80,9 +84,12 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
                case 0:
                        break;
        }
-       if (offset < 0 || offset > size)
+       if (offset < 0 || offset > size) {
+               unlock_kernel();
                return -EINVAL;
+       }
        file->f_pos = offset;
+       unlock_kernel();
        return file->f_pos;
 }
 
index 0e6cebd5641b2187e8b82a63e2f1bce28f03c47d..2cae730599ec0fdc0dae18ca9567b2438029d8ee 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/poll.h>
+#include <linux/smp_lock.h>
 #include <asm/byteorder.h>
 #include <asm/atomic.h>
 #include <asm/io.h>
@@ -732,8 +733,9 @@ static unsigned int aux_poll(struct file *file, poll_table *pt)
 
 loff_t mem_llseek(struct file *file, loff_t offs, int orig)
 {
-        loff_t newoffs;
+        loff_t newoffs = -1;
 
+        lock_kernel();
         switch (orig) {
         case 0:
                 newoffs = offs;
@@ -743,12 +745,12 @@ loff_t mem_llseek(struct file *file, loff_t offs, int orig)
                 break;
         case 2:
                 newoffs = PCILYNX_MAX_MEMORY + 1 + offs;
-                break;
-        default:
-                return -EINVAL;
         }
 
-        if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL;
+        if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) {
+                lock_kernel();
+                return -EINVAL;
+        }
 
         file->f_pos = newoffs;
         return newoffs;
index 4e7db7cd310d4b82a056d7e5021468b16e4a9895..049433afeeaf13f220d63d9699bc1d396b4b86e4 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/fcntl.h>
 #include <linux/nvram.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/nvram.h>
 
@@ -20,6 +21,7 @@
 
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
+       lock_kernel();
        switch (origin) {
        case 1:
                offset += file->f_pos;
@@ -28,9 +30,12 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
                offset += NVRAM_SIZE;
                break;
        }
-       if (offset < 0)
+       if (offset < 0) {
+               unlock_kernel();
                return -EINVAL;
+       }
        file->f_pos = offset;
+       unlock_kernel();
        return file->f_pos;
 }
 
index f602eb2b046bc9bd59ad2c386cf9834e92fc1172..9b30043aea235799b3782ca02f0e01d6c49c669b 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mtd/mtd.h>
+#include <linux/smp_lock.h>
 #include <linux/slab.h>
 
 #ifdef CONFIG_DEVFS_FS
@@ -31,6 +32,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
 {
        struct mtd_info *mtd=(struct mtd_info *)file->private_data;
 
+       lock_kernel();
        switch (orig) {
        case 0:
                /* SEEK_SET */
@@ -45,6 +47,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
                file->f_pos =mtd->size + offset;
                break;
        default:
+               unlock_kernel();
                return -EINVAL;
        }
 
@@ -53,6 +56,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
        else if (file->f_pos >= mtd->size)
                file->f_pos = mtd->size - 1;
 
+       unlock_kernel();
        return file->f_pos;
 }
 
index 8ac8673c803d3055fb4bcf78c2fa4e1b8877b092..3bc810d5ae47606a73198233ba5d5bffc7c90ab6 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
@@ -21,8 +22,9 @@
 static loff_t
 proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
 {
-       loff_t new;
+       loff_t new = -1;
 
+       lock_kernel();
        switch (whence) {
        case 0:
                new = off;
@@ -33,9 +35,8 @@ proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
        case 2:
                new = PCI_CFG_SPACE_SIZE + off;
                break;
-       default:
-               return -EINVAL;
        }
+       unlock_kernel();
        if (new < 0 || new > PCI_CFG_SPACE_SIZE)
                return -EINVAL;
        return (file->f_pos = new);
index 11e1b2c4b4a14f0e9305ffd3807f44bd8ab23516..f359e7539314516994f25fee3b55a0905649e67f 100644 (file)
@@ -84,18 +84,26 @@ static void isapnp_devid(char *str, unsigned short vendor, unsigned short device
 
 static loff_t isapnp_info_entry_lseek(struct file *file, loff_t offset, int orig)
 {
+       loff_t ret;
+
+       lock_kernel();
+
        switch (orig) {
        case 0: /* SEEK_SET */
                file->f_pos = offset;
-               return file->f_pos;
+               ret = file->f_pos;
+               break;
        case 1: /* SEEK_CUR */
                file->f_pos += offset;
-               return file->f_pos;
+               ret = file->f_pos;
+               break;
        case 2: /* SEEK_END */
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
-       return -ENXIO;
+
+       unlock_kernel();
+       return ret;
 }
 
 static ssize_t isapnp_info_entry_read(struct file *file, char *buffer,
@@ -211,8 +219,9 @@ static struct file_operations isapnp_info_entry_operations =
 
 static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
 {
-       loff_t new;
-       
+       loff_t new = -1;
+
+       lock_kernel();
        switch (whence) {
        case 0:
                new = off;
@@ -223,11 +232,12 @@ static loff_t isapnp_proc_bus_lseek(struct file *file, loff_t off, int whence)
        case 2:
                new = 256 + off;
                break;
-       default:
-               return -EINVAL;
        }
-       if (new < 0 || new > 256)
+       if (new < 0 || new > 256) {
+               unlock_kernel();
                return -EINVAL;
+       }
+       unlock_kernel();
        return (file->f_pos = new);
 }
 
index b86a62475ffa26ed02734f50e4118b1cf134e500..383fa671a3dfb26d020dbe408375ea67baaf1c8d 100644 (file)
@@ -83,6 +83,7 @@ flash_mmap(struct file *file, struct vm_area_struct *vma)
 static long long
 flash_llseek(struct file *file, long long offset, int origin)
 {
+       lock_kernel();
        switch (origin) {
                case 0:
                        file->f_pos = offset;
@@ -96,8 +97,10 @@ flash_llseek(struct file *file, long long offset, int origin)
                        file->f_pos = flash.read_size;
                        break;
                default:
+                       unlock_kernel();
                        return -EINVAL;
        }
+       unlock_kernel();
        return file->f_pos;
 }
 
index cc42d1577e342bbe0b3926b8640fc644bfa35b9a..05b38ff0dc9f5be380fc585b6b29994709b89bb8 100644 (file)
@@ -259,16 +259,23 @@ static void jsfd_do_request(request_queue_t *q)
  */
 static loff_t jsf_lseek(struct file * file, loff_t offset, int orig)
 {
+       loff_t ret;
+
+       lock_kernel();
        switch (orig) {
                case 0:
                        file->f_pos = offset;
-                       return file->f_pos;
+                       ret = file->f_pos;
+                       break;
                case 1:
                        file->f_pos += offset;
-                       return file->f_pos;
+                       ret = file->f_pos;
+                       break;
                default:
-                       return -EINVAL;
+                       ret = -EINVAL;
        }
+       unlock_kernel();
+       return ret;
 }
 
 /*
index c732e45be9869d4dfdc7af5860da0d2fa91b8bca..3e8b1d79b270d4ec5cccd6774c8fbf44da6cea7c 100644 (file)
@@ -554,21 +554,26 @@ static int usb_device_release(struct inode *inode, struct file *file)
 
 static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig)
 {
+       loff_t ret;
+
+       lock_kernel();
+
        switch (orig) {
        case 0:
                file->f_pos = offset;
-               return file->f_pos;
-
+               ret = file->f_pos;
+               break;
        case 1:
                file->f_pos += offset;
-               return file->f_pos;
-
+               ret = file->f_pos;
+               break;
        case 2:
-               return -EINVAL;
-
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
+
+       unlock_kernel();
+       return ret;
 }
 
 struct file_operations usbdevfs_devices_fops = {
index c7883b37613969a6cbf32d8db78fa904646f87f1..342c049e24cac2537a8fe6d347e32c8a50987377 100644 (file)
@@ -58,21 +58,26 @@ struct async {
 
 static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
 {
+       loff_t ret;
+
+       lock_kernel();
+
        switch (orig) {
        case 0:
                file->f_pos = offset;
-               return file->f_pos;
-
+               ret = file->f_pos;
+               break;
        case 1:
                file->f_pos += offset;
-               return file->f_pos;
-
+               ret = file->f_pos;
+               break;
        case 2:
-               return -EINVAL;
-
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
+
+       unlock_kernel();
+       return ret;
 }
 
 static ssize_t usbdev_read(struct file *file, char * buf, size_t nbytes, loff_t *ppos)
index 28589b1e6da54e7e0bc2c98fd503003e2a0916b5..ae96757ef9f6423e14392db239d01d827ca7c013 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/mm.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 
 /*****************************************************************/
@@ -96,21 +97,24 @@ static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff
 
 static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig)
 {
+       loff_t ret;
+
+       lock_kernel();
        switch (orig) {
        case 0:
                file->f_pos = offset;
-               return file->f_pos;
-
+               ret = file->f_pos;
+               break;
        case 1:
                file->f_pos += offset;
-               return file->f_pos;
-
+               ret = file->f_pos;
+               break;
        case 2:
-               return -EINVAL;
-
        default:
-               return -EINVAL;
+               ret = -EINVAL;
        }
+       unlock_kernel();
+       return ret;
 }
 
 struct file_operations usbdevfs_drivers_fops = {
index 53716ae850e5143cb52eecab740cc02d1fb37e3a..9dbc95be73f4310698f5a59b4c5e00a3fc275793 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/proc_fs.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
-
+#include <linux/smp_lock.h>
 
 static struct super_operations usbfs_ops;
 static struct address_space_operations usbfs_aops;
@@ -295,6 +295,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
 {
        loff_t retval = -EINVAL;
 
+       lock_kernel();
        switch(orig) {
        case 0:
                if (offset > 0) {
@@ -311,6 +312,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
        default:
                break;
        }
+       unlock_kernel();
        return retval;
 }
 
index ed8b768a0064d95f27fb9a76332e40c8250e57b7..3206bcdff9542d6c636b0cc2b5cc030b0512cb79 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
 #include <asm/io.h>
 
 #include "uhci.h"
@@ -507,8 +508,11 @@ out:
 
 static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
 {
-       struct uhci_proc *up = file->private_data;
-       loff_t new;
+       struct uhci_proc *up;
+       loff_t new = -1;
+
+       lock_kernel();
+       up = file->private_data;
 
        switch (whence) {
        case 0:
@@ -517,12 +521,12 @@ static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
        case 1:
                new = file->f_pos + off;
                break;
-       case 2:
-       default:
-               return -EINVAL;
        }
-       if (new < 0 || new > up->size)
+       if (new < 0 || new > up->size) {
+               unlock_kernel();
                return -EINVAL;
+       }
+       unlock_kernel();
        return (file->f_pos = new);
 }
 
index c5cc2534c4f14716868780352303613e6a377452..07a3ae80edd9e0abb5f67b24a92fc11d66fa1157 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/zorro.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/amigahw.h>
 #include <asm/setup.h>
@@ -21,7 +22,7 @@
 static loff_t
 proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
 {
-       loff_t new;
+       loff_t new = -1;
 
        switch (whence) {
        case 0:
@@ -33,11 +34,12 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
        case 2:
                new = sizeof(struct ConfigDev) + off;
                break;
-       default:
-               return -EINVAL;
        }
-       if (new < 0 || new > sizeof(struct ConfigDev))
+       if (new < 0 || new > sizeof(struct ConfigDev)) {
+               unlock_kernel();
                return -EINVAL;
+       }
+       unlock_kernel();
        return (file->f_pos = new);
 }
 
index 802d5f8597f9006b9cc7d6f2673a04617aeb33bc..e5c6de322190f6f88d894783e93f5d446aecf9ba 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 
@@ -341,6 +342,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
 {
        loff_t retval = -EINVAL;
 
+       lock_kernel();
        switch(orig) {
        case 0:
                if (offset > 0) {
@@ -357,6 +359,7 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
        default:
                break;
        }
+       unlock_kernel();
        return retval;
 }