<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff -urN linux-2.4.18-pre9/Documentation/filesystems/Locking linux/Documentation/filesystems/Locking
--- linux-2.4.18-pre9/Documentation/filesystems/Locking	Thu Feb  7 15:27:09 2002
+++ linux/Documentation/filesystems/Locking	Mon Feb 11 20:44:25 2002
@@ -234,7 +234,7 @@
 locking rules:
 	All except -&gt;poll() may block.
 		BKL
-llseek:		yes
+llseek:		yes	(see below)
 read:		no
 write:		no
 readdir:	yes	(see below)
@@ -250,6 +250,13 @@
 readv:		no
 writev:		no
 
+-&gt;llseek() locking has moved from llseek to the individual llseek
+implementations.  If your fs is not using generic_file_llseek, you
+need to acquire and release the appropriate lock(s) in your -&gt;llseek().
+For many filesystems, it is probably safe to acquire the inode
+semaphore.  Note some filesystems (i.e. remote ones) provide no
+protection for i_size so you will need to use the BKL.
+
 -&gt;open() locking is in-transit: big lock partially moved into the methods.
 The only exception is -&gt;open() in the instances of file_operations that never
 end up in -&gt;i_fop/-&gt;proc_fops, i.e. ones that belong to character devices
diff -urN linux-2.4.18-pre9/arch/cris/drivers/eeprom.c linux/arch/cris/drivers/eeprom.c
--- linux-2.4.18-pre9/arch/cris/drivers/eeprom.c	Thu Feb  7 15:27:08 2002
+++ linux/arch/cris/drivers/eeprom.c	Mon Feb 11 20:44:40 2002
@@ -71,6 +71,7 @@
 #include &lt;linux/fs.h&gt;
 #include &lt;linux/init.h&gt;
 #include &lt;linux/delay.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/uaccess.h&gt;
 #include "i2c.h"
 
@@ -445,36 +446,39 @@
  *  orig 1: relative from current position
  *  orig 2: position from last eeprom address
  */
-  
+  loff_t ret;
+
+  lock_kernel();
   switch (orig)
   {
    case 0:
-     file-&gt;f_pos = offset;
+     ret = file-&gt;f_pos = offset;
      break;
    case 1:
-     file-&gt;f_pos += offset;
+     ret = file-&gt;f_pos += offset;
      break;
    case 2:
-     file-&gt;f_pos = eeprom.size - offset;
+     ret = file-&gt;f_pos = eeprom.size - offset;
      break;
    default:
-     return -EINVAL;
+     ret = -EINVAL;
   }
 
   /* truncate position */
   if (file-&gt;f_pos &lt; 0)
   {
     file-&gt;f_pos = 0;    
-    return(-EOVERFLOW);
+    unlock_kernel();
+    ret = -EOVERFLOW;
   }
   
   if (file-&gt;f_pos &gt;= eeprom.size)
   {
     file-&gt;f_pos = eeprom.size - 1;
-    return(-EOVERFLOW);
+    ret = -EOVERFLOW;
   }
 
-  return ( file-&gt;f_pos );
+  return ( ret );
 }
 
 /* Reads data from eeprom. */
diff -urN linux-2.4.18-pre9/arch/i386/kernel/cpuid.c linux/arch/i386/kernel/cpuid.c
--- linux-2.4.18-pre9/arch/i386/kernel/cpuid.c	Thu Feb  7 15:26:57 2002
+++ linux/arch/i386/kernel/cpuid.c	Mon Feb 11 20:46:00 2002
@@ -35,6 +35,7 @@
 #include &lt;linux/poll.h&gt;
 #include &lt;linux/smp.h&gt;
 #include &lt;linux/major.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 #include &lt;asm/processor.h&gt;
 #include &lt;asm/msr.h&gt;
@@ -82,16 +83,25 @@
 
 static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
 {
+  loff_t ret;
+
+  lock_kernel();
+
   switch (orig) {
   case 0:
     file-&gt;f_pos = offset;
-    return file-&gt;f_pos;
+    ret = file-&gt;f_pos;
+    break;
   case 1:
     file-&gt;f_pos += offset;
-    return file-&gt;f_pos;
+    ret = file-&gt;f_pos;
+    break;
   default:
-    return -EINVAL;	/* SEEK_END not supported */
+    ret = -EINVAL;
   }
+
+  unlock_kernel();
+  return ret;
 }
 
 static ssize_t cpuid_read(struct file * file, char * buf,
diff -urN linux-2.4.18-pre9/arch/i386/kernel/msr.c linux/arch/i386/kernel/msr.c
--- linux-2.4.18-pre9/arch/i386/kernel/msr.c	Thu Feb  7 15:26:57 2002
+++ linux/arch/i386/kernel/msr.c	Mon Feb 11 20:44:40 2002
@@ -33,6 +33,7 @@
 #include &lt;linux/init.h&gt;
 #include &lt;linux/poll.h&gt;
 #include &lt;linux/smp.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;linux/major.h&gt;
 
 #include &lt;asm/processor.h&gt;
@@ -162,16 +163,19 @@
 
 static loff_t msr_seek(struct file *file, loff_t offset, int orig)
 {
+  loff_t ret = -EINVAL;
+  lock_kernel();
   switch (orig) {
   case 0:
     file-&gt;f_pos = offset;
-    return file-&gt;f_pos;
+    ret = file-&gt;f_pos;
+    break;
   case 1:
     file-&gt;f_pos += offset;
-    return file-&gt;f_pos;
-  default:
-    return -EINVAL;	/* SEEK_END not supported */
+    ret = file-&gt;f_pos;
   }
+  unlock_kernel();
+  return ret;
 }
 
 static ssize_t msr_read(struct file * file, char * buf,
diff -urN linux-2.4.18-pre9/arch/ppc/kernel/ppc_htab.c linux/arch/ppc/kernel/ppc_htab.c
--- linux-2.4.18-pre9/arch/ppc/kernel/ppc_htab.c	Thu Feb  7 15:27:01 2002
+++ linux/arch/ppc/kernel/ppc_htab.c	Mon Feb 11 20:44:40 2002
@@ -21,6 +21,7 @@
 #include &lt;linux/sysctl.h&gt;
 #include &lt;linux/ctype.h&gt;
 #include &lt;linux/threads.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 #include &lt;asm/uaccess.h&gt;
 #include &lt;asm/bitops.h&gt;
@@ -430,18 +431,20 @@
 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-&gt;f_pos = offset;
-	return(file-&gt;f_pos);
+	ret = file-&gt;f_pos;
+	break;
     case 1:
 	file-&gt;f_pos += offset;
-	return(file-&gt;f_pos);
-    case 2:
-	return(-EINVAL);
-    default:
-	return(-EINVAL);
+	ret = file-&gt;f_pos;
     }
+    unlock_kernel();
+    return ret;
 }
 
 int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
diff -urN linux-2.4.18-pre9/drivers/char/mem.c linux/drivers/char/mem.c
--- linux-2.4.18-pre9/drivers/char/mem.c	Thu Feb  7 15:26:33 2002
+++ linux/drivers/char/mem.c	Mon Feb 11 20:44:40 2002
@@ -21,6 +21,7 @@
 #include &lt;linux/raw.h&gt;
 #include &lt;linux/tty.h&gt;
 #include &lt;linux/capability.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 #include &lt;asm/uaccess.h&gt;
 #include &lt;asm/io.h&gt;
@@ -503,16 +504,23 @@
  */
 static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
 {
+	int ret;
+
+	lock_kernel();
 	switch (orig) {
 		case 0:
 			file-&gt;f_pos = offset;
-			return file-&gt;f_pos;
+			ret = file-&gt;f_pos;
+			break;
 		case 1:
 			file-&gt;f_pos += offset;
-			return file-&gt;f_pos;
+			ret = file-&gt;f_pos;
+			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
 	}
+	unlock_kernel();
+	return ret;
 }
 
 static int open_port(struct inode * inode, struct file * filp)
diff -urN linux-2.4.18-pre9/drivers/char/nvram.c linux/drivers/char/nvram.c
--- linux-2.4.18-pre9/drivers/char/nvram.c	Thu Feb  7 15:26:33 2002
+++ linux/drivers/char/nvram.c	Mon Feb 11 20:44:40 2002
@@ -213,6 +213,7 @@
 
 static long long nvram_llseek(struct file *file,loff_t offset, int origin )
 {
+	lock_kernel();
 	switch( origin ) {
 	  case 0:
 		/* nothing to do */
@@ -224,6 +225,7 @@
 		offset += NVRAM_BYTES;
 		break;
 	}
+	unlock_kernel();
 	return( (offset &gt;= 0) ? (file-&gt;f_pos = offset) : -EINVAL );
 }
 
diff -urN linux-2.4.18-pre9/drivers/char/nwflash.c linux/drivers/char/nwflash.c
--- linux-2.4.18-pre9/drivers/char/nwflash.c	Thu Feb  7 15:26:34 2002
+++ linux/drivers/char/nwflash.c	Mon Feb 11 20:44:40 2002
@@ -26,6 +26,7 @@
 #include &lt;linux/spinlock.h&gt;
 #include &lt;linux/rwsem.h&gt;
 #include &lt;linux/init.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 #include &lt;asm/hardware/dec21285.h&gt;
 #include &lt;asm/io.h&gt;
@@ -301,30 +302,45 @@
  */
 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 &lt; 0)
-			return -EINVAL;
+		if (offset &lt; 0) {
+			ret = -EINVAL;
+			break;
+		}
 
-		if ((unsigned int) offset &gt; gbFlashSize)
-			return -EINVAL;
+		if ((unsigned int) offset &gt; gbFlashSize) {
+			ret = -EINVAL;
+			break;
+		}
 
 		file-&gt;f_pos = (unsigned int) offset;
-		return file-&gt;f_pos;
+		ret = file-&gt;f_pos;
+		break;
 	case 1:
-		if ((file-&gt;f_pos + offset) &gt; gbFlashSize)
-			return -EINVAL;
-		if ((file-&gt;f_pos + offset) &lt; 0)
-			return -EINVAL;
+		if ((file-&gt;f_pos + offset) &gt; gbFlashSize) {
+			ret = -EINVAL;
+			break;
+		}
+		if ((file-&gt;f_pos + offset) &lt; 0) {
+			ret = -EINVAL;
+			break;
+		}
 		file-&gt;f_pos += offset;
-		return file-&gt;f_pos;
+		ret = file-&gt;f_pos;
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+	unlock_kernel();
+	return ret;
 }
 
 
diff -urN linux-2.4.18-pre9/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c
--- linux-2.4.18-pre9/drivers/char/vc_screen.c	Thu Feb  7 15:26:33 2002
+++ linux/drivers/char/vc_screen.c	Mon Feb 11 20:44:40 2002
@@ -36,6 +36,7 @@
 #include &lt;linux/selection.h&gt;
 #include &lt;linux/kbd_kern.h&gt;
 #include &lt;linux/console.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/uaccess.h&gt;
 #include &lt;asm/byteorder.h&gt;
 #include &lt;asm/unaligned.h&gt;
@@ -66,10 +67,13 @@
 
 static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 {
-	int size = vcs_size(file-&gt;f_dentry-&gt;d_inode);
+	int size;
 
+	lock_kernel();
+	size = vcs_size(file-&gt;f_dentry-&gt;d_inode);
 	switch (orig) {
 		default:
+			unlock_kernel();
 			return -EINVAL;
 		case 2:
 			offset += size;
@@ -79,9 +83,12 @@
 		case 0:
 			break;
 	}
-	if (offset &lt; 0 || offset &gt; size)
+	if (offset &lt; 0 || offset &gt; size) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 	file-&gt;f_pos = offset;
+	unlock_kernel();
 	return file-&gt;f_pos;
 }
 
diff -urN linux-2.4.18-pre9/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- linux-2.4.18-pre9/drivers/ieee1394/pcilynx.c	Thu Feb  7 15:26:51 2002
+++ linux/drivers/ieee1394/pcilynx.c	Mon Feb 11 20:44:40 2002
@@ -29,6 +29,7 @@
 #include &lt;linux/pci.h&gt;
 #include &lt;linux/fs.h&gt;
 #include &lt;linux/poll.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/byteorder.h&gt;
 #include &lt;asm/atomic.h&gt;
 #include &lt;asm/io.h&gt;
@@ -891,8 +892,9 @@
 
 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;
@@ -902,12 +904,12 @@
                 break;
         case 2:
                 newoffs = PCILYNX_MAX_MEMORY + 1 + offs;
-                break;
-        default:
-                return -EINVAL;
         }
 
-        if (newoffs &lt; 0 || newoffs &gt; PCILYNX_MAX_MEMORY + 1) return -EINVAL;
+        if (newoffs &lt; 0 || newoffs &gt; PCILYNX_MAX_MEMORY + 1) {
+                lock_kernel();
+                return -EINVAL;
+        }
 
         file-&gt;f_pos = newoffs;
         return newoffs;
diff -urN linux-2.4.18-pre9/drivers/macintosh/nvram.c linux/drivers/macintosh/nvram.c
--- linux-2.4.18-pre9/drivers/macintosh/nvram.c	Thu Feb  7 15:26:47 2002
+++ linux/drivers/macintosh/nvram.c	Mon Feb 11 20:44:40 2002
@@ -13,6 +13,7 @@
 #include &lt;linux/fcntl.h&gt;
 #include &lt;linux/nvram.h&gt;
 #include &lt;linux/init.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/uaccess.h&gt;
 #include &lt;asm/nvram.h&gt;
 
@@ -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-&gt;f_pos;
@@ -28,9 +30,12 @@
 		offset += NVRAM_SIZE;
 		break;
 	}
-	if (offset &lt; 0)
+	if (offset &lt; 0) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 	file-&gt;f_pos = offset;
+	unlock_kernel();
 	return file-&gt;f_pos;
 }
 
diff -urN linux-2.4.18-pre9/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
--- linux-2.4.18-pre9/drivers/mtd/mtdchar.c	Thu Feb  7 15:26:53 2002
+++ linux/drivers/mtd/mtdchar.c	Mon Feb 11 20:44:40 2002
@@ -10,6 +10,7 @@
 #include &lt;linux/kernel.h&gt;
 #include &lt;linux/module.h&gt;
 #include &lt;linux/mtd/mtd.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;linux/slab.h&gt;
 
 #ifdef CONFIG_DEVFS_FS
@@ -31,6 +32,7 @@
 {
 	struct mtd_info *mtd=(struct mtd_info *)file-&gt;private_data;
 
+	lock_kernel();
 	switch (orig) {
 	case 0:
 		/* SEEK_SET */
@@ -45,6 +47,7 @@
 		file-&gt;f_pos =mtd-&gt;size + offset;
 		break;
 	default:
+		unlock_kernel();
 		return -EINVAL;
 	}
 
@@ -53,6 +56,7 @@
 	else if (file-&gt;f_pos &gt;= mtd-&gt;size)
 		file-&gt;f_pos = mtd-&gt;size - 1;
 
+	unlock_kernel();
 	return file-&gt;f_pos;
 }
 
diff -urN linux-2.4.18-pre9/drivers/pci/proc.c linux/drivers/pci/proc.c
--- linux-2.4.18-pre9/drivers/pci/proc.c	Thu Feb  7 15:26:42 2002
+++ linux/drivers/pci/proc.c	Mon Feb 11 20:44:40 2002
@@ -12,6 +12,7 @@
 #include &lt;linux/proc_fs.h&gt;
 #include &lt;linux/init.h&gt;
 #include &lt;linux/seq_file.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 #include &lt;asm/uaccess.h&gt;
 #include &lt;asm/byteorder.h&gt;
@@ -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 @@
 	case 2:
 		new = PCI_CFG_SPACE_SIZE + off;
 		break;
-	default:
-		return -EINVAL;
 	}
+	unlock_kernel();
 	if (new &lt; 0 || new &gt; PCI_CFG_SPACE_SIZE)
 		return -EINVAL;
 	return (file-&gt;f_pos = new);
diff -urN linux-2.4.18-pre9/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c
--- linux-2.4.18-pre9/drivers/pnp/isapnp_proc.c	Thu Feb  7 15:26:44 2002
+++ linux/drivers/pnp/isapnp_proc.c	Mon Feb 11 20:44:40 2002
@@ -84,18 +84,26 @@
 
 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-&gt;f_pos = offset;
-		return file-&gt;f_pos;
+		ret = file-&gt;f_pos;
+		break;
 	case 1:	/* SEEK_CUR */
 		file-&gt;f_pos += offset;
-		return file-&gt;f_pos;
+		ret = file-&gt;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,
@@ -215,8 +223,9 @@
 
 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;
@@ -227,11 +236,12 @@
 	case 2:
 		new = 256 + off;
 		break;
-	default:
-		return -EINVAL;
 	}
-	if (new &lt; 0 || new &gt; 256)
+	if (new &lt; 0 || new &gt; 256) {
+		unlock_kernel();
 		return -EINVAL;
+	}
+	unlock_kernel();
 	return (file-&gt;f_pos = new);
 }
 
diff -urN linux-2.4.18-pre9/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c
--- linux-2.4.18-pre9/drivers/sbus/char/flash.c	Thu Feb  7 15:26:43 2002
+++ linux/drivers/sbus/char/flash.c	Mon Feb 11 20:44:40 2002
@@ -83,6 +83,7 @@
 static long long
 flash_llseek(struct file *file, long long offset, int origin)
 {
+	lock_kernel();
 	switch (origin) {
 		case 0:
 			file-&gt;f_pos = offset;
@@ -96,8 +97,10 @@
 			file-&gt;f_pos = flash.read_size;
 			break;
 		default:
+			unlock_kernel();
 			return -EINVAL;
 	}
+	unlock_kernel();
 	return file-&gt;f_pos;
 }
 
diff -urN linux-2.4.18-pre9/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c
--- linux-2.4.18-pre9/drivers/sbus/char/jsflash.c	Thu Feb  7 15:26:43 2002
+++ linux/drivers/sbus/char/jsflash.c	Mon Feb 11 20:44:40 2002
@@ -259,16 +259,23 @@
  */
 static loff_t jsf_lseek(struct file * file, loff_t offset, int orig)
 {
+	loff_t ret;
+
+	lock_kernel();
 	switch (orig) {
 		case 0:
 			file-&gt;f_pos = offset;
-			return file-&gt;f_pos;
+			ret = file-&gt;f_pos;
+			break;
 		case 1:
 			file-&gt;f_pos += offset;
-			return file-&gt;f_pos;
+			ret = file-&gt;f_pos;
+			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
 	}
+	unlock_kernel();
+	return ret;
 }
 
 /*
diff -urN linux-2.4.18-pre9/drivers/usb/devices.c linux/drivers/usb/devices.c
--- linux-2.4.18-pre9/drivers/usb/devices.c	Thu Feb  7 15:26:48 2002
+++ linux/drivers/usb/devices.c	Mon Feb 11 20:44:40 2002
@@ -554,21 +554,26 @@
 
 static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig)
 {
+	loff_t ret;
+
+	lock_kernel();
+
 	switch (orig) {
 	case 0:
 		file-&gt;f_pos = offset;
-		return file-&gt;f_pos;
-
+		ret = file-&gt;f_pos;
+		break;
 	case 1:
 		file-&gt;f_pos += offset;
-		return file-&gt;f_pos;
-
+		ret = file-&gt;f_pos;
+		break;
 	case 2:
-		return -EINVAL;
-
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+	unlock_kernel();
+	return ret;
 }
 
 struct file_operations usbdevfs_devices_fops = {
diff -urN linux-2.4.18-pre9/drivers/usb/devio.c linux/drivers/usb/devio.c
--- linux-2.4.18-pre9/drivers/usb/devio.c	Thu Feb  7 15:26:48 2002
+++ linux/drivers/usb/devio.c	Mon Feb 11 20:44:40 2002
@@ -57,21 +57,26 @@
 
 static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
 {
+	loff_t ret;
+
+	lock_kernel();
+
 	switch (orig) {
 	case 0:
 		file-&gt;f_pos = offset;
-		return file-&gt;f_pos;
-
+		ret = file-&gt;f_pos;
+		break;
 	case 1:
 		file-&gt;f_pos += offset;
-		return file-&gt;f_pos;
-
+		ret = file-&gt;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)
diff -urN linux-2.4.18-pre9/drivers/usb/drivers.c linux/drivers/usb/drivers.c
--- linux-2.4.18-pre9/drivers/usb/drivers.c	Thu Feb  7 15:26:48 2002
+++ linux/drivers/usb/drivers.c	Mon Feb 11 20:44:40 2002
@@ -38,6 +38,7 @@
 #include &lt;linux/mm.h&gt;
 #include &lt;linux/usb.h&gt;
 #include &lt;linux/usbdevice_fs.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/uaccess.h&gt;
 
 /*****************************************************************/
@@ -96,21 +97,24 @@
 
 static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig)
 {
+	loff_t ret;
+
+	lock_kernel();
 	switch (orig) {
 	case 0:
 		file-&gt;f_pos = offset;
-		return file-&gt;f_pos;
-
+		ret = file-&gt;f_pos;
+		break;
 	case 1:
 		file-&gt;f_pos += offset;
-		return file-&gt;f_pos;
-
+		ret = file-&gt;f_pos;
+		break;
 	case 2:
-		return -EINVAL;
-
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+	unlock_kernel();
+	return ret;
 }
 
 struct file_operations usbdevfs_drivers_fops = {
diff -urN linux-2.4.18-pre9/drivers/usb/uhci-debug.h linux/drivers/usb/uhci-debug.h
--- linux-2.4.18-pre9/drivers/usb/uhci-debug.h	Thu Feb  7 15:26:48 2002
+++ linux/drivers/usb/uhci-debug.h	Mon Feb 11 20:44:41 2002
@@ -12,6 +12,7 @@
 #include &lt;linux/config.h&gt;
 #include &lt;linux/kernel.h&gt;
 #include &lt;linux/proc_fs.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/io.h&gt;
 
 #include "uhci.h"
@@ -507,8 +508,11 @@
 
 static loff_t uhci_proc_lseek(struct file *file, loff_t off, int whence)
 {
-	struct uhci_proc *up = file-&gt;private_data;
-	loff_t new;
+	struct uhci_proc *up;
+	loff_t new = -1;
+
+	lock_kernel();
+	up = file-&gt;private_data;
 
 	switch (whence) {
 	case 0:
@@ -517,12 +521,12 @@
 	case 1:
 		new = file-&gt;f_pos + off;
 		break;
-	case 2:
-	default:
-		return -EINVAL;
 	}
-	if (new &lt; 0 || new &gt; up-&gt;size)
+	if (new &lt; 0 || new &gt; up-&gt;size) {
+		unlock_kernel();
 		return -EINVAL;
+	}
+	unlock_kernel();
 	return (file-&gt;f_pos = new);
 }
 
diff -urN linux-2.4.18-pre9/drivers/zorro/proc.c linux/drivers/zorro/proc.c
--- linux-2.4.18-pre9/drivers/zorro/proc.c	Thu Feb  7 15:26:48 2002
+++ linux/drivers/zorro/proc.c	Mon Feb 11 20:46:22 2002
@@ -14,6 +14,7 @@
 #include &lt;linux/zorro.h&gt;
 #include &lt;linux/proc_fs.h&gt;
 #include &lt;linux/init.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/uaccess.h&gt;
 #include &lt;asm/amigahw.h&gt;
 #include &lt;asm/setup.h&gt;
@@ -21,8 +22,9 @@
 static loff_t
 proc_bus_zorro_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,11 +35,12 @@
 	case 2:
 		new = sizeof(struct ConfigDev) + off;
 		break;
-	default:
-		return -EINVAL;
 	}
-	if (new &lt; 0 || new &gt; sizeof(struct ConfigDev))
+	if (new &lt; 0 || new &gt; sizeof(struct ConfigDev)) {
+		unlock_kernel();
 		return -EINVAL;
+	}
+	unlock_kernel();
 	return (file-&gt;f_pos = new);
 }
 
diff -urN linux-2.4.18-pre9/fs/block_dev.c linux/fs/block_dev.c
--- linux-2.4.18-pre9/fs/block_dev.c	Thu Feb  7 15:26:12 2002
+++ linux/fs/block_dev.c	Mon Feb 11 20:41:35 2002
@@ -149,6 +149,7 @@
 	loff_t size = file-&gt;f_dentry-&gt;d_inode-&gt;i_bdev-&gt;bd_inode-&gt;i_size;
 	loff_t retval;
 
+	lock_kernel();
 	switch (origin) {
 		case 2:
 			offset += size;
@@ -165,6 +166,7 @@
 		}
 		retval = offset;
 	}
+	unlock_kernel();
 	return retval;
 }
 	
diff -urN linux-2.4.18-pre9/fs/hfs/file_cap.c linux/fs/hfs/file_cap.c
--- linux-2.4.18-pre9/fs/hfs/file_cap.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/hfs/file_cap.c	Mon Feb 11 20:41:35 2002
@@ -24,6 +24,7 @@
 #include &lt;linux/hfs_fs_sb.h&gt;
 #include &lt;linux/hfs_fs_i.h&gt;
 #include &lt;linux/hfs_fs.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 /*================ Forward declarations ================*/
 static loff_t      cap_info_llseek(struct file *, loff_t,
@@ -91,6 +92,7 @@
 {
 	long long retval;
 
+	lock_kernel();
 	switch (origin) {
 		case 2:
 			offset += file-&gt;f_dentry-&gt;d_inode-&gt;i_size;
@@ -107,6 +109,7 @@
 		}
 		retval = offset;
 	}
+	unlock_kernel();
 	return retval;
 }
 
diff -urN linux-2.4.18-pre9/fs/hfs/file_hdr.c linux/fs/hfs/file_hdr.c
--- linux-2.4.18-pre9/fs/hfs/file_hdr.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/hfs/file_hdr.c	Mon Feb 11 20:41:35 2002
@@ -29,6 +29,7 @@
 #include &lt;linux/hfs_fs_sb.h&gt;
 #include &lt;linux/hfs_fs_i.h&gt;
 #include &lt;linux/hfs_fs.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 /* prodos types */
 #define PRODOSI_FTYPE_DIR   0x0F
@@ -347,6 +348,7 @@
 {
 	long long retval;
 
+	lock_kernel();
 	switch (origin) {
 		case 2:
 			offset += file-&gt;f_dentry-&gt;d_inode-&gt;i_size;
@@ -363,6 +365,7 @@
 		}
 		retval = offset;
 	}
+	unlock_kernel();
 	return retval;
 }
 
diff -urN linux-2.4.18-pre9/fs/hpfs/dir.c linux/fs/hpfs/dir.c
--- linux-2.4.18-pre9/fs/hpfs/dir.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/hpfs/dir.c	Mon Feb 11 20:41:35 2002
@@ -29,6 +29,7 @@
 	struct inode *i = filp-&gt;f_dentry-&gt;d_inode;
 	struct super_block *s = i-&gt;i_sb;
 	/*printk("dir lseek\n");*/
+	lock_kernel();
 	if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
 	hpfs_lock_inode(i);
 	pos = ((loff_t) hpfs_de_as_down_as_possible(s, i-&gt;i_hpfs_dno) &lt;&lt; 4) + 1;
@@ -39,10 +40,12 @@
 	}
 	hpfs_unlock_inode(i);
 	ok:
+	unlock_kernel();
 	return filp-&gt;f_pos = new_off;
 	fail:
 	hpfs_unlock_inode(i);
 	/*printk("illegal lseek: %016llx\n", new_off);*/
+	unlock_kernel();
 	return -ESPIPE;
 }
 
diff -urN linux-2.4.18-pre9/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- linux-2.4.18-pre9/fs/ncpfs/file.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/ncpfs/file.c	Mon Feb 11 20:41:47 2002
@@ -18,6 +18,7 @@
 #include &lt;linux/locks.h&gt;
 #include &lt;linux/slab.h&gt;
 #include &lt;linux/vmalloc.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 
 #include &lt;linux/ncp_fs.h&gt;
 #include "ncplib_kernel.h"
@@ -281,7 +282,7 @@
 
 struct file_operations ncp_file_operations =
 {
-	llseek:		generic_file_llseek,
+	llseek:		remote_llseek,
 	read:		ncp_file_read,
 	write:		ncp_file_write,
 	ioctl:		ncp_ioctl,
diff -urN linux-2.4.18-pre9/fs/nfs/file.c linux/fs/nfs/file.c
--- linux-2.4.18-pre9/fs/nfs/file.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/nfs/file.c	Mon Feb 11 20:41:47 2002
@@ -41,7 +41,7 @@
 static int  nfs_fsync(struct file *, struct dentry *dentry, int datasync);
 
 struct file_operations nfs_file_operations = {
-	llseek:		generic_file_llseek,
+	llseek:		remote_llseek,
 	read:		nfs_file_read,
 	write:		nfs_file_write,
 	mmap:		nfs_file_mmap,
diff -urN linux-2.4.18-pre9/fs/proc/generic.c linux/fs/proc/generic.c
--- linux-2.4.18-pre9/fs/proc/generic.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/proc/generic.c	Mon Feb 11 20:41:35 2002
@@ -16,6 +16,7 @@
 #include &lt;linux/stat.h&gt;
 #define __NO_VERSION__
 #include &lt;linux/module.h&gt;
+#include &lt;linux/smp_lock.h&gt;
 #include &lt;asm/bitops.h&gt;
 
 static ssize_t proc_file_read(struct file * file, char * buf,
@@ -140,22 +141,26 @@
 static loff_t
 proc_file_lseek(struct file * file, loff_t offset, int orig)
 {
+    lock_kernel();
+
     switch (orig) {
     case 0:
 	if (offset &lt; 0)
-	    return -EINVAL;    
+	    goto out;
 	file-&gt;f_pos = offset;
-	return(file-&gt;f_pos);
+	goto out;
     case 1:
 	if (offset + file-&gt;f_pos &lt; 0)
-	    return -EINVAL;    
+	    goto out;
 	file-&gt;f_pos += offset;
-	return(file-&gt;f_pos);
+	goto out;
     case 2:
-	return(-EINVAL);
     default:
-	return(-EINVAL);
     }
+
+out:
+    unlock_kernel();
+    return -EINVAL;
 }
 
 /*
diff -urN linux-2.4.18-pre9/fs/read_write.c linux/fs/read_write.c
--- linux-2.4.18-pre9/fs/read_write.c	Thu Feb  7 15:26:12 2002
+++ linux/fs/read_write.c	Mon Feb 11 20:41:47 2002
@@ -28,7 +28,37 @@
 loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
 {
 	long long retval;
+	struct inode *inode = file-&gt;f_dentry-&gt;d_inode-&gt;i_mapping-&gt;host;
 
+	down(&amp;inode-&gt;i_sem);
+
+	switch (origin) {
+		case 2:
+			offset += inode-&gt;i_size;
+			break;
+		case 1:
+			offset += file-&gt;f_pos;
+	}
+	retval = -EINVAL;
+	if (offset&gt;=0 &amp;&amp; offset&lt;=file-&gt;f_dentry-&gt;d_inode-&gt;i_sb-&gt;s_maxbytes) {
+		if (offset&gt;=0 &amp;&amp; offset&lt;=inode-&gt;i_sb-&gt;s_maxbytes) {
+			file-&gt;f_pos = offset;
+			file-&gt;f_reada = 0;
+			file-&gt;f_version = ++event;
+		}
+		retval = offset;
+	}
+
+	up(&amp;inode-&gt;i_sem);
+
+	return retval;
+}
+
+loff_t remote_llseek(struct file *file, loff_t offset, int origin)
+{
+	long long retval;
+
+	lock_kernel();
 	switch (origin) {
 		case 2:
 			offset += file-&gt;f_dentry-&gt;d_inode-&gt;i_size;
@@ -45,6 +75,7 @@
 		}
 		retval = offset;
 	}
+	unlock_kernel();
 	return retval;
 }
 
@@ -57,6 +88,7 @@
 {
 	long long retval;
 
+	lock_kernel();
 	switch (origin) {
 		case 2:
 			offset += file-&gt;f_dentry-&gt;d_inode-&gt;i_size;
@@ -73,21 +105,18 @@
 		}
 		retval = offset;
 	}
+	unlock_kernel();
 	return retval;
 }
 
 static inline loff_t llseek(struct file *file, loff_t offset, int origin)
 {
 	loff_t (*fn)(struct file *, loff_t, int);
-	loff_t retval;
 
 	fn = default_llseek;
 	if (file-&gt;f_op &amp;&amp; file-&gt;f_op-&gt;llseek)
 		fn = file-&gt;f_op-&gt;llseek;
-	lock_kernel();
-	retval = fn(file, offset, origin);
-	unlock_kernel();
-	return retval;
+	return fn(file, offset, origin);
 }
 
 asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
diff -urN linux-2.4.18-pre9/fs/smbfs/file.c linux/fs/smbfs/file.c
--- linux-2.4.18-pre9/fs/smbfs/file.c	Thu Feb  7 15:26:13 2002
+++ linux/fs/smbfs/file.c	Mon Feb 11 20:41:47 2002
@@ -381,7 +381,7 @@
 
 struct file_operations smb_file_operations =
 {
-	llseek:		generic_file_llseek,
+	llseek:		remote_llseek,
 	read:		smb_file_read,
 	write:		smb_file_write,
 	ioctl:		smb_ioctl,
diff -urN linux-2.4.18-pre9/include/linux/fs.h linux/include/linux/fs.h
--- linux-2.4.18-pre9/include/linux/fs.h	Thu Feb  7 15:26:14 2002
+++ linux/include/linux/fs.h	Mon Feb 11 20:41:47 2002
@@ -1415,6 +1415,7 @@
 extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
 extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
+extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
 extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
 extern int generic_file_open(struct inode * inode, struct file * filp);
 
diff -urN linux-2.4.18-pre9/kernel/ksyms.c linux/kernel/ksyms.c
--- linux-2.4.18-pre9/kernel/ksyms.c	Thu Feb  7 15:26:13 2002
+++ linux/kernel/ksyms.c	Mon Feb 11 20:41:47 2002
@@ -248,6 +248,7 @@
 EXPORT_SYMBOL(vfs_statfs);
 EXPORT_SYMBOL(generic_read_dir);
 EXPORT_SYMBOL(generic_file_llseek);
+EXPORT_SYMBOL(remote_llseek);
 EXPORT_SYMBOL(no_llseek);
 EXPORT_SYMBOL(__pollwait);
 EXPORT_SYMBOL(poll_freewait);
</pre></body></html>