## Automatically generated incremental diff
## From:   linux-2.5.4-pre1
## To:     linux-2.5.4-pre2
## Robot:  $Id: make-incremental-diff,v 1.9 2001/12/10 00:06:56 hpa Exp $

diff -urN linux-2.5.4-pre1/Documentation/filesystems/Locking linux/Documentation/filesystems/Locking
--- linux-2.5.4-pre1/Documentation/filesystems/Locking	Tue Jan 29 21:15:47 2002
+++ linux/Documentation/filesystems/Locking	Wed Feb  6 22:51:46 2002
@@ -237,7 +237,10 @@
 
 ->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 BKL in your ->llseek().
+need to acquire and release the appropriate locks in your ->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.
 
 ->open() locking is in-transit: big lock partially moved into the methods.
 The only exception is ->open() in the instances of file_operations that never
diff -urN linux-2.5.4-pre1/Documentation/usb/ibmcam.txt linux/Documentation/usb/ibmcam.txt
--- linux-2.5.4-pre1/Documentation/usb/ibmcam.txt	Sun Apr  2 15:19:56 2000
+++ linux/Documentation/usb/ibmcam.txt	Wed Feb  6 22:51:46 2002
@@ -25,12 +25,19 @@
 
 SUPPORTED CAMERAS:
 
-IBM "C-It" camera, also known as "Xirlink PC Camera"
+Xirlink "C-It" camera, also known as "IBM PC Camera".
 The device uses proprietary ASIC (and compression method);
 it is manufactured by Xirlink. See http://www.xirlink.com/
 http://www.ibmpccamera.com or http://www.c-itnow.com/ for
 details and pictures.
 
+This very chipset ("X Chip", as marked at the factory)
+is used in several other cameras, and they are supported
+as well:
+
+- IBM NetCamera
+- Veo Stingray
+
 The Linux driver was developed with camera with following
 model number (or FCC ID): KSX-XVP510. This camera has three
 interfaces, each with one endpoint (control, iso, iso). This
@@ -50,12 +57,30 @@
 Such type of cameras is referred to as "model 2". They are supported
 (with exception of 352x288 native mode).
 
+Some IBM NetCameras (Model 4) are made to generate only compressed
+video streams. This is great for performance, but unfortunately
+nobody knows how to decompress the stream :-( Therefore, these
+cameras are *unsupported* and if you try to use one of those, all
+you get is random colored horizontal streaks, not the image!
+If you have one of those cameras, you probably should return it
+to the store and get something that is supported.
+
+Tell me more about all that "model" business
+--------------------------------------------
+
+I just invented model numbers to uniquely identify flavors of the
+hardware/firmware that were sold. It was very confusing to use
+brand names or some other internal numbering schemes. So I found
+by experimentation that all Xirlink chipsets fall into four big
+classes, and I called them "models". Each model is programmed in
+its own way, and each model sends back the video in its own way.
+
 Quirks of Model 2 cameras:
 -------------------------
 
 Model 2 does not have hardware contrast control. Corresponding V4L
-control is not used at the moment. It may be possible to implement
-contrast control in software, at cost of extra processor cycles.
+control is implemented in software, which is not very nice to your
+CPU, but at least it works.
 
 This driver provides 352x288 mode by switching the camera into
 quasi-352x288 RGB mode (800 Kbits per frame) essentially limiting
@@ -67,17 +92,24 @@
 the frame rate at slowest setting, but I had to move it pretty much down
 the scale (so that framerate option barely matters). I also noticed that
 camera after first powering up produces frames slightly faster than during
-consecutive uses. All this means that if you use videosize=2 (which is
+consecutive uses. All this means that if you use 352x288 (which is
 default), be warned - you may encounter broken picture on first connect;
 try to adjust brightness - brighter image is slower, so USB will be able
 to send all data. However if you regularly use Model 2 cameras you may
-prefer videosize=1 which makes perfectly good I420, with no scaling and
+prefer 176x144 which makes perfectly good I420, with no scaling and
 lesser demands on USB (300 Kbits per second, or 26 frames per second).
 
+Another strange effect of 352x288 mode is the fine vertical grid visible
+on some colored surfaces. I am sure it is caused by me not understanding
+what the camera is trying to say. Blame trade secrets for that.
+
 The camera that I had also has a hardware quirk: if disconnected,
 it needs few minutes to "relax" before it can be plugged in again
 (poorly designed USB processor reset circuit?)
 
+[Veo Stingray with Product ID 0x800C is also Model 2, but I haven't
+observed this particular flaw in it.]
+
 Model 2 camera can be programmed for very high sensitivity (even starlight
 may be enough), this makes it convenient for tinkering with. The driver
 code has enough comments to help a programmer to tweak the camera
@@ -98,12 +130,14 @@
 precompile all modules, so you can go directly to the next
 section "HOW TO USE THE DRIVER".
 
-The driver consists of two files in usb/ directory:
-ibmcam.c and ibmcam.h These files are included into the
-Linux kernel build process if you configure the kernel
-for CONFIG_USB_IBMCAM. Run "make xconfig" and in USB section
-you will find the IBM camera driver. Select it, save the
-configuration and recompile.
+The ibmcam driver uses usbvideo helper library (module),
+so if you are studying the ibmcam code you will be led there.
+
+The driver itself consists of only one file in usb/ directory:
+ibmcam.c. This file is included into the Linux kernel build
+process if you configure the kernel for CONFIG_USB_IBMCAM.
+Run "make xconfig" and in USB section you will find the IBM
+camera driver. Select it, save the configuration and recompile.
 
 HOW TO USE THE DRIVER:
 
@@ -112,6 +146,13 @@
 settings than V4L can operate, so some settings are done using
 module options.
 
+To begin with, on most modern Linux distributions the driver
+will be automatically loaded whenever you plug the supported
+camera in. Therefore, you don't need to do anything. However
+if you want to experiment with some module parameters then
+you can load and unload the driver manually, with camera
+plugged in or unplugged.
+
 Typically module is installed with command 'modprobe', like this:
 
 # modprobe ibmcam framerate=1
@@ -138,7 +179,7 @@
 init_hue        Integer         0-255 [128]     init_hue=115
 lighting        Integer         0-2* [1]        lighting=2
 sharpness       Integer         0-6* [4]        sharpness=3
-videosize       Integer         0-2* [2]        videosize=1
+size            Integer         0-2* [2]        size=1
 
 Options for Model 2 only:
 
@@ -181,6 +222,11 @@
                                            this is a little faster but may
                                            produce flicker if frame rate is
                                            too high and Isoc data gets lost.
+                FLAGS_NO_DECODING      128 This flag turns the video stream
+                                           decoder off, and dumps the raw
+                                           Isoc data from the camera into
+                                           the reading process. Useful to
+                                           developers, but not to users.
 
 framerate       This setting controls frame rate of the camera. This is
                 an approximate setting (in terms of "worst" ... "best")
@@ -227,35 +273,38 @@
                 be greeted with "snowy" image. Default is 4. Model 2
                 cameras do not support this feature.
 
-videosize       This setting chooses one if three image sizes that are
-                supported by this driver. Camera supports more, but
+size            This setting chooses one of several image sizes that are
+                supported by this driver. Cameras may support more, but
                 it's difficult to reverse-engineer all formats.
                 Following video sizes are supported:
 
-                videosize=0     128x96  (Model 1 only)
-                videosize=1     176x144
-                videosize=2     352x288
-                videosize=3     320x240 (Model 2 only)
-                videosize=4     352x240 (Model 2 only)
+                size=0     128x96  (Model 1 only)
+                size=1     160x120
+                size=2     176x144
+                size=3     320x240 (Model 2 only)
+                size=4     352x240 (Model 2 only)
+                size=5     352x288
+                size=6     640x480 (Model 3 only)
 
-                The last one (352x288) is the native size of the sensor
-                array, so it's the best resolution camera (Model 1) can
+                The 352x288 is the native size of the Model 1 sensor
+                array, so it's the best resolution the camera can
                 yield. The best resolution of Model 2 is 176x144, and
                 larger images are produced by stretching the bitmap.
+                Model 3 has sensor with 640x480 grid, and it works too,
+                but the frame rate will be exceptionally low (1-2 FPS);
+                it may be still OK for some applications, like security.
                 Choose the image size you need. The smaller image can
                 support faster frame rate. Default is 352x288.
 
+For more information and the Troubleshooting FAQ visit this URL:
+
+                http://www.linux-usb.org/ibmcam/
+
 WHAT NEEDS TO BE DONE:
 
-- The box freezes if camera is unplugged after being used (OHCI).
-  Workaround: remove usb-ohci module first.
-- On occasion camera (model 1) does not start properly (xawtv reports
-  errors), or camera produces negative image (funny colors.)
-  Workaround: reload the driver module. Reason: [1].
 - The button on the camera is not used. I don't know how to get to it.
   I know now how to read button on Model 2, but what to do with it?
 
-[1]
 - Camera reports its status back to the driver; however I don't know
   what returned data means. If camera fails at some initialization
   stage then something should be done, and I don't do that because
@@ -263,26 +312,13 @@
   concern because Model 2 uses different commands which do not return
   status (and seem to complete successfully every time).
 
-VIDEO SIZE AND IMAGE SIZE
-
-Camera produces picture X by Y pixels. This is camera-specific and can be
-altered by programming the camera accordingly. This image is placed onto
-larger (or equal) area W by H, this is V4L image. At this time the driver
-uses V4L image size (W by H) 352x288 pixels because many programs (such
-as xawtv) expect quite specific sizes and don't want to deal with arbitrary,
-camera-specific sizes. However this approach "hides" real image size, and
-application always sees the camera as producing only 352x288 image. It is
-possible to change the V4L image size to 128x96, and then if camera is
-switched to 128x96 mode then xawtv will correctly accept this image size. But
-many other popular sizes (such as 176x144) will not be welcomed. This is the
-reason why all camera images are at this time placed onto 352x288 "canvas",
-and size of that canvas (V4L) is reported to applications. It will be easy
-to add options to control the canvas size, but it will be application-
-specific because not all applications are ready to work with variety of
-camera-specific sizes.
+- Some flavors of Model 4 NetCameras produce only compressed video
+  streams, and I don't know how to decode them.
 
 CREDITS:
 
 The code is based in no small part on the CPiA driver by Johannes Erdfelt,
 Randy Dunlap, and others. Big thanks to them for their pioneering work on that
 and the USB stack.
+
+I also thank John Lightsey for his donation of the Veo Stingray camera.
diff -urN linux-2.5.4-pre1/Makefile linux/Makefile
--- linux-2.5.4-pre1/Makefile	Wed Feb  6 22:51:45 2002
+++ linux/Makefile	Wed Feb  6 22:51:46 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 4
-EXTRAVERSION =-pre1
+EXTRAVERSION =-pre2
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.5.4-pre1/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- linux-2.5.4-pre1/arch/alpha/kernel/entry.S	Mon Jan 28 15:14:22 2002
+++ linux/arch/alpha/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -1148,3 +1148,4 @@
 	.quad sys_gettid
 	.quad sys_readahead
 	.quad sys_ni_syscall			/* 380, sys_security */
+	.quad sys_tkill
diff -urN linux-2.5.4-pre1/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
--- linux-2.5.4-pre1/arch/alpha/kernel/signal.c	Fri Nov  9 13:45:35 2001
+++ linux/arch/alpha/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -717,9 +717,7 @@
 
 			default:
 				lock_kernel();
-				sigaddset(&current->pending.signal, signr);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 			continue;
diff -urN linux-2.5.4-pre1/arch/arm/kernel/calls.S linux/arch/arm/kernel/calls.S
--- linux-2.5.4-pre1/arch/arm/kernel/calls.S	Mon Oct  8 10:39:18 2001
+++ linux/arch/arm/kernel/calls.S	Wed Feb  6 22:51:46 2002
@@ -236,6 +236,8 @@
 		.long	SYMBOL_NAME(sys_mincore)
 /* 220 */	.long	SYMBOL_NAME(sys_madvise)
 		.long	SYMBOL_NAME(sys_fcntl64)
+		.long	SYMBOL_NAME(sys_gettid)
+		.long	SYMBOL_NAME(sys_tkill)
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -urN linux-2.5.4-pre1/arch/arm/kernel/signal.c linux/arch/arm/kernel/signal.c
--- linux-2.5.4-pre1/arch/arm/kernel/signal.c	Sat Jan  5 13:04:30 2002
+++ linux/arch/arm/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -637,10 +637,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/cris/drivers/eeprom.c linux/arch/cris/drivers/eeprom.c
--- linux-2.5.4-pre1/arch/cris/drivers/eeprom.c	Mon Jan 21 16:00:39 2002
+++ linux/arch/cris/drivers/eeprom.c	Wed Feb  6 22:51:46 2002
@@ -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 @@
  *  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. */
diff -urN linux-2.5.4-pre1/arch/cris/drivers/usb-host.c linux/arch/cris/drivers/usb-host.c
--- linux-2.5.4-pre1/arch/cris/drivers/usb-host.c	Mon Jan 21 15:44:21 2002
+++ linux/arch/cris/drivers/usb-host.c	Wed Feb  6 22:51:46 2002
@@ -210,12 +210,12 @@
 static void etrax_usb_free_epid(char epid);
 static void cleanup_sb(USB_SB_Desc_t *sb);
 
-static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen);
-static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen);
+static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags);
+static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags);
 
-static int etrax_usb_submit_ctrl_urb(struct urb *urb);
+static int etrax_usb_submit_ctrl_urb(struct urb *urb, int mem_flags);
 
-static int etrax_usb_submit_urb(struct urb *urb);
+static int etrax_usb_submit_urb(struct urb *urb, int mem_flags);
 static int etrax_usb_unlink_urb(struct urb *urb);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 static int etrax_usb_allocate_dev(struct usb_device *usb_dev);
@@ -512,7 +512,7 @@
 	} while (tmp_ep != first_ep);
 }
 
-static int etrax_usb_submit_intr_urb(struct urb *urb)
+static int etrax_usb_submit_intr_urb(struct urb *urb, mem_flags)
 {
 	USB_EP_Desc_t *tmp_ep;
 	USB_EP_Desc_t *first_ep;
@@ -556,7 +556,7 @@
 	}
 	/* Ok, now we got valid endpoint, lets insert some traffic */
 
-	urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
+	urb_priv = (etrax_urb_priv_t *)kmalloc(sizeof(etrax_urb_priv_t), mem_flags);
 	urb_priv->first_sb = 0;
 	urb_priv->rx_offset = 0;
 	urb_priv->eot = 0;
@@ -591,9 +591,9 @@
 				USB_SB_Desc_t *traffic_sb;
 
 				traffic_ep = (USB_EP_Desc_t *)
-					kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+					kmem_cache_alloc(usb_desc_cache, mem_flags);
 				traffic_sb = (USB_SB_Desc_t *)
-					kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+					kmem_cache_alloc(usb_desc_cache, mem_flags);
 
 				traffic_ep->hw_len = 0;
 				traffic_ep->command = IO_FIELD(USB_EP_command, epid, epid) |
@@ -904,7 +904,7 @@
 	return -1;
 }
 
-static int etrax_usb_submit_bulk_urb(struct urb *urb)
+static int etrax_usb_submit_bulk_urb(struct urb *urb, int mem_flags)
 {
 	char epid;
 	char devnum;
@@ -954,7 +954,7 @@
 		/* If this is the first URB, add the URB and do HW add */
 		URB_List[epid] = urb;
 		restore_flags(flags);
-		etrax_usb_do_bulk_hw_add(urb, epid, maxlen);
+		etrax_usb_do_bulk_hw_add(urb, epid, maxlen, mem_flags);
 	}
 
 	DBFEXIT;
@@ -962,7 +962,7 @@
 	return 0;
 }
 
-static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen)
+static int etrax_usb_do_bulk_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags)
 {
 	USB_SB_Desc_t *sb_desc_1;
 
@@ -973,8 +973,8 @@
 
 	DBFENTER;
 
-	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
-	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), mem_flags);
+	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags);
 
 	if (usb_pipeout(urb->pipe)) {
 
@@ -1135,7 +1135,8 @@
 	if (URB_List[epid]) {
 		etrax_usb_do_bulk_hw_add(URB_List[epid], epid,
 					 usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe,
-						       usb_pipeout(URB_List[epid]->pipe)));
+						       usb_pipeout(URB_List[epid]->pipe)),
+					 GFP_KERNEL);
 	}
 #if 1
 	else {
@@ -1159,7 +1160,7 @@
 
 /* ---------------------------------------------------------------------------- */
 
-static int etrax_usb_submit_ctrl_urb(struct urb *urb)
+static int etrax_usb_submit_ctrl_urb(struct urb *urb, int mem_flags)
 {
 	char epid;
 	char devnum;
@@ -1209,7 +1210,7 @@
 		/* If this is the first URB, add the URB and do HW add */
 		URB_List[epid] = urb;
 		restore_flags(flags);
-		etrax_usb_do_ctrl_hw_add(urb, epid, maxlen);
+		etrax_usb_do_ctrl_hw_add(urb, epid, maxlen, mem_flags);
 	}
 
 	DBFEXIT;
@@ -1217,7 +1218,7 @@
 	return 0;
 }
 
-static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen)
+static int etrax_usb_do_ctrl_hw_add(struct urb *urb, char epid, char maxlen, int mem_flags)
 {
 	USB_SB_Desc_t *sb_desc_1;
 	USB_SB_Desc_t *sb_desc_2;
@@ -1231,9 +1232,9 @@
 
 	DBFENTER;
 
-	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), GFP_KERNEL);
-	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
-	sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+	urb_priv = kmalloc(sizeof(etrax_urb_priv_t), mem_flags);
+	sb_desc_1 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags);
+	sb_desc_2 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags);
 
 	if (!(sb_desc_1 && sb_desc_2)) {
 		panic("kmem_cache_alloc in ctrl_hw_add gave NULL pointers !!!\n");
@@ -1257,7 +1258,7 @@
 		
 		if (urb->transfer_buffer) {
 			dbg_ctrl("This OUT transfer has an extra data stage");
-			sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+			sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags);
 
 			sb_desc_1->next = virt_to_phys(sb_desc_3);
 			
@@ -1285,7 +1286,7 @@
 		dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length);
 		dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen);
 
-		sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_KERNEL);
+		sb_desc_3 = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, mem_flags);
 		
 		sb_desc_2->sw_len = urb->transfer_buffer_length ?
 			(urb->transfer_buffer_length - 1) / maxlen + 1 : 0;
@@ -1358,7 +1359,7 @@
 	DBFEXIT;
 }
 
-static int etrax_usb_submit_urb(struct urb *urb)
+static int etrax_usb_submit_urb(struct urb *urb, int mem_flags)
 {
 	etrax_hc_t *hc;
 	int rval = -EINVAL;
@@ -1375,10 +1376,10 @@
 		rval = etrax_rh_submit_urb(urb);
 		
 	} else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) {
-		rval = etrax_usb_submit_ctrl_urb(urb);
+		rval = etrax_usb_submit_ctrl_urb(urb, mem_flags);
 
 	} else if (usb_pipetype(urb->pipe) == PIPE_BULK) {
-		rval = etrax_usb_submit_bulk_urb(urb);
+		rval = etrax_usb_submit_bulk_urb(urb, mem_flags);
 
 	} else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) {
 		int bustime;
@@ -1389,7 +1390,7 @@
 				rval = bustime;
 			} else {
 				usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-				rval = etrax_usb_submit_intr_urb(urb);
+				rval = etrax_usb_submit_intr_urb(urb, mem_flags);
 			}
 			
 		}
@@ -1683,7 +1684,8 @@
 	if (URB_List[epid]) {
 		etrax_usb_do_ctrl_hw_add(URB_List[epid], epid,
 					 usb_maxpacket(URB_List[epid]->dev, URB_List[epid]->pipe,
-						       usb_pipeout(URB_List[epid]->pipe)));
+						       usb_pipeout(URB_List[epid]->pipe)),
+					 GFP_KERNEL);
 	}
 #if 1
 	else {
diff -urN linux-2.5.4-pre1/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- linux-2.5.4-pre1/arch/cris/kernel/entry.S	Mon Jan 21 16:00:39 2002
+++ linux/arch/cris/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -1015,6 +1015,7 @@
         .long SYMBOL_NAME(sys_ni_syscall)       /* Reserved for Security */
         .long SYMBOL_NAME(sys_gettid)
         .long SYMBOL_NAME(sys_readahead)        /* 225 */
+        .long SYMBOL_NAME(sys_tkill)
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
diff -urN linux-2.5.4-pre1/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- linux-2.5.4-pre1/arch/cris/kernel/signal.c	Mon Oct  8 11:43:54 2001
+++ linux/arch/cris/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -679,10 +679,7 @@
 
 			default:
 				lock_kernel();
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/i386/kernel/cpuid.c linux/arch/i386/kernel/cpuid.c
--- linux-2.5.4-pre1/arch/i386/kernel/cpuid.c	Thu Jan  3 12:20:00 2002
+++ linux/arch/i386/kernel/cpuid.c	Wed Feb  6 22:51:46 2002
@@ -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 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,
diff -urN linux-2.5.4-pre1/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux-2.5.4-pre1/arch/i386/kernel/entry.S	Tue Jan 29 18:50:30 2002
+++ linux/arch/i386/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -667,6 +667,7 @@
 	.long SYMBOL_NAME(sys_removexattr)	/* 235 */
 	.long SYMBOL_NAME(sys_lremovexattr)
 	.long SYMBOL_NAME(sys_fremovexattr)
+ 	.long SYMBOL_NAME(sys_tkill)
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -urN linux-2.5.4-pre1/arch/i386/kernel/msr.c linux/arch/i386/kernel/msr.c
--- linux-2.5.4-pre1/arch/i386/kernel/msr.c	Thu Jan  3 12:20:00 2002
+++ linux/arch/i386/kernel/msr.c	Wed Feb  6 22:51:46 2002
@@ -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 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,
diff -urN linux-2.5.4-pre1/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- linux-2.5.4-pre1/arch/i386/kernel/signal.c	Mon Jan 28 15:11:45 2002
+++ linux/arch/i386/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -683,10 +683,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/ia64/ia32/sys_ia32.c linux/arch/ia64/ia32/sys_ia32.c
--- linux-2.5.4-pre1/arch/ia64/ia32/sys_ia32.c	Fri Nov  9 14:26:17 2001
+++ linux/arch/ia64/ia32/sys_ia32.c	Wed Feb  6 22:51:46 2002
@@ -171,77 +171,65 @@
 }
 
 static inline int
-putstat (struct stat32 *ubuf, struct stat *kbuf)
+putstat (struct stat32 *ubuf, struct kstat *stat)
 {
 	int err;
 
+	if (stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+
 	if (clear_user(ubuf, sizeof(*ubuf)))
-		return 1;
+		return -EFAULT;
 
-	err  = __put_user(kbuf->st_dev, &ubuf->st_dev);
-	err |= __put_user(kbuf->st_ino, &ubuf->st_ino);
-	err |= __put_user(kbuf->st_mode, &ubuf->st_mode);
-	err |= __put_user(kbuf->st_nlink, &ubuf->st_nlink);
-	err |= __put_user(kbuf->st_uid, &ubuf->st_uid);
-	err |= __put_user(kbuf->st_gid, &ubuf->st_gid);
-	err |= __put_user(kbuf->st_rdev, &ubuf->st_rdev);
-	err |= __put_user(kbuf->st_size, &ubuf->st_size);
-	err |= __put_user(kbuf->st_atime, &ubuf->st_atime);
-	err |= __put_user(kbuf->st_mtime, &ubuf->st_mtime);
-	err |= __put_user(kbuf->st_ctime, &ubuf->st_ctime);
-	err |= __put_user(kbuf->st_blksize, &ubuf->st_blksize);
-	err |= __put_user(kbuf->st_blocks, &ubuf->st_blocks);
+	err  = __put_user(stat->dev, &ubuf->st_dev);
+	err |= __put_user(stat->ino, &ubuf->st_ino);
+	err |= __put_user(stat->mode, &ubuf->st_mode);
+	err |= __put_user(stat->nlink, &ubuf->st_nlink);
+	err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
+	err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
+	err |= __put_user(stat->rdev, &ubuf->st_rdev);
+	err |= __put_user(stat->size, &ubuf->st_size);
+	err |= __put_user(stat->atime, &ubuf->st_atime);
+	err |= __put_user(stat->mtime, &ubuf->st_mtime);
+	err |= __put_user(stat->ctime, &ubuf->st_ctime);
+	err |= __put_user(stat->blksize, &ubuf->st_blksize);
+	err |= __put_user(stat->blocks, &ubuf->st_blocks);
 	return err;
 }
 
-extern asmlinkage long sys_newstat (char * filename, struct stat * statbuf);
-
 asmlinkage long
 sys32_newstat (char *filename, struct stat32 *statbuf)
 {
-	int ret;
-	struct stat s;
-	mm_segment_t old_fs = get_fs();
+	struct kstat stat;
+	int ret = vfs_stat(filename, &stat);
+
+	if (!ret)
+		ret = putstat(statbuf, &stat);
 
-	set_fs(KERNEL_DS);
-	ret = sys_newstat(filename, &s);
-	set_fs(old_fs);
-	if (putstat(statbuf, &s))
-		return -EFAULT;
 	return ret;
 }
 
-extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
-
 asmlinkage long
 sys32_newlstat (char *filename, struct stat32 *statbuf)
 {
-	mm_segment_t old_fs = get_fs();
-	struct stat s;
-	int ret;
+	struct kstat stat;
+	int ret = vfs_lstat(filename, &stat);
+
+	if (!ret)
+		ret = putstat(statbuf, &stat);
 
-	set_fs(KERNEL_DS);
-	ret = sys_newlstat(filename, &s);
-	set_fs(old_fs);
-	if (putstat(statbuf, &s))
-		return -EFAULT;
 	return ret;
 }
 
-extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
-
 asmlinkage long
 sys32_newfstat (unsigned int fd, struct stat32 *statbuf)
 {
-	mm_segment_t old_fs = get_fs();
-	struct stat s;
-	int ret;
+	struct kstat stat;
+	int ret = vfs_fstat(fd, &stat);
+
+	if (!ret)
+		ret = putstat(statbuf, &stat);
 
-	set_fs(KERNEL_DS);
-	ret = sys_newfstat(fd, &s);
-	set_fs(old_fs);
-	if (putstat(statbuf, &s))
-		return -EFAULT;
 	return ret;
 }
 
@@ -3529,74 +3517,59 @@
 }
 
 static int
-putstat64 (struct stat64 *ubuf, struct stat *kbuf)
+putstat64 (struct stat64 *ubuf, struct kstat *kbuf)
 {
 	int err;
 
 	if (clear_user(ubuf, sizeof(*ubuf)))
-		return 1;
+		return -EFAULT;
 
-	err  = __put_user(kbuf->st_dev, &ubuf->st_dev);
-	err |= __put_user(kbuf->st_ino, &ubuf->__st_ino);
-	err |= __put_user(kbuf->st_ino, &ubuf->st_ino_lo);
-	err |= __put_user(kbuf->st_ino >> 32, &ubuf->st_ino_hi);
-	err |= __put_user(kbuf->st_mode, &ubuf->st_mode);
-	err |= __put_user(kbuf->st_nlink, &ubuf->st_nlink);
-	err |= __put_user(kbuf->st_uid, &ubuf->st_uid);
-	err |= __put_user(kbuf->st_gid, &ubuf->st_gid);
-	err |= __put_user(kbuf->st_rdev, &ubuf->st_rdev);
-	err |= __put_user(kbuf->st_size, &ubuf->st_size_lo);
-	err |= __put_user((kbuf->st_size >> 32), &ubuf->st_size_hi);
-	err |= __put_user(kbuf->st_atime, &ubuf->st_atime);
-	err |= __put_user(kbuf->st_mtime, &ubuf->st_mtime);
-	err |= __put_user(kbuf->st_ctime, &ubuf->st_ctime);
-	err |= __put_user(kbuf->st_blksize, &ubuf->st_blksize);
-	err |= __put_user(kbuf->st_blocks, &ubuf->st_blocks);
+	err  = __put_user(kbuf->dev, &ubuf->st_dev);
+	err |= __put_user(kbuf->ino, &ubuf->__st_ino);
+	err |= __put_user(kbuf->ino, &ubuf->st_ino_lo);
+	err |= __put_user(kbuf->ino >> 32, &ubuf->st_ino_hi);
+	err |= __put_user(kbuf->mode, &ubuf->st_mode);
+	err |= __put_user(kbuf->nlink, &ubuf->st_nlink);
+	err |= __put_user(kbuf->uid, &ubuf->st_uid);
+	err |= __put_user(kbuf->gid, &ubuf->st_gid);
+	err |= __put_user(kbuf->rdev, &ubuf->st_rdev);
+	err |= __put_user(kbuf->size, &ubuf->st_size_lo);
+	err |= __put_user((kbuf->size >> 32), &ubuf->st_size_hi);
+	err |= __put_user(kbuf->atime, &ubuf->st_atime);
+	err |= __put_user(kbuf->mtime, &ubuf->st_mtime);
+	err |= __put_user(kbuf->ctime, &ubuf->st_ctime);
+	err |= __put_user(kbuf->blksize, &ubuf->st_blksize);
+	err |= __put_user(kbuf->blocks, &ubuf->st_blocks);
 	return err;
 }
 
 asmlinkage long
 sys32_stat64 (char *filename, struct stat64 *statbuf)
 {
-	mm_segment_t old_fs = get_fs();
-	struct stat s;
-	long ret;
-
-	set_fs(KERNEL_DS);
-	ret = sys_newstat(filename, &s);
-	set_fs(old_fs);
-	if (putstat64(statbuf, &s))
-		return -EFAULT;
+	struct kstat s;
+	long ret = vfs_stat(filename, &s);
+	if (!ret)
+		ret = putstat64(statbuf, &s);
 	return ret;
 }
 
 asmlinkage long
 sys32_lstat64 (char *filename, struct stat64 *statbuf)
 {
-	mm_segment_t old_fs = get_fs();
-	struct stat s;
-	long ret;
-
-	set_fs(KERNEL_DS);
-	ret = sys_newlstat(filename, &s);
-	set_fs(old_fs);
-	if (putstat64(statbuf, &s))
-		return -EFAULT;
+	struct kstat s;
+	long ret = vfs_lstat(filename, &s);
+	if (!ret)
+		ret = putstat64(statbuf, &s);
 	return ret;
 }
 
 asmlinkage long
 sys32_fstat64 (unsigned int fd, struct stat64 *statbuf)
 {
-	mm_segment_t old_fs = get_fs();
-	struct stat s;
-	long ret;
-
-	set_fs(KERNEL_DS);
-	ret = sys_newfstat(fd, &s);
-	set_fs(old_fs);
-	if (putstat64(statbuf, &s))
-		return -EFAULT;
+	struct kstat s;
+	long ret = vfs_fstat(fd, &s);
+	if (!ret)
+		ret = putstat64(statbuf, &s);
 	return ret;
 }
 
diff -urN linux-2.5.4-pre1/arch/ia64/kernel/entry.S linux/arch/ia64/kernel/entry.S
--- linux-2.5.4-pre1/arch/ia64/kernel/entry.S	Mon Jan 28 15:14:22 2002
+++ linux/arch/ia64/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -1130,6 +1130,7 @@
 	data8 sys_getdents64
 	data8 sys_getunwind			// 1215
 	data8 sys_readahead
+	data8 sys_tkill
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
diff -urN linux-2.5.4-pre1/arch/ia64/kernel/signal.c linux/arch/ia64/kernel/signal.c
--- linux-2.5.4-pre1/arch/ia64/kernel/signal.c	Fri Nov  9 14:26:17 2001
+++ linux/arch/ia64/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -578,10 +578,7 @@
 				/* FALLTHRU */
 
 			      default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/ia64/kernel/sys_ia64.c linux/arch/ia64/kernel/sys_ia64.c
--- linux-2.5.4-pre1/arch/ia64/kernel/sys_ia64.c	Fri Nov  9 14:26:17 2001
+++ linux/arch/ia64/kernel/sys_ia64.c	Wed Feb  6 22:51:46 2002
@@ -282,120 +282,64 @@
  * call - it will be removed later once everybody migrates to the new
  * kernel stat structure that matches the glibc one - Jes
  */
-static __inline__ int
-do_revalidate (struct dentry *dentry)
-{
-	struct inode * inode = dentry->d_inode;
-	if (inode->i_op && inode->i_op->revalidate)
-		return inode->i_op->revalidate(dentry);
-	return 0;
-}
 
 static int
-cp_ia64_old_stat (struct inode *inode, struct ia64_oldstat *statbuf)
+cp_ia64_old_stat (struct kstat *stat, struct ia64_oldstat *statbuf)
 {
 	struct ia64_oldstat tmp;
 	unsigned int blocks, indirect;
 
 	memset(&tmp, 0, sizeof(tmp));
-	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
-	tmp.st_ino = inode->i_ino;
-	tmp.st_mode = inode->i_mode;
-	tmp.st_nlink = inode->i_nlink;
-	SET_STAT_UID(tmp, inode->i_uid);
-	SET_STAT_GID(tmp, inode->i_gid);
-	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-	tmp.st_size = inode->i_size;
-	tmp.st_atime = inode->i_atime;
-	tmp.st_mtime = inode->i_mtime;
-	tmp.st_ctime = inode->i_ctime;
-/*
- * st_blocks and st_blksize are approximated with a simple algorithm if
- * they aren't supported directly by the filesystem. The minix and msdos
- * filesystems don't keep track of blocks, so they would either have to
- * be counted explicitly (by delving into the file itself), or by using
- * this simple algorithm to get a reasonable (although not 100% accurate)
- * value.
- */
-
-/*
- * Use minix fs values for the number of direct and indirect blocks.  The
- * count is now exact for the minix fs except that it counts zero blocks.
- * Everything is in units of BLOCK_SIZE until the assignment to
- * tmp.st_blksize.
- */
-#define D_B   7
-#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
-
-	if (!inode->i_blksize) {
-		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
-		if (blocks > D_B) {
-			indirect = (blocks - D_B + I_B - 1) / I_B;
-			blocks += indirect;
-			if (indirect > 1) {
-				indirect = (indirect - 1 + I_B - 1) / I_B;
-				blocks += indirect;
-				if (indirect > 1)
-					blocks++;
-			}
-		}
-		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
-		tmp.st_blksize = BLOCK_SIZE;
-	} else {
-		tmp.st_blocks = inode->i_blocks;
-		tmp.st_blksize = inode->i_blksize;
-	}
+	tmp.st_dev = stat->dev;
+	tmp.st_ino = stat->ino;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	SET_STAT_UID(tmp, stat->uid);
+	SET_STAT_GID(tmp, stat->gid);
+	tmp.st_rdev = stat->rdev;
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime;
+	tmp.st_mtime = stat->mtime;
+	tmp.st_ctime = stat->ctime;
+	tmp.st_blocks = stat->i_blocks;
+	tmp.st_blksize = stat->i_blksize;
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
 asmlinkage long
 ia64_oldstat (char *filename, struct ia64_oldstat *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_ia64_old_stat(&stat, statbuf);
 
-	error = user_path_walk(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-		error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
 	return error;
 }
 
-
 asmlinkage long
-ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) {
-	struct nameidata nd;
-	int error;
-
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
+ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf)
+{
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
+
+	if (!error)
+		error = cp_ia64_old_stat(&stat, statbuf);
+
 	return error;
 }
 
 asmlinkage long
 ia64_oldfstat (unsigned int fd, struct ia64_oldstat *statbuf)
 {
-	struct file * f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
-
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_ia64_old_stat(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	return err;
+	if (!error)
+		error = cp_ia64_old_stat(&stat, statbuf);
+
+	return error;
 }
 
 #endif
diff -urN linux-2.5.4-pre1/arch/m68k/kernel/entry.S linux/arch/m68k/kernel/entry.S
--- linux-2.5.4-pre1/arch/m68k/kernel/entry.S	Mon Oct  8 10:39:18 2001
+++ linux/arch/m68k/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -646,6 +646,8 @@
 	.long SYMBOL_NAME(sys_ni_syscall)
 	.long SYMBOL_NAME(sys_ni_syscall)
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
 
 	.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -urN linux-2.5.4-pre1/arch/m68k/kernel/signal.c linux/arch/m68k/kernel/signal.c
--- linux-2.5.4-pre1/arch/m68k/kernel/signal.c	Wed Jan 24 15:21:28 2001
+++ linux/arch/m68k/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -1135,10 +1135,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/mips/kernel/signal.c linux/arch/mips/kernel/signal.c
--- linux-2.5.4-pre1/arch/mips/kernel/signal.c	Sun Sep  9 10:43:01 2001
+++ linux/arch/mips/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -661,10 +661,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h
--- linux-2.5.4-pre1/arch/mips/kernel/syscalls.h	Mon Oct  8 10:39:18 2001
+++ linux/arch/mips/kernel/syscalls.h	Wed Feb  6 22:51:46 2002
@@ -235,3 +235,5 @@
 SYS(sys_madvise, 3)
 SYS(sys_getdents64, 3)
 SYS(sys_fcntl64, 3)				/* 4220 */
+SYS(sys_gettid, 0)
+SYS(sys_tkill, 2)
diff -urN linux-2.5.4-pre1/arch/mips/kernel/sysirix.c linux/arch/mips/kernel/sysirix.c
--- linux-2.5.4-pre1/arch/mips/kernel/sysirix.c	Sun Aug 12 15:05:26 2001
+++ linux/arch/mips/kernel/sysirix.c	Wed Feb  6 22:51:46 2002
@@ -1178,7 +1178,7 @@
 	return MAJOR (t) << 18 | MINOR (t);
 }
 
-static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf)
+static inline int irix_xstat32_xlate(struct kstat *stat, void *ubuf)
 {
 	struct xstat32 {
 		u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
@@ -1191,28 +1191,32 @@
 		u32 st_pad4[8];
 	} ub;
 
-	ub.st_dev     = linux_to_irix_dev_t (kb->st_dev);
-	ub.st_ino     = kb->st_ino;
-	ub.st_mode    = kb->st_mode;
-	ub.st_nlink   = kb->st_nlink;
-	ub.st_uid     = kb->st_uid;
-	ub.st_gid     = kb->st_gid;
-	ub.st_rdev    = linux_to_irix_dev_t (kb->st_rdev);
-	ub.st_size    = kb->st_size;
-	ub.st_atime0  = kb->st_atime;
+	ub.st_dev     = linux_to_irix_dev_t(stat->dev);
+	ub.st_ino     = stat->ino;
+	ub.st_mode    = stat->mode;
+	ub.st_nlink   = stat->nlink;
+	SET_STAT_UID(ub, stat->uid);
+	SET_STAT_GID(ub, stat->gid);
+	ub.st_rdev    = linux_to_irix_dev_t(stat->rdev);
+#if BITS_PER_LONG == 32
+	if (stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+#endif	
+	ub.st_size    = stat->size;
+	ub.st_atime0  = stat->atime;
 	ub.st_atime1  = 0;
-	ub.st_mtime0  = kb->st_mtime;
+	ub.st_mtime0  = stat->mtime;
 	ub.st_mtime1  = 0;
-	ub.st_ctime0  = kb->st_ctime;
+	ub.st_ctime0  = stat->ctime;
 	ub.st_ctime1  = 0;
-	ub.st_blksize = kb->st_blksize;
-	ub.st_blocks  = kb->st_blocks;
+	ub.st_blksize = stat->blksize;
+	ub.st_blocks  = stat->blocks;
 	strcpy (ub.st_fstype, "efs");
 
 	return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
 }
 
-static inline void irix_xstat64_xlate(struct stat *sb)
+static inline void irix_xstat64_xlate(struct kstat *stat, void *ubuf)
 {
 	struct xstat64 {
 		u32 st_dev; s32 st_pad1[3];
@@ -1229,177 +1233,112 @@
 		s32 st_pad4[8];
 	} ks;
 
-	ks.st_dev = linux_to_irix_dev_t (sb->st_dev);
+	ks.st_dev = linux_to_irix_dev_t(stat->dev);
 	ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
-	ks.st_ino = (unsigned long long) sb->st_ino;
-	ks.st_mode = (u32) sb->st_mode;
-	ks.st_nlink = (u32) sb->st_nlink;
-	ks.st_uid = (s32) sb->st_uid;
-	ks.st_gid = (s32) sb->st_gid;
-	ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev);
+	ks.st_ino = (unsigned long long) stat->ino;
+	ks.st_mode = (u32) stat->mode;
+	ks.st_nlink = (u32) stat->nlink;
+	ks.st_uid = (s32) stat->uid;
+	ks.st_gid = (s32) stat->gid;
+	ks.st_rdev = linux_to_irix_dev_t (stat->rdev);
 	ks.st_pad2[0] = ks.st_pad2[1] = 0;
-	ks.st_size = (long long) sb->st_size;
+	ks.st_size = (long long) stat->size;
 	ks.st_pad3 = 0;
 
 	/* XXX hackety hack... */
-	ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0;
-	ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0;
-	ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0;
+	ks.st_atime.tv_sec = (s32) stat->atime; ks.st_atime.tv_nsec = 0;
+	ks.st_mtime.tv_sec = (s32) stat->atime; ks.st_mtime.tv_nsec = 0;
+	ks.st_ctime.tv_sec = (s32) stat->atime; ks.st_ctime.tv_nsec = 0;
 
-	ks.st_blksize = (s32) sb->st_blksize;
-	ks.st_blocks = (long long) sb->st_blocks;
+	ks.st_blksize = (s32) stat->blksize;
+	ks.st_blocks = (long long) stat->blocks;
 	memset(ks.st_fstype, 0, 16);
 	ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
 	ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
 
 	/* Now write it all back. */
-	copy_to_user(sb, &ks, sizeof(struct xstat64));
+	copy_to_user(ubuf, &ks, sizeof(struct xstat64));
 }
 
-extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
-
 asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
 {
 	int retval;
+	struct kstat stat;
 
 #ifdef DEBUG_XSTAT
 	printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
 	       current->comm, current->pid, version, filename, statbuf);
 #endif
-	switch(version) {
-	case 2: {
-		struct stat kb;
-		mm_segment_t old_fs;
-
-		old_fs = get_fs(); set_fs(get_ds());
-		retval = sys_newstat(filename, &kb);
-		set_fs(old_fs);
-#ifdef DEBUG_XSTAT
-		printk("retval[%d]\n", retval);
-#endif
-		if(retval)
-			goto out;
-		retval = irix_xstat32_xlate(&kb, statbuf);
-		goto out;
-	}
-
-	case 3: {
-		retval = sys_newstat(filename, statbuf);
-#ifdef DEBUG_XSTAT
-		printk("retval[%d]\n", retval);
-#endif
-		if(retval)
-			goto out;
 
-		irix_xstat64_xlate(statbuf);
-		retval = 0;
-		break;
+	retval = vfs_stat(filename, &stat);
+	if (!retval) {
+		switch(version) {
+			case 2:
+				retval = irix_xstat32_xlate(&stat, statbuf);
+				break;
+			case 3:
+				irix_xstat64_xlate(&stat, statbuf);
+				retval = 0; /* Really? */
+				break;
+			default:
+				retval = -EINVAL;
+		}
 	}
-
-	default:
-		retval = -EINVAL;
-		break;
-	}
-
-out:
 	return retval;
 }
 
-extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
-
 asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
 {
 	int error;
+	struct kstat stat;
 
 #ifdef DEBUG_XSTAT
 	printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
 	       current->comm, current->pid, version, filename, statbuf);
 #endif
-	switch(version) {
-	case 2: {
-		struct stat kb;
-		mm_segment_t old_fs;
-
-		old_fs = get_fs(); set_fs(get_ds());
-		error = sys_newlstat(filename, &kb);
-		set_fs(old_fs);
-#ifdef DEBUG_XSTAT
-		printk("error[%d]\n", error);
-#endif
-		if(error)
-			goto out;
-		error = irix_xstat32_xlate(&kb, statbuf);
-		goto out;
-	}
 
-	case 3: {
-		error = sys_newlstat(filename, statbuf);
-#ifdef DEBUG_XSTAT
-		printk("error[%d]\n", error);
-#endif
-		if(error)
-			goto out;
-
-		irix_xstat64_xlate(statbuf);
-		error = 0;
-		goto out;
-	}
+	error = vfs_lstat(filename, &stat);
 
-	default:
-		error = -EINVAL;
-		goto out;
+	if (!error) {
+		switch (version) {
+			case 2:
+				error = irix_xstat32_xlate(&stat, statbuf);
+				break;
+			case 3:
+				irix_xstat64_xlate(&stat, statbuf);
+				error = 0;
+				break;
+			default:
+				error = -EINVAL;
+		}
 	}
-
-out:
 	return error;
 }
 
-extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
-
 asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
 {
 	int error;
+	struct kstat stat;
 
 #ifdef DEBUG_XSTAT
 	printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
 	       current->comm, current->pid, version, fd, statbuf);
 #endif
-	switch(version) {
-	case 2: {
-		struct stat kb;
-		mm_segment_t old_fs;
-
-		old_fs = get_fs(); set_fs(get_ds());
-		error = sys_newfstat(fd, &kb);
-		set_fs(old_fs);
-#ifdef DEBUG_XSTAT
-		printk("error[%d]\n", error);
-#endif
-		if(error)
-			goto out;
-		error = irix_xstat32_xlate(&kb, statbuf);
-		goto out;
-	}
-
-	case 3: {
-		error = sys_newfstat(fd, statbuf);
-#ifdef DEBUG_XSTAT
-		printk("error[%d]\n", error);
-#endif
-		if(error)
-			goto out;
 
-		irix_xstat64_xlate(statbuf);
-		error = 0;
-		goto out;
+	error = vfs_fstat(fd, &stat);
+	if (!error) {
+		switch (version) {
+			case 2:
+				error = irix_xstat32_xlate(&stat, statbuf);
+				break;
+			case 3:
+				irix_xstat64_xlate(&stat, statbuf);
+				error = 0;
+				break;
+			default:
+				error = -EINVAL;
+		}
 	}
-
-	default:
-		error = -EINVAL;
-		goto out;
-	}
-
-out:
 	return error;
 }
 
diff -urN linux-2.5.4-pre1/arch/mips64/kernel/linux32.c linux/arch/mips64/kernel/linux32.c
--- linux-2.5.4-pre1/arch/mips64/kernel/linux32.c	Sun Sep  9 10:43:01 2001
+++ linux/arch/mips64/kernel/linux32.c	Wed Feb  6 22:51:46 2002
@@ -39,125 +39,59 @@
 /*
  * Revalidate the inode. This is required for proper NFS attribute caching.
  */
-static __inline__ int
-do_revalidate(struct dentry *dentry)
-{
-	struct inode * inode = dentry->d_inode;
-
-	if (inode->i_op && inode->i_op->revalidate)
-		return inode->i_op->revalidate(dentry);
-
-	return 0;
-}
 
-static int cp_new_stat32(struct inode * inode, struct stat32 * statbuf)
+static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
 {
 	struct stat32 tmp;
-	unsigned int blocks, indirect;
 
 	memset(&tmp, 0, sizeof(tmp));
-	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
-	tmp.st_ino = inode->i_ino;
-	tmp.st_mode = inode->i_mode;
-	tmp.st_nlink = inode->i_nlink;
-	SET_STAT_UID(tmp, inode->i_uid);
-	SET_STAT_GID(tmp, inode->i_gid);
-	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-	tmp.st_size = inode->i_size;
-	tmp.st_atime = inode->i_atime;
-	tmp.st_mtime = inode->i_mtime;
-	tmp.st_ctime = inode->i_ctime;
-
-	/*
-	 * st_blocks and st_blksize are approximated with a simple algorithm if
-	 * they aren't supported directly by the filesystem. The minix and msdos
-	 * filesystems don't keep track of blocks, so they would either have to
-	 * be counted explicitly (by delving into the file itself), or by using
-	 * this simple algorithm to get a reasonable (although not 100%
-	 * accurate) value.
-	 */
-
-	/*
-	 * Use minix fs values for the number of direct and indirect blocks.
-	 * The count is now exact for the minix fs except that it counts zero
-	 * blocks.  Everything is in units of BLOCK_SIZE until the assignment
-	 * to tmp.st_blksize.
-	 */
-#define D_B   7
-#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
-
-	if (!inode->i_blksize) {
-		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
-		if (blocks > D_B) {
-			indirect = (blocks - D_B + I_B - 1) / I_B;
-			blocks += indirect;
-			if (indirect > 1) {
-				indirect = (indirect - 1 + I_B - 1) / I_B;
-				blocks += indirect;
-				if (indirect > 1)
-					blocks++;
-			}
-		}
-		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
-		tmp.st_blksize = BLOCK_SIZE;
-	} else {
-		tmp.st_blocks = inode->i_blocks;
-		tmp.st_blksize = inode->i_blksize;
-	}
-
+	tmp.st_dev = stat->dev;
+	tmp.st_ino = stat->ino;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	SET_STAT_UID(tmp, stat->uid);
+	SET_STAT_GID(tmp, stat->gid);
+	tmp.st_rdev = stat->rdev;
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime;
+	tmp.st_mtime = stat->mtime;
+	tmp.st_ctime = stat->ctime;
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
 {
-	struct nameidata nd;
-	int error;
-
-	error = user_path_walk(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
 
-		path_release(&nd);
-	}
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
 	return error;
 }
 
 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
 
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
-
-		path_release(&nd);
-	}
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
 	return error;
 }
 
 asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 * statbuf)
 {
-	struct file * f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
-
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_new_stat32(dentry->d_inode, statbuf);
-		fput(f);
-	}
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
-	return err;
+	return error;
 }
 
 asmlinkage int sys_mmap2(void) {return 0;}
diff -urN linux-2.5.4-pre1/arch/mips64/kernel/scall_64.S linux/arch/mips64/kernel/scall_64.S
--- linux-2.5.4-pre1/arch/mips64/kernel/scall_64.S	Mon Jan 28 15:14:22 2002
+++ linux/arch/mips64/kernel/scall_64.S	Wed Feb  6 22:51:46 2002
@@ -347,3 +347,5 @@
 	PTR	sys_mincore
 	PTR	sys_madvise
 	PTR	sys_getdents64
+	PTR	sys_gettid
+	PTR	sys_tkill
diff -urN linux-2.5.4-pre1/arch/mips64/kernel/scall_o32.S linux/arch/mips64/kernel/scall_o32.S
--- linux-2.5.4-pre1/arch/mips64/kernel/scall_o32.S	Mon Jan 28 15:14:23 2002
+++ linux/arch/mips64/kernel/scall_o32.S	Wed Feb  6 22:51:46 2002
@@ -454,6 +454,8 @@
 	sys	sys_madvise	3
 	sys	sys_getdents64	3
 	sys	sys32_fcntl64	3			/* 4220 */
+	sys	sys32_gettid	0
+	sys	sys32_tkill	2
 	.endm
 
 	.macro	sys function, nargs
diff -urN linux-2.5.4-pre1/arch/mips64/kernel/signal.c linux/arch/mips64/kernel/signal.c
--- linux-2.5.4-pre1/arch/mips64/kernel/signal.c	Sun Sep  9 10:43:01 2001
+++ linux/arch/mips64/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -685,10 +685,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/mips64/kernel/signal32.c linux/arch/mips64/kernel/signal32.c
--- linux-2.5.4-pre1/arch/mips64/kernel/signal32.c	Sun Sep  9 10:43:01 2001
+++ linux/arch/mips64/kernel/signal32.c	Wed Feb  6 22:51:46 2002
@@ -757,10 +757,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/parisc/hpux/fs.c linux/arch/parisc/hpux/fs.c
--- linux-2.5.4-pre1/arch/parisc/hpux/fs.c	Sun Aug 12 15:07:55 2001
+++ linux/arch/parisc/hpux/fs.c	Wed Feb  6 22:51:46 2002
@@ -83,42 +83,20 @@
 int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count)
 {
 	struct file * file;
-	struct dentry * dentry;
-	struct inode * inode;
 	struct hpux_dirent * lastdirent;
 	struct getdents_callback buf;
-	int error;
+	int error = -EBADF;
 
-	lock_kernel();
-	error = -EBADF;
 	file = fget(fd);
 	if (!file)
 		goto out;
 
-	dentry = file->f_dentry;
-	if (!dentry)
-		goto out_putf;
-
-	inode = dentry->d_inode;
-	if (!inode)
-		goto out_putf;
-
 	buf.current_dir = dirent;
 	buf.previous = NULL;
 	buf.count = count;
 	buf.error = 0;
 
-	error = -ENOTDIR;
-	if (!file->f_op || !file->f_op->readdir)
-		goto out_putf;
-
-	/*
-	 * Get the inode's semaphore to prevent changes
-	 * to the directory while we read it.
-	 */
-	down(&inode->i_sem);
-	error = file->f_op->readdir(file, &buf, filldir);
-	up(&inode->i_sem);
+	error = vfs_readdir(file, &buf, filldir);
 	if (error < 0)
 		goto out_putf;
 	error = buf.error;
@@ -131,7 +109,6 @@
 out_putf:
 	fput(file);
 out:
-	unlock_kernel();
 	return error;
 }
 
@@ -141,110 +118,56 @@
 	return -ENOSYS;
 }
 
-static int cp_hpux_stat(struct inode * inode, struct hpux_stat64 * statbuf)
+static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 *statbuf)
 {
 	struct hpux_stat64 tmp;
-	unsigned int blocks, indirect;
 
 	memset(&tmp, 0, sizeof(tmp));
-	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
-	tmp.st_ino = inode->i_ino;
-	tmp.st_mode = inode->i_mode;
-	tmp.st_nlink = inode->i_nlink;
-	tmp.st_uid = inode->i_uid;
-	tmp.st_gid = inode->i_gid;
-	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-	tmp.st_size = inode->i_size;
-	tmp.st_atime = inode->i_atime;
-	tmp.st_mtime = inode->i_mtime;
-	tmp.st_ctime = inode->i_ctime;
-
-#define D_B   7
-#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
-
-	if (!inode->i_blksize) {
-		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
-		if (blocks > D_B) {
-			indirect = (blocks - D_B + I_B - 1) / I_B;
-			blocks += indirect;
-			if (indirect > 1) {
-				indirect = (indirect - 1 + I_B - 1) / I_B;
-				blocks += indirect;
-				if (indirect > 1)
-					blocks++;
-			}
-		}
-		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
-		tmp.st_blksize = BLOCK_SIZE;
-	} else {
-		tmp.st_blocks = inode->i_blocks;
-		tmp.st_blksize = inode->i_blksize;
-	}
+	tmp.st_dev = stat->dev;
+	tmp.st_ino = stat->ino;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	tmp.st_uid = stat->uid;
+	tmp.st_gid = stat->gid;
+	tmp.st_rdev = stat->rdev;
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime;
+	tmp.st_mtime = stat->mtime;
+	tmp.st_ctime = stat->ctime;
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
-/*
- * Revalidate the inode. This is required for proper NFS attribute caching.
- * Blatently copied wholesale from fs/stat.c
- */
-static __inline__ int
-do_revalidate(struct dentry *dentry)
-{
-	struct inode * inode = dentry->d_inode;
-	if (inode->i_op && inode->i_op->revalidate)
-		return inode->i_op->revalidate(dentry);
-	return 0;
-}
-
 long hpux_stat64(const char *path, struct hpux_stat64 *buf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_hpux_stat(&stat, statbuf);
 
-	lock_kernel();
-	error = user_path_walk(path, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_hpux_stat(nd.dentry->d_inode, buf);
-		path_release(&nd);
-	}
-	unlock_kernel();
 	return error;
 }
 
 long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf)
 {
-	struct file * f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	lock_kernel();
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
-
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_hpux_stat(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	unlock_kernel();
-	return err;
+	if (!error)
+		error = cp_hpux_stat(&stat, statbuf);
+
+	return error;
 }
 
 long hpux_lstat64(char *filename, struct hpux_stat64 *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
+
+	if (!error)
+		error = cp_hpux_stat(&stat, statbuf);
 
-	lock_kernel();
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_hpux_stat(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
-	unlock_kernel();
 	return error;
 }
diff -urN linux-2.5.4-pre1/arch/parisc/kernel/signal.c linux/arch/parisc/kernel/signal.c
--- linux-2.5.4-pre1/arch/parisc/kernel/signal.c	Wed Dec  6 11:46:39 2000
+++ linux/arch/parisc/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -581,11 +581,7 @@
 				/* FALLTHRU */
 
 			default:
-				lock_kernel();
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/parisc/kernel/syscall.S linux/arch/parisc/kernel/syscall.S
--- linux-2.5.4-pre1/arch/parisc/kernel/syscall.S	Mon Oct  8 10:39:18 2001
+++ linux/arch/parisc/kernel/syscall.S	Wed Feb  6 22:51:46 2002
@@ -552,6 +552,8 @@
 	ENTRY_UHOH(shmctl)		/* 195 */
 	ENTRY_SAME(ni_syscall)		/* streams1 */
 	ENTRY_SAME(ni_syscall)		/* streams2 */
+	ENTRY_SAME(gettid)
+	ENTRY_SAME(tkill)
 
 .end
 
diff -urN linux-2.5.4-pre1/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- linux-2.5.4-pre1/arch/ppc/kernel/misc.S	Fri Nov  2 17:43:54 2001
+++ linux/arch/ppc/kernel/misc.S	Wed Feb  6 22:51:46 2002
@@ -1121,6 +1121,7 @@
 	.long sys_madvise	/* 205 */
 	.long sys_mincore
 	.long sys_gettid
+	.long sys_tkill
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
 	.endr
diff -urN linux-2.5.4-pre1/arch/ppc/kernel/ppc_htab.c linux/arch/ppc/kernel/ppc_htab.c
--- linux-2.5.4-pre1/arch/ppc/kernel/ppc_htab.c	Fri Nov  2 17:43:54 2001
+++ linux/arch/ppc/kernel/ppc_htab.c	Wed Feb  6 22:51:46 2002
@@ -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 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,
diff -urN linux-2.5.4-pre1/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- linux-2.5.4-pre1/arch/ppc/kernel/signal.c	Mon May 21 17:04:47 2001
+++ linux/arch/ppc/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -641,10 +641,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/s390/kernel/entry.S linux/arch/s390/kernel/entry.S
--- linux-2.5.4-pre1/arch/s390/kernel/entry.S	Mon Jan 28 15:14:23 2002
+++ linux/arch/s390/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -602,6 +602,8 @@
 	.long  sys_ni_syscall		 /* 224 - reserved for posix_acl */
 	.rept  255-224
 	.long  sys_ni_syscall
+	.long  sys_gettid		/* 226 */
+	.long  sys_tkill		/* 227 */
 	.endr
 
 /*
diff -urN linux-2.5.4-pre1/arch/s390/kernel/signal.c linux/arch/s390/kernel/signal.c
--- linux-2.5.4-pre1/arch/s390/kernel/signal.c	Thu Oct 11 09:04:57 2001
+++ linux/arch/s390/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -563,10 +563,7 @@
                                 /* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/s390x/kernel/entry.S linux/arch/s390x/kernel/entry.S
--- linux-2.5.4-pre1/arch/s390x/kernel/entry.S	Mon Jan 28 15:14:23 2002
+++ linux/arch/s390x/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -635,6 +635,8 @@
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for posix_acl */
         .rept  255-224
 	.long  SYSCALL(sys_ni_syscall,sys_ni_syscall)
+	.long  SYSCALL(sys_gettid,sys_gettid)
+	.long  SYSCALL(sys_tkill,sys_tkill)
 	.endr
 
 /*
diff -urN linux-2.5.4-pre1/arch/s390x/kernel/linux32.c linux/arch/s390x/kernel/linux32.c
--- linux-2.5.4-pre1/arch/s390x/kernel/linux32.c	Thu Oct 11 09:04:57 2001
+++ linux/arch/s390x/kernel/linux32.c	Wed Feb  6 22:51:46 2002
@@ -1471,140 +1471,62 @@
 	return ret;
 }
 
-static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
+static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
 {
-	unsigned long ino, blksize, blocks;
-	kdev_t dev, rdev;
-	umode_t mode;
-	nlink_t nlink;
-	uid_t uid;
-	gid_t gid;
-	off_t size;
-	time_t atime, mtime, ctime;
-	int err;
-
-	/* Stream the loads of inode data into the load buffer,
-	 * then we push it all into the store buffer below.  This
-	 * should give optimal cache performance.
-	 */
-	ino = inode->i_ino;
-	dev = inode->i_dev;
-	mode = inode->i_mode;
-	nlink = inode->i_nlink;
-	uid = inode->i_uid;
-	gid = inode->i_gid;
-	rdev = inode->i_rdev;
-	size = inode->i_size;
-	atime = inode->i_atime;
-	mtime = inode->i_mtime;
-	ctime = inode->i_ctime;
-	blksize = inode->i_blksize;
-	blocks = inode->i_blocks;
-
-	err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
-	err |= put_user(ino, &statbuf->st_ino);
-	err |= put_user(mode, &statbuf->st_mode);
-	err |= put_user(nlink, &statbuf->st_nlink);
-	err |= put_user(high2lowuid(uid), &statbuf->st_uid);
-	err |= put_user(high2lowgid(gid), &statbuf->st_gid);
-	err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
-	err |= put_user(size, &statbuf->st_size);
-	err |= put_user(atime, &statbuf->st_atime);
+	err  = put_user(stat->dev, &statbuf->st_dev);
+	err |= put_user(stat->ino, &statbuf->st_ino);
+	err |= put_user(stat->mode, &statbuf->st_mode);
+	err |= put_user(stat->nlink, &statbuf->st_nlink);
+	err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+	err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+	err |= put_user(stat->rdev, &statbuf->st_rdev);
+	err |= put_user(stat->size, &statbuf->st_size);
+	err |= put_user(stat->atime, &statbuf->st_atime);
 	err |= put_user(0, &statbuf->__unused1);
-	err |= put_user(mtime, &statbuf->st_mtime);
+	err |= put_user(stat->mtime, &statbuf->st_mtime);
 	err |= put_user(0, &statbuf->__unused2);
-	err |= put_user(ctime, &statbuf->st_ctime);
+	err |= put_user(stat->ctime, &statbuf->st_ctime);
 	err |= put_user(0, &statbuf->__unused3);
-	if (blksize) {
-		err |= put_user(blksize, &statbuf->st_blksize);
-		err |= put_user(blocks, &statbuf->st_blocks);
-	} else {
-		unsigned int tmp_blocks;
-
-#define D_B   7
-#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
-		tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
-		if (tmp_blocks > D_B) {
-			unsigned int indirect;
-
-			indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
-			tmp_blocks += indirect;
-			if (indirect > 1) {
-				indirect = (indirect - 1 + I_B - 1) / I_B;
-				tmp_blocks += indirect;
-				if (indirect > 1)
-					tmp_blocks++;
-			}
-		}
-		err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
-		err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
-#undef D_B
-#undef I_B
-	}
+	err |= put_user(stat->blksize, &statbuf->st_blksize);
+	err |= put_user(stat->blocks, &statbuf->st_blocks);
 /* fixme
 	err |= put_user(0, &statbuf->__unused4[0]);
 	err |= put_user(0, &statbuf->__unused4[1]);
 */
-
 	return err;
 }
 
-/* Perhaps this belongs in fs.h or similar. -DaveM */
-static __inline__ int
-do_revalidate(struct dentry *dentry)
-{
-	struct inode * inode = dentry->d_inode;
-	if (inode->i_op && inode->i_op->revalidate)
-		return inode->i_op->revalidate(dentry);
-	return 0;
-}
-
 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
-	error = user_path_walk(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
 	return error;
 }
 
 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
 
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
-		path_release(&nd);
-	}
 	return error;
 }
 
 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
 {
-	struct file *f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
-
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_new_stat32(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	return err;
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
+
+	return error;
 }
 
 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
diff -urN linux-2.5.4-pre1/arch/s390x/kernel/signal.c linux/arch/s390x/kernel/signal.c
--- linux-2.5.4-pre1/arch/s390x/kernel/signal.c	Thu Oct 11 09:04:57 2001
+++ linux/arch/s390x/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -569,10 +569,7 @@
                                 /* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/s390x/kernel/signal32.c linux/arch/s390x/kernel/signal32.c
--- linux-2.5.4-pre1/arch/s390x/kernel/signal32.c	Thu Oct 11 09:04:57 2001
+++ linux/arch/s390x/kernel/signal32.c	Wed Feb  6 22:51:46 2002
@@ -699,10 +699,7 @@
                                 /* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- linux-2.5.4-pre1/arch/sh/kernel/entry.S	Mon Jan 28 15:14:23 2002
+++ linux/arch/sh/kernel/entry.S	Wed Feb  6 22:51:46 2002
@@ -1195,6 +1195,8 @@
 	.long SYMBOL_NAME(sys_madvise)
 	.long SYMBOL_NAME(sys_getdents64)	/* 220 */
 	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_gettid)
+	.long SYMBOL_NAME(sys_tkill)
 
 	/*
 	 * NOTE!! This doesn't have to be exact - we just have
diff -urN linux-2.5.4-pre1/arch/sh/kernel/signal.c linux/arch/sh/kernel/signal.c
--- linux-2.5.4-pre1/arch/sh/kernel/signal.c	Thu Jan 24 12:08:15 2002
+++ linux/arch/sh/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -673,10 +673,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
--- linux-2.5.4-pre1/arch/sparc/kernel/signal.c	Mon Jan 14 10:10:44 2002
+++ linux/arch/sparc/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -1280,10 +1280,7 @@
 #endif
 				/* fall through */
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOT REACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- linux-2.5.4-pre1/arch/sparc/kernel/sys_sunos.c	Mon Jan 14 10:10:44 2002
+++ linux/arch/sparc/kernel/sys_sunos.c	Wed Feb  6 22:51:46 2002
@@ -646,7 +646,7 @@
 
 	inode = file->f_dentry->d_inode;
 
-	socket = &inode->u.socket_i;
+	socket = SOCKET_I(inode);
 	local.sin_family = AF_INET;
 	local.sin_addr.s_addr = INADDR_ANY;
 
diff -urN linux-2.5.4-pre1/arch/sparc/kernel/systbls.S linux/arch/sparc/kernel/systbls.S
--- linux-2.5.4-pre1/arch/sparc/kernel/systbls.S	Wed Feb  6 22:51:45 2002
+++ linux/arch/sparc/kernel/systbls.S	Wed Feb  6 22:51:46 2002
@@ -70,7 +70,7 @@
 /*240*/	.long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 /*245*/	.long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
 /*250*/	.long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
-/*255*/	.long sys_nis_syscall, sys_nis_syscall
+/*255*/	.long sys_nis_syscall, sys_nis_syscall, sys_tkill
 
 #ifdef CONFIG_SUNOS_EMUL
 	/* Now the SunOS syscall table. */
diff -urN linux-2.5.4-pre1/arch/sparc64/kernel/signal.c linux/arch/sparc64/kernel/signal.c
--- linux-2.5.4-pre1/arch/sparc64/kernel/signal.c	Wed Feb  6 22:51:45 2002
+++ linux/arch/sparc64/kernel/signal.c	Wed Feb  6 22:51:46 2002
@@ -807,10 +807,7 @@
 #endif
 				/* fall through */
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOT REACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
--- linux-2.5.4-pre1/arch/sparc64/kernel/signal32.c	Wed Feb  6 22:51:45 2002
+++ linux/arch/sparc64/kernel/signal32.c	Wed Feb  6 22:51:46 2002
@@ -1479,10 +1479,7 @@
 #endif
 				/* fall through */
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOT REACHED */
 			}
 		}
diff -urN linux-2.5.4-pre1/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- linux-2.5.4-pre1/arch/sparc64/kernel/sys_sparc32.c	Sun Oct 21 10:36:54 2001
+++ linux/arch/sparc64/kernel/sys_sparc32.c	Wed Feb  6 22:51:46 2002
@@ -1459,138 +1459,60 @@
 	return ret;
 }
 
-static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
+static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
 {
-	unsigned long ino, blksize, blocks;
-	kdev_t dev, rdev;
-	umode_t mode;
-	nlink_t nlink;
-	uid_t uid;
-	gid_t gid;
-	off_t size;
-	time_t atime, mtime, ctime;
-	int err;
-
-	/* Stream the loads of inode data into the load buffer,
-	 * then we push it all into the store buffer below.  This
-	 * should give optimal cache performance.
-	 */
-	ino = inode->i_ino;
-	dev = inode->i_dev;
-	mode = inode->i_mode;
-	nlink = inode->i_nlink;
-	uid = inode->i_uid;
-	gid = inode->i_gid;
-	rdev = inode->i_rdev;
-	size = inode->i_size;
-	atime = inode->i_atime;
-	mtime = inode->i_mtime;
-	ctime = inode->i_ctime;
-	blksize = inode->i_blksize;
-	blocks = inode->i_blocks;
-
-	err  = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
-	err |= put_user(ino, &statbuf->st_ino);
-	err |= put_user(mode, &statbuf->st_mode);
-	err |= put_user(nlink, &statbuf->st_nlink);
-	err |= put_user(high2lowuid(uid), &statbuf->st_uid);
-	err |= put_user(high2lowgid(gid), &statbuf->st_gid);
-	err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
-	err |= put_user(size, &statbuf->st_size);
-	err |= put_user(atime, &statbuf->st_atime);
+	err  = put_user(stat->dev, &statbuf->st_dev);
+	err |= put_user(stat->ino, &statbuf->st_ino);
+	err |= put_user(stat->mode, &statbuf->st_mode);
+	err |= put_user(stat->nlink, &statbuf->st_nlink);
+	err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
+	err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
+	err |= put_user(stat->rdev, &statbuf->st_rdev);
+	err |= put_user(stat->size, &statbuf->st_size);
+	err |= put_user(stat->atime, &statbuf->st_atime);
 	err |= put_user(0, &statbuf->__unused1);
-	err |= put_user(mtime, &statbuf->st_mtime);
+	err |= put_user(stat->mtime, &statbuf->st_mtime);
 	err |= put_user(0, &statbuf->__unused2);
-	err |= put_user(ctime, &statbuf->st_ctime);
+	err |= put_user(stat->ctime, &statbuf->st_ctime);
 	err |= put_user(0, &statbuf->__unused3);
-	if (blksize) {
-		err |= put_user(blksize, &statbuf->st_blksize);
-		err |= put_user(blocks, &statbuf->st_blocks);
-	} else {
-		unsigned int tmp_blocks;
-
-#define D_B   7
-#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
-		tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
-		if (tmp_blocks > D_B) {
-			unsigned int indirect;
-
-			indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
-			tmp_blocks += indirect;
-			if (indirect > 1) {
-				indirect = (indirect - 1 + I_B - 1) / I_B;
-				tmp_blocks += indirect;
-				if (indirect > 1)
-					tmp_blocks++;
-			}
-		}
-		err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
-		err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
-#undef D_B
-#undef I_B
-	}
+	err |= put_user(stat->blksize, &statbuf->st_blksize);
+	err |= put_user(stat->blocks, &statbuf->st_blocks);
 	err |= put_user(0, &statbuf->__unused4[0]);
 	err |= put_user(0, &statbuf->__unused4[1]);
-
 	return err;
 }
 
-/* Perhaps this belongs in fs.h or similar. -DaveM */
-static __inline__ int
-do_revalidate(struct dentry *dentry)
-{
-	struct inode * inode = dentry->d_inode;
-	if (inode->i_op && inode->i_op->revalidate)
-		return inode->i_op->revalidate(dentry);
-	return 0;
-}
-
 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
-	error = user_path_walk(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
 	return error;
 }
 
 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
 
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat32(nd.dentry->d_inode, statbuf);
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
 
-		path_release(&nd);
-	}
 	return error;
 }
 
 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
 {
-	struct file *f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
-
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_new_stat32(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	return err;
+	if (!error)
+		error = cp_new_stat32(&stat, statbuf);
+
+	return error;
 }
 
 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
diff -urN linux-2.5.4-pre1/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- linux-2.5.4-pre1/arch/sparc64/kernel/sys_sunos32.c	Mon Jan 14 10:10:44 2002
+++ linux/arch/sparc64/kernel/sys_sunos32.c	Wed Feb  6 22:51:46 2002
@@ -612,7 +612,7 @@
 
 	inode = file->f_dentry->d_inode;
 
-	socket = &inode->u.socket_i;
+	socket = SOCKET_I(inode);
 	local.sin_family = AF_INET;
 	local.sin_addr.s_addr = INADDR_ANY;
 
diff -urN linux-2.5.4-pre1/arch/sparc64/kernel/systbls.S linux/arch/sparc64/kernel/systbls.S
--- linux-2.5.4-pre1/arch/sparc64/kernel/systbls.S	Wed Feb  6 22:51:45 2002
+++ linux/arch/sparc64/kernel/systbls.S	Wed Feb  6 22:51:46 2002
@@ -70,7 +70,7 @@
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep
 /*250*/	.word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
-	.word sys_aplib
+	.word sys_aplib, sys_tkill
 
 	/* Now the 64-bit native Linux syscall table. */
 
@@ -129,7 +129,7 @@
 /*240*/	.word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
 	.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
 /*250*/	.word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
-	.word sys_aplib
+	.word sys_aplib, sys_tkill
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
diff -urN linux-2.5.4-pre1/arch/sparc64/solaris/fs.c linux/arch/sparc64/solaris/fs.c
--- linux-2.5.4-pre1/arch/sparc64/solaris/fs.c	Mon Jan 14 10:10:44 2002
+++ linux/arch/sparc64/solaris/fs.c	Wed Feb  6 22:51:46 2002
@@ -79,47 +79,49 @@
 
 #define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8))
 
-static inline int putstat(struct sol_stat *ubuf, struct stat *kbuf)
+static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf)
 {
-	if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev)	||
-	    __put_user (kbuf->st_ino, &ubuf->st_ino)		||
-	    __put_user (kbuf->st_mode, &ubuf->st_mode)		||
-	    __put_user (kbuf->st_nlink, &ubuf->st_nlink)	||
-	    __put_user (kbuf->st_uid, &ubuf->st_uid)		||
-	    __put_user (kbuf->st_gid, &ubuf->st_gid)		||
-	    __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev)	||
-	    __put_user (kbuf->st_size, &ubuf->st_size)		||
-	    __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec)	||
+	if (kbuf->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+	if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev)	||
+	    __put_user (kbuf->ino, &ubuf->st_ino)		||
+	    __put_user (kbuf->mode, &ubuf->st_mode)		||
+	    __put_user (kbuf->nlink, &ubuf->st_nlink)	||
+	    __put_user (kbuf->uid, &ubuf->st_uid)		||
+	    __put_user (kbuf->gid, &ubuf->st_gid)		||
+	    __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev)	||
+	    __put_user (kbuf->size, &ubuf->st_size)		||
+	    __put_user (kbuf->atime, &ubuf->st_atime.tv_sec)	||
 	    __put_user (0, &ubuf->st_atime.tv_nsec)		||
-	    __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec)	||
+	    __put_user (kbuf->mtime, &ubuf->st_mtime.tv_sec)	||
 	    __put_user (0, &ubuf->st_mtime.tv_nsec)		||
-	    __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec)	||
+	    __put_user (kbuf->ctime, &ubuf->st_ctime.tv_sec)	||
 	    __put_user (0, &ubuf->st_ctime.tv_nsec)		||
-	    __put_user (kbuf->st_blksize, &ubuf->st_blksize)	||
-	    __put_user (kbuf->st_blocks, &ubuf->st_blocks)	||
+	    __put_user (kbuf->blksize, &ubuf->st_blksize)	||
+	    __put_user (kbuf->blocks, &ubuf->st_blocks)	||
 	    __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype))
 		return -EFAULT;
 	return 0;
 }
 
-static inline int putstat64(struct sol_stat64 *ubuf, struct stat *kbuf)
+static inline int putstat64(struct sol_stat64 *ubuf, struct kstat *kbuf)
 {
-	if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev)	||
-	    __put_user (kbuf->st_ino, &ubuf->st_ino)		||
-	    __put_user (kbuf->st_mode, &ubuf->st_mode)		||
-	    __put_user (kbuf->st_nlink, &ubuf->st_nlink)	||
-	    __put_user (kbuf->st_uid, &ubuf->st_uid)		||
-	    __put_user (kbuf->st_gid, &ubuf->st_gid)		||
-	    __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev)	||
-	    __put_user (kbuf->st_size, &ubuf->st_size)		||
-	    __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec)	||
+	if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev)	||
+	    __put_user (kbuf->ino, &ubuf->st_ino)		||
+	    __put_user (kbuf->mode, &ubuf->st_mode)		||
+	    __put_user (kbuf->nlink, &ubuf->st_nlink)	||
+	    __put_user (kbuf->uid, &ubuf->st_uid)		||
+	    __put_user (kbuf->gid, &ubuf->st_gid)		||
+	    __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev)	||
+	    __put_user (kbuf->size, &ubuf->st_size)		||
+	    __put_user (kbuf->atime, &ubuf->st_atime.tv_sec)	||
 	    __put_user (0, &ubuf->st_atime.tv_nsec)		||
-	    __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec)	||
+	    __put_user (kbuf->mtime, &ubuf->st_mtime.tv_sec)	||
 	    __put_user (0, &ubuf->st_mtime.tv_nsec)		||
-	    __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec)	||
+	    __put_user (kbuf->ctime, &ubuf->st_ctime.tv_sec)	||
 	    __put_user (0, &ubuf->st_ctime.tv_nsec)		||
-	    __put_user (kbuf->st_blksize, &ubuf->st_blksize)	||
-	    __put_user (kbuf->st_blocks, &ubuf->st_blocks)	||
+	    __put_user (kbuf->blksize, &ubuf->st_blksize)	||
+	    __put_user (kbuf->blocks, &ubuf->st_blocks)	||
 	    __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype))
 		return -EFAULT;
 	return 0;
@@ -128,21 +130,18 @@
 asmlinkage int solaris_stat(u32 filename, u32 statbuf)
 {
 	int ret;
-	struct stat s;
+	struct kstat s;
 	char *filenam;
 	mm_segment_t old_fs = get_fs();
-	int (*sys_newstat)(char *,struct stat *) = 
-		(int (*)(char *,struct stat *))SYS(stat);
 	
 	filenam = getname ((char *)A(filename));
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		set_fs (KERNEL_DS);
-		ret = sys_newstat(filenam, &s);
+		ret = vfs_stat(filenam, &s);
 		set_fs (old_fs);
 		putname (filenam);
-		if (putstat ((struct sol_stat *)A(statbuf), &s))
-			return -EFAULT;
+		return putstat((struct sol_stat *)A(statbuf), &s);
 	}
 	return ret;
 }
@@ -156,21 +155,18 @@
 asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
 {
 	int ret;
-	struct stat s;
+	struct kstat s;
 	char *filenam;
 	mm_segment_t old_fs = get_fs();
-	int (*sys_newstat)(char *,struct stat *) = 
-		(int (*)(char *,struct stat *))SYS(stat);
 	
 	filenam = getname ((char *)A(filename));
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		set_fs (KERNEL_DS);
-		ret = sys_newstat(filenam, &s);
+		ret = vfs_stat(filenam, &s);
 		set_fs (old_fs);
 		putname (filenam);
-		if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
-			return -EFAULT;
+		return putstat64((struct sol_stat64 *)A(statbuf), &s);
 	}
 	return ret;
 }
@@ -178,21 +174,18 @@
 asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
 {
 	int ret;
-	struct stat s;
+	struct kstat s;
 	char *filenam;
 	mm_segment_t old_fs = get_fs();
-	int (*sys_newlstat)(char *,struct stat *) = 
-		(int (*)(char *,struct stat *))SYS(lstat);
 	
 	filenam = getname ((char *)A(filename));
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		set_fs (KERNEL_DS);
-		ret = sys_newlstat(filenam, &s);
+		ret = vfs_lstat(filenam, &s);
 		set_fs (old_fs);
 		putname (filenam);
-		if (putstat ((struct sol_stat *)A(statbuf), &s))
-			return -EFAULT;
+		return putstat((struct sol_stat *)A(statbuf), &s);
 	}
 	return ret;
 }
@@ -205,21 +198,18 @@
 asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
 {
 	int ret;
-	struct stat s;
+	struct kstat s;
 	char *filenam;
 	mm_segment_t old_fs = get_fs();
-	int (*sys_newlstat)(char *,struct stat *) = 
-		(int (*)(char *,struct stat *))SYS(lstat);
 	
 	filenam = getname ((char *)A(filename));
 	ret = PTR_ERR(filenam);
 	if (!IS_ERR(filenam)) {
 		set_fs (KERNEL_DS);
-		ret = sys_newlstat(filenam, &s);
+		ret = vfs_lstat(filenam, &s);
 		set_fs (old_fs);
 		putname (filenam);
-		if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
-			return -EFAULT;
+		return putstat64((struct sol_stat64 *)A(statbuf), &s);
 	}
 	return ret;
 }
@@ -227,16 +217,10 @@
 asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf)
 {
 	int ret;
-	struct stat s;
-	mm_segment_t old_fs = get_fs();
-	int (*sys_newfstat)(unsigned,struct stat *) = 
-		(int (*)(unsigned,struct stat *))SYS(fstat);
-	
-	set_fs (KERNEL_DS);
-	ret = sys_newfstat(fd, &s);
-	set_fs (old_fs);
-	if (putstat ((struct sol_stat *)A(statbuf), &s))
-		return -EFAULT;
+	struct kstat s;
+	ret = vfs_fstat(fd, &s);
+	if (!ret)
+		return putstat((struct sol_stat *)A(statbuf), &s);
 	return ret;
 }
 
@@ -248,16 +232,11 @@
 asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf)
 {
 	int ret;
-	struct stat s;
-	mm_segment_t old_fs = get_fs();
-	int (*sys_newfstat)(unsigned,struct stat *) = 
-		(int (*)(unsigned,struct stat *))SYS(fstat);
+	struct kstat s;
 	
-	set_fs (KERNEL_DS);
-	ret = sys_newfstat(fd, &s);
-	set_fs (old_fs);
-	if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
-		return -EFAULT;
+	ret = vfs_fstat(fd, &s);
+	if (!ret)
+		return putstat64((struct sol_stat64 *)A(statbuf), &s);
 	return ret;
 }
 
diff -urN linux-2.5.4-pre1/arch/sparc64/solaris/ioctl.c linux/arch/sparc64/solaris/ioctl.c
--- linux-2.5.4-pre1/arch/sparc64/solaris/ioctl.c	Tue Nov 28 21:53:44 2000
+++ linux/arch/sparc64/solaris/ioctl.c	Wed Feb  6 22:51:46 2002
@@ -308,7 +308,7 @@
 	case 110: /* SI_GETUDATA */
 	{
 		int etsdusize, servtype;
-		switch (ino->u.socket_i.type) {
+		switch (SOCKET_I(ino)->type) {
 		case SOCK_STREAM:
 			etsdusize = 1;
 			servtype = 2;
@@ -326,16 +326,16 @@
 		    __put_user(0, &((struct solaris_si_udata *)A(arg))->so_state) ||
 		    __put_user(0, &((struct solaris_si_udata *)A(arg))->so_options) ||
 		    __put_user(16384, &((struct solaris_si_udata *)A(arg))->tsdusize) ||
-		    __put_user(ino->u.socket_i.ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_family) ||
-		    __put_user(ino->u.socket_i.type, &((struct solaris_si_udata *)A(arg))->sockparams.sp_type) ||
-		    __put_user(ino->u.socket_i.ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_protocol))
+		    __put_user(SOCKET_I(ino)->ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_family) ||
+		    __put_user(SOCKET_I(ino)->type, &((struct solaris_si_udata *)A(arg))->sockparams.sp_type) ||
+		    __put_user(SOCKET_I(ino)->ops->family, &((struct solaris_si_udata *)A(arg))->sockparams.sp_protocol))
 			return (EFAULT << 8) | TSYSERR;
 		return 0;
 	}
 	case 101: /* O_SI_GETUDATA */
 	{
 		int etsdusize, servtype;
-		switch (ino->u.socket_i.type) {
+		switch (SOCKET_I(ino)->type) {
 		case SOCK_STREAM:
 			etsdusize = 1;
 			servtype = 2;
diff -urN linux-2.5.4-pre1/arch/sparc64/solaris/socket.c linux/arch/sparc64/solaris/socket.c
--- linux-2.5.4-pre1/arch/sparc64/solaris/socket.c	Sun Feb 18 19:49:54 2001
+++ linux/arch/sparc64/solaris/socket.c	Wed Feb  6 22:51:46 2002
@@ -248,12 +248,6 @@
 					   24 for IPv6,
 					   about 80 for AX.25 */
 
-/* XXX These as well... */
-extern __inline__ struct socket *socki_lookup(struct inode *inode)
-{
-	return &inode->u.socket_i;
-}
-
 extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
 {
 	struct file *file;
@@ -265,13 +259,13 @@
 	}
 
 	inode = file->f_dentry->d_inode;
-	if (!inode->i_sock || !socki_lookup(inode)) {
+	if (!inode->i_sock) {
 		*err = -ENOTSOCK;
 		fput(file);
 		return NULL;
 	}
 
-	return socki_lookup(inode);
+	return SOCKET_I(inode);
 }
 
 extern __inline__ void sockfd_put(struct socket *sock)
diff -urN linux-2.5.4-pre1/arch/sparc64/solaris/socksys.c linux/arch/sparc64/solaris/socksys.c
--- linux-2.5.4-pre1/arch/sparc64/solaris/socksys.c	Mon Jan 14 10:10:44 2002
+++ linux/arch/sparc64/solaris/socksys.c	Wed Feb  6 22:51:46 2002
@@ -6,6 +6,13 @@
  * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
  */
 
+/*
+ *  Dave, _please_ give me specifications on this fscking mess so that I
+ * could at least get it into the state when it wouldn't screw the rest of
+ * the kernel over.  socksys.c and timod.c _stink_ and we are not talking
+ * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV
+ */
+
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -86,6 +93,9 @@
 		return fd;
 	/*
 	 * N.B. The following operations are not legal!
+	 *
+	 * No shit.  WTF is it supposed to do, anyway?
+	 *
 	 * Try instead:
 	 * d_delete(filp->f_dentry), then d_instantiate with sock inode
 	 */
@@ -93,7 +103,7 @@
 	filp->f_dentry = dget(fcheck(fd)->f_dentry);
 	filp->f_dentry->d_inode->i_rdev = inode->i_rdev;
 	filp->f_dentry->d_inode->i_flock = inode->i_flock;
-	filp->f_dentry->d_inode->u.socket_i.file = filp;
+	SOCKET_I(filp->f_dentry->d_inode)->file = filp;
 	filp->f_op = &socksys_file_ops;
         sock = (struct sol_socket_struct*) 
         	mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
diff -urN linux-2.5.4-pre1/arch/sparc64/solaris/timod.c linux/arch/sparc64/solaris/timod.c
--- linux-2.5.4-pre1/arch/sparc64/solaris/timod.c	Mon Jan 14 10:10:44 2002
+++ linux/arch/sparc64/solaris/timod.c	Wed Feb  6 22:51:46 2002
@@ -149,7 +149,7 @@
 	struct socket *sock;
 
 	SOLD("wakeing socket");
-	sock = &current->files->fd[fd]->f_dentry->d_inode->u.socket_i;
+	sock = SOCKET_I(current->files->fd[fd]->f_dentry->d_inode);
 	wake_up_interruptible(&sock->wait);
 	read_lock(&sock->sk->callback_lock);
 	if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
@@ -640,7 +640,7 @@
 	ino = filp->f_dentry->d_inode;
 	sock = (struct sol_socket_struct *)filp->private_data;
 	SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
-	if ( ctl_maxlen > 0 && !sock->pfirst && ino->u.socket_i.type == SOCK_STREAM
+	if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM
 		&& sock->state == TS_IDLE) {
 		SOLD("calling LISTEN");
 		args[0] = fd;
@@ -730,7 +730,7 @@
 	*flags_p = 0;
 	if (ctl_maxlen >= 0) {
 		SOLD("ACCEPT perhaps?");
-		if (ino->u.socket_i.type == SOCK_STREAM && sock->state == TS_IDLE) {
+		if (SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) {
 			struct T_conn_ind ind;
 			char *buf = getpage();
 			int len = BUF_SIZE;
diff -urN linux-2.5.4-pre1/drivers/block/nbd.c linux/drivers/block/nbd.c
--- linux-2.5.4-pre1/drivers/block/nbd.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/block/nbd.c	Wed Feb  6 22:51:47 2002
@@ -418,10 +418,13 @@
 		file = fget(arg);
 		if (file) {
 			inode = file->f_dentry->d_inode;
-			/* N.B. Should verify that it's a socket */
-			lo->file = file;
-			lo->sock = &inode->u.socket_i;
-			error = 0;
+			if (inode->i_sock) {
+				lo->file = file;
+				lo->sock = SOCKET_I(inode);
+				error = 0;
+			} else {
+				fput(file);
+			}
 		}
 		return error;
 	case NBD_SET_BLKSIZE:
diff -urN linux-2.5.4-pre1/drivers/bluetooth/hci_usb.c linux/drivers/bluetooth/hci_usb.c
--- linux-2.5.4-pre1/drivers/bluetooth/hci_usb.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/bluetooth/hci_usb.c	Wed Feb  6 22:51:47 2002
@@ -120,11 +120,11 @@
 	DBG("%s", hdev->name);
 
 	husb->read_urb->dev = husb->udev;
-	if ((status = usb_submit_urb(husb->read_urb)))
+	if ((status = usb_submit_urb(husb->read_urb, GFP_KERNEL)))
 		DBG("read submit failed. %d", status);
 
 	husb->intr_urb->dev = husb->udev;
-	if ((status = usb_submit_urb(husb->intr_urb)))
+	if ((status = usb_submit_urb(husb->intr_urb, GFP_KERNEL)))
 		DBG("interrupt submit failed. %d", status);
 
 	hdev->flags |= HCI_RUNNING;
@@ -428,7 +428,7 @@
 
 resubmit:
 	husb->read_urb->dev = husb->udev;
-	if ((status = usb_submit_urb(husb->read_urb)))
+	if ((status = usb_submit_urb(husb->read_urb, GFP_KERNEL)))
 		DBG("%s read URB submit failed %d", husb->hdev.name, status);
 
 	DBG("%s read URB re-submited", husb->hdev.name);
@@ -453,7 +453,7 @@
 	FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
 	                 hci_usb_ctrl, skb);
 
-	if ((status = usb_submit_urb(urb))) {
+	if ((status = usb_submit_urb(urb, GFP_KERNEL))) {
 		DBG("%s control URB submit failed %d", husb->hdev.name, status);
 		return status;
 	}
@@ -474,7 +474,7 @@
 	              hci_usb_bulk_write, skb);
 	urb->transfer_flags |= USB_QUEUE_BULK;
 
-	if ((status = usb_submit_urb(urb))) {
+	if ((status = usb_submit_urb(urb, GFP_KERNEL))) {
 		DBG("%s write URB submit failed %d", husb->hdev.name, status);
 		return status;
 	}
diff -urN linux-2.5.4-pre1/drivers/bluetooth/hci_vhci.c linux/drivers/bluetooth/hci_vhci.c
--- linux-2.5.4-pre1/drivers/bluetooth/hci_vhci.c	Fri Sep  7 09:28:38 2001
+++ linux/drivers/bluetooth/hci_vhci.c	Wed Feb  6 22:51:47 2002
@@ -221,11 +221,6 @@
 	return ret;
 }
 
-static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
 static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	return -EINVAL;
@@ -296,7 +291,7 @@
 
 static struct file_operations hci_vhci_fops = {
 	owner:	THIS_MODULE,	
-	llseek:	hci_vhci_chr_lseek,
+	llseek:	no_lseek,
 	read:	hci_vhci_chr_read,
 	write:	hci_vhci_chr_write,
 	poll:	hci_vhci_chr_poll,
diff -urN linux-2.5.4-pre1/drivers/char/mem.c linux/drivers/char/mem.c
--- linux-2.5.4-pre1/drivers/char/mem.c	Tue Jan 15 13:53:51 2002
+++ linux/drivers/char/mem.c	Wed Feb  6 22:51:47 2002
@@ -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 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)
diff -urN linux-2.5.4-pre1/drivers/char/nvram.c linux/drivers/char/nvram.c
--- linux-2.5.4-pre1/drivers/char/nvram.c	Fri Nov 30 08:26:04 2001
+++ linux/drivers/char/nvram.c	Wed Feb  6 22:51:47 2002
@@ -216,6 +216,7 @@
 
 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 @@
 		offset += NVRAM_BYTES;
 		break;
 	}
+	unlock_kernel();
 	return( (offset >= 0) ? (file->f_pos = offset) : -EINVAL );
 }
 
diff -urN linux-2.5.4-pre1/drivers/char/nwflash.c linux/drivers/char/nwflash.c
--- linux-2.5.4-pre1/drivers/char/nwflash.c	Fri Oct 12 13:48:42 2001
+++ linux/drivers/char/nwflash.c	Wed Feb  6 22:51:47 2002
@@ -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 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;
 }
 
 
diff -urN linux-2.5.4-pre1/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c
--- linux-2.5.4-pre1/drivers/char/vc_screen.c	Tue Jan  1 11:43:51 2002
+++ linux/drivers/char/vc_screen.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 
 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 @@
 		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;
 }
 
diff -urN linux-2.5.4-pre1/drivers/hotplug/pci_hotplug_core.c linux/drivers/hotplug/pci_hotplug_core.c
--- linux-2.5.4-pre1/drivers/hotplug/pci_hotplug_core.c	Wed Nov 21 09:59:11 2001
+++ linux/drivers/hotplug/pci_hotplug_core.c	Wed Feb  6 22:51:47 2002
@@ -362,7 +362,7 @@
 	put_inode:	force_delete,
 };
 
-static struct super_block *pcihpfs_read_super (struct super_block *sb, void *data, int silent)
+static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
@@ -375,20 +375,31 @@
 
 	if (!inode) {
 		dbg("%s: could not get inode!\n",__FUNCTION__);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	root = d_alloc_root(inode);
 	if (!root) {
 		dbg("%s: could not get root dentry!\n",__FUNCTION__);
 		iput(inode);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root = root;
-	return sb;
+	return 0;
 }
 
-static DECLARE_FSTYPE(pcihpfs_fs_type, "pcihpfs", pcihpfs_read_super, FS_SINGLE | FS_LITTER);
+static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, pcihpfs_fill_super);
+}
+
+static struct file_system_type pcihpfs_type = {
+	owner:		THIS_MODULE,
+	name:		"pchihpfs",
+	get_sb:		pcihpfs_get_sb,
+	fs_flags:	FS_LITTER,
+};
 
 static int get_mount (void)
 {
diff -urN linux-2.5.4-pre1/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- linux-2.5.4-pre1/drivers/ieee1394/pcilynx.c	Mon Jan 21 15:57:51 2002
+++ linux/drivers/ieee1394/pcilynx.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 
 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 @@
                 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;
diff -urN linux-2.5.4-pre1/drivers/input/joystick/iforce.c linux/drivers/input/joystick/iforce.c
--- linux-2.5.4-pre1/drivers/input/joystick/iforce.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/input/joystick/iforce.c	Wed Feb  6 22:51:47 2002
@@ -204,7 +204,7 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 			add_wait_queue(&iforce->wait, &wait);
 
-			if (usb_submit_urb(iforce->out)) {
+			if (usb_submit_urb(iforce->out, GFP_ATOMIC)) {
 				set_current_state(TASK_RUNNING);
 				remove_wait_queue(&iforce->wait, &wait);
 				return;
@@ -289,7 +289,7 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 			add_wait_queue(&iforce->wait, &wait);
 
-			if (usb_submit_urb(iforce->ctrl)) {
+			if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) {
 				set_current_state(TASK_RUNNING);
 				remove_wait_queue(&iforce->wait, &wait);
 				return -1;
@@ -345,7 +345,7 @@
 			if (iforce->open++)
 				break;
 			iforce->irq->dev = iforce->usbdev;
-			if (usb_submit_urb(iforce->irq))
+			if (usb_submit_urb(iforce->irq, GFP_KERNEL))
 					return -EIO;
 			break;
 #endif
diff -urN linux-2.5.4-pre1/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- linux-2.5.4-pre1/drivers/isdn/avmb1/capifs.c	Thu Jan  3 12:20:10 2002
+++ linux/drivers/isdn/avmb1/capifs.c	Wed Feb  6 22:51:47 2002
@@ -281,17 +281,12 @@
 	return 0;
 }
 
-struct super_block *capifs_read_super(struct super_block *s, void *data,
-				      int silent)
+static int capifs_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
 	struct dentry * root;
 	struct capifs_sb_info *sbi;
 
-	/* Super block already completed? */
-	if (s->s_root)
-		goto out;
-
 	sbi = (struct capifs_sb_info *) kmalloc(sizeof(struct capifs_sb_info), GFP_KERNEL);
 	if ( !sbi )
 		goto fail;
@@ -317,7 +312,6 @@
 	s->s_blocksize_bits = 10;
 	s->s_magic = CAPIFS_SUPER_MAGIC;
 	s->s_op = &capifs_sops;
-	s->s_root = NULL;
 
 	/*
 	 * Get the root inode and dentry, but defer checking for errors.
@@ -332,15 +326,6 @@
 	} 
 	root = d_alloc_root(root_inode);
 
-	/*
-	 * Check whether somebody else completed the super block.
-	 */
-	if (s->s_root) {
-		if (root) dput(root);
-		else iput(root_inode);
-		goto out;
-	}
-
 	if (!root) {
 		printk("capifs: get root dentry failed\n");
 		/*
@@ -352,15 +337,6 @@
 		goto fail;
 	}
 
-	/*
-	 * Check whether somebody else completed the super block.
-	 */
-	if (s->s_root)
-		goto out;
-	
-	/*
-	 * Success! Install the root dentry now to indicate completion.
-	 */
 	s->s_root = root;
 
 	sbi->next = mounts;
@@ -368,11 +344,9 @@
 		SBI(sbi->next)->back = &(sbi->next);
 	sbi->back = &mounts;
 	mounts = s;
-
-out:	/* Success ... somebody else completed the super block for us. */ 
-	return s;
+	return 0;
 fail:
-	return NULL;
+	return -EINVAL;
 }
 
 static int capifs_statfs(struct super_block *sb, struct statfs *buf)
@@ -400,7 +374,17 @@
 	return inode;
 }
 
-static DECLARE_FSTYPE(capifs_fs_type, "capifs", capifs_read_super, 0);
+static struct super_block *capifs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, capifs_fill_super);
+}
+
+static struct file_system_type capifs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"capifs",
+	get_sb:		capifs_get_sb,
+};
 
 void capifs_new_ncci(char type, unsigned int num, kdev_t device)
 {
diff -urN linux-2.5.4-pre1/drivers/isdn/hisax/st5481.h linux/drivers/isdn/hisax/st5481.h
--- linux-2.5.4-pre1/drivers/isdn/hisax/st5481.h	Mon Jan 21 15:44:21 2002
+++ linux/drivers/isdn/hisax/st5481.h	Wed Feb  6 22:51:47 2002
@@ -409,10 +409,10 @@
  * Submit an URB with error reporting. This is a macro so
  * the __FUNCTION__ returns the caller function name.
  */
-#define SUBMIT_URB(urb) \
+#define SUBMIT_URB(urb, mem_flags) \
 ({ \
 	int status; \
-	if ((status = usb_submit_urb(urb)) < 0) { \
+	if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \
 		WARN("usb_submit_urb failed,status=%d", status); \
 	} \
         status; \
diff -urN linux-2.5.4-pre1/drivers/isdn/hisax/st5481_b.c linux/drivers/isdn/hisax/st5481_b.c
--- linux-2.5.4-pre1/drivers/isdn/hisax/st5481_b.c	Sat Dec  8 20:28:45 2001
+++ linux/drivers/isdn/hisax/st5481_b.c	Wed Feb  6 22:51:47 2002
@@ -115,7 +115,7 @@
 
 	DBG_ISO_PACKET(0x200,urb);
 
-	SUBMIT_URB(urb);
+	SUBMIT_URB(urb, GFP_KERNEL);
 }
 
 /*
diff -urN linux-2.5.4-pre1/drivers/isdn/hisax/st5481_d.c linux/drivers/isdn/hisax/st5481_d.c
--- linux-2.5.4-pre1/drivers/isdn/hisax/st5481_d.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/isdn/hisax/st5481_d.c	Wed Feb  6 22:51:47 2002
@@ -356,10 +356,10 @@
 
 	DBG_ISO_PACKET(0x20,urb);
 
-	if (usb_submit_urb(urb) < 0) {
+	if (usb_submit_urb(urb, GFP_KERNEL) < 0) {
 		// There is another URB queued up
 		urb->transfer_flags = USB_ISO_ASAP;
-		SUBMIT_URB(urb);
+		SUBMIT_URB(urb, GFP_KERNEL);
 	}	
 }
 
@@ -450,7 +450,7 @@
 	urb->transfer_flags = USB_ISO_ASAP;
 
 	DBG_ISO_PACKET(0x20,urb);
-	SUBMIT_URB(urb);
+	SUBMIT_URB(urb, GFP_KERNEL);
 }
 
 static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg)
diff -urN linux-2.5.4-pre1/drivers/isdn/hisax/st5481_usb.c linux/drivers/isdn/hisax/st5481_usb.c
--- linux-2.5.4-pre1/drivers/isdn/hisax/st5481_usb.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/isdn/hisax/st5481_usb.c	Wed Feb  6 22:51:47 2002
@@ -48,7 +48,7 @@
 	// Prepare the URB
 	urb->dev = adapter->usb_dev;
 
-	SUBMIT_URB(urb);
+	SUBMIT_URB(urb, GFP_KERNEL);
 }
 
 /*
@@ -357,7 +357,7 @@
 	adapter->leds = RED_LED; 
 
 	// Start receiving on the interrupt endpoint
-	SUBMIT_URB(intr->urb); 
+	SUBMIT_URB(intr->urb, GFP_KERNEL); 
 
 	while ((request = init_cmd_table[i++])) {
 		value = init_cmd_table[i++];
@@ -517,7 +517,7 @@
 	urb->dev = in->adapter->usb_dev;
 	urb->actual_length = 0;
 
-	SUBMIT_URB(urb);
+	SUBMIT_URB(urb, GFP_KERNEL);
 }
 
 int __devinit st5481_setup_in(struct st5481_in *in)
@@ -603,10 +603,10 @@
 	DBG(4,"");
 
 	in->urb[0]->dev = adapter->usb_dev;
-	SUBMIT_URB(in->urb[0]);
+	SUBMIT_URB(in->urb[0], GFP_KERNEL);
 
 	in->urb[1]->dev = adapter->usb_dev;
-	SUBMIT_URB(in->urb[1]);
+	SUBMIT_URB(in->urb[1], GFP_KERNEL);
 }
 
 void st5481_in_mode(struct st5481_in *in, int mode)
diff -urN linux-2.5.4-pre1/drivers/macintosh/nvram.c linux/drivers/macintosh/nvram.c
--- linux-2.5.4-pre1/drivers/macintosh/nvram.c	Mon Oct 15 13:43:24 2001
+++ linux/drivers/macintosh/nvram.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 		offset += NVRAM_SIZE;
 		break;
 	}
-	if (offset < 0)
+	if (offset < 0) {
+		unlock_kernel();
 		return -EINVAL;
+	}
 	file->f_pos = offset;
+	unlock_kernel();
 	return file->f_pos;
 }
 
diff -urN linux-2.5.4-pre1/drivers/media/video/cpia_usb.c linux/drivers/media/video/cpia_usb.c
--- linux-2.5.4-pre1/drivers/media/video/cpia_usb.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/media/video/cpia_usb.c	Wed Feb  6 22:51:47 2002
@@ -246,13 +246,13 @@
 	ucpia->sbuf[1].urb->next = ucpia->sbuf[0].urb;
 	ucpia->sbuf[0].urb->next = ucpia->sbuf[1].urb;
 	
-	err = usb_submit_urb(ucpia->sbuf[0].urb);
+	err = usb_submit_urb(ucpia->sbuf[0].urb, GFP_KERNEL);
 	if (err) {
 		printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n",
 			err);
 		goto error_urb1;
 	}
-	err = usb_submit_urb(ucpia->sbuf[1].urb);
+	err = usb_submit_urb(ucpia->sbuf[1].urb, GFP_KERNEL);
 	if (err) {
 		printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n",
 			err);
diff -urN linux-2.5.4-pre1/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
--- linux-2.5.4-pre1/drivers/mtd/mtdchar.c	Thu Oct  4 15:14:59 2001
+++ linux/drivers/mtd/mtdchar.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 {
 	struct mtd_info *mtd=(struct mtd_info *)file->private_data;
 
+	lock_kernel();
 	switch (orig) {
 	case 0:
 		/* SEEK_SET */
@@ -45,6 +47,7 @@
 		file->f_pos =mtd->size + offset;
 		break;
 	default:
+		unlock_kernel();
 		return -EINVAL;
 	}
 
@@ -53,6 +56,7 @@
 	else if (file->f_pos >= mtd->size)
 		file->f_pos = mtd->size - 1;
 
+	unlock_kernel();
 	return file->f_pos;
 }
 
diff -urN linux-2.5.4-pre1/drivers/net/irda/irda-usb.c linux/drivers/net/irda/irda-usb.c
--- linux-2.5.4-pre1/drivers/net/irda/irda-usb.c	Wed Jan 23 15:28:39 2002
+++ linux/drivers/net/irda/irda-usb.c	Wed Feb  6 22:51:47 2002
@@ -278,7 +278,7 @@
 	urb->transfer_flags = USB_QUEUE_BULK | USB_ASYNC_UNLINK;
 	urb->timeout = MSECS_TO_JIFFIES(100);
 
-	if ((ret = usb_submit_urb(urb))) {
+	if ((ret = usb_submit_urb(urb, GFP_KERNEL))) {
 		WARNING(__FUNCTION__ "(), failed Speed URB\n");
 	}
 	spin_unlock_irqrestore(&self->lock, flags);
@@ -451,7 +451,7 @@
 	}
 	
 	/* Ask USB to send the packet */
-	if ((res = usb_submit_urb(urb))) {
+	if ((res = usb_submit_urb(urb, GFP_KERNEL))) {
 		WARNING(__FUNCTION__ "(), failed Tx URB\n");
 		self->stats.tx_errors++;
 		/* Let USB recover : We will catch that in the watchdog */
@@ -730,7 +730,7 @@
 	urb->status = 0;
 	urb->next = NULL;	/* Don't auto resubmit URBs */
 	
-	ret = usb_submit_urb(urb);
+	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret) {
 		/* If this ever happen, we are in deep s***.
 		 * Basically, the Rx path will stop... */
diff -urN linux-2.5.4-pre1/drivers/net/wan/comx.c linux/drivers/net/wan/comx.c
--- linux-2.5.4-pre1/drivers/net/wan/comx.c	Thu Sep 13 16:04:43 2001
+++ linux/drivers/net/wan/comx.c	Wed Feb  6 22:51:47 2002
@@ -876,7 +876,7 @@
 
 static int comx_rmdir(struct inode *dir, struct dentry *dentry)
 {
-	struct proc_dir_entry *entry = dentry->d_inode->u.generic_ip;
+	struct proc_dir_entry *entry = PDE(dentry->d_inode);
 	struct net_device *dev = entry->data;
 	struct comx_channel *ch = dev->priv;
 	int ret;
@@ -928,7 +928,7 @@
 	struct proc_dir_entry *de;
 	struct inode *inode = NULL;
 
-	if ((de = (struct proc_dir_entry *) dir->u.generic_ip) != NULL) {
+	if ((de = PDE(dir)) != NULL) {
 		for (de = de->subdir ; de ; de = de->next) {
 			if ((de && de->low_ino) && 
 			    (de->namelen == dentry->d_name.len) &&
diff -urN linux-2.5.4-pre1/drivers/net/wireless/airo.c linux/drivers/net/wireless/airo.c
--- linux-2.5.4-pre1/drivers/net/wireless/airo.c	Sun Dec 30 10:31:51 2001
+++ linux/drivers/net/wireless/airo.c	Wed Feb  6 22:51:47 2002
@@ -2280,7 +2280,7 @@
 
 static int proc_status_open( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *apriv = (struct airo_info *)dev->priv;
 	CapabilityRid cap_rid;
@@ -2289,8 +2289,6 @@
 
 	MOD_INC_USE_COUNT;
 
-	dp = inode->u.generic_ip;
-
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2364,7 +2362,7 @@
 				struct file *file,
 				u16 rid ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *apriv = (struct airo_info *)dev->priv;
 	StatsRid stats;
@@ -2372,9 +2370,6 @@
 	int *vals = stats.vals;
 	MOD_INC_USE_COUNT;
 
-
-	dp = inode->u.generic_ip;
-
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2433,7 +2428,7 @@
 
 static void proc_config_on_close( struct inode *inode, struct file *file ) {
 	struct proc_data *data = file->private_data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	ConfigRid config;
@@ -2442,7 +2437,6 @@
 	int need_reset = 0;
 
 	if ( !data->writelen ) return;
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
 
 	disable_MAC(ai);
 	readConfigRid(ai, &config);
@@ -2629,7 +2623,7 @@
 
 static int proc_config_open( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	ConfigRid config;
@@ -2637,8 +2631,6 @@
 
 	MOD_INC_USE_COUNT;
 
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2723,7 +2715,7 @@
 
 static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
 	struct proc_data *data = (struct proc_data *)file->private_data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	SsidRid SSID_rid;
@@ -2759,7 +2751,7 @@
 
 static void proc_APList_on_close( struct inode *inode, struct file *file ) {
 	struct proc_data *data = (struct proc_data *)file->private_data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	APListRid APList_rid;
@@ -2852,7 +2844,7 @@
 
 static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	int i;
@@ -2862,7 +2854,6 @@
 
 	memset(key, 0, sizeof(key));
 
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
 	data = (struct proc_data *)file->private_data;
 	if ( !data->writelen ) return;
 
@@ -2894,7 +2885,7 @@
 
 static int proc_wepkey_open( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	char *ptr;
@@ -2905,8 +2896,6 @@
 
 	MOD_INC_USE_COUNT;
 
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2948,7 +2937,7 @@
 
 static int proc_SSID_open( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	int i;
@@ -2957,8 +2946,6 @@
 
 	MOD_INC_USE_COUNT;
 
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	memset(file->private_data, 0, sizeof(struct proc_data));
@@ -2996,7 +2983,7 @@
 
 static int proc_APList_open( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	int i;
@@ -3005,8 +2992,6 @@
 
 	MOD_INC_USE_COUNT;
 
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
-
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
 	memset(file->private_data, 0, sizeof(struct proc_data));
@@ -3048,7 +3033,7 @@
 
 static int proc_BSSList_open( struct inode *inode, struct file *file ) {
 	struct proc_data *data;
-	struct proc_dir_entry *dp = inode->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(inode);
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = (struct airo_info*)dev->priv;
 	char *ptr;
@@ -3058,8 +3043,6 @@
 	int doLoseSync = -1;
 
 	MOD_INC_USE_COUNT;
-
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
 
 	if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
diff -urN linux-2.5.4-pre1/drivers/pci/proc.c linux/drivers/pci/proc.c
--- linux-2.5.4-pre1/drivers/pci/proc.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/pci/proc.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 	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);
@@ -45,7 +46,7 @@
 proc_bus_pci_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
 {
 	const struct inode *ino = file->f_dentry->d_inode;
-	const struct proc_dir_entry *dp = ino->u.generic_ip;
+	const struct proc_dir_entry *dp = PDE(ino);
 	struct pci_dev *dev = dp->data;
 	unsigned int pos = *ppos;
 	unsigned int cnt, size;
@@ -127,7 +128,7 @@
 proc_bus_pci_write(struct file *file, const char *buf, size_t nbytes, loff_t *ppos)
 {
 	const struct inode *ino = file->f_dentry->d_inode;
-	const struct proc_dir_entry *dp = ino->u.generic_ip;
+	const struct proc_dir_entry *dp = PDE(ino);
 	struct pci_dev *dev = dp->data;
 	int pos = *ppos;
 	int cnt;
@@ -199,7 +200,7 @@
 
 static int proc_bus_pci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	const struct proc_dir_entry *dp = inode->u.generic_ip;
+	const struct proc_dir_entry *dp = PDE(inode);
 	struct pci_dev *dev = dp->data;
 #ifdef HAVE_PCI_MMAP
 	struct pci_filp_private *fpriv = file->private_data;
@@ -241,7 +242,7 @@
 static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct inode *inode = file->f_dentry->d_inode;
-	const struct proc_dir_entry *dp = inode->u.generic_ip;
+	const struct proc_dir_entry *dp = PDE(inode);
 	struct pci_dev *dev = dp->data;
 	struct pci_filp_private *fpriv = file->private_data;
 	int ret;
diff -urN linux-2.5.4-pre1/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c
--- linux-2.5.4-pre1/drivers/pnp/isapnp_proc.c	Fri Nov 30 08:26:04 2001
+++ linux/drivers/pnp/isapnp_proc.c	Wed Feb  6 22:51:47 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->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 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,18 +232,19 @@
 	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);
 }
 
 static ssize_t isapnp_proc_bus_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
 {
 	struct inode *ino = file->f_dentry->d_inode;
-	struct proc_dir_entry *dp = ino->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(ino);
 	struct pci_dev *dev = dp->data;
 	int pos = *ppos;
 	int cnt, size = 256;
diff -urN linux-2.5.4-pre1/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c
--- linux-2.5.4-pre1/drivers/sbus/char/flash.c	Tue Jan 15 10:56:35 2002
+++ linux/drivers/sbus/char/flash.c	Wed Feb  6 22:51:47 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->f_pos = offset;
@@ -96,8 +97,10 @@
 			file->f_pos = flash.read_size;
 			break;
 		default:
+			unlock_kernel();
 			return -EINVAL;
 	}
+	unlock_kernel();
 	return file->f_pos;
 }
 
diff -urN linux-2.5.4-pre1/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c
--- linux-2.5.4-pre1/drivers/sbus/char/jsflash.c	Sat Dec  8 20:02:47 2001
+++ linux/drivers/sbus/char/jsflash.c	Wed Feb  6 22:51:47 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->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;
 }
 
 /*
diff -urN linux-2.5.4-pre1/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- linux-2.5.4-pre1/drivers/scsi/scsi.c	Thu Jan 10 10:15:38 2002
+++ linux/drivers/scsi/scsi.c	Wed Feb  6 22:51:47 2002
@@ -87,13 +87,16 @@
 
 struct scsi_host_sg_pool {
 	int size;
+	char *name; 
 	kmem_cache_t *slab;
 	mempool_t *pool;
 };
 
-static const int scsi_host_sg_pool_sizes[SG_MEMPOOL_NR] = { 8, 16, 32, 64, MAX_PHYS_SEGMENTS };
-struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR];
-
+#define SP(x) { x, "sgpool-" #x } 
+struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = { 
+	SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS)
+}; 	
+#undef SP 	
 /*
    static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
  */
@@ -2489,7 +2492,6 @@
 static int __init init_scsi(void)
 {
 	struct proc_dir_entry *generic;
-	char name[16];
 	int i;
 
 	printk(KERN_INFO "SCSI subsystem driver " REVISION "\n");
@@ -2499,18 +2501,15 @@
 	 */
 	for (i = 0; i < SG_MEMPOOL_NR; i++) {
 		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
-		int size = scsi_host_sg_pool_sizes[i] * sizeof(struct scatterlist);
+		int size = sgp->size * sizeof(struct scatterlist);
 
-		snprintf(name, sizeof(name) - 1, "sgpool-%d", scsi_host_sg_pool_sizes[i]);
-		sgp->slab = kmem_cache_create(name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+		sgp->slab = kmem_cache_create(sgp->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 		if (!sgp->slab)
 			panic("SCSI: can't init sg slab\n");
 
 		sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab);
 		if (!sgp->pool)
 			panic("SCSI: can't init sg mempool\n");
-
-		sgp->size = size;
 	}
 
 	/*
diff -urN linux-2.5.4-pre1/drivers/sound/ite8172.c linux/drivers/sound/ite8172.c
--- linux-2.5.4-pre1/drivers/sound/ite8172.c	Tue Jan 15 10:56:35 2002
+++ linux/drivers/sound/ite8172.c	Wed Feb  6 22:51:47 2002
@@ -824,12 +824,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
-{
-    return -ESPIPE;
-}
-
-
 static int it8172_open_mixdev(struct inode *inode, struct file *file)
 {
     int minor = MINOR(inode->i_rdev);
@@ -870,7 +864,7 @@
 
 static /*const*/ struct file_operations it8172_mixer_fops = {
     owner:	THIS_MODULE,
-    llseek:	it8172_llseek,
+    llseek:	no_llseek,
     ioctl:	it8172_ioctl_mixdev,
     open:	it8172_open_mixdev,
     release:	it8172_release_mixdev,
@@ -1633,7 +1627,7 @@
 
 static /*const*/ struct file_operations it8172_audio_fops = {
     owner:	THIS_MODULE,
-    llseek:	it8172_llseek,
+    llseek:	no_llseek,
     read:	it8172_read,
     write:	it8172_write,
     poll:	it8172_poll,
diff -urN linux-2.5.4-pre1/drivers/sound/nec_vrc5477.c linux/drivers/sound/nec_vrc5477.c
--- linux-2.5.4-pre1/drivers/sound/nec_vrc5477.c	Thu Oct 25 13:53:52 2001
+++ linux/drivers/sound/nec_vrc5477.c	Wed Feb  6 22:51:47 2002
@@ -805,12 +805,6 @@
 
 /* --------------------------------------------------------------------- */
 
-static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-
 static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file)
 {
 	int minor = MINOR(inode->i_rdev);
@@ -852,7 +846,7 @@
 
 static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = {
 	owner:		THIS_MODULE,
-	llseek:		vrc5477_ac97_llseek,
+	llseek:		no_llseek,
 	ioctl:		vrc5477_ac97_ioctl_mixdev,
 	open:		vrc5477_ac97_open_mixdev,
 	release:	vrc5477_ac97_release_mixdev,
@@ -1618,7 +1612,7 @@
 
 static /*const*/ struct file_operations vrc5477_ac97_audio_fops = {
 	owner:	THIS_MODULE,
-	llseek:		vrc5477_ac97_llseek,
+	llseek:		no_llseek,
 	read:		vrc5477_ac97_read,
 	write:		vrc5477_ac97_write,
 	poll:		vrc5477_ac97_poll,
diff -urN linux-2.5.4-pre1/drivers/usb/CDCEther.c linux/drivers/usb/CDCEther.c
--- linux-2.5.4-pre1/drivers/usb/CDCEther.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/CDCEther.c	Wed Feb  6 22:51:47 2002
@@ -132,7 +132,7 @@
 			
 	// Give this to the USB subsystem so it can tell us 
 	// when more data arrives.
-	if ( (res = usb_submit_urb(ether_dev->rx_urb)) ) {
+	if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) ) {
 		warn( __FUNCTION__ " failed submint rx_urb %d", res);
 	}
 	
@@ -302,7 +302,7 @@
 	ether_dev->tx_urb->transfer_buffer_length = count;
 	
 	// Send the URB on its merry way.
-	if ((res = usb_submit_urb(ether_dev->tx_urb)))  {
+	if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_KERNEL)))  {
 		// Hmm...  It didn't go. Tell someone...
 		warn("failed tx_urb %d", res);
 		// update some stats...
@@ -350,7 +350,7 @@
 			read_bulk_callback, ether_dev );
 
 	// Put it out there so the device can send us stuff
-	if ( (res = usb_submit_urb(ether_dev->rx_urb)) )
+	if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) )
 	{
 		// Hmm...  Okay...
 		warn( __FUNCTION__ " failed rx_urb %d", res );
diff -urN linux-2.5.4-pre1/drivers/usb/acm.c linux/drivers/usb/acm.c
--- linux-2.5.4-pre1/drivers/usb/acm.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/acm.c	Wed Feb  6 22:51:47 2002
@@ -261,7 +261,7 @@
 	urb->actual_length = 0;
 	urb->dev = acm->dev;
 
-	if (usb_submit_urb(urb))
+	if (usb_submit_urb(urb, GFP_KERNEL))
 		dbg("failed resubmitting read urb");
 }
 
@@ -316,11 +316,11 @@
         unlock_kernel();
 
 	acm->ctrlurb.dev = acm->dev;
-	if (usb_submit_urb(&acm->ctrlurb))
+	if (usb_submit_urb(&acm->ctrlurb, GFP_KERNEL))
 		dbg("usb_submit_urb(ctrl irq) failed");
 
 	acm->readurb.dev = acm->dev;
-	if (usb_submit_urb(&acm->readurb))
+	if (usb_submit_urb(&acm->readurb, GFP_KERNEL))
 		dbg("usb_submit_urb(read bulk) failed");
 
 	acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
@@ -371,7 +371,7 @@
 	acm->writeurb.transfer_buffer_length = count;
 	acm->writeurb.dev = acm->dev;
 
-	if (usb_submit_urb(&acm->writeurb))
+	if (usb_submit_urb(&acm->writeurb, GFP_KERNEL))
 		dbg("usb_submit_urb(write bulk) failed");
 
 	return count;
diff -urN linux-2.5.4-pre1/drivers/usb/audio.c linux/drivers/usb/audio.c
--- linux-2.5.4-pre1/drivers/usb/audio.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/audio.c	Wed Feb  6 22:51:47 2002
@@ -917,7 +917,7 @@
 	if (!usbin_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbin_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == 0) {
+	    (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -982,7 +982,7 @@
 	if (!usbin_sync_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbin_sync_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == 0) {
+	    (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -1055,7 +1055,7 @@
 		urb->number_of_packets = DESCFRAMES;
 		urb->context = as;
 		urb->complete = usbin_completed;
-		if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb))
+		if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 			u->flags |= FLG_URB0RUNNING;
 		else
 			u->flags &= ~FLG_RUNNING;
@@ -1068,7 +1068,7 @@
 		urb->number_of_packets = DESCFRAMES;
 		urb->context = as;
 		urb->complete = usbin_completed;
-		if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb))
+		if (!usbin_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 			u->flags |= FLG_URB1RUNNING;
 		else
 			u->flags &= ~FLG_RUNNING;
@@ -1083,7 +1083,7 @@
 			urb->context = as;
 			urb->complete = usbin_sync_completed;
 			/* stride: u->syncinterval */
-			if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb))
+			if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 				u->flags |= FLG_SYNC0RUNNING;
 			else
 				u->flags &= ~FLG_RUNNING;
@@ -1097,7 +1097,7 @@
 			urb->context = as;
 			urb->complete = usbin_sync_completed;
 			/* stride: u->syncinterval */
-			if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb))
+			if (!usbin_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 				u->flags |= FLG_SYNC1RUNNING;
 			else
 				u->flags &= ~FLG_RUNNING;
@@ -1275,7 +1275,7 @@
 	if (!usbout_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbout_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == 0) {
+	    (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -1347,7 +1347,7 @@
 	if (!usbout_sync_retire_desc(u, urb) &&
 	    u->flags & FLG_RUNNING &&
 	    !usbout_sync_prepare_desc(u, urb) && 
-	    (suret = usb_submit_urb(urb)) == 0) {
+	    (suret = usb_submit_urb(urb, GFP_KERNEL)) == 0) {
 		u->flags |= mask;
 	} else {
 		u->flags &= ~(mask | FLG_RUNNING);
@@ -1420,7 +1420,7 @@
 		urb->number_of_packets = DESCFRAMES;
 		urb->context = as;
 		urb->complete = usbout_completed;
-		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb))
+		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 			u->flags |= FLG_URB0RUNNING;
 		else
 			u->flags &= ~FLG_RUNNING;
@@ -1433,7 +1433,7 @@
 		urb->number_of_packets = DESCFRAMES;
 		urb->context = as;
 		urb->complete = usbout_completed;
-		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb))
+		if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 			u->flags |= FLG_URB1RUNNING;
 		else
 			u->flags &= ~FLG_RUNNING;
@@ -1448,7 +1448,7 @@
 			urb->context = as;
 			urb->complete = usbout_sync_completed;
 			/* stride: u->syncinterval */
-			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb))
+			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 				u->flags |= FLG_SYNC0RUNNING;
 			else
 				u->flags &= ~FLG_RUNNING;
@@ -1462,7 +1462,7 @@
 			urb->context = as;
 			urb->complete = usbout_sync_completed;
 			/* stride: u->syncinterval */
-			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb))
+			if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL))
 				u->flags |= FLG_SYNC1RUNNING;
 			else
 				u->flags &= ~FLG_RUNNING;
diff -urN linux-2.5.4-pre1/drivers/usb/auerswald.c linux/drivers/usb/auerswald.c
--- linux-2.5.4-pre1/drivers/usb/auerswald.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/auerswald.c	Wed Feb  6 22:51:47 2002
@@ -49,7 +49,7 @@
 
 /*-------------------------------------------------------------------*/
 /* Version Information */
-#define DRIVER_VERSION "0.9.9"
+#define DRIVER_VERSION "0.9.11"
 #define DRIVER_AUTHOR  "Wolfgang Mües <wmues@nexgo.de>"
 #define DRIVER_DESC    "Auerswald PBX/System Telephone usb driver"
 
@@ -191,6 +191,13 @@
         struct list_head free_list;     /* list of available elements */
 } auerchain_t,*pauerchain_t;
 
+/* urb blocking completion helper struct */
+typedef struct
+{
+	wait_queue_head_t wqh;    	/* wait for completion */
+	unsigned int done;		/* completion flag */
+} auerchain_chs_t,*pauerchain_chs_t;
+
 /* ...................................................................*/
 /* buffer element */
 struct  auerbufctl;                     /* forward */
@@ -330,7 +337,7 @@
                 urb    = acep->urbp;
                 dbg ("auerchain_complete: submitting next urb from chain");
 		urb->status = 0;	/* needed! */
-		result = usb_submit_urb( urb);
+		result = usb_submit_urb(urb, GFP_KERNEL);
 
                 /* check for submit errors */
                 if (result) {
@@ -408,7 +415,7 @@
         if (acep) {
                 dbg("submitting urb immediate");
 		urb->status = 0;	/* needed! */
-                result = usb_submit_urb( urb);
+                result = usb_submit_urb(urb, GFP_KERNEL);
                 /* check for submit errors */
                 if (result) {
                         urb->status = result;
@@ -600,8 +607,10 @@
 /* completion handler for synchronous chained URBs */
 static void auerchain_blocking_completion (struct urb *urb)
 {
-	wait_queue_head_t *wakeup = (wait_queue_head_t *)urb->context;
-	wake_up (wakeup);
+	pauerchain_chs_t pchs = (pauerchain_chs_t)urb->context;
+	pchs->done = 1;
+	wmb();
+	wake_up (&pchs->wqh);
 }
 
 
@@ -609,36 +618,43 @@
 static int auerchain_start_wait_urb (pauerchain_t acp, struct urb *urb, int timeout, int* actual_length)
 {
 	DECLARE_WAITQUEUE (wait, current);
-	DECLARE_WAIT_QUEUE_HEAD (wqh);
+	auerchain_chs_t chs;
 	int status;
 
 	dbg ("auerchain_start_wait_urb called");
-	init_waitqueue_head (&wqh);
-	current->state = TASK_INTERRUPTIBLE;
-	add_wait_queue (&wqh, &wait);
-	urb->context = &wqh;
-	status = auerchain_submit_urb ( acp, urb);
+	init_waitqueue_head (&chs.wqh);
+	chs.done = 0;
+
+	set_current_state (TASK_UNINTERRUPTIBLE);
+	add_wait_queue (&chs.wqh, &wait);
+	urb->context = &chs;
+	status = auerchain_submit_urb (acp, urb);
 	if (status) {
 		/* something went wrong */
-		current->state = TASK_RUNNING;
-		remove_wait_queue (&wqh, &wait);
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&chs.wqh, &wait);
 		return status;
 	}
 
-	if (urb->status == -EINPROGRESS) {
-		while (timeout && urb->status == -EINPROGRESS)
-			status = timeout = schedule_timeout (timeout);
-	} else
-		status = 1;
-
-	current->state = TASK_RUNNING;
-	remove_wait_queue (&wqh, &wait);
+	while (timeout && !chs.done)
+	{
+		timeout = schedule_timeout (timeout);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		rmb();
+	}
 
-	if (!status) {
-		/* timeout */
-		dbg ("auerchain_start_wait_urb: timeout");
-		auerchain_unlink_urb (acp, urb);  /* remove urb safely */
-		status = -ETIMEDOUT;
+	set_current_state (TASK_RUNNING);
+	remove_wait_queue (&chs.wqh, &wait);
+
+	if (!timeout && !chs.done) {
+		if (urb->status != -EINPROGRESS) {	/* No callback?!! */
+			dbg ("auerchain_start_wait_urb: raced timeout");
+			status = urb->status;
+		} else {
+			dbg ("auerchain_start_wait_urb: timeout");
+			auerchain_unlink_urb (acp, urb);  /* remove urb safely */
+			status = -ETIMEDOUT;
+		}
 	} else
 		status = urb->status;
 
@@ -932,6 +948,8 @@
 			/* reuse the buffer */
 			err ("control read: transmission error %d, can not retry", urb->status);
 			auerbuf_releasebuf (bp);
+			/* Wake up all processes waiting for a buffer */
+			wake_up (&cp->bufferwait);
 			return;
 		}
 		bp->retries++;
@@ -1128,7 +1146,7 @@
         FILL_INT_URB (cp->inturbp, cp->usbdev, usb_rcvintpipe (cp->usbdev,AU_IRQENDP), cp->intbufp, irqsize, auerswald_int_complete, cp, ep->bInterval);
         /* start the urb */
 	cp->inturbp->status = 0;	/* needed! */
-	ret = usb_submit_urb (cp->inturbp);
+	ret = usb_submit_urb (cp->inturbp, GFP_KERNEL);
 
 intoend:
         if (ret < 0) {
@@ -1376,9 +1394,6 @@
 	}
 	up (&dev_table_mutex);
 
-	/* prevent module unloading */
-	MOD_INC_USE_COUNT;
-
 	/* we have access to the device. Now lets allocate memory */
 	ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL);
 	if (ccp == NULL) {
@@ -1415,7 +1430,6 @@
 	/* Error exit */
 ofail:	up (&cp->mutex);
 	auerchar_delete (ccp);
-  	MOD_DEC_USE_COUNT;
 	return ret;
 }
 
@@ -1553,21 +1567,14 @@
 	return ret;
 }
 
-
-/* Seek is not supported */
-static loff_t auerchar_llseek (struct file *file, loff_t offset, int origin)
-{
-        dbg ("auerchar_seek");
-        return -ESPIPE;
-}
-
-
 /* Read data from the device */
 static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t * ppos)
 {
         unsigned long flags;
 	pauerchar_t ccp = (pauerchar_t) file->private_data;
         pauerbuf_t   bp = NULL;
+	wait_queue_t wait;
+
         dbg ("auerchar_read");
 
 	/* Error checking */
@@ -1630,6 +1637,11 @@
 
 	/* a read buffer is not available. Try to get the next data block. */
 doreadlist:
+	/* Preparing for sleep */
+	init_waitqueue_entry (&wait, current);
+	set_current_state (TASK_INTERRUPTIBLE);
+	add_wait_queue (&ccp->readwait, &wait);
+
 	bp = NULL;
 	spin_lock_irqsave (&ccp->bufctl.lock, flags);
         if (!list_empty (&ccp->bufctl.rec_buff_list)) {
@@ -1644,20 +1656,25 @@
 	if (bp) {
 		ccp->readbuf = bp;
 		ccp->readoffset = AUH_SIZE; /* for headerbyte */
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&ccp->readwait, &wait);
 		goto doreadbuf;		  /* now we can read! */
 	}
 
 	/* no data available. Should we wait? */
 	if (file->f_flags & O_NONBLOCK) {
                 dbg ("No read buffer available, returning -EAGAIN");
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&ccp->readwait, &wait);
 		up (&ccp->readmutex);
 		up (&ccp->mutex);
-                return -EAGAIN;  /* nonblocking, no data available */
+		return -EAGAIN;  /* nonblocking, no data available */
         }
 
 	/* yes, we should wait! */
 	up (&ccp->mutex); /* allow other operations while we wait */
-	interruptible_sleep_on (&ccp->readwait);
+	schedule();
+	remove_wait_queue (&ccp->readwait, &wait);
 	if (signal_pending (current)) {
 		/* waked up by a signal */
 		up (&ccp->readmutex);
@@ -1688,6 +1705,7 @@
         pauerbuf_t bp;
         unsigned long flags;
 	int ret;
+	wait_queue_t wait;
 
         dbg ("auerchar_write %d bytes", len);
 
@@ -1724,6 +1742,11 @@
 		up (&ccp->mutex);
 		return -EIO;
 	}
+	/* Prepare for sleep */
+	init_waitqueue_entry (&wait, current);
+	set_current_state (TASK_INTERRUPTIBLE);
+	add_wait_queue (&cp->bufferwait, &wait);
+
 	/* Try to get a buffer from the device pool.
 	   We can't use a buffer from ccp->bufctl because the write
 	   command will last beond a release() */
@@ -1744,16 +1767,22 @@
 
 		/* NONBLOCK: don't wait */
 		if (file->f_flags & O_NONBLOCK) {
+			set_current_state (TASK_RUNNING);
+			remove_wait_queue (&cp->bufferwait, &wait);
 			return -EAGAIN;
 		}
 
 		/* BLOCKING: wait */
-		interruptible_sleep_on (&cp->bufferwait);
+		schedule();
+		remove_wait_queue (&cp->bufferwait, &wait);
 		if (signal_pending (current)) {
 			/* waked up by a signal */
 			return -ERESTARTSYS;
 		}
 		goto write_again;
+	} else {
+		set_current_state (TASK_RUNNING);
+		remove_wait_queue (&cp->bufferwait, &wait);
 	}
 
 	/* protect against too big write requests */
@@ -1763,6 +1792,8 @@
 	if (copy_from_user ( bp->bufp+AUH_SIZE, buf, len)) {
 		dbg ("copy_from_user failed");
 		auerbuf_releasebuf (bp);
+		/* Wake up all processes waiting for a buffer */
+		wake_up (&cp->bufferwait);
 		up (&cp->mutex);
 		up (&ccp->mutex);
 		return -EIO;
@@ -1787,6 +1818,8 @@
 	if (ret) {
 		dbg ("auerchar_write: nonzero result of auerchain_submit_urb %d", ret);
 		auerbuf_releasebuf (bp);
+		/* Wake up all processes waiting for a buffer */
+		wake_up (&cp->bufferwait);
 		up (&ccp->mutex);
 		return -EIO;
 	}
@@ -1831,9 +1864,6 @@
 	up (&ccp->mutex);
 	auerchar_delete (ccp);
 
-	/* release the module */
-	MOD_DEC_USE_COUNT;
-
 	return 0;
 }
 
@@ -1843,7 +1873,7 @@
 static struct file_operations auerswald_fops =
 {
 	owner:		THIS_MODULE,
-	llseek:		auerchar_llseek,
+	llseek:		no_llseek,
 	read:		auerchar_read,
 	write:          auerchar_write,
 	ioctl:		auerchar_ioctl,
@@ -2154,3 +2184,4 @@
 module_exit (auerswald_cleanup);
 
 /* --------------------------------------------------------------------- */
+
diff -urN linux-2.5.4-pre1/drivers/usb/bluetooth.c linux/drivers/usb/bluetooth.c
--- linux-2.5.4-pre1/drivers/usb/bluetooth.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/bluetooth.c	Wed Feb  6 22:51:47 2002
@@ -335,7 +335,7 @@
 			  (unsigned char*)dr, urb->transfer_buffer, len, bluetooth_ctrl_callback, bluetooth);
 
 	/* send it down the pipe */
-	status = usb_submit_urb(urb);
+	status = usb_submit_urb(urb, GFP_KERNEL);
 	if (status)
 		dbg(__FUNCTION__ " - usb_submit_urb(control) failed with status = %d", status);
 	
@@ -390,7 +390,7 @@
 			       bluetooth->bulk_in_buffer,
 			       bluetooth->bulk_in_buffer_size,
 			       bluetooth_read_bulk_callback, bluetooth);
-		result = usb_submit_urb(bluetooth->read_urb);
+		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
 		if (result)
 			dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed with status %d", result);
 #endif
@@ -400,7 +400,7 @@
 			      bluetooth->interrupt_in_buffer_size,
 			      bluetooth_int_callback, bluetooth,
 			      bluetooth->interrupt_in_interval);
-		result = usb_submit_urb(bluetooth->interrupt_in_urb);
+		result = usb_submit_urb(bluetooth->interrupt_in_urb, GFP_KERNEL);
 		if (result)
 			dbg(__FUNCTION__ " - usb_submit_urb(interrupt in) failed with status %d", result);
 	}
@@ -540,7 +540,7 @@
 				urb->transfer_flags |= USB_QUEUE_BULK;
 
 				/* send it down the pipe */
-				retval = usb_submit_urb(urb);
+				retval = usb_submit_urb(urb, GFP_KERNEL);
 				if (retval) {
 					dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with error = %d", retval);
 					goto exit;
@@ -730,7 +730,7 @@
 			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
 			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
 			      bluetooth_read_bulk_callback, bluetooth);
-		result = usb_submit_urb(bluetooth->read_urb);
+		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
 		if (result)
 			err (__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
@@ -921,7 +921,7 @@
 			      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
 			      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
 			      bluetooth_read_bulk_callback, bluetooth);
-		result = usb_submit_urb(bluetooth->read_urb);
+		result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
 		if (result)
 			err (__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 
@@ -982,7 +982,7 @@
 		      usb_rcvbulkpipe(bluetooth->dev, bluetooth->bulk_in_endpointAddress),
 		      bluetooth->bulk_in_buffer, bluetooth->bulk_in_buffer_size, 
 		      bluetooth_read_bulk_callback, bluetooth);
-	result = usb_submit_urb(bluetooth->read_urb);
+	result = usb_submit_urb(bluetooth->read_urb, GFP_KERNEL);
 	if (result)
 		err (__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 
diff -urN linux-2.5.4-pre1/drivers/usb/catc.c linux/drivers/usb/catc.c
--- linux-2.5.4-pre1/drivers/usb/catc.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/catc.c	Wed Feb  6 22:51:47 2002
@@ -257,7 +257,7 @@
 
 	if ((data[1] & 0x80) && !test_and_set_bit(RX_RUNNING, &catc->flags)) {
 		catc->rx_urb->dev = catc->usbdev;
-		if ((status = usb_submit_urb(catc->rx_urb)) < 0) {
+		if ((status = usb_submit_urb(catc->rx_urb, GFP_KERNEL)) < 0) {
 			err("submit(rx_urb) status %d", status);
 			return;
 		} 
@@ -286,7 +286,7 @@
 	catc->tx_urb->transfer_buffer = catc->tx_buf[catc->tx_idx];
 	catc->tx_urb->dev = catc->usbdev;
 
-	if ((status = usb_submit_urb(catc->tx_urb)) < 0)
+	if ((status = usb_submit_urb(catc->tx_urb, GFP_KERNEL)) < 0)
 		err("submit(tx_urb), status %d", status);
 
 	catc->tx_idx = !catc->tx_idx;
@@ -402,7 +402,7 @@
 	if (!q->dir && q->buf && q->len)
 		memcpy(catc->ctrl_buf, q->buf, q->len);
 
-	if ((status = usb_submit_urb(catc->ctrl_urb)))
+	if ((status = usb_submit_urb(catc->ctrl_urb, GFP_KERNEL)))
 		err("submit(ctrl_urb) status %d", status);
 }
 
@@ -625,7 +625,7 @@
 	int status;
 
 	catc->irq_urb->dev = catc->usbdev;
-	if ((status = usb_submit_urb(catc->irq_urb)) < 0) {
+	if ((status = usb_submit_urb(catc->irq_urb, GFP_KERNEL)) < 0) {
 		err("submit(irq_urb) status %d", status);
 		return -1;
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/dabusb.c linux/drivers/usb/dabusb.c
--- linux-2.5.4-pre1/drivers/usb/dabusb.c	Thu Jan  3 12:20:16 2002
+++ linux/drivers/usb/dabusb.c	Wed Feb  6 22:51:47 2002
@@ -458,7 +458,7 @@
 
 			end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);
 
-			ret = usb_submit_urb (end->purb);
+			ret = usb_submit_urb (end->purb, GFP_KERNEL);
 			if (ret) {
 				err("usb_submit_urb returned:%d", ret);
 				if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
diff -urN linux-2.5.4-pre1/drivers/usb/devices.c linux/drivers/usb/devices.c
--- linux-2.5.4-pre1/drivers/usb/devices.c	Sat Dec  8 20:25:02 2001
+++ linux/drivers/usb/devices.c	Wed Feb  6 22:51:47 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->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 = {
diff -urN linux-2.5.4-pre1/drivers/usb/devio.c linux/drivers/usb/devio.c
--- linux-2.5.4-pre1/drivers/usb/devio.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/devio.c	Wed Feb  6 22:51:47 2002
@@ -58,21 +58,26 @@
 
 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)
@@ -364,7 +369,7 @@
 	if (test_bit(intf, &ps->ifclaimed))
 		return 0;
 	/* if not yet claimed, claim it for the driver */
-	printk(KERN_WARNING "usbdevfs: process %d (%s) did not claim interface %u before use\n",
+	printk(KERN_WARNING "usbfs: process %d (%s) did not claim interface %u before use\n",
 	       current->pid, current->comm, intf);
 	return claimintf(ps, intf);
 }
@@ -563,7 +568,7 @@
 	}
 	free_page((unsigned long)tbuf);
 	if (i<0) {
-		printk(KERN_DEBUG "usbdevfs: USBDEVFS_CONTROL failed dev %d rqt %u rq %u len %u ret %d\n", 
+		printk(KERN_DEBUG "usbfs: USBDEVFS_CONTROL failed dev %d rqt %u rq %u len %u ret %d\n", 
 		       dev->devnum, ctrl.bRequestType, ctrl.bRequest, ctrl.wLength, i);
 	}
 	return i;
@@ -619,7 +624,7 @@
 	}
 	free_page((unsigned long)tbuf);
 	if (i < 0) {
-		printk(KERN_WARNING "usbdevfs: USBDEVFS_BULK failed dev %d ep 0x%x len %u ret %d\n", 
+		printk(KERN_WARNING "usbfs: USBDEVFS_BULK failed dev %d ep 0x%x len %u ret %d\n", 
 		       dev->devnum, bulk.ep, bulk.len, i);
 		return i;
 	}
@@ -906,8 +911,8 @@
 		}
 	}
         async_newpending(as);
-        if ((ret = usb_submit_urb(as->urb))) {
-		printk(KERN_DEBUG "usbdevfs: usb_submit_urb returned %d\n", ret);
+        if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) {
+		printk(KERN_DEBUG "usbfs: usb_submit_urb returned %d\n", ret);
                 async_removepending(as);
                 free_async(as);
                 return ret;
diff -urN linux-2.5.4-pre1/drivers/usb/drivers.c linux/drivers/usb/drivers.c
--- linux-2.5.4-pre1/drivers/usb/drivers.c	Wed Apr 26 15:22:55 2000
+++ linux/drivers/usb/drivers.c	Wed Feb  6 22:51:47 2002
@@ -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 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 = {
diff -urN linux-2.5.4-pre1/drivers/usb/hcd.c linux/drivers/usb/hcd.c
--- linux-2.5.4-pre1/drivers/usb/hcd.c	Tue Jan 29 13:52:28 2002
+++ linux/drivers/usb/hcd.c	Wed Feb  6 22:51:47 2002
@@ -916,14 +916,13 @@
 /* may be called in any context with a valid urb->dev usecount */
 /* caller surrenders "ownership" of urb (and chain at urb->next).  */
 
-static int hcd_submit_urb (struct urb *urb)
+static int hcd_submit_urb (struct urb *urb, int mem_flags)
 {
 	int			status;
 	struct usb_hcd		*hcd;
 	struct hcd_dev		*dev;
 	unsigned long		flags;
 	int			pipe;
-	int			mem_flags;
 
 	if (!urb || urb->hcpriv || !urb->complete)
 		return -EINVAL;
@@ -947,11 +946,6 @@
 			usb_pipeout (pipe)))
 		return -EPIPE;
 
-	// FIXME paging/swapping requests over USB should not use GFP_KERNEL
-	// and might even need to use GFP_NOIO ... that flag actually needs
-	// to be passed from the higher level.
-	mem_flags = in_interrupt () ? GFP_ATOMIC : GFP_KERNEL;
-
 #ifdef DEBUG
 	{
 	unsigned int	orig_flags = urb->transfer_flags;
@@ -1316,7 +1310,7 @@
 	else if (urb->next) {
 		int 	status;
 
-		status = usb_submit_urb (urb->next);
+		status = usb_submit_urb (urb->next, GFP_ATOMIC);
 		if (status) {
 			dbg ("urb %p chain fail, %d", urb->next, status);
 			urb->next->status = -ENOTCONN;
diff -urN linux-2.5.4-pre1/drivers/usb/hid-core.c linux/drivers/usb/hid-core.c
--- linux-2.5.4-pre1/drivers/usb/hid-core.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/hid-core.c	Wed Feb  6 22:51:47 2002
@@ -992,7 +992,7 @@
 	hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr);
 	hid->urbout.dev = hid->dev;
 
-	if (usb_submit_urb(&hid->urbout)) {
+	if (usb_submit_urb(&hid->urbout, GFP_KERNEL)) {
 		err("usb_submit_urb(out) failed");
 		return -1;
 	}
@@ -1036,7 +1036,7 @@
 
 	hid->urb.dev = hid->dev;
 
-	if (usb_submit_urb(&hid->urb))
+	if (usb_submit_urb(&hid->urb, GFP_KERNEL))
 		return -EIO;
 
 	return 0;
diff -urN linux-2.5.4-pre1/drivers/usb/hpusbscsi.c linux/drivers/usb/hpusbscsi.c
--- linux-2.5.4-pre1/drivers/usb/hpusbscsi.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/hpusbscsi.c	Wed Feb  6 22:51:47 2002
@@ -245,7 +245,7 @@
 			desc->interrupt_interval
 	);
 
-	if ( 0  >  usb_submit_urb(desc->controlurb)) {
+	if ( 0  >  usb_submit_urb(desc->controlurb, GFP_KERNEL)) {
 		kfree(sht->proc_name);
 		return 0;
 	}
@@ -321,7 +321,7 @@
 	hpusbscsi->scallback = callback;
 	hpusbscsi->srb = srb;
 
-	res = usb_submit_urb(hpusbscsi->dataurb);
+	res = usb_submit_urb(hpusbscsi->dataurb, GFP_ATOMIC);
 	if (unlikely(res)) {
 		hpusbscsi->state = HP_STATE_FREE;
 		TRACE_STATE;
@@ -460,7 +460,7 @@
                 hpusbscsi
         );
 
-        res = usb_submit_urb(u);
+        res = usb_submit_urb(u, GFP_ATOMIC);
         if (unlikely(res))
                 hpusbscsi->state = HP_STATE_ERROR;
 	TRACE_STATE;
@@ -509,7 +509,7 @@
 		hpusbscsi
 	);
 
-	res = usb_submit_urb(u);
+	res = usb_submit_urb(u, GFP_ATOMIC);
 	if (unlikely(res)) {
                 handle_usb_error(hpusbscsi);
 		return;
diff -urN linux-2.5.4-pre1/drivers/usb/hub.c linux/drivers/usb/hub.c
--- linux-2.5.4-pre1/drivers/usb/hub.c	Thu Jan 17 14:06:53 2002
+++ linux/drivers/usb/hub.c	Wed Feb  6 22:51:47 2002
@@ -312,7 +312,7 @@
 
 	FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
-	ret = usb_submit_urb(hub->urb);
+	ret = usb_submit_urb(hub->urb, GFP_KERNEL);
 	if (ret) {
 		err("usb_submit_urb failed (%d)", ret);
 		kfree(hub->descriptor);
@@ -498,7 +498,7 @@
 		return -1;
 
 	hub->urb->dev = dev;                                                    
-	if (usb_submit_urb(hub->urb))
+	if (usb_submit_urb(hub->urb, GFP_KERNEL))
 		return -1;
 
 	usb_hub_power_on(hub);
diff -urN linux-2.5.4-pre1/drivers/usb/ibmcam.c linux/drivers/usb/ibmcam.c
--- linux-2.5.4-pre1/drivers/usb/ibmcam.c	Fri Oct  5 12:04:51 2001
+++ linux/drivers/usb/ibmcam.c	Wed Feb  6 22:51:47 2002
@@ -1,7 +1,8 @@
 /*
  * USB IBM C-It Video Camera driver
  *
- * Supports IBM C-It Video Camera.
+ * Supports Xirlink C-It Video Camera, IBM PC Camera,
+ * IBM NetCamera and Veo Stingray.
  *
  * This driver is based on earlier work of:
  *
@@ -33,9 +34,11 @@
 
 #include "usbvideo.h"
 
-#define	IBMCAM_VENDOR_ID	0x0545
-#define	IBMCAM_PRODUCT_ID	0x8080
+#define IBMCAM_VENDOR_ID	0x0545
+#define IBMCAM_PRODUCT_ID	0x8080
 #define NETCAM_PRODUCT_ID	0x8002	/* IBM NetCamera, close to model 2 */
+#define VEO_800C_PRODUCT_ID	0x800C	/* Veo Stingray, repackaged Model 2 */
+#define VEO_800D_PRODUCT_ID	0x800D	/* Veo Stingray, repackaged Model 4 */
 
 #define MAX_IBMCAM		4	/* How many devices we allow to connect */
 #define USES_IBMCAM_PUTPIXEL    0       /* 0=Fast/oops 1=Slow/secure */
@@ -3671,6 +3674,8 @@
 	if (dev->descriptor.idVendor != IBMCAM_VENDOR_ID)
 		return NULL;
 	if ((dev->descriptor.idProduct != IBMCAM_PRODUCT_ID) &&
+	    (dev->descriptor.idProduct != VEO_800C_PRODUCT_ID) &&
+	    (dev->descriptor.idProduct != VEO_800D_PRODUCT_ID) &&
 	    (dev->descriptor.idProduct != NETCAM_PRODUCT_ID))
 		return NULL;
 
@@ -3684,7 +3689,8 @@
 	case 0x030A:
 		if (ifnum != 0)
 			return NULL;
-		if (dev->descriptor.idProduct == NETCAM_PRODUCT_ID)
+		if ((dev->descriptor.idProduct == NETCAM_PRODUCT_ID) ||
+		    (dev->descriptor.idProduct == VEO_800D_PRODUCT_ID))
 			model = IBMCAM_MODEL_4;
 		else
 			model = IBMCAM_MODEL_2;
@@ -3699,8 +3705,28 @@
 			dev->descriptor.bcdDevice);
 		return NULL;
 	}
-	info("IBM USB camera found (model %d, rev. 0x%04x)",
-		model, dev->descriptor.bcdDevice);
+
+	/* Print detailed info on what we found so far */
+	do {
+		char *brand = NULL;
+		switch (dev->descriptor.idProduct) {
+		case NETCAM_PRODUCT_ID:
+			brand = "IBM NetCamera";
+			break;
+		case VEO_800C_PRODUCT_ID:
+			brand = "Veo Stingray [800C]";
+			break;
+		case VEO_800D_PRODUCT_ID:
+			brand = "Veo Stingray [800D]";
+			break;
+		case IBMCAM_PRODUCT_ID:
+		default:
+			brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */
+			break;
+		}
+		info("%s USB camera found (model %d, rev. 0x%04x)",
+		     brand, model, dev->descriptor.bcdDevice);
+	} while (0);
 
 	/* Validate found interface: must have one ISO endpoint */
 	nas = dev->actconfig->interface[ifnum].num_altsetting;
@@ -3908,18 +3934,16 @@
 	usbvideo_Deregister(&cams);
 }
 
-#if defined(usb_device_id_ver)
-
 static __devinitdata struct usb_device_id id_table[] = {
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0002, 0x0002) },	/* Model 1 */
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 2 */
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, IBMCAM_PRODUCT_ID, 0x0301, 0x0301) },	/* Model 3 */
 	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, NETCAM_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 4 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800C_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 2 */
+	{ USB_DEVICE_VER(IBMCAM_VENDOR_ID, VEO_800D_PRODUCT_ID, 0x030a, 0x030a) },	/* Model 4 */
 	{ }  /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
-
-#endif /* defined(usb_device_id_ver) */
 
 module_init(ibmcam_init);
 module_exit(ibmcam_cleanup);
diff -urN linux-2.5.4-pre1/drivers/usb/inode.c linux/drivers/usb/inode.c
--- linux-2.5.4-pre1/drivers/usb/inode.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/inode.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 {
 	loff_t retval = -EINVAL;
 
+	lock_kernel();
 	switch(orig) {
 	case 0:
 		if (offset > 0) {
@@ -311,6 +312,7 @@
 	default:
 		break;
 	}
+	unlock_kernel();
 	return retval;
 }
 
@@ -362,15 +364,14 @@
 	put_inode:	force_delete,
 };
 
-static struct super_block *usbfs_read_super (struct super_block *sb, void *data, 
-					     int silent)
+static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
 
 	if (parse_options(sb, data)) {
 		warn("usbfs: mount parameter error:");
-		return NULL;
+		return -EINVAL;
 	}
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -381,17 +382,17 @@
 
 	if (!inode) {
 		dbg("%s: could not get inode!\n",__FUNCTION__);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	root = d_alloc_root(inode);
 	if (!root) {
 		dbg("%s: could not get root dentry!\n",__FUNCTION__);
 		iput(inode);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root = root;
-	return sb;
+	return 0;
 }
 
 /**
@@ -520,8 +521,24 @@
  * It will be removed when the 2.7.x development cycle is started.
  * You have been warned :)
  */
-static DECLARE_FSTYPE(usbdevice_fs_type, "usbdevfs", usbfs_read_super, FS_SINGLE);
-static DECLARE_FSTYPE(usb_fs_type,       "usbfs",    usbfs_read_super, FS_SINGLE);
+
+static struct super_block *usb_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, usb_fill_super);
+}
+
+static struct file_system_type usbdevice_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"usbdevfs",
+	get_sb:		usb_get_sb,
+};
+
+static struct file_system_type usb_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"usbfs",
+	get_sb:		usb_get_sb,
+};
 
 /* --------------------------------------------------------------------- */
 static int get_mount (void)
diff -urN linux-2.5.4-pre1/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c
--- linux-2.5.4-pre1/drivers/usb/kaweth.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/usb/kaweth.c	Wed Feb  6 22:51:47 2002
@@ -447,7 +447,8 @@
 /****************************************************************
  *     kaweth_resubmit_rx_urb
  ****************************************************************/
-static inline void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth)
+static inline void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
+						int mem_flags)
 {
 	int result;
 
@@ -461,7 +462,7 @@
 		      kaweth_usb_receive,
 		      kaweth);
 
-	if((result = usb_submit_urb(kaweth->rx_urb))) {
+	if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {
 		kaweth_err("resubmitting rx_urb %d failed", result);
 	}
 }
@@ -493,7 +494,7 @@
 			   urb->status,
 			   count, 
 			   (int)pkt_len);
-		kaweth_resubmit_rx_urb(kaweth);
+		kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
                 return;
 	}
 
@@ -502,12 +503,12 @@
 			kaweth_err("Packet length too long for USB frame (pkt_len: %x, count: %x)",pkt_len, count);
 			kaweth_err("Packet len & 2047: %x", pkt_len & 2047);
 			kaweth_err("Count 2: %x", count2);
-		        kaweth_resubmit_rx_urb(kaweth);
+		        kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
                         return;
                 }
 		
 		if(!(skb = dev_alloc_skb(pkt_len+2))) {
-		        kaweth_resubmit_rx_urb(kaweth);
+		        kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
                         return;
 		}
 
@@ -525,7 +526,7 @@
 		kaweth->stats.rx_bytes += pkt_len;
 	}
 
-	kaweth_resubmit_rx_urb(kaweth);
+	kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
 }
 
 /****************************************************************
@@ -539,11 +540,11 @@
 
 	kaweth_dbg("Opening network device.");
 
-	kaweth_resubmit_rx_urb(kaweth);
+	MOD_INC_USE_COUNT;
 
-	netif_start_queue(net);
+	kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL);
 
-	MOD_INC_USE_COUNT;
+	netif_start_queue(net);
 
 	kaweth_async_set_rx_mode(kaweth);
 	return 0;
@@ -621,7 +622,7 @@
 		      kaweth_usb_transmit_complete,
 		      kaweth);
 
-	if((res = usb_submit_urb(kaweth->tx_urb)))
+	if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
 	{
 		kaweth_warn("kaweth failed tx_urb %d", res);
 		kaweth->stats.tx_errors++;
@@ -975,7 +976,7 @@
         set_current_state(TASK_INTERRUPTIBLE);
         add_wait_queue(&awd.wqh, &wait);
         urb->context = &awd;
-        status = usb_submit_urb(urb);
+        status = usb_submit_urb(urb, GFP_KERNEL);
         if (status) {
                 // something went wrong
                 usb_free_urb(urb);
diff -urN linux-2.5.4-pre1/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c
--- linux-2.5.4-pre1/drivers/usb/mdc800.c	Tue Jan  1 13:52:10 2002
+++ linux/drivers/usb/mdc800.c	Wed Feb  6 22:51:47 2002
@@ -605,7 +605,7 @@
 
 	retval=0;
 	mdc800->irq_urb->dev = mdc800->dev;
-	if (usb_submit_urb (mdc800->irq_urb))
+	if (usb_submit_urb (mdc800->irq_urb, GFP_KERNEL))
 	{
 		err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status);
 		errn = -EIO;
@@ -694,7 +694,7 @@
 
 				/* Download -> Request new bytes */
 				mdc800->download_urb->dev = mdc800->dev;
-				if (usb_submit_urb (mdc800->download_urb))
+				if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL))
 				{
 					err ("Can't submit download urb (status=%i)",mdc800->download_urb->status);
 					up (&mdc800->io_lock);
@@ -808,7 +808,7 @@
 			mdc800->state=WORKING;
 			memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8);
 			mdc800->write_urb->dev = mdc800->dev;
-			if (usb_submit_urb (mdc800->write_urb))
+			if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL))
 			{
 				err ("submitting write urb fails (status=%i)", mdc800->write_urb->status);
 				up (&mdc800->io_lock);
diff -urN linux-2.5.4-pre1/drivers/usb/microtek.c linux/drivers/usb/microtek.c
--- linux-2.5.4-pre1/drivers/usb/microtek.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/microtek.c	Wed Feb  6 22:51:47 2002
@@ -499,7 +499,7 @@
 
 	transfer->status = 0;
 
-	res = usb_submit_urb( transfer );
+	res = usb_submit_urb( transfer, GFP_ATOMIC );
 	if ( unlikely(res) ) {
 		MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res );
 		context->srb->result = DID_ERROR << 16;
@@ -719,7 +719,8 @@
 	mts_build_transfer_context( srb, desc );
 	desc->context.final_callback = callback;
 	
-	res=usb_submit_urb(desc->urb);
+	/* here we need ATOMIC as we are called with the iolock */
+	res=usb_submit_urb(desc->urb, GFP_ATOMIC);
 
 	if(unlikely(res)){
 		MTS_ERROR("error %d submitting URB\n",(int)res);
diff -urN linux-2.5.4-pre1/drivers/usb/ov511.c linux/drivers/usb/ov511.c
--- linux-2.5.4-pre1/drivers/usb/ov511.c	Tue Jan 29 13:52:28 2002
+++ linux/drivers/usb/ov511.c	Wed Feb  6 22:51:47 2002
@@ -4457,7 +4457,7 @@
 
 	for (n = 0; n < OV511_NUMSBUF; n++) {
 		ov511->sbuf[n].urb->dev = ov511->dev;
-		err = usb_submit_urb(ov511->sbuf[n].urb);
+		err = usb_submit_urb(ov511->sbuf[n].urb, GFP_KERNEL);
 		if (err)
 			err("init isoc: usb_submit_urb(%d) ret %d", n, err);
 	}
@@ -5618,7 +5618,7 @@
 	void *arg = (void *) ularg;
 	int rc;
 
-	pde = (struct proc_dir_entry *) inode->u.generic_ip;
+	pde = PDE(inode);
 	if (!pde)
 		return -ENOENT;
 
diff -urN linux-2.5.4-pre1/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
--- linux-2.5.4-pre1/drivers/usb/pegasus.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/usb/pegasus.c	Wed Feb  6 22:51:47 2002
@@ -157,7 +157,8 @@
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_UNINTERRUPTIBLE );
 
-	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) {
+	/* using ATOMIC, we'd never wake up if we slept */
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) {
 		err("%s: BAD CTRLs %d", __FUNCTION__, ret);
 		goto out;
 	}
@@ -207,7 +208,7 @@
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_UNINTERRUPTIBLE );
 
-	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) {
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) {
 		err("%s: BAD CTRL %d", __FUNCTION__, ret);
 		goto out;
 	}
@@ -257,7 +258,7 @@
 	add_wait_queue( &pegasus->ctrl_wait, &wait );
 	set_current_state( TASK_UNINTERRUPTIBLE );
 
-	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) ) {
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) ) {
 		err("%s: BAD CTRL %d", __FUNCTION__, ret);
 		goto out;
 	}
@@ -287,7 +288,7 @@
 			  (char *)&pegasus->dr,
 			  pegasus->eth_regs, 3, ctrl_callback, pegasus );
 
-	if ( (ret = usb_submit_urb( pegasus->ctrl_urb )) )
+	if ( (ret = usb_submit_urb( pegasus->ctrl_urb, GFP_ATOMIC )) )
 		err("%s: BAD CTRL %d, flgs %x",__FUNCTION__,ret,pegasus->flags);
 
 	return	ret;
@@ -573,7 +574,7 @@
 			usb_rcvbulkpipe(pegasus->usb, 1),
 			pegasus->rx_buff, PEGASUS_MAX_MTU, 
 			read_bulk_callback, pegasus );
-	if ( (res = usb_submit_urb(pegasus->rx_urb)) )
+	if ( (res = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) )
 		warn("%s: failed submint rx_urb %d", __FUNCTION__, res);
 	pegasus->flags &= ~PEGASUS_RX_BUSY;
 }
@@ -661,7 +662,7 @@
 			pegasus->tx_buff, PEGASUS_MAX_MTU, 
 			write_bulk_callback, pegasus );
 	pegasus->tx_urb->transfer_buffer_length = count;
-	if ((res = usb_submit_urb(pegasus->tx_urb))) {
+	if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
 		warn("failed tx_urb %d", res);
 		pegasus->stats.tx_errors++;
 		netif_start_queue( net );
@@ -721,14 +722,14 @@
 			usb_rcvbulkpipe(pegasus->usb, 1),
 			pegasus->rx_buff, PEGASUS_MAX_MTU, 
 			read_bulk_callback, pegasus );
-	if ( (res = usb_submit_urb(pegasus->rx_urb)) )
+	if ( (res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL)) )
 		warn("%s: failed rx_urb %d", __FUNCTION__, res);
 #ifdef	PEGASUS_USE_INTR
 	FILL_INT_URB( pegasus->intr_urb, pegasus->usb,
 			usb_rcvintpipe(pegasus->usb, 3),
 			pegasus->intr_buff, sizeof(pegasus->intr_buff),
 			intr_callback, pegasus, pegasus->intr_interval );
-	if ( (res = usb_submit_urb(pegasus->intr_urb)) )
+	if ( (res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL)) )
 		warn("%s: failed intr_urb %d", __FUNCTION__, res);
 #endif
 	netif_start_queue( net );
diff -urN linux-2.5.4-pre1/drivers/usb/printer.c linux/drivers/usb/printer.c
--- linux-2.5.4-pre1/drivers/usb/printer.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/usb/printer.c	Wed Feb  6 22:51:47 2002
@@ -261,7 +261,7 @@
 	if (usblp->bidir) {
 		usblp->readcount = 0;
 		usblp->readurb.dev = usblp->dev;
-		if (usb_submit_urb(&usblp->readurb) < 0) {
+		if (usb_submit_urb(&usblp->readurb, GFP_KERNEL) < 0) {
 			retval = -EIO;
 			usblp->used = 0;
 			file->private_data = NULL;
@@ -456,7 +456,7 @@
 
 		usblp->writeurb.dev = usblp->dev;
 		usblp->wcomplete = 0;
-		if (usb_submit_urb(&usblp->writeurb)) {
+		if (usb_submit_urb(&usblp->writeurb, GFP_KERNEL)) {
 			count = -EIO;
 			up (&usblp->sem);
 			break;
@@ -521,7 +521,7 @@
 			usblp->minor, usblp->readurb.status);
 		usblp->readurb.dev = usblp->dev;
  		usblp->readcount = 0;
-		usb_submit_urb(&usblp->readurb);
+		usb_submit_urb(&usblp->readurb, GFP_KERNEL);
 		count = -EIO;
 		goto done;
 	}
@@ -538,7 +538,7 @@
 		usblp->readcount = 0;
 		usblp->readurb.dev = usblp->dev;
 		usblp->rcomplete = 0;
-		if (usb_submit_urb(&usblp->readurb)) {
+		if (usb_submit_urb(&usblp->readurb, GFP_KERNEL)) {
 			count = -EIO;
 			goto done;
 		}
diff -urN linux-2.5.4-pre1/drivers/usb/pwc-if.c linux/drivers/usb/pwc-if.c
--- linux-2.5.4-pre1/drivers/usb/pwc-if.c	Tue Jan 15 10:56:35 2002
+++ linux/drivers/usb/pwc-if.c	Wed Feb  6 22:51:47 2002
@@ -869,7 +869,7 @@
 
 	/* link */
 	for (i = 0; i < MAX_ISO_BUFS; i++) {
-		ret = usb_submit_urb(pdev->sbuf[i].urb);
+		ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
 		if (ret)
 			Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
 		else
diff -urN linux-2.5.4-pre1/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- linux-2.5.4-pre1/drivers/usb/scanner.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/scanner.c	Wed Feb  6 22:51:47 2002
@@ -992,7 +992,7 @@
 			     // endpoint[(int)have_intr].bInterval);
 			     250);
 
-	        if (usb_submit_urb(scn->scn_irq)) {
+	        if (usb_submit_urb(scn->scn_irq, GFP_KERNEL)) {
 			err("probe_scanner(%d): Unable to allocate INT URB.", scn_minor);
                 	kfree(scn);
 			up(&scn_mutex);
diff -urN linux-2.5.4-pre1/drivers/usb/se401.c linux/drivers/usb/se401.c
--- linux-2.5.4-pre1/drivers/usb/se401.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/se401.c	Wed Feb  6 22:51:47 2002
@@ -556,7 +556,7 @@
 	/* Resubmit urb for new data */
 	urb->status=0;
 	urb->dev=se401->dev;
-	if(usb_submit_urb(urb))
+	if(usb_submit_urb(urb, GFP_KERNEL))
 		info("urb burned down");
 	return;
 }
@@ -657,7 +657,7 @@
 
 		se401->urb[i]=urb;
 
-		err=usb_submit_urb(se401->urb[i]);
+		err=usb_submit_urb(se401->urb[i], GFP_KERNEL);
 		if(err)
 			err("urb burned down");
 	}
@@ -1477,7 +1477,7 @@
 	    se401,
 	    HZ/10
 	);
-	if (usb_submit_urb(se401->inturb)) {
+	if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
 		info("int urb burned down");
 		return 1;
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/serial/belkin_sa.c linux/drivers/usb/serial/belkin_sa.c
--- linux-2.5.4-pre1/drivers/usb/serial/belkin_sa.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/belkin_sa.c	Wed Feb  6 22:51:47 2002
@@ -217,14 +217,14 @@
 		 *       enhance buffering.  Win trace shows 16 initial read URBs.
 		 */
 		port->read_urb->dev = port->serial->dev;
-		retval = usb_submit_urb(port->read_urb);
+		retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (retval) {
 			err("usb_submit_urb(read bulk) failed");
 			goto exit;
 		}
 
 		port->interrupt_in_urb->dev = port->serial->dev;
-		retval = usb_submit_urb(port->interrupt_in_urb);
+		retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (retval)
 			err(" usb_submit_urb(read int) failed");
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/serial/cyberjack.c linux/drivers/usb/serial/cyberjack.c
--- linux-2.5.4-pre1/drivers/usb/serial/cyberjack.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/cyberjack.c	Wed Feb  6 22:51:47 2002
@@ -173,7 +173,7 @@
 		usb_unlink_urb (port->interrupt_in_urb);
 
 		port->interrupt_in_urb->dev = port->serial->dev;
-		result = usb_submit_urb(port->interrupt_in_urb);
+		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (result)
 			err(" usb_submit_urb(read int) failed");
 		dbg(__FUNCTION__ " - usb_submit_urb(int urb)");
@@ -271,7 +271,7 @@
 			      port);
 
 		/* send the data out the bulk port */
-		result = usb_submit_urb(port->write_urb);
+		result = usb_submit_urb(port->write_urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 			/* Throw away data. No better idea what to do with it. */
@@ -342,7 +342,7 @@
 
 		if( !old_rdtodo ) {
 			port->read_urb->dev = port->serial->dev;
-			result = usb_submit_urb(port->read_urb);
+			result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 			if( result )
 				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 			dbg(__FUNCTION__ " - usb_submit_urb(read urb)");
@@ -398,7 +398,7 @@
 	/* Continue to read if we have still urbs to do. */
 	if( priv->rdtodo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
 		port->read_urb->dev = port->serial->dev;
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 		dbg(__FUNCTION__ " - usb_submit_urb(read urb)");
@@ -453,7 +453,7 @@
 			      port);
 
 		/* send the data out the bulk port */
-		result = usb_submit_urb(port->write_urb);
+		result = usb_submit_urb(port->write_urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 			/* Throw away data. No better idea what to do with it. */
diff -urN linux-2.5.4-pre1/drivers/usb/serial/digi_acceleport.c linux/drivers/usb/serial/digi_acceleport.c
--- linux-2.5.4-pre1/drivers/usb/serial/digi_acceleport.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/digi_acceleport.c	Wed Feb  6 22:51:47 2002
@@ -676,7 +676,7 @@
 		oob_port->write_urb->transfer_buffer_length = len;
 		oob_port->write_urb->dev = port->serial->dev;
 
-		if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) {
+		if( (ret=usb_submit_urb(oob_port->write_urb, GFP_KERNEL)) == 0 ) {
 			oob_priv->dp_write_urb_in_use = 1;
 			count -= len;
 			buf += len;
@@ -764,7 +764,7 @@
 		}
 		port->write_urb->dev = port->serial->dev;
 
-		if( (ret=usb_submit_urb(port->write_urb)) == 0 ) {
+		if( (ret=usb_submit_urb(port->write_urb, GFP_KERNEL)) == 0 ) {
 			priv->dp_write_urb_in_use = 1;
 			priv->dp_out_buf_len = 0;
 			count -= len;
@@ -841,7 +841,7 @@
 	oob_port->write_urb->transfer_buffer_length = 8;
 	oob_port->write_urb->dev = port->serial->dev;
 
-	if( (ret=usb_submit_urb(oob_port->write_urb)) == 0 ) {
+	if( (ret=usb_submit_urb(oob_port->write_urb, GFP_KERNEL)) == 0 ) {
 		oob_priv->dp_write_urb_in_use = 1;
 		port_priv->dp_modem_signals =
 			(port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS))
@@ -962,7 +962,7 @@
 	/* restart read chain */
 	if( priv->dp_throttle_restart ) {
 		port->read_urb->dev = port->serial->dev;
-		ret = usb_submit_urb( port->read_urb );
+		ret = usb_submit_urb( port->read_urb, GFP_KERNEL );
 	}
 
 	/* turn throttle off */
@@ -1323,7 +1323,7 @@
 	/* copy in new data */
 	memcpy( data, from_user ? user_buf : buf, new_len );
 
-	if( (ret=usb_submit_urb(port->write_urb)) == 0 ) {
+	if( (ret=usb_submit_urb(port->write_urb, GFP_KERNEL)) == 0 ) {
 		priv->dp_write_urb_in_use = 1;
 		ret = new_len;
 		priv->dp_out_buf_len = 0;
@@ -1399,7 +1399,7 @@
 		memcpy( port->write_urb->transfer_buffer+2, priv->dp_out_buf,
 			priv->dp_out_buf_len );
 
-		if( (ret=usb_submit_urb(port->write_urb)) == 0 ) {
+		if( (ret=usb_submit_urb(port->write_urb, GFP_KERNEL)) == 0 ) {
 			priv->dp_write_urb_in_use = 1;
 			priv->dp_out_buf_len = 0;
 		}
@@ -1677,7 +1677,7 @@
 
 		port->write_urb->dev = port->serial->dev;
 
-		if( (ret=usb_submit_urb(port->read_urb)) != 0 ) {
+		if( (ret=usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0 ) {
 			err(
 			__FUNCTION__ ": usb_submit_urb failed, ret=%d, port=%d",
 			ret, i );
@@ -1837,7 +1837,7 @@
 
 	/* continue read */
 	urb->dev = port->serial->dev;
-	if( (ret=usb_submit_urb(urb)) != 0 ) {
+	if( (ret=usb_submit_urb(urb, GFP_KERNEL)) != 0 ) {
 		err( __FUNCTION__ ": failed resubmitting urb, ret=%d, port=%d",
 			ret, priv->dp_port_num );
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/serial/empeg.c linux/drivers/usb/serial/empeg.c
--- linux-2.5.4-pre1/drivers/usb/serial/empeg.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/empeg.c	Wed Feb  6 22:51:47 2002
@@ -182,7 +182,7 @@
 
 		port->read_urb->transfer_flags |= USB_QUEUE_BULK;
 
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 
 		if (result)
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
@@ -296,7 +296,7 @@
 		urb->transfer_flags |= USB_QUEUE_BULK;
 
 		/* send it down the pipe */
-		status = usb_submit_urb(urb);
+		status = usb_submit_urb(urb, GFP_KERNEL);
 		if (status) {
 			err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
 			bytes_sent = status;
@@ -449,7 +449,7 @@
 
 	port->read_urb->transfer_flags |= USB_QUEUE_BULK;
 
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
@@ -484,7 +484,7 @@
 
 	port->read_urb->dev = port->serial->dev;
 
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 
 	if (result)
 		err(__FUNCTION__ " - failed submitting read urb, error %d", result);
diff -urN linux-2.5.4-pre1/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- linux-2.5.4-pre1/drivers/usb/serial/ftdi_sio.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/serial/ftdi_sio.c	Wed Feb  6 22:51:47 2002
@@ -356,7 +356,7 @@
 			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
 			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
 			      ftdi_sio_read_bulk_callback, port);
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
@@ -479,7 +479,7 @@
 		      port->write_urb->transfer_buffer, count,
 		      ftdi_sio_write_bulk_callback, port);
 		
-	result = usb_submit_urb(port->write_urb);
+	result = usb_submit_urb(port->write_urb, GFP_KERNEL);
 	if (result) {
 		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 		up (&port->sem);
@@ -644,7 +644,7 @@
 		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
 		      ftdi_sio_read_bulk_callback, port);
 
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 
diff -urN linux-2.5.4-pre1/drivers/usb/serial/io_edgeport.c linux/drivers/usb/serial/io_edgeport.c
--- linux-2.5.4-pre1/drivers/usb/serial/io_edgeport.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/serial/io_edgeport.c	Wed Feb  6 22:51:47 2002
@@ -787,7 +787,7 @@
 
 					/* we have pending bytes on the bulk in pipe, send a request */
 					edge_serial->read_urb->dev = edge_serial->serial->dev;
-					result = usb_submit_urb(edge_serial->read_urb);
+					result = usb_submit_urb(edge_serial->read_urb, GFP_KERNEL);
 					if (result) {
 						dbg(__FUNCTION__" - usb_submit_urb(read bulk) failed with result = %d", result);
 					}
@@ -864,7 +864,7 @@
 
 			/* there is, so resubmit our urb */
 			edge_serial->read_urb->dev = edge_serial->serial->dev;
-			status = usb_submit_urb(edge_serial->read_urb);
+			status = usb_submit_urb(edge_serial->read_urb, GFP_KERNEL);
 			if (status) {
 				err(__FUNCTION__" - usb_submit_urb(read bulk) failed, status = %d", status);
 			}
@@ -1031,7 +1031,7 @@
 
 			/* start interrupt read for this edgeport
 			 * this interrupt will continue as long as the edgeport is connected */
-			response = usb_submit_urb (edge_serial->interrupt_read_urb);
+			response = usb_submit_urb (edge_serial->interrupt_read_urb, GFP_KERNEL);
 			if (response) {
 				err(__FUNCTION__" - Error %d submitting control urb", response);
 			}
@@ -1471,7 +1471,7 @@
 	urb->transfer_flags |= USB_QUEUE_BULK;
 
 	urb->dev = edge_serial->serial->dev;
-	status = usb_submit_urb(urb);
+	status = usb_submit_urb(urb, GFP_KERNEL);
 	if (status) {
 		/* something went wrong */
 		dbg(__FUNCTION__" - usb_submit_urb(write bulk) failed");
@@ -2477,7 +2477,7 @@
 	urb->transfer_flags |= USB_QUEUE_BULK;
 
 	edge_port->commandPending = TRUE;
-	status = usb_submit_urb(urb);
+	status = usb_submit_urb(urb, GFP_KERNEL);
 
 	if (status) {
 		/* something went wrong */
diff -urN linux-2.5.4-pre1/drivers/usb/serial/ipaq.c linux/drivers/usb/serial/ipaq.c
--- linux-2.5.4-pre1/drivers/usb/serial/ipaq.c	Tue Jan  1 13:52:10 2002
+++ linux/drivers/usb/serial/ipaq.c	Wed Feb  6 22:51:47 2002
@@ -171,7 +171,7 @@
 			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
 			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
 			      ipaq_read_bulk_callback, port);
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 		}
@@ -288,7 +288,7 @@
 		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
 		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
 		      ipaq_read_bulk_callback, port);
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 	return;
@@ -403,7 +403,7 @@
 		      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
 		      port->write_urb->transfer_buffer, count, ipaq_write_bulk_callback,
 		      port);
-	result = usb_submit_urb(urb);
+	result = usb_submit_urb(urb, GFP_KERNEL);
 	if (result) {
 		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/serial/ir-usb.c linux/drivers/usb/serial/ir-usb.c
--- linux-2.5.4-pre1/drivers/usb/serial/ir-usb.c	Thu Jan 17 14:06:53 2002
+++ linux/drivers/usb/serial/ir-usb.c	Wed Feb  6 22:51:47 2002
@@ -289,7 +289,7 @@
 			ir_read_bulk_callback,
 			port);
 		port->read_urb->transfer_flags = USB_QUEUE_BULK;
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (result)
 			err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
 	}
@@ -382,7 +382,7 @@
 		= USB_QUEUE_BULK
 		| USB_ZERO_PACKET;
 
-	result = usb_submit_urb (port->write_urb);
+	result = usb_submit_urb (port->write_urb, GFP_KERNEL);
 	if (result)
 		err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
 	else
@@ -492,7 +492,7 @@
 
 			port->read_urb->transfer_flags = USB_QUEUE_BULK;
 
-			result = usb_submit_urb(port->read_urb);
+			result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 
 			if (result)
 				err("%s - failed resubmitting read urb, error %d",
@@ -591,7 +591,7 @@
 			= USB_QUEUE_BULK
 			| USB_ZERO_PACKET;
 
-		result = usb_submit_urb (port->write_urb);
+		result = usb_submit_urb (port->write_urb, GFP_KERNEL);
 		if (result)
 			err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/serial/keyspan.c linux/drivers/usb/serial/keyspan.c
--- linux-2.5.4-pre1/drivers/usb/serial/keyspan.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/serial/keyspan.c	Wed Feb  6 22:51:47 2002
@@ -378,7 +378,7 @@
 
 		this_urb->transfer_flags &= ~USB_ASYNC_UNLINK;
 		this_urb->dev = port->serial->dev;
-		if ((err = usb_submit_urb(this_urb)) != 0) {
+		if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) {
 			dbg("usb_submit_urb(write bulk) failed (%d)\n", err);
 		}
 		p_priv->tx_start_time[flip] = jiffies;
@@ -436,7 +436,7 @@
 				
 		/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
-	if ((err = usb_submit_urb(urb)) != 0) {
+	if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 	return;
@@ -535,7 +535,7 @@
 exit:
 	/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
-	if ((err = usb_submit_urb(urb)) != 0) {
+	if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
@@ -586,7 +586,7 @@
 
 		/* Resubmit urb so we continue receiving */
 		urb->dev = port->serial->dev;
-		if ((err = usb_submit_urb(urb)) != 0) {
+		if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 			dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n",
 err);
 		}
@@ -671,7 +671,7 @@
 exit:	
 		/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
-	if ((err = usb_submit_urb(urb)) != 0) {
+	if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
@@ -764,7 +764,7 @@
 		/* Resubmit urb so we continue receiving */
 	urb->dev = serial->dev;
 
-	if ((err = usb_submit_urb(urb)) != 0) {
+	if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
@@ -819,7 +819,7 @@
 				
 		/* Resubmit urb so we continue receiving */
 	urb->dev = port->serial->dev;
-	if ((err = usb_submit_urb(urb)) != 0) {
+	if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ "resubmit read urb failed. (%d)\n", err);
 	}
 }
@@ -880,7 +880,7 @@
 		if ((urb = p_priv->in_urbs[i]) == NULL)
 			continue;
 		urb->dev = serial->dev;
-		if ((err = usb_submit_urb(urb)) != 0) {
+		if ((err = usb_submit_urb(urb, GFP_KERNEL)) != 0) {
 			dbg(__FUNCTION__ " submit urb %d failed (%d)\n", i, err);
 		}
 	}
@@ -1408,7 +1408,7 @@
 	this_urb->transfer_buffer_length = sizeof(msg);
 
 	this_urb->dev = serial->dev;
-	if ((err = usb_submit_urb(this_urb)) != 0) {
+	if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err);
 	}
 #if 0
@@ -1494,7 +1494,7 @@
 	this_urb->transfer_buffer_length = sizeof(msg);
 
 	this_urb->dev = serial->dev;
-	if ((err = usb_submit_urb(this_urb)) != 0) {
+	if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ " usb_submit_urb(setup) failed\n");
 	}
 #if 0
@@ -1622,7 +1622,7 @@
 	this_urb->transfer_buffer_length = sizeof(msg);
 
 	this_urb->dev = serial->dev;
-	if ((err = usb_submit_urb(this_urb)) != 0) {
+	if ((err = usb_submit_urb(this_urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ " usb_submit_urb(setup) failed (%d)\n", err);
 	}
 #if 0
@@ -1708,7 +1708,7 @@
 	keyspan_setup_urbs(serial);
 
 	s_priv->instat_urb->dev = serial->dev;
-	if ((err = usb_submit_urb(s_priv->instat_urb)) != 0) {
+	if ((err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL)) != 0) {
 		dbg(__FUNCTION__ " submit instat urb failed %d\n", err);
 	}
 			
diff -urN linux-2.5.4-pre1/drivers/usb/serial/keyspan_pda.c linux/drivers/usb/serial/keyspan_pda.c
--- linux-2.5.4-pre1/drivers/usb/serial/keyspan_pda.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/keyspan_pda.c	Wed Feb  6 22:51:47 2002
@@ -292,7 +292,7 @@
 	/* just restart the receive interrupt URB */
 	dbg("keyspan_pda_rx_unthrottle port %d", port->number);
 	port->interrupt_in_urb->dev = port->serial->dev;
-	if (usb_submit_urb(port->interrupt_in_urb))
+	if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
 		dbg(" usb_submit_urb(read urb) failed");
 	return;
 }
@@ -584,7 +584,7 @@
 		priv->tx_room -= count;
 
 		port->write_urb->dev = port->serial->dev;
-		rc = usb_submit_urb(port->write_urb);
+		rc = usb_submit_urb(port->write_urb, GFP_KERNEL);
 		if (rc) {
 			dbg(" usb_submit_urb(write bulk) failed");
 			goto exit;
@@ -699,7 +699,7 @@
 
 		/*Start reading from the device*/
 		port->interrupt_in_urb->dev = serial->dev;
-		rc = usb_submit_urb(port->interrupt_in_urb);
+		rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (rc) {
 			dbg(__FUNCTION__" - usb_submit_urb(read int) failed");
 			goto error;
diff -urN linux-2.5.4-pre1/drivers/usb/serial/kl5kusb105.c linux/drivers/usb/serial/kl5kusb105.c
--- linux-2.5.4-pre1/drivers/usb/serial/kl5kusb105.c	Tue Jan  1 13:52:10 2002
+++ linux/drivers/usb/serial/kl5kusb105.c	Wed Feb  6 22:51:47 2002
@@ -404,7 +404,7 @@
 			      port);
 		port->read_urb->transfer_flags |= USB_QUEUE_BULK;
 
-		rc = usb_submit_urb(port->read_urb);
+		rc = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (rc) {
 			err(__FUNCTION__ 
 			    " - failed submitting read urb, error %d", rc);
@@ -567,7 +567,7 @@
 
 
 		/* send the data out the bulk port */
-		result = usb_submit_urb(urb);
+		result = usb_submit_urb(urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__
 			    " - failed submitting write urb, error %d", result);
@@ -734,7 +734,7 @@
 		      port->read_urb->transfer_buffer_length,
 		      klsi_105_read_bulk_callback,
 		      port);
-	rc = usb_submit_urb(port->read_urb);
+	rc = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (rc)
 		err(__FUNCTION__ 
 		    " - failed resubmitting read urb, error %d", rc);
@@ -1041,7 +1041,7 @@
 	down (&port->sem);
 
 	port->read_urb->dev = port->serial->dev;
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed submitting read urb, error %d",
 		    result);
diff -urN linux-2.5.4-pre1/drivers/usb/serial/mct_u232.c linux/drivers/usb/serial/mct_u232.c
--- linux-2.5.4-pre1/drivers/usb/serial/mct_u232.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/mct_u232.c	Wed Feb  6 22:51:47 2002
@@ -384,14 +384,14 @@
 		}
 
 		port->read_urb->dev = port->serial->dev;
-		retval = usb_submit_urb(port->read_urb);
+		retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (retval) {
 			err("usb_submit_urb(read bulk) failed");
 			goto exit;
 		}
 
 		port->interrupt_in_urb->dev = port->serial->dev;
-		retval = usb_submit_urb(port->interrupt_in_urb);
+		retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
 		if (retval)
 			err(" usb_submit_urb(read int) failed");
 
@@ -482,7 +482,7 @@
 			      port);
 		
 		/* send the data out the bulk port */
-		result = usb_submit_urb(port->write_urb);
+		result = usb_submit_urb(port->write_urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__
 			    " - failed submitting write urb, error %d", result);
diff -urN linux-2.5.4-pre1/drivers/usb/serial/omninet.c linux/drivers/usb/serial/omninet.c
--- linux-2.5.4-pre1/drivers/usb/serial/omninet.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/omninet.c	Wed Feb  6 22:51:47 2002
@@ -179,7 +179,7 @@
 			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
 			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
 			      omninet_read_bulk_callback, port);
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
@@ -274,7 +274,7 @@
 		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
 		      urb->transfer_buffer, urb->transfer_buffer_length,
 		      omninet_read_bulk_callback, port);
-	result = usb_submit_urb(urb);
+	result = usb_submit_urb(urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 
@@ -325,7 +325,7 @@
 	wport->write_urb->transfer_buffer_length = 64;
 
 	wport->write_urb->dev = serial->dev;
-	result = usb_submit_urb(wport->write_urb);
+	result = usb_submit_urb(wport->write_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 	else
diff -urN linux-2.5.4-pre1/drivers/usb/serial/pl2303.c linux/drivers/usb/serial/pl2303.c
--- linux-2.5.4-pre1/drivers/usb/serial/pl2303.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/pl2303.c	Wed Feb  6 22:51:47 2002
@@ -195,7 +195,7 @@
 
 	port->write_urb->transfer_buffer_length = count;
 	port->write_urb->dev = port->serial->dev;
-	result = usb_submit_urb (port->write_urb);
+	result = usb_submit_urb (port->write_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 	else
@@ -404,7 +404,7 @@
 
 		dbg (__FUNCTION__ " - submitting read urb");
 		port->read_urb->dev = serial->dev;
-		result = usb_submit_urb (port->read_urb);
+		result = usb_submit_urb (port->read_urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 			up (&port->sem);
@@ -414,7 +414,7 @@
 
 		dbg (__FUNCTION__ " - submitting interrupt urb");
 		port->interrupt_in_urb->dev = serial->dev;
-		result = usb_submit_urb (port->interrupt_in_urb);
+		result = usb_submit_urb (port->interrupt_in_urb, GFP_KERNEL);
 		if (result) {
 			err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result);
 			up (&port->sem);
@@ -652,7 +652,7 @@
 			dbg (__FUNCTION__ " - caught -EPROTO, resubmitting the urb");
 			urb->status = 0;
 			urb->dev = serial->dev;
-			result = usb_submit_urb(urb);
+			result = usb_submit_urb(urb, GFP_KERNEL);
 			if (result)
 				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 			return;
@@ -677,7 +677,7 @@
 	/* Schedule the next read _if_ we are still open */
 	if (port->open_count) {
 		urb->dev = serial->dev;
-		result = usb_submit_urb(urb);
+		result = usb_submit_urb(urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 	}
@@ -706,7 +706,7 @@
 		dbg (__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
 		port->write_urb->transfer_buffer_length = 1;
 		port->write_urb->dev = port->serial->dev;
-		result = usb_submit_urb (port->write_urb);
+		result = usb_submit_urb (port->write_urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed resubmitting write urb, error %d", result);
 
diff -urN linux-2.5.4-pre1/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- linux-2.5.4-pre1/drivers/usb/serial/usbserial.c	Thu Jan  3 18:52:28 2002
+++ linux/drivers/usb/serial/usbserial.c	Wed Feb  6 22:51:47 2002
@@ -813,7 +813,7 @@
 					     serial->type->read_bulk_callback :
 					     generic_read_bulk_callback),
 					   port);
-			result = usb_submit_urb(port->read_urb);
+			result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 			if (result)
 				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 		}
@@ -894,7 +894,7 @@
 				     generic_write_bulk_callback), port);
 
 		/* send the data out the bulk port */
-		result = usb_submit_urb(port->write_urb);
+		result = usb_submit_urb(port->write_urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
 		else
@@ -987,7 +987,7 @@
 			   ((serial->type->read_bulk_callback) ? 
 			     serial->type->read_bulk_callback : 
 			     generic_read_bulk_callback), port);
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 }
diff -urN linux-2.5.4-pre1/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- linux-2.5.4-pre1/drivers/usb/serial/visor.c	Thu Jan  3 18:52:28 2002
+++ linux/drivers/usb/serial/visor.c	Wed Feb  6 22:51:47 2002
@@ -274,7 +274,7 @@
 				   port->read_urb->transfer_buffer,
 				   port->read_urb->transfer_buffer_length,
 				   visor_read_bulk_callback, port);
-		result = usb_submit_urb(port->read_urb);
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (result)
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
@@ -388,7 +388,7 @@
 		urb->transfer_flags |= USB_QUEUE_BULK;
 
 		/* send it down the pipe */
-		status = usb_submit_urb(urb);
+		status = usb_submit_urb(urb, GFP_KERNEL);
 		if (status) {
 			err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
 			bytes_sent = status;
@@ -520,7 +520,7 @@
 			   port->read_urb->transfer_buffer,
 			   port->read_urb->transfer_buffer_length,
 			   visor_read_bulk_callback, port);
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 	return;
@@ -551,7 +551,7 @@
 	down (&port->sem);
 
 	port->read_urb->dev = port->serial->dev;
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 
diff -urN linux-2.5.4-pre1/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
--- linux-2.5.4-pre1/drivers/usb/serial/whiteheat.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/serial/whiteheat.c	Wed Feb  6 22:51:47 2002
@@ -240,7 +240,7 @@
 		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
 		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
 		      command_port_read_callback, port);
-	result = usb_submit_urb(port->read_urb);
+	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result)
 		dbg(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 }
@@ -265,7 +265,7 @@
 	memcpy (&transfer_buffer[1], data, datasize);
 	port->write_urb->transfer_buffer_length = datasize + 1;
 	port->write_urb->dev = serial->dev;
-	retval = usb_submit_urb (port->write_urb);
+	retval = usb_submit_urb (port->write_urb, GFP_KERNEL);
 	if (retval) {
 		dbg (__FUNCTION__" - submit urb failed");
 		goto exit;
@@ -327,7 +327,7 @@
 			command_port->read_urb->complete = command_port_read_callback;
 			command_port->read_urb->dev = port->serial->dev;
 			command_port->tty = port->tty;		/* need this to "fake" our our sanity check macros */
-			retval = usb_submit_urb (command_port->read_urb);
+			retval = usb_submit_urb (command_port->read_urb, GFP_KERNEL);
 			if (retval) {
 				err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
 				goto error_exit;
@@ -336,7 +336,7 @@
 		
 		/* Start reading from the device */
 		port->read_urb->dev = port->serial->dev;
-		retval = usb_submit_urb(port->read_urb);
+		retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
 		if (retval) {
 			err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
 			goto error_exit;
diff -urN linux-2.5.4-pre1/drivers/usb/storage/scsiglue.c linux/drivers/usb/storage/scsiglue.c
--- linux-2.5.4-pre1/drivers/usb/storage/scsiglue.c	Wed Nov 28 10:22:27 2001
+++ linux/drivers/usb/storage/scsiglue.c	Wed Feb  6 22:51:47 2002
@@ -278,7 +278,7 @@
 	if (us->protocol == US_PR_CBI) {
 		down(&(us->irq_urb_sem));
 		us->irq_urb->dev = us->pusb_dev;
-		result = usb_submit_urb(us->irq_urb);
+		result = usb_submit_urb(us->irq_urb, GFP_NOIO);
 		US_DEBUGP("usb_submit_urb() returns %d\n", result);
 		up(&(us->irq_urb_sem));
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/storage/transport.c linux/drivers/usb/storage/transport.c
--- linux-2.5.4-pre1/drivers/usb/storage/transport.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/storage/transport.c	Wed Feb  6 22:51:47 2002
@@ -414,7 +414,7 @@
 	us->current_urb->transfer_flags = USB_ASYNC_UNLINK;
 
 	/* submit the URB */
-	status = usb_submit_urb(us->current_urb);
+	status = usb_submit_urb(us->current_urb, GFP_NOIO);
 	if (status) {
 		/* something went wrong */
 		up(&(us->current_urb_sem));
@@ -461,7 +461,7 @@
 	us->current_urb->transfer_flags = USB_ASYNC_UNLINK;
 
 	/* submit the URB */
-	status = usb_submit_urb(us->current_urb);
+	status = usb_submit_urb(us->current_urb, GFP_NOIO);
 	if (status) {
 		/* something went wrong */
 		up(&(us->current_urb_sem));
diff -urN linux-2.5.4-pre1/drivers/usb/storage/usb.c linux/drivers/usb/storage/usb.c
--- linux-2.5.4-pre1/drivers/usb/storage/usb.c	Thu Jan 17 14:06:53 2002
+++ linux/drivers/usb/storage/usb.c	Wed Feb  6 22:51:47 2002
@@ -534,7 +534,7 @@
 		     usb_stor_CBI_irq, ss, ss->ep_int->bInterval); 
 
 	/* submit the URB for processing */
-	result = usb_submit_urb(ss->irq_urb);
+	result = usb_submit_urb(ss->irq_urb, GFP_KERNEL);
 	US_DEBUGP("usb_submit_urb() returns %d\n", result);
 	if (result) {
 		usb_free_urb(ss->irq_urb);
diff -urN linux-2.5.4-pre1/drivers/usb/stv680.c linux/drivers/usb/stv680.c
--- linux-2.5.4-pre1/drivers/usb/stv680.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/usb/stv680.c	Wed Feb  6 22:51:47 2002
@@ -765,7 +765,7 @@
 	/* Resubmit urb for new data */
 	urb->status = 0;
 	urb->dev = stv680->udev;
-	if (usb_submit_urb (urb))
+	if (usb_submit_urb (urb, GFP_KERNEL))
 		PDEBUG (0, "STV(e): urb burned down in video irq");
 	return;
 }				/*  _video_irq  */
@@ -816,7 +816,7 @@
 		urb->timeout = PENCAM_TIMEOUT * 2;
 		urb->transfer_flags |= USB_QUEUE_BULK;
 		stv680->urb[i] = urb;
-		err = usb_submit_urb (stv680->urb[i]);
+		err = usb_submit_urb (stv680->urb[i], GFP_KERNEL);
 		if (err)
 			PDEBUG (0, "STV(e): urb burned down in start stream");
 	}			/* i STV680_NUMSBUF */
diff -urN linux-2.5.4-pre1/drivers/usb/uhci-debug.h linux/drivers/usb/uhci-debug.h
--- linux-2.5.4-pre1/drivers/usb/uhci-debug.h	Tue Jan 29 21:44:57 2002
+++ linux/drivers/usb/uhci-debug.h	Wed Feb  6 22:51:47 2002
@@ -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"
@@ -476,7 +477,7 @@
 
 static int uhci_proc_open(struct inode *inode, struct file *file)
 {
-	const struct proc_dir_entry *dp = inode->u.generic_ip;
+	const struct proc_dir_entry *dp = PDE(inode);
 	struct uhci *uhci = dp->data;
 	struct uhci_proc *up;
 	unsigned long flags;
@@ -507,8 +508,11 @@
 
 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 @@
 	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);
 }
 
diff -urN linux-2.5.4-pre1/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- linux-2.5.4-pre1/drivers/usb/uhci.c	Fri Jan 25 16:17:51 2002
+++ linux/drivers/usb/uhci.c	Wed Feb  6 22:51:47 2002
@@ -1476,7 +1476,7 @@
 	return u;
 }
 
-static int uhci_submit_urb(struct urb *urb)
+static int uhci_submit_urb(struct urb *urb, int mem_flags)
 {
 	int ret = -EINVAL;
 	struct uhci *uhci;
@@ -1823,11 +1823,11 @@
 }
 
 struct usb_operations uhci_device_operations = {
-	uhci_alloc_dev,
-	uhci_free_dev,
-	uhci_get_current_frame_number,
-	uhci_submit_urb,
-	uhci_unlink_urb
+	allocate:		uhci_alloc_dev,
+	deallocate:		uhci_free_dev,
+	get_frame_number:	uhci_get_current_frame_number,
+	submit_urb:		uhci_submit_urb,
+	unlink_urb:		uhci_unlink_urb,
 };
 
 /* Virtual Root Hub */
@@ -2294,7 +2294,7 @@
 	} else {
 		if (is_ring && !killed) {
 			urb->dev = dev;
-			uhci_submit_urb(urb);
+			uhci_submit_urb(urb, GFP_KERNEL);
 		} else {
 			/* We decrement the usage count after we're done */
 			/*  with everything */
diff -urN linux-2.5.4-pre1/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- linux-2.5.4-pre1/drivers/usb/usb-ohci.c	Fri Jan 25 16:17:51 2002
+++ linux/drivers/usb/usb-ohci.c	Wed Feb  6 22:51:47 2002
@@ -532,7 +532,7 @@
 
 /* get a transfer request */
  
-static int sohci_submit_urb (struct urb * urb)
+static int sohci_submit_urb (struct urb * urb, int mem_flags)
 {
 	ohci_t * ohci;
 	ed_t * ed;
@@ -542,7 +542,6 @@
 	int i, size = 0;
 	unsigned long flags;
 	int bustime = 0;
-	int mem_flags = ALLOC_FLAGS;
 	
 	if (!urb->dev || !urb->dev->bus)
 		return -ENODEV;
@@ -612,8 +611,7 @@
 	}
 
 	/* allocate the private part of the URB */
-	urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), 
-							in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+	urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags);
 	if (!urb_priv) {
 		usb_dec_dev_use (urb->dev);	
 		return -ENOMEM;
@@ -919,11 +917,11 @@
 /*-------------------------------------------------------------------------*/
 
 struct usb_operations sohci_device_operations = {
-	sohci_alloc_dev,
-	sohci_free_dev,
-	sohci_get_current_frame_number,
-	sohci_submit_urb,
-	sohci_unlink_urb
+	allocate:		sohci_alloc_dev,
+	deallocate:		sohci_free_dev,
+	get_frame_number:	sohci_get_current_frame_number,
+	submit_urb:		sohci_submit_urb,
+	unlink_urb:		sohci_unlink_urb,
 };
 
 /*-------------------------------------------------------------------------*
diff -urN linux-2.5.4-pre1/drivers/usb/usb-skeleton.c linux/drivers/usb/usb-skeleton.c
--- linux-2.5.4-pre1/drivers/usb/usb-skeleton.c	Sun Jan  6 18:49:21 2002
+++ linux/drivers/usb/usb-skeleton.c	Wed Feb  6 22:51:47 2002
@@ -431,7 +431,9 @@
 		      skel_write_bulk_callback, dev);
 
 	/* send the data out the bulk port */
-	retval = usb_submit_urb(dev->write_urb);
+	/* a character device write uses GFP_KERNEL,
+	 unless a spinlock is held */
+	retval = usb_submit_urb(dev->write_urb, GFP_KERNEL);
 	if (retval) {
 		err(__FUNCTION__ " - failed submitting write urb, error %d",
 		    retval);
diff -urN linux-2.5.4-pre1/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- linux-2.5.4-pre1/drivers/usb/usb-uhci.c	Fri Jan 25 16:17:51 2002
+++ linux/drivers/usb/usb-uhci.c	Wed Feb  6 22:51:47 2002
@@ -87,7 +87,6 @@
 #endif
 
 #define SLAB_FLAG     (in_interrupt ()? SLAB_ATOMIC : SLAB_KERNEL)
-#define KMALLOC_FLAG  (in_interrupt ()? GFP_ATOMIC : GFP_KERNEL)
 
 /* CONFIG_USB_UHCI_HIGH_BANDWITH turns on Full Speed Bandwidth
  * Reclamation: feature that puts loop on descriptor loop when
@@ -1502,7 +1501,7 @@
 	return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_iso_urb (struct urb *urb)
+_static int uhci_submit_iso_urb (struct urb *urb, int mem_flags)
 {
 	uhci_t *s = (uhci_t*) urb->dev->bus->hcpriv;
 	urb_priv_t *urb_priv = urb->hcpriv;
@@ -1522,7 +1521,7 @@
 	if (ret)
 		goto err;
 
-	tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), KMALLOC_FLAG);
+	tdm = (uhci_desc_t **) kmalloc (urb->number_of_packets * sizeof (uhci_desc_t*), mem_flags);
 
 	if (!tdm) {
 		ret = -ENOMEM;
@@ -1619,7 +1618,7 @@
 	return 0;
 }
 /*-------------------------------------------------------------------*/
-_static int uhci_submit_urb (struct urb *urb)
+_static int uhci_submit_urb (struct urb *urb, int mem_flags)
 {
 	uhci_t *s;
 	urb_priv_t *urb_priv;
@@ -1676,7 +1675,7 @@
 #ifdef DEBUG_SLAB
 	urb_priv = kmem_cache_alloc(urb_priv_kmem, SLAB_FLAG);
 #else
-	urb_priv = kmalloc (sizeof (urb_priv_t), KMALLOC_FLAG);
+	urb_priv = kmalloc (sizeof (urb_priv_t), mem_flags);
 #endif
 	if (!urb_priv) {
 		usb_dec_dev_use (urb->dev);
@@ -1729,12 +1728,12 @@
 				if (bustime < 0) 
 					ret = bustime;
 				else {
-					ret = uhci_submit_iso_urb(urb);
+					ret = uhci_submit_iso_urb(urb, mem_flags);
 					if (ret == 0)
 						usb_claim_bandwidth (urb->dev, urb, bustime, 1);
 				}
 			} else {        /* bandwidth is already set */
-				ret = uhci_submit_iso_urb(urb);
+				ret = uhci_submit_iso_urb(urb, mem_flags);
 			}
 			break;
 		case PIPE_INTERRUPT:
@@ -2279,11 +2278,11 @@
 
 struct usb_operations uhci_device_operations =
 {
-	uhci_alloc_dev,
-	uhci_free_dev,
-	uhci_get_current_frame_number,
-	uhci_submit_urb,
-	uhci_unlink_urb
+	allocate:		uhci_alloc_dev,
+	deallocate:		uhci_free_dev,
+	get_frame_number:	uhci_get_current_frame_number,
+	submit_urb:		uhci_submit_urb,
+	unlink_urb:		uhci_unlink_urb,
 };
 
 _static void correct_data_toggles(struct urb *urb)
@@ -2697,7 +2696,10 @@
 
 						spin_unlock(&s->urb_list_lock);
 
-						ret_submit=uhci_submit_urb(next_urb);
+						// FIXME!!!
+						// We need to know the real state, so 
+						// GFP_ATOMIC is probably not correct
+						ret_submit=uhci_submit_urb(next_urb, GFP_ATOMIC);
 						spin_lock(&s->urb_list_lock);
 						
 						if (ret_submit)
@@ -2721,7 +2723,10 @@
 				// Re-submit the URB if ring-linked
 				if (is_ring && !was_unlinked && !contains_killed) {
 					urb->dev=usb_dev;
-					uhci_submit_urb (urb);
+					// FIXME!!!
+					// We need to know the real state, so 
+					// GFP_ATOMIC is probably not correct
+					uhci_submit_urb (urb, GFP_ATOMIC);
 				}
 				spin_lock(&s->urb_list_lock);
 			}
diff -urN linux-2.5.4-pre1/drivers/usb/usb.c linux/drivers/usb/usb.c
--- linux-2.5.4-pre1/drivers/usb/usb.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/usb/usb.c	Wed Feb  6 22:51:47 2002
@@ -1148,6 +1148,7 @@
 /**
  * usb_submit_urb - asynchronously issue a transfer request for an endpoint
  * @urb: pointer to the urb describing the request
+ * @mem_flags: the type of memory to allocate, see kmalloc() for a list of valid options for this.
  *
  * This submits a transfer request, and transfers control of the URB
  * describing that request to the USB subsystem.  Request completion will
@@ -1197,12 +1198,49 @@
  *
  * If the USB subsystem can't reserve sufficient bandwidth to perform
  * the periodic request, and bandwidth reservation is being done for
- * this controller, submitting such a periodic request will fail. 
+ * this controller, submitting such a periodic request will fail.
+ *
+ * Memory Flags:
+ *
+ * General rules for how to decide which mem_flags to use:
+ * 
+ * Basically the rules are the same as for kmalloc.  There are four
+ * different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and
+ * GFP_ATOMIC.
+ *
+ * GFP_NOFS is not ever used, as it has not been implemented yet.
+ *
+ * There are three situations you must use GFP_ATOMIC.
+ *    a) you are inside a completion handler, an interrupt, bottom half,
+ *       tasklet or timer.
+ *    b) you are holding a spinlock or rwlock (does not apply to
+ *       semaphores)
+ *    c) current->state != TASK_RUNNING, this is the case only after
+ *       you've changed it.
+ * 
+ * GFP_NOIO is used in the block io path and error handling of storage
+ * devices.
+ *
+ * All other situations use GFP_KERNEL.
+ *
+ * Specfic rules for how to decide which mem_flags to use:
+ *
+ *    - start_xmit, timeout, and receive methods of network drivers must
+ *      use GFP_ATOMIC (spinlock)
+ *    - queuecommand methods of scsi drivers must use GFP_ATOMIC (spinlock)
+ *    - If you use a kernel thread with a network driver you must use
+ *      GFP_NOIO, unless b) or c) apply
+ *    - After you have done a down() you use GFP_KERNEL, unless b) or c)
+ *      apply or your are in a storage driver's block io path
+ *    - probe and disconnect use GFP_KERNEL unless b) or c) apply
+ *    - Changing firmware on a running storage or net device uses
+ *      GFP_NOIO, unless b) or c) apply
+ *
  */
-int usb_submit_urb(struct urb *urb)
+int usb_submit_urb(struct urb *urb, int mem_flags)
 {
 	if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
-		return urb->dev->bus->op->submit_urb(urb);
+		return urb->dev->bus->op->submit_urb(urb, mem_flags);
 	else
 		return -ENODEV;
 }
@@ -1272,7 +1310,7 @@
 	add_wait_queue(&awd.wqh, &wait);
 
 	urb->context = &awd;
-	status = usb_submit_urb(urb);
+	status = usb_submit_urb(urb, GFP_KERNEL);
 	if (status) {
 		// something went wrong
 		usb_free_urb(urb);
diff -urN linux-2.5.4-pre1/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c
--- linux-2.5.4-pre1/drivers/usb/usbkbd.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/usbkbd.c	Wed Feb  6 22:51:47 2002
@@ -129,7 +129,7 @@
 
 	kbd->leds = kbd->newleds;
 	kbd->led->dev = kbd->usbdev;
-	if (usb_submit_urb(kbd->led))
+	if (usb_submit_urb(kbd->led, GFP_KERNEL))
 		err("usb_submit_urb(leds) failed");
 
 	return 0;
@@ -147,7 +147,7 @@
 
 	kbd->leds = kbd->newleds;
 	kbd->led->dev = kbd->usbdev;
-	if (usb_submit_urb(kbd->led))
+	if (usb_submit_urb(kbd->led, GFP_KERNEL))
 		err("usb_submit_urb(leds) failed");
 }
 
@@ -159,7 +159,7 @@
 		return 0;
 
 	kbd->irq->dev = kbd->usbdev;
-	if (usb_submit_urb(kbd->irq))
+	if (usb_submit_urb(kbd->irq, GFP_KERNEL))
 		return -EIO;
 
 	return 0;
diff -urN linux-2.5.4-pre1/drivers/usb/usbmouse.c linux/drivers/usb/usbmouse.c
--- linux-2.5.4-pre1/drivers/usb/usbmouse.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/usbmouse.c	Wed Feb  6 22:51:47 2002
@@ -85,7 +85,7 @@
 		return 0;
 
 	mouse->irq->dev = mouse->usbdev;
-	if (usb_submit_urb(mouse->irq))
+	if (usb_submit_urb(mouse->irq, GFP_KERNEL))
 		return -EIO;
 
 	return 0;
diff -urN linux-2.5.4-pre1/drivers/usb/usbnet.c linux/drivers/usb/usbnet.c
--- linux-2.5.4-pre1/drivers/usb/usbnet.c	Thu Jan  3 18:52:28 2002
+++ linux/drivers/usb/usbnet.c	Wed Feb  6 22:51:47 2002
@@ -373,7 +373,7 @@
 	// issue usb interrupt read
 	if (priv && priv->irq_urb) {
 		// submit urb
-		if ((retval = usb_submit_urb (priv->irq_urb)) != 0)
+		if ((retval = usb_submit_urb (priv->irq_urb, GFP_KERNEL)) != 0)
 			dbg ("gl_interrupt_read: submit fail - %X...", retval);
 		else
 			dbg ("gl_interrupt_read: submit success...");
@@ -1281,7 +1281,7 @@
 	spin_lock_irqsave (&dev->rxq.lock, lockflags);
 
 	if (netif_running (&dev->net)) {
-		if ((retval = usb_submit_urb (urb)) != 0) {
+		if ((retval = usb_submit_urb (urb, GFP_ATOMIC)) != 0) {
 			dbg ("%s rx submit, %d", dev->net.name, retval);
 			tasklet_schedule (&dev->bh);
 		} else {
@@ -1642,7 +1642,7 @@
 #endif	/* CONFIG_USB_NET1080 */
 
 	netif_stop_queue (net);
-	if ((retval = usb_submit_urb (urb)) != 0) {
+	if ((retval = usb_submit_urb (urb, GFP_ATOMIC)) != 0) {
 		netif_start_queue (net);
 		dbg ("%s tx: submit urb err %d", net->name, retval);
 	} else {
diff -urN linux-2.5.4-pre1/drivers/usb/usbvideo.c linux/drivers/usb/usbvideo.c
--- linux-2.5.4-pre1/drivers/usb/usbvideo.c	Mon Jan 21 15:44:21 2002
+++ linux/drivers/usb/usbvideo.c	Wed Feb  6 22:51:47 2002
@@ -1916,7 +1916,7 @@
 
 	/* Submit all URBs */
 	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
-		errFlag = usb_submit_urb(uvd->sbuf[i].urb);
+		errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
 		if (errFlag)
 			err("%s: usb_submit_isoc(%d) ret %d", proc, i, errFlag);
 	}
diff -urN linux-2.5.4-pre1/drivers/usb/vicam.c linux/drivers/usb/vicam.c
--- linux-2.5.4-pre1/drivers/usb/vicam.c	Wed Feb  6 22:51:45 2002
+++ linux/drivers/usb/vicam.c	Wed Feb  6 22:51:47 2002
@@ -350,7 +350,7 @@
 	synchronize(vicam);
 	mdelay(10);
 	vicam_parameters(vicam);
-	printk("Submiting urb: %d\n", usb_submit_urb(vicam->readurb));
+	printk(KERN_DEBUG "Submiting urb: %d\n", usb_submit_urb(vicam->readurb, GFP_KERNEL));
 #endif
 }
 
@@ -765,7 +765,7 @@
 		memcpy(vicam->fbuf, buf+64, 0x1e480);
 
 	if (!change_pending) {
-		if (usb_submit_urb(urb))
+		if (usb_submit_urb(urb, GFP_ATOMIC))
 			dbg("failed resubmitting read urb");
 	} else {
 		change_pending = 0;
@@ -849,7 +849,7 @@
 
 	FILL_BULK_URB(vicam->readurb, vicam->udev, usb_rcvbulkpipe(vicam->udev, 0x81),
 		      buf, 0x1e480, vicam_bulk, vicam);
-	printk("Submiting urb: %d\n", usb_submit_urb(vicam->readurb));
+	printk(KERN_DEBUG "Submiting urb: %d\n", usb_submit_urb(vicam->readurb, GFP_KERNEL));
 
 	return 0;
 error:
diff -urN linux-2.5.4-pre1/drivers/usb/wacom.c linux/drivers/usb/wacom.c
--- linux-2.5.4-pre1/drivers/usb/wacom.c	Wed Jan 23 15:33:46 2002
+++ linux/drivers/usb/wacom.c	Wed Feb  6 22:51:47 2002
@@ -336,7 +336,7 @@
 		return 0;
 
 	wacom->irq->dev = wacom->usbdev;
-	if (usb_submit_urb(wacom->irq))
+	if (usb_submit_urb(wacom->irq, GFP_KERNEL))
 		return -EIO;
 
 	return 0;
diff -urN linux-2.5.4-pre1/drivers/zorro/proc.c linux/drivers/zorro/proc.c
--- linux-2.5.4-pre1/drivers/zorro/proc.c	Tue Mar  7 10:52:41 2000
+++ linux/drivers/zorro/proc.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 	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);
 }
 
@@ -45,7 +47,7 @@
 proc_bus_zorro_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
 {
 	struct inode *ino = file->f_dentry->d_inode;
-	struct proc_dir_entry *dp = ino->u.generic_ip;
+	struct proc_dir_entry *dp = PDE(ino);
 	struct zorro_dev *dev = dp->data;
 	struct ConfigDev cd;
 	int pos = *ppos;
diff -urN linux-2.5.4-pre1/fs/autofs/autofs_i.h linux/fs/autofs/autofs_i.h
--- linux-2.5.4-pre1/fs/autofs/autofs_i.h	Thu Jul 26 13:43:12 2001
+++ linux/fs/autofs/autofs_i.h	Wed Feb  6 22:51:47 2002
@@ -145,7 +145,7 @@
 
 /* Initializing function */
 
-struct super_block *autofs_read_super(struct super_block *, void *,int);
+int autofs_fill_super(struct super_block *, void *, int);
 
 /* Queue management functions */
 
diff -urN linux-2.5.4-pre1/fs/autofs/init.c linux/fs/autofs/init.c
--- linux-2.5.4-pre1/fs/autofs/init.c	Sun Sep 30 12:26:08 2001
+++ linux/fs/autofs/init.c	Wed Feb  6 22:51:47 2002
@@ -14,7 +14,17 @@
 #include <linux/init.h>
 #include "autofs_i.h"
 
-static DECLARE_FSTYPE(autofs_fs_type, "autofs", autofs_read_super, 0);
+static struct super_block *autofs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, autofs_fill_super);
+}
+
+static struct file_system_type autofs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"autofs",
+	get_sb:		autofs_get_sb,
+};
 
 static int __init init_autofs_fs(void)
 {
diff -urN linux-2.5.4-pre1/fs/autofs/inode.c linux/fs/autofs/inode.c
--- linux-2.5.4-pre1/fs/autofs/inode.c	Sat Dec 29 17:30:07 2001
+++ linux/fs/autofs/inode.c	Wed Feb  6 22:51:47 2002
@@ -111,8 +111,7 @@
 	return (*pipefd < 0);
 }
 
-struct super_block *autofs_read_super(struct super_block *s, void *data,
-				      int silent)
+int autofs_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
 	struct dentry * root;
@@ -175,7 +174,7 @@
 	 * Success! Install the root dentry now to indicate completion.
 	 */
 	s->s_root = root;
-	return s;
+	return 0;
 
 fail_fput:
 	printk("autofs: pipe file descriptor does not contain proper ops\n");
@@ -189,7 +188,7 @@
 fail_free:
 	kfree(sbi);
 fail_unlock:
-	return NULL;
+	return -EINVAL;
 }
 
 static int autofs_statfs(struct super_block *sb, struct statfs *buf)
diff -urN linux-2.5.4-pre1/fs/autofs4/autofs_i.h linux/fs/autofs4/autofs_i.h
--- linux-2.5.4-pre1/fs/autofs4/autofs_i.h	Tue Jan 29 21:41:16 2002
+++ linux/fs/autofs4/autofs_i.h	Wed Feb  6 22:51:47 2002
@@ -144,7 +144,7 @@
 
 /* Initializing function */
 
-struct super_block *autofs4_read_super(struct super_block *, void *,int);
+int autofs4_fill_super(struct super_block *, void *, int);
 struct autofs_info *autofs4_init_ino(struct autofs_info *, struct autofs_sb_info *sbi, mode_t mode);
 
 /* Queue management functions */
diff -urN linux-2.5.4-pre1/fs/autofs4/init.c linux/fs/autofs4/init.c
--- linux-2.5.4-pre1/fs/autofs4/init.c	Sun Sep 30 12:26:08 2001
+++ linux/fs/autofs4/init.c	Wed Feb  6 22:51:47 2002
@@ -14,7 +14,17 @@
 #include <linux/init.h>
 #include "autofs_i.h"
 
-static DECLARE_FSTYPE(autofs_fs_type, "autofs", autofs4_read_super, 0);
+static struct super_block *autofs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, autofs4_fill_super);
+}
+
+static struct file_system_type autofs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"autofs",
+	get_sb:		autofs_get_sb,
+};
 
 static int __init init_autofs4_fs(void)
 {
diff -urN linux-2.5.4-pre1/fs/autofs4/inode.c linux/fs/autofs4/inode.c
--- linux-2.5.4-pre1/fs/autofs4/inode.c	Mon Dec 31 18:25:49 2001
+++ linux/fs/autofs4/inode.c	Wed Feb  6 22:51:47 2002
@@ -173,8 +173,7 @@
 	return ino;
 }
 
-struct super_block *autofs4_read_super(struct super_block *s, void *data,
-				      int silent)
+int autofs4_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
 	struct dentry * root;
@@ -251,7 +250,7 @@
 	 * Success! Install the root dentry now to indicate completion.
 	 */
 	s->s_root = root;
-	return s;
+	return 0;
 	
 	/*
 	 * Failure ... clean up.
@@ -278,7 +277,7 @@
 fail_free:
 	kfree(sbi);
 fail_unlock:
-	return NULL;
+	return -EINVAL;
 }
 
 static int autofs4_statfs(struct super_block *sb, struct statfs *buf)
diff -urN linux-2.5.4-pre1/fs/binfmt_misc.c linux/fs/binfmt_misc.c
--- linux-2.5.4-pre1/fs/binfmt_misc.c	Thu Jan 17 14:25:43 2002
+++ linux/fs/binfmt_misc.c	Wed Feb  6 22:51:47 2002
@@ -656,7 +656,7 @@
 	clear_inode:	bm_clear_inode,
 };
 
-static struct super_block *bm_read_super(struct super_block * sb, void * data, int silent)
+static int bm_fill_super(struct super_block * sb, void * data, int silent)
 {
 	struct qstr names[2] = {{name:"status"}, {name:"register"}};
 	struct inode * inode;
@@ -675,13 +675,13 @@
 
 	inode = bm_get_inode(sb, S_IFDIR | 0755);
 	if (!inode)
-		return NULL;
+		return -ENOMEM;
 	inode->i_op = &bm_dir_inode_operations;
 	inode->i_fop = &bm_dir_operations;
 	dentry[0] = d_alloc_root(inode);
 	if (!dentry[0]) {
 		iput(inode);
-		return NULL;
+		return -ENOMEM;
 	}
 	dentry[1] = d_alloc(dentry[0], &names[0]);
 	if (!dentry[1])
@@ -701,7 +701,7 @@
 	d_add(dentry[2], inode);
 
 	sb->s_root = dentry[0];
-	return sb;
+	return 0;
 
 out3:
 	dput(dentry[2]);
@@ -709,14 +709,26 @@
 	dput(dentry[1]);
 out1:
 	dput(dentry[0]);
-	return NULL;
+	return -ENOMEM;
+}
+
+static struct super_block *bm_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, bm_fill_super);
 }
 
 static struct linux_binfmt misc_format = {
-	NULL, THIS_MODULE, load_misc_binary, NULL, NULL, 0
+	module: THIS_MODULE,
+	load_binary: load_misc_binary,
 };
 
-static DECLARE_FSTYPE(bm_fs_type, "binfmt_misc", bm_read_super, FS_SINGLE|FS_LITTER);
+static struct file_system_type bm_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"binfmt_misc",
+	get_sb:		bm_get_sb,
+	fs_flags:	FS_LITTER,
+};
 
 static int __init init_misc_binfmt(void)
 {
diff -urN linux-2.5.4-pre1/fs/bio.c linux/fs/bio.c
--- linux-2.5.4-pre1/fs/bio.c	Thu Dec 27 08:15:15 2001
+++ linux/fs/bio.c	Wed Feb  6 22:51:47 2002
@@ -33,20 +33,24 @@
 
 struct biovec_pool {
 	int size;
+	char *name; 
 	kmem_cache_t *slab;
 	mempool_t *pool;
 };
 
-static struct biovec_pool bvec_array[BIOVEC_NR_POOLS];
-
 /*
  * if you change this list, also change bvec_alloc or things will
  * break badly! cannot be bigger than what you can fit into an
  * unsigned short
  */
-static const int bvec_pool_sizes[BIOVEC_NR_POOLS] = { 1, 4, 16, 64, 128, 256 };
 
-#define BIO_MAX_PAGES	(bvec_pool_sizes[BIOVEC_NR_POOLS - 1])
+#define BV(x) { x, "biovec-" #x }
+static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = { 
+	BV(1), BV(4), BV(16), BV(64), BV(128), BV(256)
+}; 
+#undef BV
+
+#define BIO_MAX_PAGES	(bvec_array[BIOVEC_NR_POOLS - 1].size)
 
 static void *slab_pool_alloc(int gfp_mask, void *data)
 {
@@ -64,7 +68,7 @@
 	struct bio_vec *bvl;
 
 	/*
-	 * see comment near bvec_pool_sizes define!
+	 * see comment near bvec_array define!
 	 */
 	switch (nr) {
 		case   1        : *idx = 0; break;
@@ -452,21 +456,17 @@
 
 static void __init biovec_init_pool(void)
 {
-	char name[16];
 	int i, size;
 
-	memset(&bvec_array, 0, sizeof(bvec_array));
-
 	for (i = 0; i < BIOVEC_NR_POOLS; i++) {
 		struct biovec_pool *bp = bvec_array + i;
 
-		size = bvec_pool_sizes[i] * sizeof(struct bio_vec);
+		size = bp->size * sizeof(struct bio_vec);
 
 		printk("biovec: init pool %d, %d entries, %d bytes\n", i,
-						bvec_pool_sizes[i], size);
+						bp->size, size);
 
-		snprintf(name, sizeof(name) - 1,"biovec-%d",bvec_pool_sizes[i]);
-		bp->slab = kmem_cache_create(name, size, 0,
+		bp->slab = kmem_cache_create(bp->name, size, 0,
 						SLAB_HWCACHE_ALIGN, NULL, NULL);
 		if (!bp->slab)
 			panic("biovec: can't init slab cache\n");
@@ -474,7 +474,7 @@
 					slab_pool_free, bp->slab);
 		if (!bp->pool)
 			panic("biovec: can't init mempool\n");
-		bp->size = size;
+		bp->size = size;	
 	}
 }
 
diff -urN linux-2.5.4-pre1/fs/block_dev.c linux/fs/block_dev.c
--- linux-2.5.4-pre1/fs/block_dev.c	Tue Jan 29 21:15:47 2002
+++ linux/fs/block_dev.c	Wed Feb  6 22:51:47 2002
@@ -220,7 +220,7 @@
  * pseudo-fs
  */
 
-static struct super_block *bd_read_super(struct super_block *sb, void *data, int silent)
+static int bd_fill_super(struct super_block *sb, void *data, int silent)
 {
 	static struct super_operations sops = {};
 	struct inode *root;
@@ -232,22 +232,32 @@
 	sb->s_op = &sops;
 	root = new_inode(sb);
 	if (!root)
-		return NULL;
+		return -ENOMEM;
 	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
 	root->i_uid = root->i_gid = 0;
 	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
 	sb->s_root = d_alloc(NULL, &(const struct qstr) { "bdev:", 5, 0 });
 	if (!sb->s_root) {
 		iput(root);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root->d_sb = sb;
 	sb->s_root->d_parent = sb->s_root;
 	d_instantiate(sb->s_root, root);
-	return sb;
+	return 0;
 }
 
-static DECLARE_FSTYPE(bd_type, "bdev", bd_read_super, FS_NOMOUNT);
+static struct super_block *bd_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, bd_fill_super);
+}
+
+static struct file_system_type bd_type = {
+	name:		"bdev",
+	get_sb:		bd_get_sb,
+	fs_flags:	FS_NOMOUNT,
+};
 
 static struct vfsmount *bd_mnt;
 
diff -urN linux-2.5.4-pre1/fs/dcache.c linux/fs/dcache.c
--- linux-2.5.4-pre1/fs/dcache.c	Mon Jan 14 09:41:57 2002
+++ linux/fs/dcache.c	Wed Feb  6 22:51:47 2002
@@ -1283,6 +1283,7 @@
 
 	dcache_init(mempages);
 	inode_init(mempages);
+	files_init(mempages); 
 	mnt_init(mempages);
 	bdev_cache_init();
 	cdev_cache_init();
diff -urN linux-2.5.4-pre1/fs/devfs/base.c linux/fs/devfs/base.c
--- linux-2.5.4-pre1/fs/devfs/base.c	Tue Jan 29 10:59:46 2002
+++ linux/fs/devfs/base.c	Wed Feb  6 22:51:47 2002
@@ -3218,8 +3218,7 @@
     setattr:        devfs_notify_change,
 };
 
-static struct super_block *devfs_read_super (struct super_block *sb,
-					     void *data, int silent)
+static int devfs_fill_super (struct super_block *sb, void *data, int silent)
 {
     struct inode *root_inode = NULL;
 
@@ -3238,17 +3237,24 @@
     sb->s_root = d_alloc_root (root_inode);
     if (!sb->s_root) goto out_no_root;
     DPRINTK (DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->u.generic_sbp);
-    return sb;
+    return 0;
 
 out_no_root:
     PRINTK ("(): get root inode failed\n");
     if (root_inode) iput (root_inode);
-    return NULL;
+    return -EINVAL;
 }   /*  End Function devfs_read_super  */
 
+static struct super_block *devfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, devfs_fill_super);
+}
 
-static DECLARE_FSTYPE (devfs_fs_type, DEVFS_NAME, devfs_read_super, FS_SINGLE);
-
+static struct file_system_type devfs_fs_type = {
+	name:		DEVFS_NAME,
+	get_sb:		devfs_get_sb,
+};
 
 /*  File operations for devfsd follow  */
 
diff -urN linux-2.5.4-pre1/fs/devpts/inode.c linux/fs/devpts/inode.c
--- linux-2.5.4-pre1/fs/devpts/inode.c	Fri Jan 18 16:00:26 2002
+++ linux/fs/devpts/inode.c	Wed Feb  6 22:51:47 2002
@@ -118,9 +118,9 @@
 	return 0;
 }
 
-struct super_block *devpts_read_super(struct super_block *s, void *data,
-				      int silent)
+static int devpts_fill_super(struct super_block *s, void *data, int silent)
 {
+	int error = -ENOMEM;
 	struct inode * inode;
 	struct devpts_sb_info *sbi;
 
@@ -136,6 +136,7 @@
 	memset(sbi->inodes, 0, sizeof(struct inode *) * sbi->max_ptys);
 
 	if ( devpts_parse_options(data,sbi) && !silent) {
+		error = -EINVAL;
 		printk("devpts: called with bogus options\n");
 		goto fail_free;
 	}
@@ -160,14 +161,14 @@
 
 	s->s_root = d_alloc_root(inode);
 	if (s->s_root)
-		return s;
+		return 0;
 	
 	printk("devpts: get root dentry failed\n");
 	iput(inode);
 fail_free:
 	kfree(sbi);
 fail:
-	return NULL;
+	return error;
 }
 
 static int devpts_statfs(struct super_block *sb, struct statfs *buf)
@@ -178,7 +179,17 @@
 	return 0;
 }
 
-static DECLARE_FSTYPE(devpts_fs_type, "devpts", devpts_read_super, FS_SINGLE);
+static struct super_block *devpts_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, devpts_fill_super);
+}
+
+static struct file_system_type devpts_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"devpts",
+	get_sb:		devpts_get_sb,
+};
 
 void devpts_pty_new(int number, kdev_t device)
 {
diff -urN linux-2.5.4-pre1/fs/driverfs/inode.c linux/fs/driverfs/inode.c
--- linux-2.5.4-pre1/fs/driverfs/inode.c	Mon Jan 28 16:57:27 2002
+++ linux/fs/driverfs/inode.c	Wed Feb  6 22:51:47 2002
@@ -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 @@
 {
 	loff_t retval = -EINVAL;
 
+	lock_kernel();
 	switch(orig) {
 	case 0:
 		if (offset > 0) {
@@ -357,6 +359,7 @@
 	default:
 		break;
 	}
+	unlock_kernel();
 	return retval;
 }
 
@@ -446,8 +449,7 @@
 	put_inode:	force_delete,
 };
 
-static struct super_block*
-driverfs_read_super(struct super_block *sb, void *data, int silent)
+static int driverfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
@@ -460,20 +462,31 @@
 
 	if (!inode) {
 		DBG("%s: could not get inode!\n",__FUNCTION__);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	root = d_alloc_root(inode);
 	if (!root) {
 		DBG("%s: could not get root dentry!\n",__FUNCTION__);
 		iput(inode);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root = root;
-	return sb;
+	return 0;
 }
 
-static DECLARE_FSTYPE(driverfs_fs_type, "driverfs", driverfs_read_super, FS_SINGLE | FS_LITTER);
+static struct super_block *driverfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, driverfs_fill_super);
+}
+
+static struct file_system_type driverfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"driverfs",
+	get_sb:		driverfs_get_sb,
+	fs_flags:	FS_LITTER,
+};
 
 static int get_mount(void)
 {
diff -urN linux-2.5.4-pre1/fs/ext2/ext2.h linux/fs/ext2/ext2.h
--- linux-2.5.4-pre1/fs/ext2/ext2.h	Tue Jan 29 21:41:28 2002
+++ linux/fs/ext2/ext2.h	Wed Feb  6 22:51:47 2002
@@ -96,7 +96,6 @@
 extern void ext2_put_super (struct super_block *);
 extern void ext2_write_super (struct super_block *);
 extern int ext2_remount (struct super_block *, int *, char *);
-extern struct super_block * ext2_read_super (struct super_block *,void *,int);
 extern int ext2_statfs (struct super_block *, struct statfs *);
 
 /*
diff -urN linux-2.5.4-pre1/fs/ext2/super.c linux/fs/ext2/super.c
--- linux-2.5.4-pre1/fs/ext2/super.c	Mon Jan 21 15:37:32 2002
+++ linux/fs/ext2/super.c	Wed Feb  6 22:51:47 2002
@@ -441,8 +441,7 @@
 	return res;
 }
 
-struct super_block * ext2_read_super (struct super_block * sb, void * data,
-				      int silent)
+static int ext2_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct buffer_head * bh;
 	struct ext2_super_block * es;
@@ -465,14 +464,13 @@
 
 	sb->u.ext2_sb.s_mount_opt = 0;
 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
-	    &sb->u.ext2_sb.s_mount_opt)) {
-		return NULL;
-	}
+	    &sb->u.ext2_sb.s_mount_opt))
+		return -EINVAL;
 
 	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
 	if (!blocksize) {
 		printk ("EXT2-fs: unable to set blocksize\n");
-		return NULL;
+		return -EINVAL;
 	}
 
 	/*
@@ -487,7 +485,7 @@
 
 	if (!(bh = sb_bread(sb, logic_sb_block))) {
 		printk ("EXT2-fs: unable to read superblock\n");
-		return NULL;
+		return -EINVAL;
 	}
 	/*
 	 * Note: s_es must be initialized as soon as possible because
@@ -533,7 +531,7 @@
 
 		if (!sb_set_blocksize(sb, blocksize)) {
 			printk(KERN_ERR "EXT2-fs: blocksize too small for device.\n");
-			return NULL;
+			return -EINVAL;
 		}
 
 		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
@@ -684,14 +682,14 @@
 		goto failed_mount2;
 	}
 	ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
-	return sb;
+	return 0;
 failed_mount2:
 	for (i = 0; i < db_count; i++)
 		brelse(sb->u.ext2_sb.s_group_desc[i]);
 	kfree(sb->u.ext2_sb.s_group_desc);
 failed_mount:
 	brelse(bh);
-	return NULL;
+	return -EINVAL;
 }
 
 static void ext2_commit_super (struct super_block * sb,
@@ -843,7 +841,18 @@
 	return 0;
 }
 
-static DECLARE_FSTYPE_DEV(ext2_fs_type, "ext2", ext2_read_super);
+static struct super_block *ext2_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super);
+}
+
+static struct file_system_type ext2_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"ext2",
+	get_sb:		ext2_get_sb,
+	fs_flags:	FS_REQUIRES_DEV,
+};
 
 static int __init init_ext2_fs(void)
 {
diff -urN linux-2.5.4-pre1/fs/fat/fatfs_syms.c linux/fs/fat/fatfs_syms.c
--- linux-2.5.4-pre1/fs/fat/fatfs_syms.c	Mon Jan 28 13:20:44 2002
+++ linux/fs/fat/fatfs_syms.c	Wed Feb  6 22:51:47 2002
@@ -47,5 +47,10 @@
 	return fat_init_inodecache();
 }
 
+static void __exit exit_fat_fs(void)
+{
+	fat_destroy_inodecache();
+}
+
 module_init(init_fat_fs)
-module_exit(fat_destroy_inodecache)
+module_exit(exit_fat_fs)
diff -urN linux-2.5.4-pre1/fs/file_table.c linux/fs/file_table.c
--- linux-2.5.4-pre1/fs/file_table.c	Mon Sep 17 13:16:30 2001
+++ linux/fs/file_table.c	Wed Feb  6 22:51:47 2002
@@ -186,3 +186,17 @@
 	file_list_unlock();
 	return 0;
 }
+
+void __init files_init(unsigned long mempages)
+{ 
+	int n; 
+	/* One file with associated inode and dcache is very roughly 1K. 
+	 * Per default don't use more than 10% of our memory for files. 
+	 */ 
+
+	n = (mempages * (PAGE_SIZE / 1024)) / 10;
+	files_stat.max_files = n; 
+	if (files_stat.max_files < NR_FILE)
+		files_stat.max_files = NR_FILE;
+} 
+
diff -urN linux-2.5.4-pre1/fs/hfs/catalog.c linux/fs/hfs/catalog.c
--- linux-2.5.4-pre1/fs/hfs/catalog.c	Mon Oct 15 19:30:33 2001
+++ linux/fs/hfs/catalog.c	Wed Feb  6 22:51:47 2002
@@ -1346,13 +1346,6 @@
 		return -EINVAL;
 	}
 
-	while (mdb->rename_lock) {
-		hfs_sleep_on(&mdb->rename_wait);
-	}
-	spin_lock(&entry_lock);
-	mdb->rename_lock = 1; /* XXX: should be atomic_inc */
-	spin_unlock(&entry_lock);
-
 	/* keep readers from getting confused by changing dir size */
 	start_write(new_dir);
 	if (old_dir != new_dir) {
@@ -1567,11 +1560,6 @@
 		end_write(old_dir);
 	}
 	end_write(new_dir);
-	spin_lock(&entry_lock);
-	mdb->rename_lock = 0; /* XXX: should use atomic_dec */
-	hfs_wake_up(&mdb->rename_wait);
-	spin_unlock(&entry_lock);
-
 	return error;
 }
 
diff -urN linux-2.5.4-pre1/fs/hfs/extent.c linux/fs/hfs/extent.c
--- linux-2.5.4-pre1/fs/hfs/extent.c	Tue Feb 13 14:13:45 2001
+++ linux/fs/hfs/extent.c	Wed Feb  6 22:51:47 2002
@@ -48,10 +48,7 @@
  * Get an exclusive lock on the B-tree bitmap.
  */
 static inline void lock_bitmap(struct hfs_mdb *mdb) {
-	while (mdb->bitmap_lock) {
-		hfs_sleep_on(&mdb->bitmap_wait);
-	}
-	mdb->bitmap_lock = 1;
+	down(&mdb->bitmap_sem);
 }
 
 /*
@@ -60,8 +57,7 @@
  * Relinquish an exclusive lock on the B-tree bitmap.
  */
 static inline void unlock_bitmap(struct hfs_mdb *mdb) {
-	mdb->bitmap_lock = 0;
-	hfs_wake_up(&mdb->bitmap_wait);
+	up(&mdb->bitmap_sem);
 }
 
 /*
diff -urN linux-2.5.4-pre1/fs/hfs/file_cap.c linux/fs/hfs/file_cap.c
--- linux-2.5.4-pre1/fs/hfs/file_cap.c	Tue Jan 29 21:15:47 2002
+++ linux/fs/hfs/file_cap.c	Wed Feb  6 22:51:47 2002
@@ -24,6 +24,7 @@
 #include <linux/hfs_fs_sb.h>
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
+#include <linux/smp_lock.h>
 
 /*================ Forward declarations ================*/
 static loff_t      cap_info_llseek(struct file *, loff_t,
diff -urN linux-2.5.4-pre1/fs/hfs/file_hdr.c linux/fs/hfs/file_hdr.c
--- linux-2.5.4-pre1/fs/hfs/file_hdr.c	Tue Jan 29 21:15:47 2002
+++ linux/fs/hfs/file_hdr.c	Wed Feb  6 22:51:47 2002
@@ -29,6 +29,7 @@
 #include <linux/hfs_fs_sb.h>
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
+#include <linux/smp_lock.h>
 
 /* prodos types */
 #define PRODOSI_FTYPE_DIR   0x0F
diff -urN linux-2.5.4-pre1/fs/hfs/hfs.h linux/fs/hfs/hfs.h
--- linux-2.5.4-pre1/fs/hfs/hfs.h	Sun Dec 16 12:23:00 2001
+++ linux/fs/hfs/hfs.h	Wed Feb  6 22:51:47 2002
@@ -271,10 +271,7 @@
 						   512-byte blocks per
 						   "allocation block" */
 	hfs_u16			attrib;		/* Attribute word */
-	hfs_wait_queue		rename_wait;
-	int			rename_lock;
-	hfs_wait_queue		bitmap_wait;
-	int			bitmap_lock;
+	struct semaphore	bitmap_sem;
         struct list_head        entry_dirty;
 };
 
diff -urN linux-2.5.4-pre1/fs/hfs/mdb.c linux/fs/hfs/mdb.c
--- linux-2.5.4-pre1/fs/hfs/mdb.c	Tue Feb 13 14:13:45 2001
+++ linux/fs/hfs/mdb.c	Wed Feb  6 22:51:47 2002
@@ -100,8 +100,7 @@
 	mdb->magic = HFS_MDB_MAGIC;
 	mdb->sys_mdb = sys_mdb;
 	INIT_LIST_HEAD(&mdb->entry_dirty);
-	hfs_init_waitqueue(&mdb->rename_wait);
-	hfs_init_waitqueue(&mdb->bitmap_wait);
+	init_MUTEX(&mdb->bitmap_sem);
 
 	/* See if this is an HFS filesystem */
 	buf = hfs_buffer_get(sys_mdb, part_start + HFS_MDB_BLK, 1);
diff -urN linux-2.5.4-pre1/fs/hpfs/buffer.c linux/fs/hpfs/buffer.c
--- linux-2.5.4-pre1/fs/hpfs/buffer.c	Mon Jan 21 15:37:32 2002
+++ linux/fs/hpfs/buffer.c	Wed Feb  6 22:51:47 2002
@@ -14,8 +14,7 @@
 #ifdef DEBUG_LOCKS
 	printk("lock creation\n");
 #endif
-	while (s->s_hpfs_creation_de_lock) sleep_on(&s->s_hpfs_creation_de);
-	s->s_hpfs_creation_de_lock = 1;
+	down(&s->u.hpfs_sb.hpfs_creation_de);
 }
 
 void hpfs_unlock_creation(struct super_block *s)
@@ -23,8 +22,7 @@
 #ifdef DEBUG_LOCKS
 	printk("unlock creation\n");
 #endif
-	s->s_hpfs_creation_de_lock = 0;
-	wake_up(&s->s_hpfs_creation_de);
+	up(&s->u.hpfs_sb.hpfs_creation_de);
 }
 
 void hpfs_lock_iget(struct super_block *s, int mode)
diff -urN linux-2.5.4-pre1/fs/hpfs/super.c linux/fs/hpfs/super.c
--- linux-2.5.4-pre1/fs/hpfs/super.c	Mon Jan 21 15:37:32 2002
+++ linux/fs/hpfs/super.c	Wed Feb  6 22:51:47 2002
@@ -427,8 +427,8 @@
 	s->s_hpfs_bmp_dir = NULL;
 	s->s_hpfs_cp_table = NULL;
 
-	s->s_hpfs_creation_de_lock = s->s_hpfs_rd_inode = 0;
-	init_waitqueue_head(&s->s_hpfs_creation_de);
+	s->s_hpfs_rd_inode = 0;
+	init_MUTEX(&s->u.hpfs_sb.hpfs_creation_de);
 	init_waitqueue_head(&s->s_hpfs_iget_q);
 
 	uid = current->uid;
diff -urN linux-2.5.4-pre1/fs/namespace.c linux/fs/namespace.c
--- linux-2.5.4-pre1/fs/namespace.c	Wed Jan 23 15:32:20 2002
+++ linux/fs/namespace.c	Wed Feb  6 22:51:47 2002
@@ -1048,15 +1048,9 @@
 	if (!mnt_cache)
 		panic("Cannot create vfsmount cache");
 
-	mempages >>= (16 - PAGE_SHIFT);
-	mempages *= sizeof(struct list_head);
-	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)
-		;
-
-	do {
-		mount_hashtable = (struct list_head *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (mount_hashtable == NULL && --order >= 0);
+	order = 0; 
+	mount_hashtable = (struct list_head *)
+		__get_free_pages(GFP_ATOMIC, order);
 
 	if (!mount_hashtable)
 		panic("Failed to allocate mount hash table\n");
diff -urN linux-2.5.4-pre1/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- linux-2.5.4-pre1/fs/ncpfs/file.c	Mon Sep 10 09:04:53 2001
+++ linux/fs/ncpfs/file.c	Wed Feb  6 22:51:47 2002
@@ -18,6 +18,7 @@
 #include <linux/locks.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/smp_lock.h>
 
 #include <linux/ncp_fs.h>
 #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.5.4-pre1/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- linux-2.5.4-pre1/fs/ncpfs/inode.c	Wed Jan 23 15:32:20 2002
+++ linux/fs/ncpfs/inode.c	Wed Feb  6 22:51:47 2002
@@ -365,7 +365,7 @@
 	sock_inode = ncp_filp->f_dentry->d_inode;
 	if (!S_ISSOCK(sock_inode->i_mode))
 		goto out_bad_file2;
-	sock = &sock_inode->u.socket_i;
+	sock = SOCKET_I(sock_inode);
 	if (!sock)
 		goto out_bad_file2;
 		
diff -urN linux-2.5.4-pre1/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c
--- linux-2.5.4-pre1/fs/ncpfs/sock.c	Sat Jan 20 08:51:51 2001
+++ linux/fs/ncpfs/sock.c	Wed Feb  6 22:51:47 2002
@@ -101,7 +101,7 @@
 	struct ncp_reply_header reply;
 
 	file = server->ncp_filp;
-	sock = &file->f_dentry->d_inode->u.socket_i;
+	sock = SOCKET_I(file->f_dentry->d_inode);
 
 	init_timeout = server->m.time_out;
 	max_timeout = NCP_MAX_RPC_TIMEOUT;
@@ -269,7 +269,7 @@
 	int result = 0;
 	
 	file = server->ncp_filp;
-	sock = &file->f_dentry->d_inode->u.socket_i;
+	sock = SOCKET_I(file->f_dentry->d_inode);
 	
 	dataread = 0;
 
@@ -348,7 +348,7 @@
 	*((struct ncp_request_header *) (server->packet));
 
 	file = server->ncp_filp;
-	sock = &file->f_dentry->d_inode->u.socket_i;
+	sock = SOCKET_I(file->f_dentry->d_inode);
 	
 	ncptcp_xmit_hdr[0] = htonl(NCP_TCP_XMIT_MAGIC);
 	ncptcp_xmit_hdr[1] = htonl(size + 16);
@@ -444,7 +444,7 @@
 	}
 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
 	file = server->ncp_filp;
-	sock = &file->f_dentry->d_inode->u.socket_i;
+	sock = SOCKET_I(file->f_dentry->d_inode);
 	/* N.B. this isn't needed ... check socket type? */
 	if (!sock) {
 		printk(KERN_ERR "ncp_rpc_call: socki_lookup failed\n");
diff -urN linux-2.5.4-pre1/fs/nfs/file.c linux/fs/nfs/file.c
--- linux-2.5.4-pre1/fs/nfs/file.c	Fri Jan  4 09:42:12 2002
+++ linux/fs/nfs/file.c	Wed Feb  6 22:51: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.5.4-pre1/fs/nfs/inode.c linux/fs/nfs/inode.c
--- linux-2.5.4-pre1/fs/nfs/inode.c	Wed Feb  6 22:51:45 2002
+++ linux/fs/nfs/inode.c	Wed Feb  6 22:51:47 2002
@@ -245,8 +245,7 @@
  * and the root file handle obtained from the server's mount
  * daemon. We stash these away in the private superblock fields.
  */
-struct super_block *
-nfs_read_super(struct super_block *sb, void *raw_data, int silent)
+int nfs_fill_super(struct super_block *sb, void *raw_data, int silent)
 {
 	struct nfs_mount_data	*data = (struct nfs_mount_data *) raw_data;
 	struct nfs_server	*server;
@@ -455,6 +454,8 @@
                 server->namelen = maxlen;
 
 	sb->s_maxbytes = fsinfo.maxfilesize;
+	if (sb->s_maxbytes > MAX_LFS_FILESIZE) 
+		sb->s_maxbytes = MAX_LFS_FILESIZE; 
 
 	/* Fire up the writeback cache */
 	if (nfs_reqlist_alloc(server) < 0) {
@@ -467,7 +468,7 @@
 	/* Check whether to start the lockd process */
 	if (!(server->flags & NFS_MOUNT_NONLM))
 		lockd_up();
-	return sb;
+	return 0;
 
 	/* Yargs. It didn't work out. */
  failure_kill_reqlist:
@@ -506,7 +507,7 @@
 	printk("nfs_read_super: missing data argument\n");
 
 out_fail:
-	return NULL;
+	return -EINVAL;
 }
 
 static int
@@ -1137,7 +1138,25 @@
 /*
  * File system information
  */
-static DECLARE_FSTYPE(nfs_fs_type, "nfs", nfs_read_super, FS_ODD_RENAME);
+
+/*
+ *  Right now we are using get_sb_nodev, but we ought to switch to
+ *  get_anon_super() with appropriate comparison function.  The only
+ *  question being, when two NFS mounts are the same?  Identical IP
+ *  of server + identical root fhandle?  Trond?
+ */
+static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, nfs_fill_super);
+}
+
+static struct file_system_type nfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"nfs",
+	get_sb:		nfs_get_sb,
+	fs_flags:	FS_ODD_RENAME,
+};
 
 extern int nfs_init_nfspagecache(void);
 extern void nfs_destroy_nfspagecache(void);
diff -urN linux-2.5.4-pre1/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- linux-2.5.4-pre1/fs/ntfs/fs.c	Mon Jan 28 13:20:35 2002
+++ linux/fs/ntfs/fs.c	Wed Feb  6 22:51:47 2002
@@ -1130,7 +1130,7 @@
 	/* Inform the kernel about which super operations are available. */
 	sb->s_op = &ntfs_super_operations;
 	sb->s_magic = NTFS_SUPER_MAGIC;
-	sb->s_maxbytes = ~0ULL >> 1;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	ntfs_debug(DEBUG_OTHER, "Reading special files\n");
 	if (ntfs_load_special_files(vol)) {
 		ntfs_error("Error loading special files\n");
diff -urN linux-2.5.4-pre1/fs/openpromfs/inode.c linux/fs/openpromfs/inode.c
--- linux-2.5.4-pre1/fs/openpromfs/inode.c	Mon Jan 14 10:10:44 2002
+++ linux/fs/openpromfs/inode.c	Wed Feb  6 22:51:47 2002
@@ -998,8 +998,7 @@
 	statfs:		openprom_statfs,
 };
 
-struct super_block *openprom_read_super(struct super_block *s,void *data, 
-				    int silent)
+static int openprom_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
 
@@ -1013,15 +1012,25 @@
 	s->s_root = d_alloc_root(root_inode);
 	if (!s->s_root)
 		goto out_no_root;
-	return s;
+	return 0;
 
 out_no_root:
-	printk("openprom_read_super: get root inode failed\n");
+	printk("openprom_fill_super: get root inode failed\n");
 	iput(root_inode);
-	return NULL;
+	return -ENOMEM;
 }
 
-static DECLARE_FSTYPE(openprom_fs_type, "openpromfs", openprom_read_super, 0);
+static struct super_block *openprom_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, openprom_fill_super);
+}
+
+static struct file_system_type openprom_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"openpromfs",
+	get_sb:		openprom_get_sb,
+};
 
 static int __init init_openprom_fs(void)
 {
diff -urN linux-2.5.4-pre1/fs/pipe.c linux/fs/pipe.c
--- linux-2.5.4-pre1/fs/pipe.c	Fri Jan 18 16:00:26 2002
+++ linux/fs/pipe.c	Wed Feb  6 22:51:47 2002
@@ -246,12 +246,6 @@
 	return -EPIPE;
 }
 
-static loff_t
-pipe_lseek(struct file *file, loff_t offset, int orig)
-{
-	return -ESPIPE;
-}
-
 static ssize_t
 bad_pipe_r(struct file *filp, char *buf, size_t count, loff_t *ppos)
 {
@@ -381,7 +375,7 @@
  * are also used in linux/fs/fifo.c to do operations on FIFOs.
  */
 struct file_operations read_fifo_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		bad_pipe_w,
 	poll:		fifo_poll,
@@ -391,7 +385,7 @@
 };
 
 struct file_operations write_fifo_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		bad_pipe_r,
 	write:		pipe_write,
 	poll:		fifo_poll,
@@ -401,7 +395,7 @@
 };
 
 struct file_operations rdwr_fifo_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		pipe_write,
 	poll:		fifo_poll,
@@ -411,7 +405,7 @@
 };
 
 struct file_operations read_pipe_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		bad_pipe_w,
 	poll:		pipe_poll,
@@ -421,7 +415,7 @@
 };
 
 struct file_operations write_pipe_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		bad_pipe_r,
 	write:		pipe_write,
 	poll:		pipe_poll,
@@ -431,7 +425,7 @@
 };
 
 struct file_operations rdwr_pipe_fops = {
-	llseek:		pipe_lseek,
+	llseek:		no_llseek,
 	read:		pipe_read,
 	write:		pipe_write,
 	poll:		pipe_poll,
@@ -606,7 +600,7 @@
 	statfs:		pipefs_statfs,
 };
 
-static struct super_block * pipefs_read_super(struct super_block *sb, void *data, int silent)
+static int pipefs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *root;
 
@@ -616,22 +610,32 @@
 	sb->s_op	= &pipefs_ops;
 	root = new_inode(sb);
 	if (!root)
-		return NULL;
+		return -ENOMEM;
 	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
 	root->i_uid = root->i_gid = 0;
 	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
 	sb->s_root = d_alloc(NULL, &(const struct qstr) { "pipe:", 5, 0 });
 	if (!sb->s_root) {
 		iput(root);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root->d_sb = sb;
 	sb->s_root->d_parent = sb->s_root;
 	d_instantiate(sb->s_root, root);
-	return sb;
+	return 0;
 }
 
-static DECLARE_FSTYPE(pipe_fs_type, "pipefs", pipefs_read_super, FS_NOMOUNT);
+static struct super_block *pipefs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, pipefs_fill_super);
+}
+
+static struct file_system_type pipe_fs_type = {
+	name:		"pipefs",
+	get_sb:		pipefs_get_sb,
+	fs_flags:	FS_NOMOUNT,
+};
 
 static int __init init_pipe_fs(void)
 {
diff -urN linux-2.5.4-pre1/fs/proc/base.c linux/fs/proc/base.c
--- linux-2.5.4-pre1/fs/proc/base.c	Sat Dec 29 17:30:07 2001
+++ linux/fs/proc/base.c	Wed Feb  6 22:51:47 2002
@@ -37,6 +37,11 @@
 
 #define fake_ino(pid,ino) (((pid)<<16)|(ino))
 
+static inline struct task_struct *proc_task(struct inode *inode)
+{
+	return PROC_I(inode)->task;
+}
+
 ssize_t proc_pid_read_maps(struct task_struct*,struct file*,char*,size_t,loff_t*);
 int proc_pid_stat(struct task_struct*,char*);
 int proc_pid_status(struct task_struct*,char*);
@@ -45,9 +50,10 @@
 
 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
-	if (inode->u.proc_i.file) {
-		*mnt = mntget(inode->u.proc_i.file->f_vfsmnt);
-		*dentry = dget(inode->u.proc_i.file->f_dentry);
+	struct file *file = PROC_I(inode)->file;
+	if (file) {
+		*mnt = mntget(file->f_vfsmnt);
+		*dentry = dget(file->f_dentry);
 		return 0;
 	}
 	return -ENOENT;
@@ -58,7 +64,7 @@
 	struct mm_struct * mm;
 	struct vm_area_struct * vma;
 	int result = -ENOENT;
-	struct task_struct *task = inode->u.proc_i.task;
+	struct task_struct *task = proc_task(inode);
 
 	task_lock(task);
 	mm = task->mm;
@@ -89,11 +95,11 @@
 {
 	struct fs_struct *fs;
 	int result = -ENOENT;
-	task_lock(inode->u.proc_i.task);
-	fs = inode->u.proc_i.task->fs;
+	task_lock(proc_task(inode));
+	fs = proc_task(inode)->fs;
 	if(fs)
 		atomic_inc(&fs->count);
-	task_unlock(inode->u.proc_i.task);
+	task_unlock(proc_task(inode));
 	if (fs) {
 		read_lock(&fs->lock);
 		*mnt = mntget(fs->pwdmnt);
@@ -109,11 +115,11 @@
 {
 	struct fs_struct *fs;
 	int result = -ENOENT;
-	task_lock(inode->u.proc_i.task);
-	fs = inode->u.proc_i.task->fs;
+	task_lock(proc_task(inode));
+	fs = proc_task(inode)->fs;
 	if(fs)
 		atomic_inc(&fs->count);
-	task_unlock(inode->u.proc_i.task);
+	task_unlock(proc_task(inode));
 	if (fs) {
 		read_lock(&fs->lock);
 		*mnt = mntget(fs->rootmnt);
@@ -238,7 +244,7 @@
 			      size_t count, loff_t *ppos)
 {
 	struct inode * inode = file->f_dentry->d_inode;
-	struct task_struct *task = inode->u.proc_i.task;
+	struct task_struct *task = proc_task(inode);
 	ssize_t res;
 
 	res = proc_pid_read_maps(task, file, buf, count, ppos);
@@ -252,7 +258,7 @@
 extern struct seq_operations mounts_op;
 static int mounts_open(struct inode *inode, struct file *file)
 {
-	struct task_struct *task = inode->u.proc_i.task;
+	struct task_struct *task = proc_task(inode);
 	int ret = seq_open(file, &mounts_op);
 
 	if (!ret) {
@@ -298,14 +304,14 @@
 	unsigned long page;
 	ssize_t length;
 	ssize_t end;
-	struct task_struct *task = inode->u.proc_i.task;
+	struct task_struct *task = proc_task(inode);
 
 	if (count > PROC_BLOCK_SIZE)
 		count = PROC_BLOCK_SIZE;
 	if (!(page = __get_free_page(GFP_KERNEL)))
 		return -ENOMEM;
 
-	length = inode->u.proc_i.op.proc_read(task, (char*)page);
+	length = PROC_I(inode)->op.proc_read(task, (char*)page);
 
 	if (length < 0) {
 		free_page(page);
@@ -342,7 +348,7 @@
 static ssize_t mem_read(struct file * file, char * buf,
 			size_t count, loff_t *ppos)
 {
-	struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
+	struct task_struct *task = proc_task(file->f_dentry->d_inode);
 	char *page;
 	unsigned long src = *ppos;
 	int copied = 0;
@@ -404,7 +410,7 @@
 {
 	int copied = 0;
 	char *page;
-	struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task;
+	struct task_struct *task = proc_task(file->f_dentry->d_inode);
 	unsigned long dst = *ppos;
 
 	if (!MAY_PTRACE(task))
@@ -463,7 +469,7 @@
 	if (error)
 		goto out;
 
-	error = inode->u.proc_i.op.proc_get_link(inode, &nd->dentry, &nd->mnt);
+	error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
 	nd->last_type = LAST_BIND;
 out:
 	return error;
@@ -503,7 +509,7 @@
 	if (error)
 		goto out;
 
-	error = inode->u.proc_i.op.proc_get_link(inode, &de, &mnt);
+	error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
 	if (error)
 		goto out;
 
@@ -570,7 +576,7 @@
 static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir)
 {
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct task_struct *p = inode->u.proc_i.task;
+	struct task_struct *p = proc_task(inode);
 	unsigned int fd, pid, ino;
 	int retval;
 	char buf[NUMBUF];
@@ -598,6 +604,7 @@
 			task_unlock(p);
 			if (!files)
 				goto out;
+			read_lock(&files->file_lock);
 			for (fd = filp->f_pos-2;
 			     fd < files->max_fds;
 			     fd++, filp->f_pos++) {
@@ -605,6 +612,7 @@
 
 				if (!fcheck_files(files, fd))
 					continue;
+				read_unlock(&files->file_lock);
 
 				j = NUMBUF;
 				i = fd;
@@ -617,7 +625,9 @@
 				ino = fake_ino(pid, PROC_PID_FD_DIR + fd);
 				if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino, DT_LNK) < 0)
 					break;
+				read_lock(&files->file_lock);
 			}
+			read_unlock(&files->file_lock);
 			put_files_struct(files);
 	}
 out:
@@ -632,7 +642,7 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct pid_entry *p;
 
-	pid = inode->u.proc_i.task->pid;
+	pid = proc_task(inode)->pid;
 	if (!pid)
 		return -ENOENT;
 	i = filp->f_pos;
@@ -684,6 +694,7 @@
 static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino)
 {
 	struct inode * inode;
+	struct proc_inode *ei;
 
 	/* We need a new inode */
 	
@@ -692,7 +703,9 @@
 		goto out;
 
 	/* Common stuff */
-
+	ei = PROC_I(inode);
+	ei->task = NULL;
+	ei->file = NULL;
 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 	inode->i_ino = fake_ino(task->pid, ino);
 
@@ -703,7 +716,7 @@
 	 * grab the reference to task.
 	 */
 	get_task_struct(task);
-	inode->u.proc_i.task = task;
+	ei->task = task;
 	inode->i_uid = 0;
 	inode->i_gid = 0;
 	if (ino == PROC_PID_INO || task_dumpable(task)) {
@@ -733,7 +746,7 @@
  */
 static int pid_base_revalidate(struct dentry * dentry, int flags)
 {
-	if (dentry->d_inode->u.proc_i.task->pid)
+	if (proc_task(dentry->d_inode)->pid)
 		return 1;
 	d_drop(dentry);
 	return 0;
@@ -767,10 +780,11 @@
 static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry)
 {
 	unsigned int fd, c;
-	struct task_struct *task = dir->u.proc_i.task;
+	struct task_struct *task = proc_task(dir);
 	struct file * file;
 	struct files_struct * files;
 	struct inode *inode;
+	struct proc_inode *ei;
 	const char *name;
 	int len;
 
@@ -792,6 +806,7 @@
 	inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd);
 	if (!inode)
 		goto out;
+	ei = PROC_I(inode);
 	task_lock(task);
 	files = task->files;
 	if (files)
@@ -800,7 +815,7 @@
 	if (!files)
 		goto out_unlock;
 	read_lock(&files->file_lock);
-	file = inode->u.proc_i.file = fcheck_files(files, fd);
+	file = ei->file = fcheck_files(files, fd);
 	if (!file)
 		goto out_unlock2;
 	get_file(file);
@@ -809,7 +824,7 @@
 	inode->i_op = &proc_pid_link_inode_operations;
 	inode->i_size = 64;
 	inode->i_mode = S_IFLNK;
-	inode->u.proc_i.op.proc_get_link = proc_fd_link;
+	ei->op.proc_get_link = proc_fd_link;
 	if (file->f_mode & 1)
 		inode->i_mode |= S_IRUSR | S_IXUSR;
 	if (file->f_mode & 2)
@@ -844,8 +859,9 @@
 {
 	struct inode *inode;
 	int error;
-	struct task_struct *task = dir->u.proc_i.task;
+	struct task_struct *task = proc_task(dir);
 	struct pid_entry *p;
+	struct proc_inode *ei;
 
 	error = -ENOENT;
 	inode = NULL;
@@ -864,6 +880,7 @@
 	if (!inode)
 		goto out;
 
+	ei = PROC_I(inode);
 	inode->i_mode = p->mode;
 	/*
 	 * Yes, it does not scale. And it should not. Don't add
@@ -877,35 +894,35 @@
 			break;
 		case PROC_PID_EXE:
 			inode->i_op = &proc_pid_link_inode_operations;
-			inode->u.proc_i.op.proc_get_link = proc_exe_link;
+			ei->op.proc_get_link = proc_exe_link;
 			break;
 		case PROC_PID_CWD:
 			inode->i_op = &proc_pid_link_inode_operations;
-			inode->u.proc_i.op.proc_get_link = proc_cwd_link;
+			ei->op.proc_get_link = proc_cwd_link;
 			break;
 		case PROC_PID_ROOT:
 			inode->i_op = &proc_pid_link_inode_operations;
-			inode->u.proc_i.op.proc_get_link = proc_root_link;
+			ei->op.proc_get_link = proc_root_link;
 			break;
 		case PROC_PID_ENVIRON:
 			inode->i_fop = &proc_info_file_operations;
-			inode->u.proc_i.op.proc_read = proc_pid_environ;
+			ei->op.proc_read = proc_pid_environ;
 			break;
 		case PROC_PID_STATUS:
 			inode->i_fop = &proc_info_file_operations;
-			inode->u.proc_i.op.proc_read = proc_pid_status;
+			ei->op.proc_read = proc_pid_status;
 			break;
 		case PROC_PID_STAT:
 			inode->i_fop = &proc_info_file_operations;
-			inode->u.proc_i.op.proc_read = proc_pid_stat;
+			ei->op.proc_read = proc_pid_stat;
 			break;
 		case PROC_PID_CMDLINE:
 			inode->i_fop = &proc_info_file_operations;
-			inode->u.proc_i.op.proc_read = proc_pid_cmdline;
+			ei->op.proc_read = proc_pid_cmdline;
 			break;
 		case PROC_PID_STATM:
 			inode->i_fop = &proc_info_file_operations;
-			inode->u.proc_i.op.proc_read = proc_pid_statm;
+			ei->op.proc_read = proc_pid_statm;
 			break;
 		case PROC_PID_MAPS:
 			inode->i_fop = &proc_maps_operations;
@@ -913,7 +930,7 @@
 #ifdef CONFIG_SMP
 		case PROC_PID_CPU:
 			inode->i_fop = &proc_info_file_operations;
-			inode->u.proc_i.op.proc_read = proc_pid_cpu;
+			ei->op.proc_read = proc_pid_cpu;
 			break;
 #endif
 		case PROC_PID_MEM:
@@ -973,6 +990,7 @@
 	struct task_struct *task;
 	const char *name;
 	struct inode *inode;
+	struct proc_inode *ei;
 	int len;
 
 	pid = 0;
@@ -982,10 +1000,11 @@
 		inode = new_inode(dir->i_sb);
 		if (!inode)
 			return ERR_PTR(-ENOMEM);
+		ei = PROC_I(inode);
 		inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 		inode->i_ino = fake_ino(0, PROC_PID_INO);
-		inode->u.proc_i.file = NULL;
-		inode->u.proc_i.task = NULL;
+		ei->file = NULL;
+		ei->task = NULL;
 		inode->i_mode = S_IFLNK|S_IRWXUGO;
 		inode->i_uid = inode->i_gid = 0;
 		inode->i_size = 64;
@@ -1035,10 +1054,10 @@
 
 void proc_pid_delete_inode(struct inode *inode)
 {
-	if (inode->u.proc_i.file)
-		fput(inode->u.proc_i.file);
-	if (inode->u.proc_i.task)
-		free_task_struct(inode->u.proc_i.task);
+	if (PROC_I(inode)->file)
+		fput(PROC_I(inode)->file);
+	if (proc_task(inode))
+		free_task_struct(proc_task(inode));
 }
 
 #define PROC_NUMBUF 10
diff -urN linux-2.5.4-pre1/fs/proc/generic.c linux/fs/proc/generic.c
--- linux-2.5.4-pre1/fs/proc/generic.c	Tue Jan 29 21:15:47 2002
+++ linux/fs/proc/generic.c	Wed Feb  6 22:51:47 2002
@@ -58,7 +58,7 @@
 	char	*start;
 	struct proc_dir_entry * dp;
 
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	dp = PDE(inode);
 	if (!(page = (char*) __get_free_page(GFP_KERNEL)))
 		return -ENOMEM;
 
@@ -128,7 +128,7 @@
 	struct inode *inode = file->f_dentry->d_inode;
 	struct proc_dir_entry * dp;
 	
-	dp = (struct proc_dir_entry *) inode->u.generic_ip;
+	dp = PDE(inode);
 
 	if (!dp->write_proc)
 		return -EIO;
@@ -221,13 +221,13 @@
 
 static int proc_readlink(struct dentry *dentry, char *buffer, int buflen)
 {
-	char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
+	char *s=PDE(dentry->d_inode)->data;
 	return vfs_readlink(dentry, buffer, buflen, s);
 }
 
 static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-	char *s=((struct proc_dir_entry *)dentry->d_inode->u.generic_ip)->data;
+	char *s=PDE(dentry->d_inode)->data;
 	return vfs_follow_link(nd, s);
 }
 
@@ -264,7 +264,7 @@
 
 	error = -ENOENT;
 	inode = NULL;
-	de = (struct proc_dir_entry *) dir->u.generic_ip;
+	de = PDE(dir);
 	if (de) {
 		for (de = de->subdir; de ; de = de->next) {
 			if (!de || !de->low_ino)
@@ -306,7 +306,7 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 
 	ino = inode->i_ino;
-	de = (struct proc_dir_entry *) inode->u.generic_ip;
+	de = PDE(inode);
 	if (!de)
 		return -EINVAL;
 	i = filp->f_pos;
@@ -413,7 +413,7 @@
 		if (dentry->d_op != &proc_dentry_operations)
 			continue;
 		inode = dentry->d_inode;
-		if (inode->u.generic_ip != de)
+		if (PDE(inode) != de)
 			continue;
 		fops = filp->f_op;
 		filp->f_op = NULL;
diff -urN linux-2.5.4-pre1/fs/proc/inode.c linux/fs/proc/inode.c
--- linux-2.5.4-pre1/fs/proc/inode.c	Sat Nov 17 11:24:32 2001
+++ linux/fs/proc/inode.c	Wed Feb  6 22:51:47 2002
@@ -58,7 +58,7 @@
  */
 static void proc_delete_inode(struct inode *inode)
 {
-	struct proc_dir_entry *de = inode->u.generic_ip;
+	struct proc_dir_entry *de = PDE(inode);
 
 	inode->i_state = I_CLEAR;
 
@@ -91,14 +91,51 @@
 	return 0;
 }
 
+static kmem_cache_t * proc_inode_cachep;
+
+static struct inode *proc_alloc_inode(struct super_block *sb)
+{
+	struct proc_inode *ei;
+	ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL);
+	if (!ei)
+		return NULL;
+	return &ei->vfs_inode;
+}
+
+static void proc_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(proc_inode_cachep, PROC_I(inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+	struct proc_inode *ei = (struct proc_inode *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR)
+		inode_init_once(&ei->vfs_inode);
+}
+ 
+int __init proc_init_inodecache(void)
+{
+	proc_inode_cachep = kmem_cache_create("proc_inode_cache",
+					     sizeof(struct proc_inode),
+					     0, SLAB_HWCACHE_ALIGN,
+					     init_once, NULL);
+	if (proc_inode_cachep == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
 static struct super_operations proc_sops = { 
+	alloc_inode:	proc_alloc_inode,
+	destroy_inode:	proc_destroy_inode,
 	read_inode:	proc_read_inode,
 	put_inode:	force_delete,
 	delete_inode:	proc_delete_inode,
 	statfs:		proc_statfs,
 };
 
-
 static int parse_options(char *options,uid_t *uid,gid_t *gid)
 {
 	char *this_char,*value;
@@ -147,7 +184,7 @@
 	if (!inode)
 		goto out_fail;
 	
-	inode->u.generic_ip = (void *) de;
+	PROC_I(inode)->pde = de;
 	if (de) {
 		if (de->mode) {
 			inode->i_mode = de->mode;
@@ -176,8 +213,7 @@
 	goto out;
 }			
 
-struct super_block *proc_read_super(struct super_block *s,void *data, 
-				    int silent)
+int proc_fill_super(struct super_block *s, void *data, int silent)
 {
 	struct inode * root_inode;
 	struct task_struct *p;
@@ -200,11 +236,11 @@
 	if (!s->s_root)
 		goto out_no_root;
 	parse_options(data, &root_inode->i_uid, &root_inode->i_gid);
-	return s;
+	return 0;
 
 out_no_root:
 	printk("proc_read_super: get root inode failed\n");
 	iput(root_inode);
-	return NULL;
+	return -ENOMEM;
 }
 MODULE_LICENSE("GPL");
diff -urN linux-2.5.4-pre1/fs/proc/root.c linux/fs/proc/root.c
--- linux-2.5.4-pre1/fs/proc/root.c	Sat Oct 20 19:14:42 2001
+++ linux/fs/proc/root.c	Wed Feb  6 22:51:47 2002
@@ -23,11 +23,24 @@
 struct proc_dir_entry *proc_sys_root;
 #endif
 
-static DECLARE_FSTYPE(proc_fs_type, "proc", proc_read_super, FS_SINGLE);
+static struct super_block *proc_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, proc_fill_super);
+}
+
+static struct file_system_type proc_fs_type = {
+	name:		"proc",
+	get_sb:		proc_get_sb,
+};
 
+extern int __init proc_init_inodecache(void);
 void __init proc_root_init(void)
 {
-	int err = register_filesystem(&proc_fs_type);
+	int err = proc_init_inodecache();
+	if (err)
+		return;
+	err = register_filesystem(&proc_fs_type);
 	if (err)
 		return;
 	proc_mnt = kern_mount(&proc_fs_type);
diff -urN linux-2.5.4-pre1/fs/ramfs/inode.c linux/fs/ramfs/inode.c
--- linux-2.5.4-pre1/fs/ramfs/inode.c	Tue Dec 25 15:39:20 2001
+++ linux/fs/ramfs/inode.c	Wed Feb  6 22:51:47 2002
@@ -302,7 +302,7 @@
 	put_inode:	force_delete,
 };
 
-static struct super_block *ramfs_read_super(struct super_block * sb, void * data, int silent)
+static int ramfs_fill_super(struct super_block * sb, void * data, int silent)
 {
 	struct inode * inode;
 	struct dentry * root;
@@ -313,19 +313,33 @@
 	sb->s_op = &ramfs_ops;
 	inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
 	if (!inode)
-		return NULL;
+		return -ENOMEM;
 
 	root = d_alloc_root(inode);
 	if (!root) {
 		iput(inode);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root = root;
-	return sb;
+	return 0;
 }
 
-static DECLARE_FSTYPE(ramfs_fs_type, "ramfs", ramfs_read_super, FS_LITTER);
-static DECLARE_FSTYPE(rootfs_fs_type, "rootfs", ramfs_read_super, FS_NOMOUNT|FS_LITTER);
+static struct super_block *ramfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, ramfs_fill_super);
+}
+
+static struct file_system_type ramfs_fs_type = {
+	name:		"ramfs",
+	get_sb:		ramfs_get_sb,
+	fs_flags:	FS_LITTER,
+};
+static struct file_system_type rootfs_fs_type = {
+	name:		"rootfs",
+	get_sb:		ramfs_get_sb,
+	fs_flags:	FS_NOMOUNT|FS_LITTER,
+};
 
 static int __init init_ramfs_fs(void)
 {
diff -urN linux-2.5.4-pre1/fs/read_write.c linux/fs/read_write.c
--- linux-2.5.4-pre1/fs/read_write.c	Tue Jan 29 21:22:41 2002
+++ linux/fs/read_write.c	Wed Feb  6 22:51:47 2002
@@ -51,6 +51,31 @@
 	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->f_dentry->d_inode->i_size;
+			break;
+		case 1:
+			offset += file->f_pos;
+	}
+	retval = -EINVAL;
+	if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
+		if (offset != file->f_pos) {
+			file->f_pos = offset;
+			file->f_reada = 0;
+			file->f_version = ++event;
+		}
+		retval = offset;
+	}
+	unlock_kernel();
+	return retval;
+}
+
 loff_t no_llseek(struct file *file, loff_t offset, int origin)
 {
 	return -ESPIPE;
diff -urN linux-2.5.4-pre1/fs/reiserfs/inode.c linux/fs/reiserfs/inode.c
--- linux-2.5.4-pre1/fs/reiserfs/inode.c	Wed Feb  6 22:51:45 2002
+++ linux/fs/reiserfs/inode.c	Wed Feb  6 22:51:47 2002
@@ -890,6 +890,13 @@
     inode->i_blksize = PAGE_SIZE;
 
     INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
+    REISERFS_I(inode)->i_flags = 0;
+    REISERFS_I(inode)->i_prealloc_block = 0;
+    REISERFS_I(inode)->i_prealloc_count = 0;
+    REISERFS_I(inode)->i_trans_id = 0;
+    REISERFS_I(inode)->i_trans_index = 0;
+    /* nopack = 0, by default */
+    REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
 
     if (stat_data_v1 (ih)) {
 	struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
@@ -950,13 +957,6 @@
 	    set_inode_item_key_version (inode, KEY_FORMAT_3_6);
 	REISERFS_I(inode)->i_first_direct_byte = 0;
     }
-    REISERFS_I(inode)->i_flags = 0;
-    REISERFS_I(inode)->i_prealloc_block = 0;
-    REISERFS_I(inode)->i_prealloc_count = 0;
-    REISERFS_I(inode)->i_trans_id = 0;
-    REISERFS_I(inode)->i_trans_index = 0;
-    /* nopack = 0, by default */
-    REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
 
     pathrelse (path);
     if (S_ISREG (inode->i_mode)) {
diff -urN linux-2.5.4-pre1/fs/smbfs/file.c linux/fs/smbfs/file.c
--- linux-2.5.4-pre1/fs/smbfs/file.c	Mon Jan 28 13:20:34 2002
+++ linux/fs/smbfs/file.c	Wed Feb  6 22:51: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.5.4-pre1/fs/smbfs/sock.c linux/fs/smbfs/sock.c
--- linux-2.5.4-pre1/fs/smbfs/sock.c	Tue Oct  2 17:03:34 2001
+++ linux/fs/smbfs/sock.c	Wed Feb  6 22:51:47 2002
@@ -176,7 +176,7 @@
 smb_valid_socket(struct inode * inode)
 {
 	return (inode && S_ISSOCK(inode->i_mode) && 
-		inode->u.socket_i.type == SOCK_STREAM);
+		SOCKET_I(inode)->type == SOCK_STREAM);
 }
 
 static struct socket *
@@ -190,7 +190,7 @@
 		if (!smb_valid_socket(file->f_dentry->d_inode))
 			PARANOIA("bad socket!\n");
 #endif
-		return &file->f_dentry->d_inode->u.socket_i;
+		return SOCKET_I(file->f_dentry->d_inode);
 	}
 	return NULL;
 }
diff -urN linux-2.5.4-pre1/fs/stat.c linux/fs/stat.c
--- linux-2.5.4-pre1/fs/stat.c	Thu Sep 13 16:04:43 2001
+++ linux/fs/stat.c	Wed Feb  6 22:51:47 2002
@@ -25,68 +25,28 @@
 	return 0;
 }
 
-
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
-
-/*
- * For backward compatibility?  Maybe this should be moved
- * into arch/i386 instead?
- */
-static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
+static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
-	static int warncount = 5;
-	struct __old_kernel_stat tmp;
-
-	if (warncount > 0) {
-		warncount--;
-		printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
-			current->comm);
-	} else if (warncount < 0) {
-		/* it's laughable, but... */
-		warncount = 0;
-	}
-
-	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
-	tmp.st_ino = inode->i_ino;
-	tmp.st_mode = inode->i_mode;
-	tmp.st_nlink = inode->i_nlink;
-	SET_OLDSTAT_UID(tmp, inode->i_uid);
-	SET_OLDSTAT_GID(tmp, inode->i_gid);
-	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-#if BITS_PER_LONG == 32
-	if (inode->i_size > MAX_NON_LFS)
-		return -EOVERFLOW;
-#endif	
-	tmp.st_size = inode->i_size;
-	tmp.st_atime = inode->i_atime;
-	tmp.st_mtime = inode->i_mtime;
-	tmp.st_ctime = inode->i_ctime;
-	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
-}
-
-#endif
-
-static int cp_new_stat(struct inode * inode, struct stat * statbuf)
-{
-	struct stat tmp;
+	int res = 0;
 	unsigned int blocks, indirect;
+	struct inode *inode = dentry->d_inode;
 
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
-	tmp.st_ino = inode->i_ino;
-	tmp.st_mode = inode->i_mode;
-	tmp.st_nlink = inode->i_nlink;
-	SET_STAT_UID(tmp, inode->i_uid);
-	SET_STAT_GID(tmp, inode->i_gid);
-	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-#if BITS_PER_LONG == 32
-	if (inode->i_size > MAX_NON_LFS)
-		return -EOVERFLOW;
-#endif	
-	tmp.st_size = inode->i_size;
-	tmp.st_atime = inode->i_atime;
-	tmp.st_mtime = inode->i_mtime;
-	tmp.st_ctime = inode->i_ctime;
+	res = do_revalidate(dentry);
+	if (res)
+		return res;
+
+	stat->dev = kdev_t_to_nr(inode->i_dev);
+	stat->ino = inode->i_ino;
+	stat->mode = inode->i_mode;
+	stat->nlink = inode->i_nlink;
+	stat->uid = inode->i_uid;
+	stat->gid = inode->i_gid;
+	stat->rdev = kdev_t_to_nr(inode->i_rdev);
+	stat->atime = inode->i_atime;
+	stat->mtime = inode->i_mtime;
+	stat->ctime = inode->i_ctime;
+	stat->ctime = inode->i_ctime;
+	stat->size = inode->i_size;
 /*
  * st_blocks and st_blksize are approximated with a simple algorithm if
  * they aren't supported directly by the filesystem. The minix and msdos
@@ -106,7 +66,7 @@
 #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
 
 	if (!inode->i_blksize) {
-		blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
+		blocks = (stat->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
 		if (blocks > D_B) {
 			indirect = (blocks - D_B + I_B - 1) / I_B;
 			blocks += indirect;
@@ -117,130 +77,178 @@
 					blocks++;
 			}
 		}
-		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
-		tmp.st_blksize = BLOCK_SIZE;
+		stat->blocks = (BLOCK_SIZE / 512) * blocks;
+		stat->blksize = BLOCK_SIZE;
 	} else {
-		tmp.st_blocks = inode->i_blocks;
-		tmp.st_blksize = inode->i_blksize;
+		stat->blocks = inode->i_blocks;
+		stat->blksize = inode->i_blksize;
 	}
-	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+	return 0;
 }
 
-
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
-/*
- * For backward compatibility?  Maybe this should be moved
- * into arch/i386 instead?
- */
-asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
+int vfs_stat(char *name, struct kstat *stat)
 {
 	struct nameidata nd;
 	int error;
 
-	error = user_path_walk(filename, &nd);
+	error = user_path_walk(name, &nd);
 	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_old_stat(nd.dentry->d_inode, statbuf);
+		error = do_getattr(nd.mnt, nd.dentry, stat);
 		path_release(&nd);
 	}
 	return error;
 }
-#endif
 
-asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+int vfs_lstat(char *name, struct kstat *stat)
 {
 	struct nameidata nd;
 	int error;
 
-	error = user_path_walk(filename, &nd);
+	error = user_path_walk_link(name, &nd);
 	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat(nd.dentry->d_inode, statbuf);
+		error = do_getattr(nd.mnt, nd.dentry, stat);
 		path_release(&nd);
 	}
 	return error;
 }
 
+int vfs_fstat(unsigned int fd, struct kstat *stat)
+{
+	struct file *f = fget(fd);
+	int error = -EBADF;
+
+	if (f) {
+		error = do_getattr(f->f_vfsmnt, f->f_dentry, stat);
+		fput(f);
+	}
+	return error;
+}
+
 #if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
 
 /*
  * For backward compatibility?  Maybe this should be moved
  * into arch/i386 instead?
  */
-asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
+static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat * statbuf)
 {
-	struct nameidata nd;
-	int error;
+	static int warncount = 5;
+	struct __old_kernel_stat tmp;
 
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_old_stat(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
+	if (warncount > 0) {
+		warncount--;
+		printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
+			current->comm);
+	} else if (warncount < 0) {
+		/* it's laughable, but... */
+		warncount = 0;
 	}
-	return error;
-}
 
-#endif
+	tmp.st_dev = stat->dev;
+	tmp.st_ino = stat->ino;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	SET_OLDSTAT_UID(tmp, stat->uid);
+	SET_OLDSTAT_GID(tmp, stat->gid);
+	tmp.st_rdev = stat->rdev;
+#if BITS_PER_LONG == 32
+	if (stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+#endif	
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime;
+	tmp.st_mtime = stat->mtime;
+	tmp.st_ctime = stat->ctime;
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
 
-asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
+asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_old_stat(&stat, statbuf);
 
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
 	return error;
 }
+asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
+{
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
 
-#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
+	if (!error)
+		error = cp_old_stat(&stat, statbuf);
 
-/*
- * For backward compatibility?  Maybe this should be moved
- * into arch/i386 instead?
- */
+	return error;
+}
 asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat * statbuf)
 {
-	struct file * f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
+	if (!error)
+		error = cp_old_stat(&stat, statbuf);
 
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_old_stat(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	return err;
+	return error;
 }
 
 #endif
 
+static int cp_new_stat(struct kstat *stat, struct stat *statbuf)
+{
+	struct stat tmp;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.st_dev = stat->dev;
+	tmp.st_ino = stat->ino;
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	SET_STAT_UID(tmp, stat->uid);
+	SET_STAT_GID(tmp, stat->gid);
+	tmp.st_rdev = stat->rdev;
+#if BITS_PER_LONG == 32
+	if (stat->size > MAX_NON_LFS)
+		return -EOVERFLOW;
+#endif	
+	tmp.st_size = stat->size;
+	tmp.st_atime = stat->atime;
+	tmp.st_mtime = stat->mtime;
+	tmp.st_ctime = stat->ctime;
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
+	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
+{
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
+
+	return error;
+}
+asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
+{
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
+
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
+
+	return error;
+}
 asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf)
 {
-	struct file * f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
+	if (!error)
+		error = cp_new_stat(&stat, statbuf);
 
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_new_stat(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	return err;
+	return error;
 }
 
 asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz)
@@ -270,110 +278,59 @@
 /* ---------- LFS-64 ----------- */
 #if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips64) && !defined(__x86_64__) && !defined(CONFIG_ARCH_S390X)
 
-static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
+static long cp_new_stat64(struct kstat *stat, struct stat64 *statbuf)
 {
 	struct stat64 tmp;
-	unsigned int blocks, indirect;
 
 	memset(&tmp, 0, sizeof(tmp));
-	tmp.st_dev = kdev_t_to_nr(inode->i_dev);
-	tmp.st_ino = inode->i_ino;
+	tmp.st_dev = stat->dev;
+	tmp.st_ino = stat->ino;
 #ifdef STAT64_HAS_BROKEN_ST_INO
-	tmp.__st_ino = inode->i_ino;
+	tmp.__st_ino = stat->ino;
 #endif
-	tmp.st_mode = inode->i_mode;
-	tmp.st_nlink = inode->i_nlink;
-	tmp.st_uid = inode->i_uid;
-	tmp.st_gid = inode->i_gid;
-	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
-	tmp.st_atime = inode->i_atime;
-	tmp.st_mtime = inode->i_mtime;
-	tmp.st_ctime = inode->i_ctime;
-	tmp.st_size = inode->i_size;
-/*
- * st_blocks and st_blksize are approximated with a simple algorithm if
- * they aren't supported directly by the filesystem. The minix and msdos
- * filesystems don't keep track of blocks, so they would either have to
- * be counted explicitly (by delving into the file itself), or by using
- * this simple algorithm to get a reasonable (although not 100% accurate)
- * value.
- */
-
-/*
- * Use minix fs values for the number of direct and indirect blocks.  The
- * count is now exact for the minix fs except that it counts zero blocks.
- * Everything is in units of BLOCK_SIZE until the assignment to
- * tmp.st_blksize.
- */
-#define D_B   7
-#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
-
-	if (!inode->i_blksize) {
-		blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
-		if (blocks > D_B) {
-			indirect = (blocks - D_B + I_B - 1) / I_B;
-			blocks += indirect;
-			if (indirect > 1) {
-				indirect = (indirect - 1 + I_B - 1) / I_B;
-				blocks += indirect;
-				if (indirect > 1)
-					blocks++;
-			}
-		}
-		tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
-		tmp.st_blksize = BLOCK_SIZE;
-	} else {
-		tmp.st_blocks = inode->i_blocks;
-		tmp.st_blksize = inode->i_blksize;
-	}
+	tmp.st_mode = stat->mode;
+	tmp.st_nlink = stat->nlink;
+	tmp.st_uid = stat->uid;
+	tmp.st_gid = stat->gid;
+	tmp.st_rdev = stat->rdev;
+	tmp.st_atime = stat->atime;
+	tmp.st_mtime = stat->mtime;
+	tmp.st_ctime = stat->ctime;
+	tmp.st_size = stat->size;
+	tmp.st_blocks = stat->blocks;
+	tmp.st_blksize = stat->blksize;
 	return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
 }
 
 asmlinkage long sys_stat64(char * filename, struct stat64 * statbuf, long flags)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_stat(filename, &stat);
+
+	if (!error)
+		error = cp_new_stat64(&stat, statbuf);
 
-	error = user_path_walk(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
 	return error;
 }
-
 asmlinkage long sys_lstat64(char * filename, struct stat64 * statbuf, long flags)
 {
-	struct nameidata nd;
-	int error;
+	struct kstat stat;
+	int error = vfs_lstat(filename, &stat);
+
+	if (!error)
+		error = cp_new_stat64(&stat, statbuf);
 
-	error = user_path_walk_link(filename, &nd);
-	if (!error) {
-		error = do_revalidate(nd.dentry);
-		if (!error)
-			error = cp_new_stat64(nd.dentry->d_inode, statbuf);
-		path_release(&nd);
-	}
 	return error;
 }
-
 asmlinkage long sys_fstat64(unsigned long fd, struct stat64 * statbuf, long flags)
 {
-	struct file * f;
-	int err = -EBADF;
+	struct kstat stat;
+	int error = vfs_fstat(fd, &stat);
 
-	f = fget(fd);
-	if (f) {
-		struct dentry * dentry = f->f_dentry;
+	if (!error)
+		error = cp_new_stat64(&stat, statbuf);
 
-		err = do_revalidate(dentry);
-		if (!err)
-			err = cp_new_stat64(dentry->d_inode, statbuf);
-		fput(f);
-	}
-	return err;
+	return error;
 }
 
 #endif /* LFS-64 */
diff -urN linux-2.5.4-pre1/fs/super.c linux/fs/super.c
--- linux-2.5.4-pre1/fs/super.c	Wed Jan 23 15:32:20 2002
+++ linux/fs/super.c	Wed Feb  6 22:51:47 2002
@@ -641,8 +641,9 @@
 	return s;
 }
 
-static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
-	int flags, char *dev_name, void * data)
+struct super_block *get_sb_bdev(struct file_system_type *fs_type,
+	int flags, char *dev_name, void * data,
+	int (*fill_super)(struct super_block *, void *, int))
 {
 	struct inode *inode;
 	struct block_device *bdev;
@@ -698,7 +699,7 @@
 
 	list_for_each(p, &super_blocks) {
 		struct super_block *old = sb_entry(p);
-		if (!kdev_same(old->s_dev, dev))
+		if (old->s_bdev != bdev)
 			continue;
 		if (old->s_type != fs_type ||
 		    ((flags ^ old->s_flags) & MS_RDONLY)) {
@@ -718,8 +719,8 @@
 	s->s_flags = flags;
 	insert_super(s, fs_type);
 	strncpy(s->s_id, bdevname(dev), sizeof(s->s_id));
-	error = -EINVAL;
-	if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
+	error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+	if (error)
 		goto failed;
 	s->s_flags |= MS_ACTIVE;
 	path_release(&nd);
@@ -736,19 +737,23 @@
 	return ERR_PTR(error);
 }
 
-static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
+struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+	int flags, void *data,
+	int (*fill_super)(struct super_block *, void *, int))
 {
+	int error;
 	struct super_block *s = get_anon_super(fs_type, NULL, NULL);
 
 	if (IS_ERR(s))
 		return s;
 
 	s->s_flags = flags;
-	if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
+
+	error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+	if (error) {
 		deactivate_super(s);
 		remove_super(s);
-		return ERR_PTR(-EINVAL);
+		return ERR_PTR(error);
 	}
 	s->s_flags |= MS_ACTIVE;
 	return s;
@@ -759,19 +764,22 @@
 	return 1;
 }
 
-static struct super_block *get_sb_single(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
+struct super_block *get_sb_single(struct file_system_type *fs_type,
+	int flags, void *data,
+	int (*fill_super)(struct super_block *, void *, int))
 {
+	int error;
 	struct super_block *s = get_anon_super(fs_type, compare_single, NULL);
 
 	if (IS_ERR(s))
 		return s;
 	if (!s->s_root) {
 		s->s_flags = flags;
-		if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
+		error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
+		if (error) {
 			deactivate_super(s);
 			remove_super(s);
-			return ERR_PTR(-EINVAL);
+			return ERR_PTR(error);
 		}
 		s->s_flags |= MS_ACTIVE;
 	}
@@ -779,6 +787,22 @@
 	return s;
 }
 
+/* Will go away */
+static int fill_super(struct super_block *sb, void *data, int verbose)
+{
+	return sb->s_type->read_super(sb, data, verbose) ? 0 : -EINVAL;
+}
+static struct super_block *__get_sb_bdev(struct file_system_type *fs_type,
+	int flags, char *dev_name, void * data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, fill_super);
+}
+static struct super_block *__get_sb_nodev(struct file_system_type *fs_type,
+	int flags, char *dev_name, void * data)
+{
+	return get_sb_nodev(fs_type, flags, data, fill_super);
+}
+
 struct vfsmount *
 do_kern_mount(const char *fstype, int flags, char *name, void *data)
 {
@@ -792,12 +816,12 @@
 	mnt = alloc_vfsmnt(name);
 	if (!mnt)
 		goto out;
-	if (type->fs_flags & FS_REQUIRES_DEV)
-		sb = get_sb_bdev(type, flags, name, data);
-	else if (type->fs_flags & FS_SINGLE)
-		sb = get_sb_single(type, flags, name, data);
+	if (type->get_sb)
+		sb = type->get_sb(type, flags, name, data);
+	else if (type->fs_flags & FS_REQUIRES_DEV)
+		sb = __get_sb_bdev(type, flags, name, data);
 	else
-		sb = get_sb_nodev(type, flags, name, data);
+		sb = __get_sb_nodev(type, flags, name, data);
 	if (IS_ERR(sb))
 		goto out_mnt;
 	if (type->fs_flags & FS_NOMOUNT)
diff -urN linux-2.5.4-pre1/fs/udf/super.c linux/fs/udf/super.c
--- linux-2.5.4-pre1/fs/udf/super.c	Wed Jan 23 15:32:20 2002
+++ linux/fs/udf/super.c	Wed Feb  6 22:51:47 2002
@@ -1544,7 +1544,7 @@
 		iput(inode);
 		goto error_out;
 	}
-	sb->s_maxbytes = ~0ULL;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	return sb;
 
 error_out:
diff -urN linux-2.5.4-pre1/fs/ufs/file.c linux/fs/ufs/file.c
--- linux-2.5.4-pre1/fs/ufs/file.c	Wed Feb  6 22:51:45 2002
+++ linux/fs/ufs/file.c	Wed Feb  6 22:51:47 2002
@@ -38,46 +38,12 @@
 #include <linux/smp_lock.h>
 
 /*
- * Make sure the offset never goes beyond the 32-bit mark..
- */
-static long long ufs_file_lseek(
-	struct file *file,
-	long long offset,
-	int origin )
-{
-	long long retval;
-	struct inode *inode = file->f_dentry->d_inode;
-
-	lock_kernel();
-
-	switch (origin) {
-		case 2:
-			offset += inode->i_size;
-			break;
-		case 1:
-			offset += file->f_pos;
-	}
-	retval = -EINVAL;
-	/* make sure the offset fits in 32 bits */
-	if (((unsigned long long) offset >> 32) == 0) {
-		if (offset != file->f_pos) {
-			file->f_pos = offset;
-			file->f_reada = 0;
-			file->f_version = ++event;
-		}
-		retval = offset;
-	}
-	unlock_kernel();
-	return retval;
-}
-
-/*
  * We have mostly NULL's here: the current defaults are ok for
  * the ufs filesystem.
  */
  
 struct file_operations ufs_file_operations = {
-	llseek:		ufs_file_lseek,
+	llseek:		generic_file_llseek,
 	read:		generic_file_read,
 	write:		generic_file_write,
 	mmap:		generic_file_mmap,
diff -urN linux-2.5.4-pre1/include/asm-alpha/siginfo.h linux/include/asm-alpha/siginfo.h
--- linux-2.5.4-pre1/include/asm-alpha/siginfo.h	Wed May 24 18:38:26 2000
+++ linux/include/asm-alpha/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- linux-2.5.4-pre1/include/asm-alpha/unistd.h	Fri Nov  9 13:45:35 2001
+++ linux/include/asm-alpha/unistd.h	Wed Feb  6 22:51:47 2002
@@ -318,6 +318,7 @@
 #define __NR_gettid			378
 #define __NR_readahead			379
 #define __NR_security			380 /* syscall for security modules */
+#define __NR_tkill			381
 
 #if defined(__GNUC__)
 
diff -urN linux-2.5.4-pre1/include/asm-arm/siginfo.h linux/include/asm-arm/siginfo.h
--- linux-2.5.4-pre1/include/asm-arm/siginfo.h	Sun Aug 12 11:14:00 2001
+++ linux/include/asm-arm/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL        -6              /* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-cris/siginfo.h linux/include/asm-cris/siginfo.h
--- linux-2.5.4-pre1/include/asm-cris/siginfo.h	Thu Feb  8 16:32:44 2001
+++ linux/include/asm-cris/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-cris/unistd.h linux/include/asm-cris/unistd.h
--- linux-2.5.4-pre1/include/asm-cris/unistd.h	Mon Jan 21 16:00:39 2002
+++ linux/include/asm-cris/unistd.h	Wed Feb  6 22:51:47 2002
@@ -230,6 +230,7 @@
 #define __NR_security           223     /* syscall for security modules */
 #define __NR_gettid             224
 #define __NR_readahead          225
+#define __NR_tkill              226
 
 /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
 #define _syscall0(type,name) \
diff -urN linux-2.5.4-pre1/include/asm-i386/siginfo.h linux/include/asm-i386/siginfo.h
--- linux-2.5.4-pre1/include/asm-i386/siginfo.h	Tue Jan 29 21:41:10 2002
+++ linux/include/asm-i386/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h
--- linux-2.5.4-pre1/include/asm-i386/unistd.h	Tue Jan 29 18:46:00 2002
+++ linux/include/asm-i386/unistd.h	Wed Feb  6 22:51:47 2002
@@ -242,6 +242,7 @@
 #define __NR_removexattr	235
 #define __NR_lremovexattr	236
 #define __NR_fremovexattr	237
+#define __NR_tkill		238
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
diff -urN linux-2.5.4-pre1/include/asm-ia64/siginfo.h linux/include/asm-ia64/siginfo.h
--- linux-2.5.4-pre1/include/asm-ia64/siginfo.h	Thu Apr  5 12:51:47 2001
+++ linux/include/asm-ia64/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -124,6 +124,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-ia64/unistd.h linux/include/asm-ia64/unistd.h
--- linux-2.5.4-pre1/include/asm-ia64/unistd.h	Fri Nov  9 14:26:17 2001
+++ linux/include/asm-ia64/unistd.h	Wed Feb  6 22:51:47 2002
@@ -206,6 +206,7 @@
 #define __NR_getdents64			1214
 #define __NR_getunwind			1215
 #define __NR_readahead			1216
+#define __NR_tkill			1217
 
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
diff -urN linux-2.5.4-pre1/include/asm-m68k/siginfo.h linux/include/asm-m68k/siginfo.h
--- linux-2.5.4-pre1/include/asm-m68k/siginfo.h	Mon Nov 27 17:11:26 2000
+++ linux/include/asm-m68k/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -117,6 +117,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-m68k/unistd.h linux/include/asm-m68k/unistd.h
--- linux-2.5.4-pre1/include/asm-m68k/unistd.h	Thu Oct 25 13:53:55 2001
+++ linux/include/asm-m68k/unistd.h	Wed Feb  6 22:51:47 2002
@@ -222,6 +222,8 @@
 #define __NR_setfsuid32		215
 #define __NR_setfsgid32		216
 #define __NR_getdents64		220
+#define __NR_gettid		221
+#define __NR_tkill		222
 
 /* user-visible error numbers are in the range -1 - -122: see
    <asm-m68k/errno.h> */
diff -urN linux-2.5.4-pre1/include/asm-mips/siginfo.h linux/include/asm-mips/siginfo.h
--- linux-2.5.4-pre1/include/asm-mips/siginfo.h	Wed May 24 18:38:26 2000
+++ linux/include/asm-mips/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -127,6 +127,7 @@
 #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */
 #define SI_MESGQ	-4	/* sent by real time mesq state change */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-mips/unistd.h linux/include/asm-mips/unistd.h
--- linux-2.5.4-pre1/include/asm-mips/unistd.h	Mon Jul  2 13:56:40 2001
+++ linux/include/asm-mips/unistd.h	Wed Feb  6 22:51:47 2002
@@ -233,6 +233,8 @@
 #define __NR_madvise			(__NR_Linux + 218)
 #define __NR_getdents64			(__NR_Linux + 219)
 #define __NR_fcntl64			(__NR_Linux + 220)
+#define __NR_gettid			(__NR_Linux + 221)
+#define __NR_tkill			(__NR_Linux + 222)
 
 /*
  * Offset of the last Linux flavoured syscall
diff -urN linux-2.5.4-pre1/include/asm-mips64/siginfo.h linux/include/asm-mips64/siginfo.h
--- linux-2.5.4-pre1/include/asm-mips64/siginfo.h	Wed Jul  4 11:50:39 2001
+++ linux/include/asm-mips64/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -127,6 +127,7 @@
 #define SI_TIMER __SI_CODE(__SI_TIMER,-3) /* sent by timer expiration */
 #define SI_MESGQ	-4	/* sent by real time mesq state change */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-mips64/unistd.h linux/include/asm-mips64/unistd.h
--- linux-2.5.4-pre1/include/asm-mips64/unistd.h	Tue Nov 28 21:42:04 2000
+++ linux/include/asm-mips64/unistd.h	Wed Feb  6 22:51:47 2002
@@ -461,11 +461,13 @@
 #define __NR_mincore			(__NR_Linux + 211)
 #define __NR_madvise			(__NR_Linux + 212)
 #define __NR_getdents64			(__NR_Linux + 213)
+#define __NR_gettid			(__NR_Linux + 214)
+#define __NR_tkill			(__NR_Linux + 215)
 
 /*
  * Offset of the last Linux flavoured syscall
  */
-#define __NR_Linux_syscalls		213
+#define __NR_Linux_syscalls		215
 
 #ifndef _LANGUAGE_ASSEMBLY
 
diff -urN linux-2.5.4-pre1/include/asm-parisc/siginfo.h linux/include/asm-parisc/siginfo.h
--- linux-2.5.4-pre1/include/asm-parisc/siginfo.h	Tue Dec  5 12:29:39 2000
+++ linux/include/asm-parisc/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-parisc/unistd.h linux/include/asm-parisc/unistd.h
--- linux-2.5.4-pre1/include/asm-parisc/unistd.h	Tue Dec  5 12:29:39 2000
+++ linux/include/asm-parisc/unistd.h	Wed Feb  6 22:51:47 2002
@@ -689,8 +689,10 @@
 
 #define __NR_getpmsg            (__NR_Linux + 196)      /* some people actually want streams */
 #define __NR_putpmsg            (__NR_Linux + 197)      /* some people actually want streams */
+#define __NR_gettid             (__NR_Linux + 198)
+#define __NR_tkill              (__NR_Linux + 199)
 
-#define __NR_Linux_syscalls     197
+#define __NR_Linux_syscalls     199
 
 #define HPUX_GATEWAY_ADDR       0xC0000004
 #define LINUX_GATEWAY_ADDR      0x100
diff -urN linux-2.5.4-pre1/include/asm-ppc/siginfo.h linux/include/asm-ppc/siginfo.h
--- linux-2.5.4-pre1/include/asm-ppc/siginfo.h	Mon May 21 15:02:06 2001
+++ linux/include/asm-ppc/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -108,6 +108,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- linux-2.5.4-pre1/include/asm-ppc/unistd.h	Fri Nov  2 17:43:54 2001
+++ linux/include/asm-ppc/unistd.h	Wed Feb  6 22:51:47 2002
@@ -215,6 +215,7 @@
 #define __NR_madvise		205
 #define __NR_mincore		206
 #define __NR_gettid		207
+#define __NR_tkill		208
 
 #define __NR(n)	#n
 
diff -urN linux-2.5.4-pre1/include/asm-s390/siginfo.h linux/include/asm-s390/siginfo.h
--- linux-2.5.4-pre1/include/asm-s390/siginfo.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -115,6 +115,7 @@
 #define SI_MESGQ	-3	/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4	/* sent by AIO completion */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-s390/unistd.h linux/include/asm-s390/unistd.h
--- linux-2.5.4-pre1/include/asm-s390/unistd.h	Thu Oct 11 09:43:38 2001
+++ linux/include/asm-s390/unistd.h	Wed Feb  6 22:51:47 2002
@@ -211,6 +211,8 @@
 #define __NR_mincore            218
 #define __NR_madvise            219
 #define __NR_getdents64		220
+#define __NR_gettid		226
+#define __NR_tkill		227
 
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
diff -urN linux-2.5.4-pre1/include/asm-s390x/siginfo.h linux/include/asm-s390x/siginfo.h
--- linux-2.5.4-pre1/include/asm-s390x/siginfo.h	Tue Feb 13 14:13:44 2001
+++ linux/include/asm-s390x/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -115,6 +115,7 @@
 #define SI_MESGQ	-3	/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4	/* sent by AIO completion */
 #define SI_SIGIO	-5	/* sent by queued SIGIO */
+#define SI_TKILL	-6	/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-s390x/unistd.h linux/include/asm-s390x/unistd.h
--- linux-2.5.4-pre1/include/asm-s390x/unistd.h	Thu Oct 11 09:43:38 2001
+++ linux/include/asm-s390x/unistd.h	Wed Feb  6 22:51:47 2002
@@ -181,6 +181,8 @@
 #define __NR_mincore            218
 #define __NR_madvise            219
 #define __NR_getdents64         220
+#define __NR_gettid		226
+#define __NR_tkill 	        227
 
 
 /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */
diff -urN linux-2.5.4-pre1/include/asm-sh/siginfo.h linux/include/asm-sh/siginfo.h
--- linux-2.5.4-pre1/include/asm-sh/siginfo.h	Thu Jan  4 13:19:13 2001
+++ linux/include/asm-sh/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -107,6 +107,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-sh/unistd.h linux/include/asm-sh/unistd.h
--- linux-2.5.4-pre1/include/asm-sh/unistd.h	Mon Oct  2 11:57:34 2000
+++ linux/include/asm-sh/unistd.h	Wed Feb  6 22:51:47 2002
@@ -231,6 +231,8 @@
 #define __NR_madvise		219
 #define __NR_getdents64		220
 #define __NR_fcntl64		221
+#define __NR_gettid		222
+#define __NR_tkill		223
 
 /* user-visible error numbers are in the range -1 - -125: see <asm-sh/errno.h> */
 
diff -urN linux-2.5.4-pre1/include/asm-sparc/siginfo.h linux/include/asm-sparc/siginfo.h
--- linux-2.5.4-pre1/include/asm-sparc/siginfo.h	Mon Jun 19 17:59:39 2000
+++ linux/include/asm-sparc/siginfo.h	Wed Feb  6 22:51:47 2002
@@ -112,6 +112,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-sparc/unistd.h linux/include/asm-sparc/unistd.h
--- linux-2.5.4-pre1/include/asm-sparc/unistd.h	Wed Feb  6 22:51:45 2002
+++ linux/include/asm-sparc/unistd.h	Wed Feb  6 22:51:48 2002
@@ -271,6 +271,7 @@
 #define __NR_fdatasync          253
 #define __NR_nfsservctl         254
 #define __NR_aplib              255
+#define __NR_tkill              257
 
 #define _syscall0(type,name) \
 type name(void) \
diff -urN linux-2.5.4-pre1/include/asm-sparc64/siginfo.h linux/include/asm-sparc64/siginfo.h
--- linux-2.5.4-pre1/include/asm-sparc64/siginfo.h	Wed May 24 18:38:26 2000
+++ linux/include/asm-sparc64/siginfo.h	Wed Feb  6 22:51:48 2002
@@ -172,6 +172,7 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.5.4-pre1/include/asm-sparc64/unistd.h linux/include/asm-sparc64/unistd.h
--- linux-2.5.4-pre1/include/asm-sparc64/unistd.h	Sun Oct 21 10:36:54 2001
+++ linux/include/asm-sparc64/unistd.h	Wed Feb  6 22:51:48 2002
@@ -273,6 +273,7 @@
 #define __NR_fdatasync          253
 #define __NR_nfsservctl         254
 #define __NR_aplib              255
+#define __NR_tkill              256
 
 #define _syscall0(type,name) \
 type name(void) \
diff -urN linux-2.5.4-pre1/include/linux/fs.h linux/include/linux/fs.h
--- linux-2.5.4-pre1/include/linux/fs.h	Tue Jan 29 21:41:12 2002
+++ linux/include/linux/fs.h	Wed Feb  6 22:51:48 2002
@@ -91,7 +91,6 @@
 #define FS_NO_PRELIM	4 /* prevent preloading of dentries, even if
 			   * FS_NO_DCACHE is not set.
 			   */
-#define FS_SINGLE	8 /* Filesystem that can have only one superblock */
 #define FS_NOMOUNT	16 /* Never mount from userland */
 #define FS_LITTER	32 /* Keeps the tree in dcache */
 #define FS_ODD_RENAME	32768	/* Temporary stuff; will go away as soon
@@ -208,6 +207,7 @@
 extern void buffer_init(unsigned long);
 extern void inode_init(unsigned long);
 extern void mnt_init(unsigned long);
+extern void files_init(unsigned long);
 
 /* bh state bits */
 enum bh_state_bits {
@@ -289,7 +289,6 @@
 #include <linux/pipe_fs_i.h>
 /* #include <linux/umsdos_fs_i.h> */
 #include <linux/romfs_fs_i.h>
-#include <linux/proc_fs_i.h>
 #include <linux/cramfs_fs_sb.h>
 
 /*
@@ -455,12 +454,25 @@
 	union {
 		/* struct umsdos_inode_info	umsdos_i; */
 		struct romfs_inode_info		romfs_i;
-		struct proc_inode_info		proc_i;
-		struct socket			socket_i;
 		void				*generic_ip;
 	} u;
 };
 
+struct socket_alloc {
+	struct socket socket;
+	struct inode vfs_inode;
+};
+
+static inline struct socket *SOCKET_I(struct inode *inode)
+{
+	return &list_entry(inode, struct socket_alloc, vfs_inode)->socket;
+}
+
+static inline struct inode *SOCK_INODE(struct socket *socket)
+{
+	return &list_entry(socket, struct socket_alloc, socket)->vfs_inode;
+}
+
 #include <linux/shmem_fs.h>
 /* will die */
 #include <linux/coda_fs_i.h>
@@ -507,6 +519,14 @@
 
 #define	MAX_NON_LFS	((1UL<<31) - 1)
 
+/* Page cache limit. The filesystems should put that into their s_maxbytes 
+   limits, otherwise bad things can happen in VM. */ 
+#if BITS_PER_LONG==32
+#define MAX_LFS_FILESIZE	(((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
+#elif BITS_PER_LONG==64
+#define MAX_LFS_FILESIZE 	0x7fffffffffffffff
+#endif
+
 #define FL_POSIX	1
 #define FL_FLOCK	2
 #define FL_BROKEN	4	/* broken flock() emulation */
@@ -914,15 +934,36 @@
 	int (*transfer) (struct inode *, struct iattr *);
 };
 
+/*
+ *		NOTE NOTE NOTE
+ *
+ *	->read_super() is going to die.  New method (->get_sb) should replace
+ * it.  The only reason why ->read_super() is left for _SHORT_ transition
+ * period is to avoid a single patch touching every fs.  They will be
+ * converted one-by-one and ONCE THAT IS DONE OR TWO WEEKS HAD PASSED
+ * (whatever sooner) ->read_super() WILL DISAPPEAR.  
+ */
+
 struct file_system_type {
 	const char *name;
 	int fs_flags;
+	struct super_block *(*get_sb) (struct file_system_type *, int, char *, void *);
 	struct super_block *(*read_super) (struct super_block *, void *, int);
 	struct module *owner;
 	struct file_system_type * next;
 	struct list_head fs_supers;
 };
 
+struct super_block *get_sb_bdev(struct file_system_type *fs_type,
+	int flags, char *dev_name, void * data,
+	int (*fill_super)(struct super_block *, void *, int));
+struct super_block *get_sb_single(struct file_system_type *fs_type,
+	int flags, void *data,
+	int (*fill_super)(struct super_block *, void *, int));
+struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+	int flags, void *data,
+	int (*fill_super)(struct super_block *, void *, int));
+
 #define DECLARE_FSTYPE(var,type,read,flags) \
 struct file_system_type var = { \
 	name:		type, \
@@ -1449,6 +1490,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);
 
@@ -1463,6 +1505,10 @@
 extern int vfs_readdir(struct file *, filldir_t, void *);
 extern int dcache_readdir(struct file *, void *, filldir_t);
 
+extern int vfs_stat(char *, struct kstat *);
+extern int vfs_lstat(char *, struct kstat *);
+extern int vfs_fstat(unsigned int, struct kstat *);
+
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(kdev_t);
 extern void drop_super(struct super_block *sb);
@@ -1475,8 +1521,6 @@
 	}
 	return 0;
 }
-unsigned long generate_cluster(kdev_t, int b[], int);
-unsigned long generate_cluster_swab32(kdev_t, int b[], int);
 extern kdev_t ROOT_DEV;
 extern char root_device_name[];
 
diff -urN linux-2.5.4-pre1/include/linux/hpfs_fs_sb.h linux/include/linux/hpfs_fs_sb.h
--- linux-2.5.4-pre1/include/linux/hpfs_fs_sb.h	Sun May 16 10:33:30 1999
+++ linux/include/linux/hpfs_fs_sb.h	Wed Feb  6 22:51:48 2002
@@ -30,9 +30,8 @@
 					/*	128 bytes lowercasing table */
 	unsigned *sb_bmp_dir;		/* main bitmap directory */
 	unsigned sb_c_bitmap;		/* current bitmap */
-	wait_queue_head_t sb_creation_de;/* when creating dirents, nobody else
+	struct semaphore hpfs_creation_de; /* when creating dirents, nobody else
 					   can alloc blocks */
-	unsigned sb_creation_de_lock : 1;
 	/*unsigned sb_mounting : 1;*/
 	int sb_timeshift;
 };
@@ -60,8 +59,6 @@
 #define s_hpfs_cp_table u.hpfs_sb.sb_cp_table
 #define s_hpfs_bmp_dir u.hpfs_sb.sb_bmp_dir
 #define s_hpfs_c_bitmap u.hpfs_sb.sb_c_bitmap
-#define s_hpfs_creation_de u.hpfs_sb.sb_creation_de
-#define s_hpfs_creation_de_lock u.hpfs_sb.sb_creation_de_lock
 #define s_hpfs_iget_q u.hpfs_sb.sb_iget_q
 /*#define s_hpfs_mounting u.hpfs_sb.sb_mounting*/
 #define s_hpfs_timeshift u.hpfs_sb.sb_timeshift
diff -urN linux-2.5.4-pre1/include/linux/net.h linux/include/linux/net.h
--- linux-2.5.4-pre1/include/linux/net.h	Tue Jan 29 21:41:12 2002
+++ linux/include/linux/net.h	Wed Feb  6 22:51:48 2002
@@ -23,6 +23,7 @@
 #include <linux/wait.h>
 
 struct poll_table_struct;
+struct inode;
 
 #define NPROTO		32		/* should be enough for now..	*/
 
@@ -68,7 +69,6 @@
 
 	unsigned long		flags;
 	struct proto_ops	*ops;
-	struct inode		*inode;
 	struct fasync_struct	*fasync_list;	/* Asynchronous wake up list	*/
 	struct file		*file;		/* File back pointer for gc	*/
 	struct sock		*sk;
@@ -77,8 +77,6 @@
 	short			type;
 	unsigned char		passcred;
 };
-
-#define SOCK_INODE(S)	((S)->inode)
 
 struct scm_cookie;
 struct vm_area_struct;
diff -urN linux-2.5.4-pre1/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- linux-2.5.4-pre1/include/linux/nfs_fs.h	Wed Feb  6 22:51:45 2002
+++ linux/include/linux/nfs_fs.h	Wed Feb  6 22:51:48 2002
@@ -226,7 +226,6 @@
 /*
  * linux/fs/nfs/inode.c
  */
-extern struct super_block *nfs_read_super(struct super_block *, void *, int);
 extern void nfs_zap_caches(struct inode *);
 extern int nfs_inode_is_stale(struct inode *, struct nfs_fh *,
 				struct nfs_fattr *);
diff -urN linux-2.5.4-pre1/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- linux-2.5.4-pre1/include/linux/proc_fs.h	Tue Jan 29 21:41:31 2002
+++ linux/include/linux/proc_fs.h	Wed Feb  6 22:51:48 2002
@@ -97,7 +97,7 @@
 extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
 
 extern struct vfsmount *proc_mnt;
-extern struct super_block *proc_read_super(struct super_block *,void *,int);
+extern int proc_fill_super(struct super_block *,void *,int);
 extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *);
 
 extern int proc_match(int, const char *,struct proc_dir_entry *);
@@ -204,5 +204,27 @@
 extern struct proc_dir_entry proc_root;
 
 #endif /* CONFIG_PROC_FS */
+
+struct proc_inode {
+	struct task_struct *task;
+	int type;
+	union {
+		int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **);
+		int (*proc_read)(struct task_struct *task, char *page);
+	} op;
+	struct file *file;
+	struct proc_dir_entry *pde;
+	struct inode vfs_inode;
+};
+
+static inline struct proc_inode *PROC_I(struct inode *inode)
+{
+	return list_entry(inode, struct proc_inode, vfs_inode);
+}
+
+static inline struct proc_dir_entry *PDE(struct inode *inode)
+{
+	return PROC_I(inode)->pde;
+}
 
 #endif /* _LINUX_PROC_FS_H */
diff -urN linux-2.5.4-pre1/include/linux/sched.h linux/include/linux/sched.h
--- linux-2.5.4-pre1/include/linux/sched.h	Tue Jan 29 21:41:12 2002
+++ linux/include/linux/sched.h	Wed Feb  6 22:51:48 2002
@@ -564,6 +564,7 @@
 extern void proc_caches_init(void);
 extern void flush_signals(struct task_struct *);
 extern void flush_signal_handlers(struct task_struct *);
+extern void sig_exit(int, int, struct siginfo *);
 extern int dequeue_signal(sigset_t *, siginfo_t *);
 extern void block_all_signals(int (*notifier)(void *priv), void *priv,
 			      sigset_t *mask);
@@ -839,8 +840,13 @@
 #define for_each_task(p) \
 	for (p = &init_task ; (p = p->next_task) != &init_task ; )
 
+#define for_each_thread(task) \
+	for (task = next_thread(current) ; task != current ; task = next_thread(task))
+
 #define next_thread(p) \
 	list_entry((p)->thread_group.next, struct task_struct, thread_group)
+
+#define thread_group_leader(p)	(p->pid == p->tgid)
 
 static inline void unhash_process(struct task_struct *p)
 {
diff -urN linux-2.5.4-pre1/include/linux/stat.h linux/include/linux/stat.h
--- linux-2.5.4-pre1/include/linux/stat.h	Thu Aug  3 16:02:39 2000
+++ linux/include/linux/stat.h	Wed Feb  6 22:51:48 2002
@@ -52,6 +52,25 @@
 #define S_IRUGO		(S_IRUSR|S_IRGRP|S_IROTH)
 #define S_IWUGO		(S_IWUSR|S_IWGRP|S_IWOTH)
 #define S_IXUGO		(S_IXUSR|S_IXGRP|S_IXOTH)
+
+#include <linux/types.h>
+
+struct kstat {
+	unsigned long	ino;
+	dev_t		dev;
+	umode_t		mode;
+	nlink_t		nlink;
+	uid_t		uid;
+	gid_t		gid;
+	dev_t		rdev;
+	loff_t		size;
+	time_t		atime;
+	time_t		mtime;
+	time_t		ctime;
+	unsigned long	blksize;
+	unsigned long	blocks;
+};
+
 #endif
 
 #endif
diff -urN linux-2.5.4-pre1/include/linux/usb.h linux/include/linux/usb.h
--- linux-2.5.4-pre1/include/linux/usb.h	Tue Jan 29 21:44:41 2002
+++ linux/include/linux/usb.h	Wed Feb  6 22:51:48 2002
@@ -857,7 +857,7 @@
 extern void usb_free_urb(struct urb *urb);
 #define usb_put_urb usb_free_urb
 extern struct urb *usb_get_urb(struct urb *urb);
-extern int usb_submit_urb(struct urb *urb);
+extern int usb_submit_urb(struct urb *urb, int mem_flags);
 extern int usb_unlink_urb(struct urb *urb);
 
 /*-------------------------------------------------------------------*
@@ -906,7 +906,7 @@
 	int (*allocate)(struct usb_device *);
 	int (*deallocate)(struct usb_device *);
 	int (*get_frame_number) (struct usb_device *usb_dev);
-	int (*submit_urb) (struct urb *urb);
+	int (*submit_urb) (struct urb *urb, int mem_flags);
 	int (*unlink_urb) (struct urb *urb);
 };
 
diff -urN linux-2.5.4-pre1/include/net/sock.h linux/include/net/sock.h
--- linux-2.5.4-pre1/include/net/sock.h	Tue Jan 29 21:41:56 2002
+++ linux/include/net/sock.h	Wed Feb  6 22:51:48 2002
@@ -1022,7 +1022,7 @@
 	int uid;
 
 	read_lock(&sk->callback_lock);
-	uid = sk->socket ? sk->socket->inode->i_uid : 0;
+	uid = sk->socket ? SOCK_INODE(sk->socket)->i_uid : 0;
 	read_unlock(&sk->callback_lock);
 	return uid;
 }
@@ -1032,7 +1032,7 @@
 	unsigned long ino;
 
 	read_lock(&sk->callback_lock);
-	ino = sk->socket ? sk->socket->inode->i_ino : 0;
+	ino = sk->socket ? SOCK_INODE(sk->socket)->i_ino : 0;
 	read_unlock(&sk->callback_lock);
 	return ino;
 }
diff -urN linux-2.5.4-pre1/kernel/fork.c linux/kernel/fork.c
--- linux-2.5.4-pre1/kernel/fork.c	Mon Jan 28 15:11:45 2002
+++ linux/kernel/fork.c	Wed Feb  6 22:51:48 2002
@@ -724,10 +724,10 @@
 	/* Need tasklist lock for parent etc handling! */
 	write_lock_irq(&tasklist_lock);
 
-	/* CLONE_PARENT and CLONE_THREAD re-use the old parent */
+	/* CLONE_PARENT re-uses the old parent */
 	p->p_opptr = current->p_opptr;
 	p->p_pptr = current->p_pptr;
-	if (!(clone_flags & (CLONE_PARENT | CLONE_THREAD))) {
+	if (!(clone_flags & CLONE_PARENT)) {
 		p->p_opptr = current;
 		if (!(p->ptrace & PT_PTRACED))
 			p->p_pptr = current;
diff -urN linux-2.5.4-pre1/kernel/ksyms.c linux/kernel/ksyms.c
--- linux-2.5.4-pre1/kernel/ksyms.c	Tue Jan 29 10:47:10 2002
+++ linux/kernel/ksyms.c	Wed Feb  6 22:51:48 2002
@@ -251,6 +251,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);
@@ -274,6 +275,9 @@
 EXPORT_SYMBOL(dcache_readdir);
 EXPORT_SYMBOL(fd_install);
 EXPORT_SYMBOL(put_unused_fd);
+EXPORT_SYMBOL(get_sb_bdev);
+EXPORT_SYMBOL(get_sb_nodev);
+EXPORT_SYMBOL(get_sb_single);
 
 /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
 EXPORT_SYMBOL(default_llseek);
diff -urN linux-2.5.4-pre1/kernel/signal.c linux/kernel/signal.c
--- linux-2.5.4-pre1/kernel/signal.c	Mon Jan 28 15:11:45 2002
+++ linux/kernel/signal.c	Wed Feb  6 22:51:48 2002
@@ -142,6 +142,35 @@
 	}
 }
 
+/*
+ * sig_exit - cause the current task to exit due to a signal.
+ */
+
+void
+sig_exit(int sig, int exit_code, struct siginfo *info)
+{
+	struct task_struct *t;
+
+	sigaddset(&current->pending.signal, sig);
+	recalc_sigpending(current);
+	current->flags |= PF_SIGNALED;
+
+	/* Propagate the signal to all the tasks in
+	 *  our thread group
+	 */
+	if (info && (unsigned long)info != 1
+	    && info->si_code != SI_TKILL) {
+		read_lock(&tasklist_lock);
+		for_each_thread(t) {
+			force_sig_info(sig, info, t);
+		}
+		read_unlock(&tasklist_lock);
+	}
+
+	do_exit(exit_code);
+	/* NOTREACHED */
+}
+
 /* Notify the system that a driver wants to block all signals for this
  * process, and wants to be notified if any signals at all were to be
  * sent/acted upon.  If the notifier routine returns non-zero, then the
@@ -589,7 +618,7 @@
 		retval = -ESRCH;
 		read_lock(&tasklist_lock);
 		for_each_task(p) {
-			if (p->pgrp == pgrp) {
+			if (p->pgrp == pgrp && thread_group_leader(p)) {
 				int err = send_sig_info(sig, info, p);
 				if (retval)
 					retval = err;
@@ -636,8 +665,15 @@
 	read_lock(&tasklist_lock);
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
-	if (p)
+	if (p) {
+		if (!thread_group_leader(p)) {
+                       struct task_struct *tg;
+                       tg = find_task_by_pid(p->tgid);
+                       if (tg)
+                               p = tg;
+                }
 		error = send_sig_info(sig, info, p);
+	}
 	read_unlock(&tasklist_lock);
 	return error;
 }
@@ -660,7 +696,7 @@
 
 		read_lock(&tasklist_lock);
 		for_each_task(p) {
-			if (p->pid > 1 && p != current) {
+			if (p->pid > 1 && p != current && thread_group_leader(p)) {
 				int err = send_sig_info(sig, info, p);
 				++count;
 				if (err != -EPERM)
@@ -983,6 +1019,36 @@
 	info.si_uid = current->uid;
 
 	return kill_something_info(sig, &info, pid);
+}
+
+/*
+ *  Kill only one task, even if it's a CLONE_THREAD task.
+ */
+asmlinkage long
+sys_tkill(int pid, int sig)
+{
+       struct siginfo info;
+       int error;
+       struct task_struct *p;
+
+       /* This is only valid for single tasks */
+       if (pid <= 0)
+           return -EINVAL;
+
+       info.si_signo = sig;
+       info.si_errno = 0;
+       info.si_code = SI_TKILL;
+       info.si_pid = current->pid;
+       info.si_uid = current->uid;
+
+       read_lock(&tasklist_lock);
+       p = find_task_by_pid(pid);
+       error = -ESRCH;
+       if (p) {
+               error = send_sig_info(sig, &info, p);
+       }
+       read_unlock(&tasklist_lock);
+       return error;
 }
 
 asmlinkage long
diff -urN linux-2.5.4-pre1/kernel/sysctl.c linux/kernel/sysctl.c
--- linux-2.5.4-pre1/kernel/sysctl.c	Sat Dec 29 17:30:07 2001
+++ linux/kernel/sysctl.c	Wed Feb  6 22:51:48 2002
@@ -677,7 +677,7 @@
 	size_t res;
 	ssize_t error;
 	
-	de = (struct proc_dir_entry*) file->f_dentry->d_inode->u.generic_ip;
+	de = PDE(file->f_dentry->d_inode);
 	if (!de || !de->data)
 		return -ENOTDIR;
 	table = (struct ctl_table *) de->data;
diff -urN linux-2.5.4-pre1/mm/bootmem.c linux/mm/bootmem.c
--- linux-2.5.4-pre1/mm/bootmem.c	Mon Jan 14 10:10:43 2002
+++ linux/mm/bootmem.c	Wed Feb  6 22:51:48 2002
@@ -247,19 +247,30 @@
 	bootmem_data_t *bdata = pgdat->bdata;
 	unsigned long i, count, total = 0;
 	unsigned long idx;
+	unsigned long *map; 
 
 	if (!bdata->node_bootmem_map) BUG();
 
 	count = 0;
 	idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
-	for (i = 0; i < idx; i++, page++) {
-		if (!test_bit(i, bdata->node_bootmem_map)) {
+	map = bdata->node_bootmem_map;
+	for (i = 0; i < idx; ) {
+		unsigned long v = ~map[i / BITS_PER_LONG];
+		if (v) { 
+			unsigned long m;
+			for (m = 1; m && i < idx; m<<=1, page++, i++) { 
+				if (v & m) {
 			count++;
 			ClearPageReserved(page);
 			set_page_count(page, 1);
 			__free_page(page);
 		}
 	}
+		} else {
+			i+=BITS_PER_LONG;
+			page+=BITS_PER_LONG; 
+		} 	
+	}	
 	total += count;
 
 	/*
diff -urN linux-2.5.4-pre1/mm/shmem.c linux/mm/shmem.c
--- linux-2.5.4-pre1/mm/shmem.c	Mon Jan 21 15:37:32 2002
+++ linux/mm/shmem.c	Wed Feb  6 22:51:48 2002
@@ -1267,7 +1267,7 @@
 }
 #endif
 
-static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent)
+static int shmem_fill_super(struct super_block * sb, void * data, int silent)
 {
 	struct inode * inode;
 	struct dentry * root;
@@ -1286,7 +1286,7 @@
 #ifdef CONFIG_TMPFS
 	if (shmem_parse_options (data, &mode, &blocks, &inodes)) {
 		printk(KERN_ERR "tmpfs invalid option\n");
-		return NULL;
+		return -EINVAL;
 	}
 #endif
 
@@ -1302,15 +1302,15 @@
 	sb->s_op = &shmem_ops;
 	inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
 	if (!inode)
-		return NULL;
+		return -ENOMEM;
 
 	root = d_alloc_root(inode);
 	if (!root) {
 		iput(inode);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root = root;
-	return sb;
+	return 0;
 }
 
 static kmem_cache_t * shmem_inode_cachep;
@@ -1410,12 +1410,33 @@
 	nopage:	shmem_nopage,
 };
 
+static struct super_block *shmem_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, shmem_fill_super);
+}
+
 #ifdef CONFIG_TMPFS
 /* type "shm" will be tagged obsolete in 2.5 */
-static DECLARE_FSTYPE(shmem_fs_type, "shm", shmem_read_super, FS_LITTER);
-static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER);
+static struct file_system_type shmem_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"shmem",
+	get_sb:		shmem_get_sb,
+	fs_flags:	FS_LITTER,
+};
+static struct file_system_type tmpfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"tmpfs",
+	get_sb:		shmem_get_sb,
+	fs_flags:	FS_LITTER,
+};
 #else
-static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER|FS_NOMOUNT);
+static struct file_system_type tmpfs_fs_type = {
+	owner:		THIS_MODULE,
+	name:		"tmpfs",
+	get_sb:		shmem_get_sb,
+	fs_flags:	FS_LITTER|FS_NOMOUNT,
+};
 #endif
 static struct vfsmount *shm_mnt;
 
diff -urN linux-2.5.4-pre1/mm/slab.c linux/mm/slab.c
--- linux-2.5.4-pre1/mm/slab.c	Sat Dec 29 17:30:07 2001
+++ linux/mm/slab.c	Wed Feb  6 22:51:48 2002
@@ -186,8 +186,6 @@
  * manages a cache.
  */
 
-#define CACHE_NAMELEN	20	/* max name length for a slab cache */
-
 struct kmem_cache_s {
 /* 1) each alloc & free */
 	/* full, partial first, then free */
@@ -225,7 +223,7 @@
 	unsigned long		failures;
 
 /* 3) cache creation/removal */
-	char			name[CACHE_NAMELEN];
+	const char		*name;
 	struct list_head	next;
 #ifdef CONFIG_SMP
 /* 4) per-cpu data */
@@ -335,6 +333,7 @@
 	kmem_cache_t	*cs_dmacachep;
 } cache_sizes_t;
 
+/* These are the default caches for kmalloc. Custom caches can have other sizes. */
 static cache_sizes_t cache_sizes[] = {
 #if PAGE_SIZE == 4096
 	{    32,	NULL, NULL},
@@ -353,6 +352,29 @@
 	{131072,	NULL, NULL},
 	{     0,	NULL, NULL}
 };
+/* Must match cache_sizes above. Out of line to keep cache footprint low. */
+#define CN(x) { x, x " (DMA)" }
+static struct { 
+	char *name; 
+	char *name_dma;
+} cache_names[] = { 
+#if PAGE_SIZE == 4096
+	CN("size-32"),
+#endif
+	CN("size-64"),
+	CN("size-128"),
+	CN("size-256"),
+	CN("size-512"),
+	CN("size-1024"),
+	CN("size-2048"),
+	CN("size-4096"),
+	CN("size-8192"),
+	CN("size-16384"),
+	CN("size-32768"),
+	CN("size-65536"),
+	CN("size-131072")
+}; 
+#undef CN
 
 /* internal cache of cache description objs */
 static kmem_cache_t cache_cache = {
@@ -437,7 +459,6 @@
 void __init kmem_cache_sizes_init(void)
 {
 	cache_sizes_t *sizes = cache_sizes;
-	char name[20];
 	/*
 	 * Fragmentation resistance on low memory - only use bigger
 	 * page orders on machines with more than 32MB of memory.
@@ -450,9 +471,9 @@
 		 * eliminates "false sharing".
 		 * Note for systems short on memory removing the alignment will
 		 * allow tighter packing of the smaller caches. */
-		sprintf(name,"size-%Zd",sizes->cs_size);
 		if (!(sizes->cs_cachep =
-			kmem_cache_create(name, sizes->cs_size,
+			kmem_cache_create(cache_names[sizes-cache_sizes].name, 
+					  sizes->cs_size,
 					0, SLAB_HWCACHE_ALIGN, NULL, NULL))) {
 			BUG();
 		}
@@ -462,9 +483,10 @@
 			offslab_limit = sizes->cs_size-sizeof(slab_t);
 			offslab_limit /= 2;
 		}
-		sprintf(name, "size-%Zd(DMA)",sizes->cs_size);
-		sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,
-			      SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
+		sizes->cs_dmacachep = kmem_cache_create(
+		    cache_names[sizes-cache_sizes].name_dma, 
+			sizes->cs_size, 0,
+			SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
 		if (!sizes->cs_dmacachep)
 			BUG();
 		sizes++;
@@ -604,6 +626,11 @@
  * Cannot be called within a int, but can be interrupted.
  * The @ctor is run when new pages are allocated by the cache
  * and the @dtor is run before the pages are handed back.
+ *
+ * @name must be valid until the cache is destroyed. This implies that
+ * the module calling this has to destroy the cache before getting 
+ * unloaded.
+ * 
  * The flags are
  *
  * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
@@ -632,7 +659,6 @@
 	 * Sanity checks... these are all serious usage bugs.
 	 */
 	if ((!name) ||
-		((strlen(name) >= CACHE_NAMELEN - 1)) ||
 		in_interrupt() ||
 		(size < BYTES_PER_WORD) ||
 		(size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) ||
@@ -797,8 +823,7 @@
 		cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
 	cachep->ctor = ctor;
 	cachep->dtor = dtor;
-	/* Copy name over so we don't have problems with unloaded modules */
-	strcpy(cachep->name, name);
+	cachep->name = name;
 
 #ifdef CONFIG_SMP
 	if (g_cpucache_up)
@@ -811,10 +836,20 @@
 
 		list_for_each(p, &cache_chain) {
 			kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
-
-			/* The name field is constant - no lock needed. */
-			if (!strcmp(pc->name, name))
-				BUG();
+			char tmp;
+			/* This happens when the module gets unloaded and doesn't
+			   destroy its slab cache and noone else reuses the vmalloc
+			   area of the module. Print a warning. */
+			if (__get_user(tmp,pc->name)) { 
+				printk("SLAB: cache with size %d has lost its name\n", 
+					pc->objsize); 
+				continue; 
+			} 	
+			if (!strcmp(pc->name,name)) { 
+				printk("kmem_cache_create: duplicate cache %s\n",name); 
+				up(&cache_chain_sem); 
+				BUG(); 
+			}	
 		}
 	}
 
@@ -1878,6 +1913,7 @@
 		unsigned long	num_objs;
 		unsigned long	active_slabs = 0;
 		unsigned long	num_slabs;
+		const char *name; 
 		cachep = list_entry(p, kmem_cache_t, next);
 
 		spin_lock_irq(&cachep->spinlock);
@@ -1906,8 +1942,15 @@
 		num_slabs+=active_slabs;
 		num_objs = num_slabs*cachep->num;
 
+		name = cachep->name; 
+		{
+		char tmp; 
+		if (__get_user(tmp, name)) 
+			name = "broken"; 
+		} 	
+
 		len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
-			cachep->name, active_objs, num_objs, cachep->objsize,
+			name, active_objs, num_objs, cachep->objsize,
 			active_slabs, num_slabs, (1<<cachep->gfporder));
 
 #if STATS
diff -urN linux-2.5.4-pre1/net/8021q/vlanproc.c linux/net/8021q/vlanproc.c
--- linux-2.5.4-pre1/net/8021q/vlanproc.c	Mon Jan 14 10:10:43 2002
+++ linux/net/8021q/vlanproc.c	Wed Feb  6 22:51:48 2002
@@ -236,7 +236,7 @@
 	if (count <= 0)
 		return 0;
 
-	dent = inode->u.generic_ip;
+	dent = PDE(inode);
 	if ((dent == NULL) || (dent->get_info == NULL))
 		return 0;
 
diff -urN linux-2.5.4-pre1/net/atm/proc.c linux/net/atm/proc.c
--- linux-2.5.4-pre1/net/atm/proc.c	Wed Jul  4 11:50:38 2001
+++ linux/net/atm/proc.c	Wed Feb  6 22:51:48 2002
@@ -498,8 +498,7 @@
 	if (count == 0) return 0;
 	page = get_free_page(GFP_KERNEL);
 	if (!page) return -ENOMEM;
-	dev = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip)
-	    ->data;
+	dev = PDE(file->f_dentry->d_inode)->data;
 	if (!dev->ops->proc_read)
 		length = -EINVAL;
 	else {
@@ -521,8 +520,7 @@
 	unsigned long page;
 	int length;
 	int (*info)(loff_t,char *);
-	info = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip)
-	    ->data;
+	info = PDE(file->f_dentry->d_inode)->data;
 
 	if (count == 0) return 0;
 	page = get_free_page(GFP_KERNEL);
diff -urN linux-2.5.4-pre1/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
--- linux-2.5.4-pre1/net/ax25/af_ax25.c	Thu Sep 13 17:16:23 2001
+++ linux/net/ax25/af_ax25.c	Wed Feb  6 22:51:48 2002
@@ -1756,7 +1756,7 @@
 			len += sprintf(buffer + len, " %d %d %ld\n",
 				atomic_read(&ax25->sk->wmem_alloc),
 				atomic_read(&ax25->sk->rmem_alloc),
-				ax25->sk->socket != NULL ? ax25->sk->socket->inode->i_ino : 0L);
+				ax25->sk->socket != NULL ? SOCK_INODE(ax25->sk->socket)->i_ino : 0L);
 		} else {
 			len += sprintf(buffer + len, " * * *\n");
 		}
diff -urN linux-2.5.4-pre1/net/ipv6/icmp.c linux/net/ipv6/icmp.c
--- linux-2.5.4-pre1/net/ipv6/icmp.c	Thu Sep 20 14:12:56 2001
+++ linux/net/ipv6/icmp.c	Wed Feb  6 22:51:48 2002
@@ -637,21 +637,11 @@
 	struct sock *sk;
 	int err;
 
-	icmpv6_socket = sock_alloc();
-	if (icmpv6_socket == NULL) {
-		printk(KERN_ERR
-		       "Failed to create the ICMP6 control socket.\n");
-		return -1;
-	}
-	icmpv6_socket->inode->i_uid = 0;
-	icmpv6_socket->inode->i_gid = 0;
-	icmpv6_socket->type = SOCK_RAW;
-
-	if ((err = ops->create(icmpv6_socket, IPPROTO_ICMPV6)) < 0) {
+	err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &icmpv6_socket);
+	if (err < 0) {
 		printk(KERN_ERR
 		       "Failed to initialize the ICMP6 control socket (err %d).\n",
 		       err);
-		sock_release(icmpv6_socket);
 		icmpv6_socket = NULL; /* for safety */
 		return err;
 	}
diff -urN linux-2.5.4-pre1/net/ipv6/mcast.c linux/net/ipv6/mcast.c
--- linux-2.5.4-pre1/net/ipv6/mcast.c	Wed Aug 15 01:54:24 2001
+++ linux/net/ipv6/mcast.c	Wed Feb  6 22:51:48 2002
@@ -751,21 +751,11 @@
 	struct sock *sk;
 	int err;
 
-	igmp6_socket = sock_alloc();
-	if (igmp6_socket == NULL) {
+	err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket);
+	if (err < 0) {
 		printk(KERN_ERR
-		       "Failed to create the IGMP6 control socket.\n");
-		return -1;
-	}
-	igmp6_socket->inode->i_uid = 0;
-	igmp6_socket->inode->i_gid = 0;
-	igmp6_socket->type = SOCK_RAW;
-
-	if((err = ops->create(igmp6_socket, IPPROTO_ICMPV6)) < 0) {
-		printk(KERN_DEBUG 
 		       "Failed to initialize the IGMP6 control socket (err %d).\n",
 		       err);
-		sock_release(igmp6_socket);
 		igmp6_socket = NULL; /* For safety. */
 		return err;
 	}
diff -urN linux-2.5.4-pre1/net/ipv6/ndisc.c linux/net/ipv6/ndisc.c
--- linux-2.5.4-pre1/net/ipv6/ndisc.c	Wed Jan 23 15:28:40 2002
+++ linux/net/ipv6/ndisc.c	Wed Feb  6 22:51:48 2002
@@ -1214,21 +1214,11 @@
 	struct sock *sk;
         int err;
 
-	ndisc_socket = sock_alloc();
-	if (ndisc_socket == NULL) {
+	err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &ndisc_socket);
+	if (err < 0) {
 		printk(KERN_ERR
-		       "Failed to create the NDISC control socket.\n");
-		return -1;
-	}
-	ndisc_socket->inode->i_uid = 0;
-	ndisc_socket->inode->i_gid = 0;
-	ndisc_socket->type = SOCK_RAW;
-
-	if((err = ops->create(ndisc_socket, IPPROTO_ICMPV6)) < 0) {
-		printk(KERN_DEBUG 
 		       "Failed to initialize the NDISC control socket (err %d).\n",
 		       err);
-		sock_release(ndisc_socket);
 		ndisc_socket = NULL; /* For safety. */
 		return err;
 	}
diff -urN linux-2.5.4-pre1/net/netlink/netlink_dev.c linux/net/netlink/netlink_dev.c
--- linux-2.5.4-pre1/net/netlink/netlink_dev.c	Tue Jan 15 10:56:35 2002
+++ linux/net/netlink/netlink_dev.c	Wed Feb  6 22:51:48 2002
@@ -98,11 +98,6 @@
 	return sock_recvmsg(sock, &msg, count, msg.msg_flags);
 }
 
-static loff_t netlink_lseek(struct file * file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
 static int netlink_open(struct inode * inode, struct file * file)
 {
 	unsigned int minor = minor(inode->i_rdev);
@@ -166,7 +161,7 @@
 
 static struct file_operations netlink_fops = {
 	owner:		THIS_MODULE,
-	llseek:		netlink_lseek,
+	llseek:		no_llseek,
 	read:		netlink_read,
 	write:		netlink_write,
 	poll:		netlink_poll,
diff -urN linux-2.5.4-pre1/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
--- linux-2.5.4-pre1/net/netrom/af_netrom.c	Mon Sep 10 07:58:35 2001
+++ linux/net/netrom/af_netrom.c	Wed Feb  6 22:51:48 2002
@@ -1204,7 +1204,7 @@
 			s->protinfo.nr->window,
 			atomic_read(&s->wmem_alloc),
 			atomic_read(&s->rmem_alloc),
-			s->socket != NULL ? s->socket->inode->i_ino : 0L);
+			s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L);
 
 		pos = begin + len;
 
diff -urN linux-2.5.4-pre1/net/packet/af_packet.c linux/net/packet/af_packet.c
--- linux-2.5.4-pre1/net/packet/af_packet.c	Tue Jan 15 10:56:36 2002
+++ linux/net/packet/af_packet.c	Wed Feb  6 22:51:48 2002
@@ -1575,7 +1575,7 @@
 {
 	struct file *file = vma->vm_file;
 	struct inode *inode = file->f_dentry->d_inode;
-	struct socket * sock = &inode->u.socket_i;
+	struct socket * sock = SOCKET_I(inode);
 	struct sock *sk = sock->sk;
 	
 	if (sk)
@@ -1586,7 +1586,7 @@
 {
 	struct file *file = vma->vm_file;
 	struct inode *inode = file->f_dentry->d_inode;
-	struct socket * sock = &inode->u.socket_i;
+	struct socket * sock = SOCKET_I(inode);
 	struct sock *sk = sock->sk;
 	
 	if (sk)
diff -urN linux-2.5.4-pre1/net/rose/af_rose.c linux/net/rose/af_rose.c
--- linux-2.5.4-pre1/net/rose/af_rose.c	Sun Dec 30 10:31:51 2001
+++ linux/net/rose/af_rose.c	Wed Feb  6 22:51:48 2002
@@ -1370,7 +1370,7 @@
 			s->protinfo.rose->idle / (60 * HZ),
 			atomic_read(&s->wmem_alloc),
 			atomic_read(&s->rmem_alloc),
-			s->socket != NULL ? s->socket->inode->i_ino : 0L);
+			s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L);
 
 		pos = begin + len;
 
diff -urN linux-2.5.4-pre1/net/socket.c linux/net/socket.c
--- linux-2.5.4-pre1/net/socket.c	Fri Jan 18 16:00:26 2002
+++ linux/net/socket.c	Wed Feb  6 22:51:48 2002
@@ -86,7 +86,6 @@
 #include <linux/netfilter.h>
 
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
-static loff_t sock_lseek(struct file *file, loff_t offset, int whence);
 static ssize_t sock_read(struct file *file, char *buf,
 			 size_t size, loff_t *ppos);
 static ssize_t sock_write(struct file *file, const char *buf,
@@ -113,7 +112,7 @@
  */
 
 static struct file_operations socket_file_ops = {
-	llseek:		sock_lseek,
+	llseek:		no_llseek,
 	read:		sock_read,
 	write:		sock_write,
 	poll:		sock_poll,
@@ -272,36 +271,87 @@
 	return 0;
 }
 
+static kmem_cache_t * sock_inode_cachep;
+
+static struct inode *sock_alloc_inode(struct super_block *sb)
+{
+	struct socket_alloc *ei;
+	ei = (struct socket_alloc *)kmem_cache_alloc(sock_inode_cachep, SLAB_KERNEL);
+	if (!ei)
+		return NULL;
+	init_waitqueue_head(&ei->socket.wait);
+	return &ei->vfs_inode;
+}
+
+static void sock_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(sock_inode_cachep,
+			list_entry(inode, struct socket_alloc, vfs_inode));
+}
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+	struct socket_alloc *ei = (struct socket_alloc *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR)
+		inode_init_once(&ei->vfs_inode);
+}
+ 
+static int init_inodecache(void)
+{
+	sock_inode_cachep = kmem_cache_create("sock_inode_cache",
+					     sizeof(struct socket_alloc),
+					     0, SLAB_HWCACHE_ALIGN,
+					     init_once, NULL);
+	if (sock_inode_cachep == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
 static struct super_operations sockfs_ops = {
+	alloc_inode:	sock_alloc_inode,
+	destroy_inode:	sock_destroy_inode,
 	statfs:		sockfs_statfs,
 };
 
-static struct super_block * sockfs_read_super(struct super_block *sb, void *data, int silent)
+static int sockfs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *root;
 	sb->s_blocksize = 1024;
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = SOCKFS_MAGIC;
-	sb->s_op	= &sockfs_ops;
+	sb->s_op = &sockfs_ops;
 	root = new_inode(sb);
 	if (!root)
-		return NULL;
+		return -ENOMEM;
 	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
 	root->i_uid = root->i_gid = 0;
 	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
 	sb->s_root = d_alloc(NULL, &(const struct qstr) { "socket:", 7, 0 });
 	if (!sb->s_root) {
 		iput(root);
-		return NULL;
+		return -ENOMEM;
 	}
 	sb->s_root->d_sb = sb;
 	sb->s_root->d_parent = sb->s_root;
 	d_instantiate(sb->s_root, root);
-	return sb;
+	return 0;
+}
+
+static struct super_block *sockfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, sockfs_fill_super);
 }
 
 static struct vfsmount *sock_mnt;
-static DECLARE_FSTYPE(sock_fs_type, "sockfs", sockfs_read_super, FS_NOMOUNT);
+
+static struct file_system_type sock_fs_type = {
+	name:		"sockfs",
+	get_sb:		sockfs_get_sb,
+	fs_flags:	FS_NOMOUNT,
+};
 static int sockfs_delete_dentry(struct dentry *dentry)
 {
 	return 1;
@@ -347,10 +397,10 @@
 			goto out;
 		}
 
-		sprintf(name, "[%lu]", sock->inode->i_ino);
+		sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
 		this.name = name;
 		this.len = strlen(name);
-		this.hash = sock->inode->i_ino;
+		this.hash = SOCK_INODE(sock)->i_ino;
 
 		file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
 		if (!file->f_dentry) {
@@ -360,11 +410,11 @@
 			goto out;
 		}
 		file->f_dentry->d_op = &sockfs_dentry_operations;
-		d_add(file->f_dentry, sock->inode);
+		d_add(file->f_dentry, SOCK_INODE(sock));
 		file->f_vfsmnt = mntget(sock_mnt);
 
 		sock->file = file;
-		file->f_op = sock->inode->i_fop = &socket_file_ops;
+		file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
 		file->f_mode = 3;
 		file->f_flags = O_RDWR;
 		file->f_pos = 0;
@@ -375,11 +425,6 @@
 	return fd;
 }
 
-extern __inline__ struct socket *socki_lookup(struct inode *inode)
-{
-	return &inode->u.socket_i;
-}
-
 /**
  *	sockfd_lookup	- 	Go from a file number to its socket slot
  *	@fd: file handle
@@ -406,7 +451,7 @@
 	}
 
 	inode = file->f_dentry->d_inode;
-	if (!inode->i_sock || !(sock = socki_lookup(inode)))
+	if (!inode->i_sock || !(sock = SOCKET_I(inode)))
 	{
 		*err = -ENOTSOCK;
 		fput(file);
@@ -443,15 +488,13 @@
 		return NULL;
 
 	inode->i_dev = NODEV;
-	sock = socki_lookup(inode);
+	sock = SOCKET_I(inode);
 
 	inode->i_mode = S_IFSOCK|S_IRWXUGO;
 	inode->i_sock = 1;
 	inode->i_uid = current->fsuid;
 	inode->i_gid = current->fsgid;
 
-	sock->inode = inode;
-	init_waitqueue_head(&sock->wait);
 	sock->fasync_list = NULL;
 	sock->state = SS_UNCONNECTED;
 	sock->flags = 0;
@@ -493,7 +536,7 @@
 
 	sockets_in_use[smp_processor_id()].counter--;
 	if (!sock->file) {
-		iput(sock->inode);
+		iput(SOCK_INODE(sock));
 		return;
 	}
 	sock->file=NULL;
@@ -527,15 +570,6 @@
 
 
 /*
- *	Sockets are not seekable.
- */
-
-static loff_t sock_lseek(struct file *file, loff_t offset, int whence)
-{
-	return -ESPIPE;
-}
-
-/*
  *	Read data from a socket. ubuf is a user mode pointer. We make sure the user
  *	area ubuf...ubuf+size-1 is writable before asking the protocol.
  */
@@ -553,7 +587,7 @@
 	if (size==0)		/* Match SYS5 behaviour */
 		return 0;
 
-	sock = socki_lookup(file->f_dentry->d_inode); 
+	sock = SOCKET_I(file->f_dentry->d_inode); 
 
 	msg.msg_name=NULL;
 	msg.msg_namelen=0;
@@ -586,7 +620,7 @@
 	if(size==0)		/* Match SYS5 behaviour */
 		return 0;
 
-	sock = socki_lookup(file->f_dentry->d_inode); 
+	sock = SOCKET_I(file->f_dentry->d_inode); 
 
 	msg.msg_name=NULL;
 	msg.msg_namelen=0;
@@ -612,7 +646,7 @@
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
 
-	sock = socki_lookup(file->f_dentry->d_inode);
+	sock = SOCKET_I(file->f_dentry->d_inode);
 
 	flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
 	if (more)
@@ -627,7 +661,7 @@
 	struct msghdr msg;
 	struct socket *sock;
 
-	sock = socki_lookup(inode);
+	sock = SOCKET_I(inode);
 
 	msg.msg_name = NULL;
 	msg.msg_namelen = 0;
@@ -681,7 +715,7 @@
 	int err;
 
 	unlock_kernel();
-	sock = socki_lookup(inode);
+	sock = SOCKET_I(inode);
 	err = sock->ops->ioctl(sock, cmd, arg);
 	lock_kernel();
 
@@ -697,13 +731,13 @@
 	/*
 	 *	We can't return errors to poll, so it's either yes or no. 
 	 */
-	sock = socki_lookup(file->f_dentry->d_inode);
+	sock = SOCKET_I(file->f_dentry->d_inode);
 	return sock->ops->poll(file, sock, wait);
 }
 
 static int sock_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	struct socket *sock = socki_lookup(file->f_dentry->d_inode);
+	struct socket *sock = SOCKET_I(file->f_dentry->d_inode);
 
 	return sock->ops->mmap(file, sock, vma);
 }
@@ -721,7 +755,7 @@
 		return 0;
 	}
 	sock_fasync(-1, filp, 0);
-	sock_release(socki_lookup(inode));
+	sock_release(SOCKET_I(inode));
 	return 0;
 }
 
@@ -754,7 +788,7 @@
 	}
 
 
-	sock = socki_lookup(filp->f_dentry->d_inode);
+	sock = SOCKET_I(filp->f_dentry->d_inode);
 	
 	if ((sk=sock->sk) == NULL)
 		return -EINVAL;
@@ -1521,7 +1555,7 @@
 {
 	struct socket *sock;
 
-	sock = socki_lookup (filp->f_dentry->d_inode);
+	sock = SOCKET_I (filp->f_dentry->d_inode);
 	if (sock && sock->ops)
 		return sock_no_fcntl(sock, cmd, arg);
 	return(-EINVAL);
@@ -1711,6 +1745,7 @@
 	 *	Initialize the protocols module. 
 	 */
 
+	init_inodecache();
 	register_filesystem(&sock_fs_type);
 	sock_mnt = kern_mount(&sock_fs_type);
 	/* The real protocol initialization is performed when
diff -urN linux-2.5.4-pre1/net/unix/af_unix.c linux/net/unix/af_unix.c
--- linux-2.5.4-pre1/net/unix/af_unix.c	Tue Jan 15 10:56:35 2002
+++ linux/net/unix/af_unix.c	Wed Feb  6 22:51:48 2002
@@ -711,7 +711,7 @@
 		/*
 		 * All right, let's create it.
 		 */
-		mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
+		mode = S_IFSOCK | (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
 		err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
 		if (err)
 			goto out_mknod_dput;
diff -urN linux-2.5.4-pre1/net/unix/garbage.c linux/net/unix/garbage.c
--- linux-2.5.4-pre1/net/unix/garbage.c	Tue Jan 15 10:56:35 2002
+++ linux/net/unix/garbage.c	Wed Feb  6 22:51:48 2002
@@ -101,7 +101,7 @@
 	 *	Socket ?
 	 */
 	if (inode->i_sock) {
-		struct socket * sock = &inode->u.socket_i;
+		struct socket * sock = SOCKET_I(inode);
 		struct sock * s = sock->sk;
 
 		/*
diff -urN linux-2.5.4-pre1/net/wanrouter/wanmain.c linux/net/wanrouter/wanmain.c
--- linux-2.5.4-pre1/net/wanrouter/wanmain.c	Sun Dec 30 16:52:34 2001
+++ linux/net/wanrouter/wanmain.c	Wed Feb  6 22:51:48 2002
@@ -500,7 +500,7 @@
 	if ((cmd >> 8) != ROUTER_IOCTL)
 		return -EINVAL;
 		
-	dent = inode->u.generic_ip;
+	dent = PDE(inode);
 	if ((dent == NULL) || (dent->data == NULL))
 		return -EINVAL;
 		
diff -urN linux-2.5.4-pre1/net/wanrouter/wanproc.c linux/net/wanrouter/wanproc.c
--- linux-2.5.4-pre1/net/wanrouter/wanproc.c	Sun Dec 30 16:52:34 2001
+++ linux/net/wanrouter/wanproc.c	Wed Feb  6 22:51:48 2002
@@ -248,7 +248,7 @@
 		if (count <= 0)
 			return 0;
 			
-		dent = inode->u.generic_ip;
+		dent = PDE(inode);
 		if ((dent == NULL) || (dent->get_info == NULL))
 			return 0;
 			
@@ -794,7 +794,7 @@
 		if (count <= 0)
 			return 0;
 			
-		dent = inode->u.generic_ip;
+		dent = PDE(inode);
 		if ((dent == NULL) || (dent->get_info == NULL))
 			return 0;
 			
@@ -828,7 +828,7 @@
 
 		if (count <= 0)
 			return 0;
-		dent = inode->u.generic_ip;
+		dent = PDE(inode);
 		if ((dent == NULL) || (dent->get_info == NULL))
 			return -ENODATA;
 		err = verify_area(VERIFY_WRITE, buf, count);
@@ -1068,7 +1068,7 @@
 
         if (err) return err;
 
-        dent = inode->u.generic_ip;
+        dent = PDE(inode);
         if ((dent == NULL) || (dent->data == NULL))
                 return -ENODATA;
 
diff -urN linux-2.5.4-pre1/net/x25/af_x25.c linux/net/x25/af_x25.c
--- linux-2.5.4-pre1/net/x25/af_x25.c	Sun Dec 30 10:31:51 2001
+++ linux/net/x25/af_x25.c	Wed Feb  6 22:51:48 2002
@@ -1239,7 +1239,7 @@
 			s->protinfo.x25->t23 / HZ,
 			atomic_read(&s->wmem_alloc),
 			atomic_read(&s->rmem_alloc),
-			s->socket != NULL ? s->socket->inode->i_ino : 0L);
+			s->socket != NULL ? SOCK_INODE(s->socket)->i_ino : 0L);
 
 		pos = begin + len;
 
