Merge mainline to 2.5.4 final.  This is very
possibly the last vger CVS merge I'll be doing
as Linus moves over to Bitkeeper which I am already
using to push 2.5.x changes to him.
The 2.4.x CVS will remain active assuming Marcelo decides
to not use BK for his work.
diff --git a/CREDITS b/CREDITS
index b36c8b6..bc44a4c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -990,8 +990,8 @@
 
 N: Nigel Gamble
 E: nigel@nrg.org
-E: nigel@sgi.com
 D: Interrupt-driven printer driver
+D: Preemptible kernel
 S: 120 Alley Way
 S: Mountain View, California 94040
 S: USA
diff --git a/Documentation/preempt-locking.txt b/Documentation/preempt-locking.txt
new file mode 100644
index 0000000..08e2b47
--- /dev/null
+++ b/Documentation/preempt-locking.txt
@@ -0,0 +1,104 @@
+		  Proper Locking Under a Preemptible Kernel:
+		       Keeping Kernel Code Preempt-Safe
+			  Robert Love <rml@tech9.net>
+			   Last Updated: 22 Jan 2002
+
+
+INTRODUCTION
+
+
+A preemptible kernel creates new locking issues.  The issues are the same as
+those under SMP: concurrency and reentrancy.  Thankfully, the Linux preemptible
+kernel model leverages existing SMP locking mechanisms.  Thus, the kernel
+requires explicit additional locking for very few additional situations.
+
+This document is for all kernel hackers.  Developing code in the kernel
+requires protecting these situations.
+ 
+
+RULE #1: Per-CPU data structures need explicit protection
+
+
+Two similar problems arise. An example code snippet:
+
+	struct this_needs_locking tux[NR_CPUS];
+	tux[smp_processor_id()] = some_value;
+	/* task is preempted here... */
+	something = tux[smp_processor_id()];
+
+First, since the data is per-CPU, it may not have explicit SMP locking, but
+require it otherwise.  Second, when a preempted task is finally rescheduled,
+the previous value of smp_processor_id may not equal the current.  You must
+protect these situations by disabling preemption around them.
+
+
+RULE #2: CPU state must be protected.
+
+
+Under preemption, the state of the CPU must be protected.  This is arch-
+dependent, but includes CPU structures and state not preserved over a context
+switch.  For example, on x86, entering and exiting FPU mode is now a critical
+section that must occur while preemption is disabled.  Think what would happen
+if the kernel is executing a floating-point instruction and is then preempted.
+Remember, the kernel does not save FPU state except for user tasks.  Therefore,
+upon preemption, the FPU registers will be sold to the lowest bidder.  Thus,
+preemption must be disabled around such regions.
+
+Note, some FPU functions are already explicitly preempt safe.  For example,
+kernel_fpu_begin and kernel_fpu_end will disable and enable preemption.
+However, math_state_restore must be called with preemption disabled.
+
+
+RULE #3: Lock acquire and release must be performed by same task
+
+
+A lock acquired in one task must be released by the same task.  This
+means you can't do oddball things like acquire a lock and go off to
+play while another task releases it.  If you want to do something
+like this, acquire and release the task in the same code path and
+have the caller wait on an event by the other task.
+
+
+SOLUTION
+
+
+Data protection under preemption is achieved by disabling preemption for the
+duration of the critical region.
+
+preempt_enable()		decrement the preempt counter
+preempt_disable()		increment the preempt counter
+preempt_enable_no_resched()	decrement, but do not immediately preempt
+preempt_get_count()		return the preempt counter
+
+The functions are nestable.  In other words, you can call preempt_disable
+n-times in a code path, and preemption will not be reenabled until the n-th
+call to preempt_enable.  The preempt statements define to nothing if
+preemption is not enabled.
+
+Note that you do not need to explicitly prevent preemption if you are holding
+any locks or interrupts are disabled, since preemption is implicitly disabled
+in those cases.
+
+Example:
+
+	cpucache_t *cc; /* this is per-CPU */
+	preempt_disable();
+	cc = cc_data(searchp);
+	if (cc && cc->avail) {
+		__free_block(searchp, cc_entry(cc), cc->avail);
+		cc->avail = 0;
+	}
+	preempt_enable();
+	return 0;
+
+Notice how the preemption statements must encompass every reference of the
+critical variables.  Another example:
+
+	int buf[NR_CPUS];
+	set_cpu_val(buf);
+	if (buf[smp_processor_id()] == -1) printf(KERN_INFO "wee!\n");
+	spin_lock(&buf_lock);
+	/* ... */
+
+This code is not preempt-safe, but see how easily we can fix it by simply
+moving the spin_lock up two lines.
diff --git a/MAINTAINERS b/MAINTAINERS
index f716e1a..f2d6ca4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1240,6 +1240,14 @@
 M:	mostrows@styx.uwaterloo.ca
 S:	Maintained
 
+PREEMPTIBLE KERNEL
+P:	Robert Love
+M:	rml@tech9.net
+L:	linux-kernel@vger.kernel.org
+L:	kpreempt-tech@lists.sourceforge.net
+W:	ftp://ftp.kernel.org/pub/linux/kernel/people/rml/preempt-kernel
+S:	Supported
+
 PROMISE DC4030 CACHING DISK CONTROLLER DRIVER
 P:	Peter Denison
 M:	promise@pnd-pc.demon.co.uk
diff --git a/Makefile b/Makefile
index d45179e..3d47f03 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 4
-EXTRAVERSION =-pre5
+EXTRAVERSION =
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -140,7 +140,6 @@
 DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
 DRIVERS-$(CONFIG_DRM) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
-DRIVERS-$(CONFIG_ISDN) += drivers/isdn/isdn.a
 DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.o
 DRIVERS-$(CONFIG_APPLETALK) += drivers/net/appletalk/appletalk.o
 DRIVERS-$(CONFIG_TR) += drivers/net/tokenring/tr.o
@@ -187,6 +186,7 @@
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
+DRIVERS-$(CONFIG_ISDN) += drivers/isdn/vmlinux-obj.o
 
 DRIVERS := $(DRIVERS-y)
 
@@ -207,7 +207,7 @@
 	drivers/scsi/aic7xxx/aicasm/aicasm_scan.c \
 	drivers/scsi/aic7xxx/aicasm/y.tab.h \
 	drivers/scsi/aic7xxx/aicasm/aicasm \
-	drivers/scsi/53c700-mem.c \
+	drivers/scsi/53c700_d.h \
 	net/khttpd/make_times_h \
 	net/khttpd/times.h \
 	submenu*
diff --git a/arch/alpha/Config.help b/arch/alpha/Config.help
index 4a5b503..3a7e6b9 100644
--- a/arch/alpha/Config.help
+++ b/arch/alpha/Config.help
@@ -597,31 +597,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_SRM_ENV
   If you enable this option, a subdirectory called srm_environment
   will give you access to the most important SRM environment
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index a7dedd3..b1c6709 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -12,6 +12,14 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
 # Loadable module support
 #
 CONFIG_MODULES=y
@@ -63,10 +71,6 @@
 CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 # CONFIG_BINFMT_AOUT is not set
@@ -89,6 +93,7 @@
 #
 CONFIG_PNP=y
 CONFIG_ISAPNP=y
+# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -98,6 +103,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=m
 # CONFIG_BLK_DEV_NBD is not set
@@ -121,7 +127,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+CONFIG_NETLINK_DEV=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 # CONFIG_FILTER is not set
@@ -133,6 +139,7 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 CONFIG_INET_ECN=y
 # CONFIG_SYN_COOKIES is not set
 
@@ -142,12 +149,14 @@
 CONFIG_IP_NF_CONNTRACK=m
 CONFIG_IP_NF_FTP=m
 CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 # CONFIG_IP_NF_MATCH_LIMIT is not set
 # CONFIG_IP_NF_MATCH_MAC is not set
 # CONFIG_IP_NF_MATCH_MARK is not set
 # CONFIG_IP_NF_MATCH_MULTIPORT is not set
 # CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_AH_ESP is not set
 # CONFIG_IP_NF_MATCH_LENGTH is not set
 # CONFIG_IP_NF_MATCH_TTL is not set
 # CONFIG_IP_NF_MATCH_TCPMSS is not set
@@ -166,6 +175,7 @@
 CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
 # CONFIG_IP_NF_TARGET_TCPMSS is not set
 CONFIG_IP_NF_COMPAT_IPCHAINS=y
 CONFIG_IP_NF_NAT_NEEDED=y
@@ -212,6 +222,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -226,6 +237,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -237,12 +249,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_IDEPCI_SHARE_IRQ is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 CONFIG_BLK_DEV_ALI15X3=y
@@ -257,6 +272,7 @@
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC_ADMA is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
 # CONFIG_PDC202XX_BURST is not set
 # CONFIG_PDC202XX_FORCE is not set
@@ -294,7 +310,6 @@
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
-# CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -331,6 +346,7 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
 CONFIG_SCSI_NCR53C8XX=y
 CONFIG_SCSI_SYM53C8XX=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
@@ -356,6 +372,15 @@
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -368,6 +393,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
 #
@@ -378,7 +404,6 @@
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 CONFIG_NET_VENDOR_3COM=y
 # CONFIG_EL1 is not set
@@ -403,23 +428,32 @@
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_DE4X5 is not set
+CONFIG_DE2104X=m
 CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+CONFIG_TULIP_MMIO=y
+# CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -497,19 +531,6 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -543,11 +564,15 @@
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
@@ -557,7 +582,7 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
@@ -585,6 +610,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
@@ -604,7 +630,6 @@
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 # CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -677,8 +702,10 @@
 # CONFIG_USB is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
 # CONFIG_USB_OHCI is not set
@@ -750,6 +777,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 # CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
 # CONFIG_USB_SERIAL_EDGEPORT is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
@@ -763,6 +791,7 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
@@ -772,15 +801,26 @@
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
 
 #
-# Input core support
+# Input device support
 #
 # CONFIG_INPUT is not set
 # CONFIG_INPUT_KEYBDEV is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_JOYDEV is not set
 # CONFIG_INPUT_EVDEV is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_GAMEPORT_PCIGAME is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_SERPORT is not set
 
 #
 # Bluetooth support
@@ -795,3 +835,13 @@
 CONFIG_MATHEMU=y
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_RWLOCK is not set
+# CONFIG_DEBUG_SEMAPHORE is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff --git a/arch/arm/Config.help b/arch/arm/Config.help
index ff4735b..7b8bfc3 100644
--- a/arch/arm/Config.help
+++ b/arch/arm/Config.help
@@ -471,31 +471,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_ARCH_ARCA5K
   This selects what ARM system you wish to build the kernel for. It
   also selects to some extent the CPU type. If you are unsure what
diff --git a/arch/cris/Config.help b/arch/cris/Config.help
index 6dc300a..3f31085 100644
--- a/arch/cris/Config.help
+++ b/arch/cris/Config.help
@@ -171,31 +171,6 @@
   Kernel patches and supporting utilities to do that are in the pcsp
   package, available at <ftp://ftp.infradead.org/pub/pcsp/>.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_ETRAX100LX
   Support version 1 of the Etrax 100LX.
 
diff --git a/arch/i386/Config.help b/arch/i386/Config.help
index 98b4c75..c5d53f7 100644
--- a/arch/i386/Config.help
+++ b/arch/i386/Config.help
@@ -25,6 +25,16 @@
 
   If you don't know what to do here, say N.
 
+CONFIG_PREEMPT
+  This option reduces the latency of the kernel when reacting to
+  real-time or interactive events by allowing a low priority process to
+  be preempted even if it is in kernel mode executing a system call.
+  This allows applications to run more reliably even when the system is
+  under load.
+
+  Say Y here if you are building a kernel for a desktop, embedded
+  or real-time system.  Say N if you are unsure.
+
 CONFIG_X86
   This is Linux's home port.  Linux was originally native to the Intel
   386, and runs on all the later x86 processors including the Intel
@@ -890,31 +900,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_DEBUG_HIGHMEM
   This options enables addition error checking for high memory systems.
   Disable for production systems.
diff --git a/arch/i386/config.in b/arch/i386/config.in
index ae7cd0b..21c2586 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -167,6 +167,7 @@
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'Preemptible Kernel' CONFIG_PREEMPT
 if [ "$CONFIG_SMP" != "y" ]; then
    bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
    dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
@@ -180,9 +181,12 @@
    bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
 fi
 
-if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
-   define_bool CONFIG_HAVE_DEC_LOCK y
+if [ "$CONFIG_SMP" = "y" -o "$CONFIG_PREEMPT" = "y" ]; then
+   if [ "$CONFIG_X86_CMPXCHG" = "y" ]; then
+      define_bool CONFIG_HAVE_DEC_LOCK y
+   fi
 fi
+
 endmenu
 
 mainmenu_option next_comment
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 0d33e70..deccdea 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -7,6 +7,11 @@
 CONFIG_UID16=y
 
 #
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+
+#
 # General setup
 #
 CONFIG_NET=y
@@ -15,11 +20,6 @@
 CONFIG_SYSCTL=y
 
 #
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-
-#
 # Loadable module support
 #
 CONFIG_MODULES=y
@@ -68,6 +68,7 @@
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_MTRR is not set
 CONFIG_SMP=y
+# CONFIG_PREEMPT is not set
 # CONFIG_MULTIQUAD is not set
 CONFIG_HAVE_DEC_LOCK=y
 
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 16b69e8..499b2fd 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -36,6 +36,7 @@
 #include <linux/smp.h>
 #include <linux/major.h>
 #include <linux/smp_lock.h>
+#include <linux/fs.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 65bfc86..f006f47 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -69,6 +69,37 @@
 NT_MASK		= 0x00004000
 VM_MASK		= 0x00020000
 
+/* These are offsets into the irq_stat structure
+ * There is one per cpu and it is aligned to 32
+ * byte boundry (we put that here as a shift count)
+ */
+irq_array_shift			= CONFIG_X86_L1_CACHE_SHIFT
+irq_stat_local_irq_count	= 4
+irq_stat_local_bh_count		= 8
+
+#ifdef CONFIG_SMP
+#define GET_CPU_INDX	movl TI_CPU(%ebx),%eax;  \
+                        shll $irq_array_shift,%eax
+#define GET_CURRENT_CPU_INDX GET_THREAD_INFO(%ebx); \
+                             GET_CPU_INDX
+#define CPU_INDX (,%eax)
+#else
+#define GET_CPU_INDX
+#define GET_CURRENT_CPU_INDX GET_THREAD_INFO(%ebx)
+#define CPU_INDX
+#endif
+
+#ifdef CONFIG_PREEMPT
+#define preempt_stop cli
+#define init_ret_intr \
+	cli; \
+	decl TI_PRE_COUNT(%ebx);
+#else
+#define preempt_stop
+#define init_ret_intr
+#define resume_kernel restore_all
+#endif
+
 #define SAVE_ALL \
 	cld; \
 	pushl %es; \
@@ -176,11 +207,12 @@
 	ALIGN
 ENTRY(ret_from_intr)
 	GET_THREAD_INFO(%ebx)
+	init_ret_intr
 ret_from_exception:
 	movl EFLAGS(%esp),%eax		# mix EFLAGS and CS
 	movb CS(%esp),%al
 	testl $(VM_MASK | 3),%eax
-	jz restore_all			# returning to kernel-space or vm86-space
+	jz resume_kernel		# returning to kernel or vm86-space
 ENTRY(resume_userspace)
  	cli				# make sure we don't miss an interrupt setting need_resched
  					# or sigpending between sampling and the iret
@@ -189,6 +221,22 @@
 	jne work_pending
 	jmp restore_all
 
+#ifdef CONFIG_PREEMPT
+ENTRY(resume_kernel)
+	cmpl $0,TI_PRE_COUNT(%ebx)
+	jnz restore_all
+	movl TI_FLAGS(%ebx),%ecx
+	testb $_TIF_NEED_RESCHED,%cl
+	jz restore_all
+	movl SYMBOL_NAME(irq_stat)+irq_stat_local_bh_count CPU_INDX,%ecx
+	addl SYMBOL_NAME(irq_stat)+irq_stat_local_irq_count CPU_INDX,%ecx
+	jnz restore_all
+	incl TI_PRE_COUNT(%ebx)
+	sti
+	call SYMBOL_NAME(preempt_schedule)
+	jmp ret_from_intr
+#endif
+
 	# system call handler stub
 	ALIGN
 ENTRY(system_call)
@@ -302,6 +350,7 @@
 	GET_THREAD_INFO(%ebx)
 	call *%edi
 	addl $8,%esp
+	preempt_stop
 	jmp ret_from_exception
 
 ENTRY(coprocessor_error)
@@ -321,12 +370,14 @@
 	movl %cr0,%eax
 	testl $0x4,%eax			# EM (math emulation bit)
 	jne device_not_available_emulate
+	preempt_stop
 	call SYMBOL_NAME(math_state_restore)
 	jmp ret_from_exception
 device_not_available_emulate:
 	pushl $0		# temporary storage for ORIG_EIP
 	call  SYMBOL_NAME(math_emulate)
 	addl $4,%esp
+	preempt_stop
 	jmp ret_from_exception
 
 ENTRY(debug)
diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
index a87a362..c237c22 100644
--- a/arch/i386/kernel/i387.c
+++ b/arch/i386/kernel/i387.c
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/sched.h>
+#include <linux/spinlock.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/math_emu.h>
@@ -63,6 +64,7 @@
 
 void kernel_fpu_begin(void)
 {
+	preempt_disable();
 	if (test_thread_flag(TIF_USEDFPU)) {
 		__save_init_fpu(current);
 		return;
diff --git a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
index d127032..f652f27 100644
--- a/arch/i386/kernel/init_task.c
+++ b/arch/i386/kernel/init_task.c
@@ -2,6 +2,7 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/init_task.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 1856035..4d377ee 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -35,6 +35,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/major.h>
+#include <linux/fs.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 142915b..99710bb 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -16,6 +16,7 @@
 
 #include <linux/errno.h>
 #include <linux/sched.h>
+#include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -47,6 +48,7 @@
 #endif
 
 #include <linux/irq.h>
+#include <linux/err.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c
index 09c0852..06bdf8a 100644
--- a/arch/i386/kernel/semaphore.c
+++ b/arch/i386/kernel/semaphore.c
@@ -14,6 +14,7 @@
  */
 #include <linux/config.h>
 #include <linux/sched.h>
+#include <linux/err.h>
 #include <asm/semaphore.h>
 
 /*
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index af1dc73..7fdbdfd 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -497,7 +497,7 @@
 	/*
 	 * The target CPU will unlock the migration spinlock:
 	 */
-	spin_lock(&migration_lock);
+	_raw_spin_lock(&migration_lock);
 	new_task = p;
 	send_IPI_mask(1 << cpu, TASK_MIGRATION_VECTOR);
 }
@@ -511,7 +511,7 @@
 
 	ack_APIC_irq();
 	p = new_task;
-	spin_unlock(&migration_lock);
+	_raw_spin_unlock(&migration_lock);
 	sched_task_migrated(p);
 }
 /*
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index ad68256..7c2c252 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -710,6 +710,8 @@
  *
  * Careful.. There are problems with IBM-designed IRQ13 behaviour.
  * Don't touch unless you *really* know how it works.
+ *
+ * Must be called with kernel preemption disabled.
  */
 asmlinkage void math_state_restore(struct pt_regs regs)
 {
diff --git a/arch/ia64/Config.help b/arch/ia64/Config.help
index 23ae7ec..2da7592 100644
--- a/arch/ia64/Config.help
+++ b/arch/ia64/Config.help
@@ -424,31 +424,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_ITANIUM
   Select your IA64 processor type.  The default is Intel Itanium.
 
diff --git a/arch/mips/Config.help b/arch/mips/Config.help
index 82851d0..56a6426 100644
--- a/arch/mips/Config.help
+++ b/arch/mips/Config.help
@@ -899,31 +899,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_GDB_CONSOLE
   If you are using GDB for remote debugging over a serial port and
   would like kernel messages to be formatted into GDB $O packets so
diff --git a/arch/mips64/Config.help b/arch/mips64/Config.help
index f82765e..3e09dbb 100644
--- a/arch/mips64/Config.help
+++ b/arch/mips64/Config.help
@@ -438,31 +438,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_BINFMT_ELF32
   This allows you to run 32-bit Linux/ELF binaries on your Ultra.
   Everybody wants this; say Y.
diff --git a/arch/ppc/Config.help b/arch/ppc/Config.help
index 5786797..603820e 100644
--- a/arch/ppc/Config.help
+++ b/arch/ppc/Config.help
@@ -551,31 +551,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_PROC_HARDWARE
   Say Y here to support the /proc/hardware file, which gives you
   access to information about the machine you're running on,
diff --git a/arch/sparc/Config.help b/arch/sparc/Config.help
index a6c2290..f64c934 100644
--- a/arch/sparc/Config.help
+++ b/arch/sparc/Config.help
@@ -1054,31 +1054,6 @@
   keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
   unless you really know what this hack does.
 
-CONFIG_ISDN
-  ISDN ("Integrated Services Digital Networks", called RNIS in France)
-  is a special type of fully digital telephone service; it's mostly
-  used to connect to your Internet service provider (with SLIP or
-  PPP).  The main advantage is that the speed is higher than ordinary
-  modem/telephone connections, and that you can have voice
-  conversations while downloading stuff.  It only works if your
-  computer is equipped with an ISDN card and both you and your service
-  provider purchased an ISDN line from the phone company.  For
-  details, read <http://alumni.caltech.edu/~dank/isdn/> on the WWW.
-
-  This driver allows you to use an ISDN-card for networking
-  connections and as dialin/out device.  The isdn-tty's have a built
-  in AT-compatible modem emulator.  Network devices support autodial,
-  channel-bundling, callback and caller-authentication without having
-  a daemon running.  A reduced T.70 protocol is supported with tty's
-  suitable for German BTX.  On D-Channel, the protocols EDSS1
-  (Euro-ISDN) and 1TR6 (German style) are supported.  See
-  <file:Documentation/isdn/README> for more information.
-
-  If you want to compile the ISDN code as a module ( = code which can
-  be inserted in and removed from the running kernel whenever you
-  want), say M here and read <file:Documentation/modules.txt>.  The
-  module will be called isdn.o. If unsure, say N.
-
 CONFIG_SUN4
   Say Y here if, and only if, your machine is a Sun4. Note that
   a kernel compiled with this option will run only on Sun4.
diff --git a/arch/sparc64/Config.help b/arch/sparc64/Config.help
index 907510a..237c8af 100644
--- a/arch/sparc64/Config.help
+++ b/arch/sparc64/Config.help
@@ -25,6 +25,16 @@
 
   If you don't know what to do here, say N.
 
+CONFIG_PREEMPT
+  This option reduces the latency of the kernel when reacting to
+  real-time or interactive events by allowing a low priority process to
+  be preempted even if it is in kernel mode executing a system call.
+  This allows applications to run more reliably even when the system is
+  under load.
+
+  Say Y here if you are building a kernel for a desktop, embedded
+  or real-time system.  Say N if you are unsure.
+
 CONFIG_SPARC64
   SPARC is a family of RISC microprocessors designed and marketed by
   Sun Microsystems, incorporated.  This port covers the newer 64-bit
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index cd712df..616a2f6 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.158 2002-01-24 22:14:44 davem Exp $
+# $Id: config.in,v 1.159 2002-02-11 06:42:06 davem Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -15,6 +15,7 @@
 define_bool CONFIG_VT_CONSOLE y
 
 bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'Preemptible kernel' CONFIG_PREEMPT
 
 # Identify this as a Sparc64 build
 define_bool CONFIG_SPARC64 y
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 285da21..7069592 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.144 2002-02-09 19:49:30 davem Exp $
+/* $Id: entry.S,v 1.145 2002-02-11 06:42:06 davem Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -713,8 +713,8 @@
 	call		sparc_floppy_irq
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o2
 
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 #endif /* CONFIG_BLK_DEV_FD */
 
@@ -883,7 +883,7 @@
 	mov	%l5, %o1
 	call	cee_log
 	 add	%sp, STACK_BIAS + REGWIN_SZ, %o2
-	ba,a,pt	%xcc, rtrap_clr_l6
+	ba,a,pt	%xcc, rtrap_irq
 
 	/* Capture I/D/E-cache state into per-cpu error scoreboard.
 	 *
@@ -1109,7 +1109,7 @@
 	mov		%l5, %o2
 	call		cheetah_fecc_handler
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	ba,a,pt		%xcc, rtrap_clr_l6
+	ba,a,pt		%xcc, rtrap_irq
 
 	/* Our caller has disabled I-cache and performed membar Sync. */
 	.globl		cheetah_cee
@@ -1135,7 +1135,7 @@
 	mov		%l5, %o2
 	call		cheetah_cee_handler
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	ba,a,pt		%xcc, rtrap_clr_l6
+	ba,a,pt		%xcc, rtrap_irq
 
 	/* Our caller has disabled I-cache+D-cache and performed membar Sync. */
 	.globl		cheetah_deferred_trap
@@ -1161,7 +1161,7 @@
 	mov		%l5, %o2
 	call		cheetah_deferred_handler
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	ba,a,pt		%xcc, rtrap_clr_l6
+	ba,a,pt		%xcc, rtrap_irq
 
 	.globl		__do_privact
 __do_privact:
diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
index 70e07ef..3624e50 100644
--- a/arch/sparc64/kernel/etrap.S
+++ b/arch/sparc64/kernel/etrap.S
@@ -1,10 +1,12 @@
-/* $Id: etrap.S,v 1.46 2002-02-09 19:49:30 davem Exp $
+/* $Id: etrap.S,v 1.47 2002-02-11 06:42:06 davem Exp $
  * etrap.S: Preparing for entry into the kernel on Sparc V9.
  *
  * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
  * Copyright (C) 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
+#include <linux/config.h>
+
 #include <asm/asi.h>
 #include <asm/pstate.h>
 #include <asm/ptrace.h>
@@ -25,9 +27,17 @@
 		.text		
 		.align	64
 		.globl	etrap, etrap_irq, etraptl1
-
+#ifdef CONFIG_PREEMPT
+etrap_irq:	ldsw	[%g6 + TI_PRE_COUNT], %g1
+		add	%g1, 1, %g1
+		ba,pt	%xcc, etrap_irq2
+		 stw	%g1, [%g6 + TI_PRE_COUNT]
+#endif
 etrap:		rdpr	%pil, %g2						! Single 	Group
-etrap_irq:	rdpr	%tstate, %g1						! Single 	Group
+#ifndef CONFIG_PREEMPT
+etrap_irq:
+#endif
+etrap_irq2:	rdpr	%tstate, %g1						! Single 	Group
 		sllx	%g2, 20, %g3						! IEU0		Group
 		andcc	%g1, TSTATE_PRIV, %g0					! IEU1
 		or	%g1, %g3, %g1						! IEU0		Group
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 561b24d..56d55e5 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/*  $Id: process.c,v 1.133 2002-02-11 04:47:29 davem Exp $
+/*  $Id: process.c,v 1.134 2002-02-11 06:42:06 davem Exp $
  *  arch/sparc64/kernel/process.c
  *
  *  Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -100,6 +100,18 @@
 
 #endif
 
+#ifdef CONFIG_PREEMPT
+void kpreempt_maybe(void)
+{
+	int cpu = smp_processor_id();
+
+	if (local_irq_count(cpu) == 0 &&
+	    local_bh_count(cpu) == 0)
+		preempt_schedule();
+	current_thread_info()->preempt_count--;
+}
+#endif
+
 extern char reboot_command [];
 
 #ifdef CONFIG_SUN_CONSOLE
@@ -371,7 +383,7 @@
 {
 	struct thread_info *ti = tsk->thread_info;
 	unsigned long ret = 0xdeadbeefUL;
-
+	
 	if (ti && ti->ksp) {
 		unsigned long *sp;
 		sp = (unsigned long *)(ti->ksp + STACK_BIAS);
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index 76b9b32..5cdddfd 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -1,10 +1,12 @@
-/* $Id: rtrap.S,v 1.61 2002-02-09 19:49:31 davem Exp $
+/* $Id: rtrap.S,v 1.62 2002-02-11 06:42:06 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
  */
 
+#include <linux/config.h>
+
 #include <asm/asi.h>
 #include <asm/pstate.h>
 #include <asm/ptrace.h>
@@ -148,7 +150,13 @@
 		 andn			%l1, %l4, %l1
 
 		.align			64
-		.globl			rtrap_clr_l6, rtrap, irqsz_patchme
+		.globl			rtrap_irq, rtrap_clr_l6, rtrap, irqsz_patchme
+rtrap_irq:
+#ifdef CONFIG_PREEMPT
+		ldsw			[%g6 + TI_PRE_COUNT], %l0
+		sub			%l0, 1, %l0
+		stw			%l0, [%g6 + TI_PRE_COUNT]
+#endif
 rtrap_clr_l6:	clr			%l6
 rtrap:		ldub			[%g6 + TI_CPU], %l0
 		sethi			%hi(irq_stat), %l2	! &softirq_active
@@ -261,7 +269,18 @@
 
 kern_rtt:	restore
 		retry
-to_kernel:	ldub			[%g6 + TI_FPDEPTH], %l5
+to_kernel:
+#ifdef CONFIG_PREEMPT
+		ldsw			[%g6 + TI_PRE_COUNT], %l5
+		brnz			%l5, kern_fpucheck
+		 add			%l5, 1, %l6
+		stw			%l6, [%g6 + TI_PRE_COUNT]
+		call			kpreempt_maybe
+		 wrpr			%g0, RTRAP_PSTATE, %pstate
+		wrpr			%g0, RTRAP_PSTATE_IRQOFF, %pstate		
+		stw			%l5, [%g6 + TI_PRE_COUNT]
+#endif
+kern_fpucheck:	ldub			[%g6 + TI_FPDEPTH], %l5
 		brz,pt			%l5, rt_continue
 		 srl			%l5, 1, %o0
 		add			%g6, TI_FPSAVED, %l6
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 218b9d3..e0b6632 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -902,7 +902,7 @@
 	if (smp_processors_ready && (cpu_present_map & mask) != 0) {
 		u64 data0 = (((u64)&xcall_migrate_task) & 0xffffffff);
 
-		spin_lock(&migration_lock);
+		_raw_spin_lock(&migration_lock);
 		new_task = p;
 
 		if (tlb_type == spitfire)
@@ -923,7 +923,7 @@
 	clear_softint(1 << irq);
 
 	p = new_task;
-	spin_unlock(&migration_lock);
+	_raw_spin_unlock(&migration_lock);
 	sched_task_migrated(p);
 }
 
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index b5a876d..494c2a0 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.184 2002-02-09 19:49:31 davem Exp $
+/* $Id: sys_sparc32.c,v 1.185 2002-02-11 06:42:06 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -49,6 +49,7 @@
 #include <linux/in.h>
 #include <linux/icmpv6.h>
 #include <linux/sysctl.h>
+#include <linux/binfmts.h>
 
 #include <asm/types.h>
 #include <asm/ipc.h>
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 3f8e7ab..0aa221c 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.85 2002-02-09 19:49:31 davem Exp $
+/* $Id: traps.c,v 1.86 2002-02-11 06:42:06 davem Exp $
  * arch/sparc64/kernel/traps.c
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -1700,6 +1700,7 @@
 	    TI_KERN_CNTD1 != offsetof(struct thread_info, kernel_cntd1) ||
 	    TI_PCR != offsetof(struct thread_info, pcr_reg) ||
 	    TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) ||
+	    TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
 	    TI_FPREGS != offsetof(struct thread_info, fpregs) ||
 	    (TI_FPREGS & (64 - 1)))
 		thread_info_offsets_are_bolixed_dave();
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S
index b95beb5..e2aeb6d 100644
--- a/arch/sparc64/lib/VISsave.S
+++ b/arch/sparc64/lib/VISsave.S
@@ -1,4 +1,4 @@
-/* $Id: VISsave.S,v 1.6 2002-02-09 19:49:30 davem Exp $
+/* $Id: VISsave.S,v 1.7 2002-02-11 06:42:06 davem Exp $
  * VISsave.S: Code for saving FPU register state for
  *            VIS routines. One should not call this directly,
  *            but use macros provided in <asm/visasm.h>.
@@ -18,6 +18,10 @@
 	/* On entry: %o5=current FPRS value, %g7 is callers address */
 	/* May clobber %o5, %g1, %g2, %g3, %g7, %icc, %xcc */
 
+	/* Nothing special need be done here to handle pre-emption, this
+	 * FPU save/restore mechanism is already preemption safe.
+	 */
+
 	.align		32
 VISenter:
 	ldub		[%g6 + TI_FPDEPTH], %g1
diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S
index 28b7a9b..f837938 100644
--- a/arch/sparc64/lib/dec_and_lock.S
+++ b/arch/sparc64/lib/dec_and_lock.S
@@ -1,10 +1,11 @@
-/* $Id: dec_and_lock.S,v 1.5 2001-11-18 00:12:56 davem Exp $
+/* $Id: dec_and_lock.S,v 1.6 2002-02-11 06:42:06 davem Exp $
  * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()"
  *                 using cas and ldstub instructions.
  *
  * Copyright (C) 2000 David S. Miller (davem@redhat.com)
  */
 #include <linux/config.h>
+#include <asm/thread_info.h>
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 	.text
@@ -40,6 +41,11 @@
 	membar	#StoreLoad | #StoreStore
 	retl
 	 mov	%g1, %o0
+#ifdef CONFIG_PREEMPT
+	ldsw	[%g6 + TI_PRE_COUNT], %g3
+	add	%g3, 1, %g3
+	stw	%g3, [%g6 + TI_PRE_COUNT]
+#endif
 to_zero:
 	ldstub	[%o1], %g3
 	brnz,pn	%g3, spin_on_lock
@@ -55,6 +61,11 @@
 	 nop
 	membar	#StoreStore | #LoadStore
 	stb	%g0, [%o1]
+#ifdef CONFIG_PREEMPT
+	ldsw	[%g6 + TI_PRE_COUNT], %g3
+	sub	%g3, 1, %g3
+	stw	%g3, [%g6 + TI_PRE_COUNT]
+#endif
 
 	b,pt	%xcc, nzero
 	 nop
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 948a3b4..5344dcd 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.72 2002-02-09 19:49:31 davem Exp $
+/* $Id: ultra.S,v 1.73 2002-02-11 06:42:06 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -493,8 +493,8 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		__show_regs
 	 add		%sp, STACK_BIAS + REGWIN_SZ, %o0
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 	.align		32
 	.globl		xcall_flush_dcache_page_cheetah
@@ -554,8 +554,8 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		smp_penguin_jailcell
 	 nop
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 	.globl		xcall_promstop
 xcall_promstop:
@@ -681,8 +681,8 @@
 109:	 or		%g7, %lo(109b), %g7
 	call		smp_call_function_client
 	 nop
-	b,pt		%xcc, rtrap
-	 clr		%l6
+	b,pt		%xcc, rtrap_irq
+	 nop
 
 	.globl		xcall_migrate_task
 xcall_migrate_task:
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 4a8b527..978e3f5 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/err.h>
 
 #undef DEBUG
 
diff --git a/drivers/base/fs.c b/drivers/base/fs.c
index 363ac8a..39cf1fb50 100644
--- a/drivers/base/fs.c
+++ b/drivers/base/fs.c
@@ -9,6 +9,8 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/stat.h>
 
 extern struct driver_file_entry * device_default_files[];
 
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
index 61a3fa5..f7698d3 100644
--- a/drivers/base/interface.c
+++ b/drivers/base/interface.c
@@ -6,6 +6,8 @@
  */
 
 #include <linux/device.h>
+#include <linux/err.h>
+#include <linux/stat.h>
 
 /**
  * device_read_status - report some device information
diff --git a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
index 2f717b9..3c4b24e 100644
--- a/drivers/char/agp/agpgart_be.c
+++ b/drivers/char/agp/agpgart_be.c
@@ -2391,7 +2391,7 @@
 
 	agp_bridge.gatt_table_real = page_dir.real;
 	agp_bridge.gatt_table = page_dir.remapped;
-	agp_bridge.gatt_bus_addr = virt_to_bus(page_dir.real);
+	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -2405,7 +2405,7 @@
 	/* Calculate the agp offset */
 	for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
 		page_dir.remapped[GET_PAGE_DIR_OFF(addr)] =
-			virt_to_bus(amd_irongate_private.gatt_pages[i]->real);
+			virt_to_phys(amd_irongate_private.gatt_pages[i]->real);
 		page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001;
 	}
 
@@ -3027,7 +3027,7 @@
 	for(i = 0; i < 1024; i++) {
 		serverworks_private.scratch_dir.remapped[i] = (unsigned long) agp_bridge.scratch_page;
 		page_dir.remapped[i] =
-			virt_to_bus(serverworks_private.scratch_dir.real);
+			virt_to_phys(serverworks_private.scratch_dir.real);
 		page_dir.remapped[i] |= 0x00000001;
 	}
 
@@ -3040,7 +3040,7 @@
 
 	agp_bridge.gatt_table_real = page_dir.real;
 	agp_bridge.gatt_table = page_dir.remapped;
-	agp_bridge.gatt_bus_addr = virt_to_bus(page_dir.real);
+	agp_bridge.gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -3056,7 +3056,7 @@
 
 	for(i = 0; i < value->num_entries / 1024; i++) {
 		page_dir.remapped[i] =
-			virt_to_bus(serverworks_private.gatt_pages[i]->real);
+			virt_to_phys(serverworks_private.gatt_pages[i]->real);
 		page_dir.remapped[i] |= 0x00000001;
 	}
 
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 9fa07e6..4ff7dc3 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -143,9 +143,14 @@
 		/* Can't copy more? break out! */
 		if (c <= 0) break;
 		if (from_user)
-			copy_from_user (port->xmit_buf + port->xmit_head, buf, c);
+			if (copy_from_user (port->xmit_buf + port->xmit_head, 
+					    buf, c)) {
+				up (& port->port_write_sem);
+				return -EFAULT;
+			}
+
 		else
-			memcpy         (port->xmit_buf + port->xmit_head, buf, c);
+			memcpy (port->xmit_buf + port->xmit_head, buf, c);
 
 		port -> xmit_cnt += c;
 		port -> xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE -1);
@@ -604,7 +609,7 @@
 	 * until it's done, and then try again.
 	 */
 	if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
-	  interruptible_sleep_on(&port->close_wait);
+		interruptible_sleep_on(&port->close_wait);
 		if (port->flags & ASYNC_HUP_NOTIFY)
 			return -EAGAIN;
 		else
@@ -1003,7 +1008,8 @@
 {
 	struct serial_struct sio;
 
-	copy_from_user(&sio, sp, sizeof(struct serial_struct));
+	if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
+		return(-EFAULT);
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((sio.baud_base != port->baud_base) ||
@@ -1033,7 +1039,7 @@
  *      Generate the serial struct info.
  */
 
-void gs_getserial(struct gs_port *port, struct serial_struct *sp)
+int gs_getserial(struct gs_port *port, struct serial_struct *sp)
 {
 	struct serial_struct    sio;
 
@@ -1055,7 +1061,10 @@
 	if (port->rd->getserial)
 		port->rd->getserial (port, &sio);
 
-	copy_to_user(sp, &sio, sizeof(struct serial_struct));
+	if (copy_to_user(sp, &sio, sizeof(struct serial_struct)))
+		return -EFAULT;
+	return 0;
+
 }
 
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 656a38b..0efd9b3 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -251,6 +251,7 @@
 #include <linux/random.h>
 #include <linux/poll.h>
 #include <linux/init.h>
+#include <linux/fs.h>
 
 #include <asm/processor.h>
 #include <asm/uaccess.h>
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 3b41b68..293008c 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -742,7 +742,7 @@
   case TIOCGSERIAL:
     if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
                           sizeof(struct serial_struct))) == 0)
-      gs_getserial(&PortP->gs, (struct serial_struct *) arg);
+      rc = gs_getserial(&PortP->gs, (struct serial_struct *) arg);
     break;
   case TCSBRK:
     if ( PortP->State & RIO_DELETED ) {
diff --git a/drivers/char/serial_tx3912.c b/drivers/char/serial_tx3912.c
index d2b46ac..4743489 100644
--- a/drivers/char/serial_tx3912.c
+++ b/drivers/char/serial_tx3912.c
@@ -673,7 +673,7 @@
 	case TIOCGSERIAL:
 		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
 		                      sizeof(struct serial_struct))) == 0)
-			gs_getserial(&port->gs, (struct serial_struct *) arg);
+			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
 		break;
 	case TIOCSSERIAL:
 		if ((rc = verify_area(VERIFY_READ, (void *) arg,
diff --git a/drivers/char/sh-sci.c b/drivers/char/sh-sci.c
index 7b5b22b..6ae9b63 100644
--- a/drivers/char/sh-sci.c
+++ b/drivers/char/sh-sci.c
@@ -919,7 +919,7 @@
 	case TIOCGSERIAL:
 		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
 		                      sizeof(struct serial_struct))) == 0)
-			gs_getserial(&port->gs, (struct serial_struct *) arg);
+			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
 		break;
 	case TIOCSSERIAL:
 		if ((rc = verify_area(VERIFY_READ, (void *) arg,
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 3ff0984..947f76a 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1160,7 +1160,8 @@
 				/* DCD went UP */
 				if( (~(port->gs.flags & ASYNC_NORMAL_ACTIVE) || 
 						 ~(port->gs.flags & ASYNC_CALLOUT_ACTIVE)) &&
-						(sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) {
+						(sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) &&
+						!(port->gs.tty->termios->c_cflag & CLOCAL) ) {
 					/* Are we blocking in open?*/
 					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n");
 					wake_up_interruptible(&port->gs.open_wait);
@@ -1170,7 +1171,8 @@
 			} else {
 				/* DCD went down! */
 				if (!((port->gs.flags & ASYNC_CALLOUT_ACTIVE) &&
-				      (port->gs.flags & ASYNC_CALLOUT_NOHUP))) {
+				      (port->gs.flags & ASYNC_CALLOUT_NOHUP)) &&
+				    !(port->gs.tty->termios->c_cflag & CLOCAL) ) {
 					sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. hanging up....\n");
 					tty_hangup (port->gs.tty);
 				} else {
@@ -1815,7 +1817,7 @@
 	case TIOCGSERIAL:
 		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
 		                      sizeof(struct serial_struct))) == 0)
-			gs_getserial(&port->gs, (struct serial_struct *) arg);
+			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
 		break;
 	case TIOCSSERIAL:
 		if ((rc = verify_area(VERIFY_READ, (void *) arg,
diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile
index a30e5f9..88e37e3 100644
--- a/drivers/isdn/Makefile
+++ b/drivers/isdn/Makefile
@@ -2,7 +2,7 @@
 
 # The target object and module list name.
 
-O_TARGET	:= isdn.a
+O_TARGET	:= vmlinux-obj.o
 
 # Objects that export symbols.
 
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 65043e6..4462060 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -1017,7 +1017,7 @@
 			return(0);
 		}
 		if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) {
-			printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated");
+			printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n");
 			set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
 		}
 		cs->hw.elsa.ale  = cs->hw.elsa.base;
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c
index a99fc45..3de9d21 100644
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -636,7 +636,7 @@
 			if (cs->hw.gazel.cfg_reg & 0x80) {
 				pci_read_config_byte(dev_tel, PCI_REVISION_ID, &pci_rev);
 				if (pci_rev == 1) {
-					printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated");
+					printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated\n");
 					set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags);
 				}
 			}
diff --git a/drivers/net/aironet4500_proc.c b/drivers/net/aironet4500_proc.c
index 1946e9c..94a77d9 100644
--- a/drivers/net/aironet4500_proc.c
+++ b/drivers/net/aironet4500_proc.c
@@ -33,15 +33,10 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 
-
 #ifdef CONFIG_PROC_FS
 
-#ifdef CONFIG_PROC_FS
 #include <linux/sysctl.h>
-#else
-#error awc driver needs CONFIG_PROC_FS
-#endif
-
+#include <linux/fs.h>
 
 #include "aironet4500.h"
 #include "aironet4500_rid.c"
@@ -603,5 +598,8 @@
 module_init(aironet_proc_init);
 module_exit(aironet_proc_exit);
 
+#else
+#error awc driver needs CONFIG_PROC_FS
+
 #endif // whole proc system styff
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c
index a93784d..09afb23 100644
--- a/drivers/net/bsd_comp.c
+++ b/drivers/net/bsd_comp.c
@@ -73,6 +73,8 @@
 #include <linux/ppp-comp.h>
 #undef   PACKETPTR
 
+#include <asm/byteorder.h>
+
 /*
  * PPP "BSD compress" compression
  *  The differences between this compression and the classic BSD LZW
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index c670ba0..cc17bdd 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -162,13 +162,6 @@
 									(dev)->watchdog_timeo = (tm); \
 								} while(0)
 
-#ifndef PCI_DEVICE_ID_INTEL_ID1029
-#define PCI_DEVICE_ID_INTEL_ID1029 0x1029
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_ID1030
-#define PCI_DEVICE_ID_INTEL_ID1030 0x1030
-#endif
-
 
 static int speedo_debug = 1;
 
@@ -2272,18 +2265,24 @@
 static struct pci_device_id eepro100_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
 		PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562ET,
-		PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER,
 		PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CAM,
-		PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029,
-		PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,
-		PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_7,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1228, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
 };
 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 7001c37..580c9d9 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -279,13 +279,13 @@
 		pci_readw(dev, PCI_DEVICE_ID, &dev->device);
 		dev->hdr_type = hdr & 0x7f;
 
+		pci_setup_device(dev);
+
 		dev->dev.parent = bus->dev;
 		strcpy(dev->dev.name, dev->name);
 		strcpy(dev->dev.bus_id, dev->slot_name);
 		device_register(&dev->dev);
 
-		pci_setup_device(dev);
-
 		/* FIXME: Do we need to enable the expansion ROM? */
 		for (r = 0; r < 7; r++) {
 			struct resource *res = dev->resource + r;
diff --git a/drivers/pnp/pnpbios_core.c b/drivers/pnp/pnpbios_core.c
index d60ec74..55a844e 100644
--- a/drivers/pnp/pnpbios_core.c
+++ b/drivers/pnp/pnpbios_core.c
@@ -45,6 +45,7 @@
 #include <linux/completion.h>
 #include <linux/spinlock.h>
 #include <asm/system.h>
+#include <asm/byteorder.h>
 
 
 /*
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index f4da711..14f8e55 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -51,6 +51,14 @@
 
 /* CHANGELOG
  *
+ * Version 2.7
+ *
+ * Fixed scripts problem which caused certain devices (notably CDRWs)
+ * to hang on initial INQUIRY.  Updated NCR_700_readl/writel to use
+ * __raw_readl/writel for parisc compatibility (Thomas
+ * Bogendoerfer). Added missing SCp->request_bufflen initialisation
+ * for sense requests (Ryan Bradetich).
+ *
  * Version 2.6
  *
  * Following test of the 64 bit parisc kernel by Richard Hirst,
@@ -96,7 +104,7 @@
  * Initial modularisation from the D700.  See NCR_D700.c for the rest of
  * the changelog.
  * */
-#define NCR_700_VERSION "2.6"
+#define NCR_700_VERSION "2.7"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -310,7 +318,6 @@
 	hostdata->pScript = pScript;
 	NCR_700_dma_cache_wback((unsigned long)script, sizeof(SCRIPT));
 	hostdata->state = NCR_700_HOST_FREE;
-	spin_lock_init(&hostdata->lock);
 	hostdata->cmd = NULL;
 	host->max_id = 7;
 	host->max_lun = NCR_700_MAX_LUNS;
@@ -1048,6 +1055,7 @@
 						    slot->pCmd,
 						    SCp->cmd_len,
 						    PCI_DMA_TODEVICE);
+				SCp->request_bufflen = sizeof(SCp->sense_buffer);
 				slot->dma_handle = pci_map_single(hostdata->pci_dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), PCI_DMA_FROMDEVICE);
 				slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
 				slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
@@ -1508,6 +1516,11 @@
 	__u8 pun = 0xff, lun = 0xff;
 	unsigned long flags;
 
+	/* Use the host lock to serialise acess to the 53c700
+	 * hardware.  Note: In future, we may need to take the queue
+	 * lock to enter the done routines.  When that happens, we
+	 * need to ensure that for this driver, the host lock and the
+	 * queue lock point to the same thing. */
 	spin_lock_irqsave(host->host_lock, flags);
 	if((istat = NCR_700_readb(host, ISTAT_REG))
 	      & (SCSI_INT_PENDING | DMA_INT_PENDING)) {
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index 66721ea..c106937 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -210,7 +210,7 @@
 struct NCR_700_Host_Parameters {
 	/* These must be filled in by the calling driver */
 	int	clock;			/* board clock speed in MHz */
-	__u32	base;			/* the base for the port (copied to host) */
+	unsigned long	base;		/* the base for the port (copied to host) */
 	struct pci_dev	*pci_dev;
 	__u32	dmode_extra;	/* adjustable bus settings */
 	__u32	differential:1;	/* if we are differential */
@@ -234,10 +234,6 @@
 	__u32	*script;		/* pointer to script location */
 	__u32	pScript;		/* physical mem addr of script */
 
-	/* This will be the host lock.  Unfortunately, we can't use it
-	 * at the moment because of the necessity of holding the
-	 * io_request_lock */
-	spinlock_t lock;
 	enum NCR_700_Host_State state; /* protected by state lock */
 	Scsi_Cmnd *cmd;
 	/* Note: pScript contains the single consistent block of
@@ -503,7 +499,7 @@
 static inline __u32
 NCR_700_readl(struct Scsi_Host *host, __u32 reg)
 {
-	__u32 value = readl(host->base + reg);
+	__u32 value = __raw_readl(host->base + reg);
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
 #if 1
@@ -536,7 +532,7 @@
 		BUG();
 #endif
 
-	writel(bS_to_host(value), host->base + reg);
+	__raw_writel(bS_to_host(value), host->base + reg);
 }
 #elif defined(CONFIG_53C700_IO_MAPPED)
 static inline __u8
diff --git a/drivers/scsi/53c700.scr b/drivers/scsi/53c700.scr
index 737c3c7..a064a09 100644
--- a/drivers/scsi/53c700.scr
+++ b/drivers/scsi/53c700.scr
@@ -242,7 +242,7 @@
 
 SendIdentifyMsg:
 	CALL	SendMessage
-	JUMP	SendCommand
+	CLEAR	ATN
 
 IgnoreMsgBeforeCommand:
 	CLEAR	ACK
diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
index 80a6c1d..810d81e 100644
--- a/drivers/scsi/NCR_D700.c
+++ b/drivers/scsi/NCR_D700.c
@@ -36,6 +36,10 @@
 
 /* CHANGELOG 
  *
+ * Version 2.2
+ *
+ * Added mca_set_adapter_name().
+ *
  * Version 2.1
  *
  * Modularise the driver into a Board piece (this file) and a chip
@@ -86,7 +90,7 @@
  * disconnections and reselections are being processed correctly.
  * */
 
-#define NCR_D700_VERSION "2.1"
+#define NCR_D700_VERSION "2.2"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -299,6 +303,7 @@
 				continue;
 			}
 			found++;
+			mca_set_adapter_name(slot, "NCR D700 SCSI Adapter (version " NCR_D700_VERSION ")");
 		}
 	}
 
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index a93ff6d..b49fb0e 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -58,7 +58,7 @@
 {
 	printk(KERN_CRIT "buf vaddress %p paddress 0x%lx length %d\n",
 	       address,
-	       SCSI_BUS_PA(address),
+	       SCSI_BUF_PA(address),
 	       length);
 	panic("Buffer at physical address > 16Mb used for aha1542");
 }
@@ -68,7 +68,7 @@
 		       int nseg,
 		       int badseg)
 {
-	printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%lx length %d\n",
+	printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%x length %d\n",
 	       badseg, nseg,
 	       page_address(sgpnt[badseg].page) + sgpnt[badseg].offset,
 	       SCSI_SG_PA(&sgpnt[badseg]),
@@ -727,7 +727,7 @@
 				panic("Foooooooood fight!");
 			};
 			any2scsi(cptr[i].dataptr, SCSI_SG_PA(&sgpnt[i]));
-			if (SCSI_SG_PA(&sgpnt[i].page) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD)
+			if (SCSI_SG_PA(&sgpnt[i]) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD)
 				BAD_SG_DMA(SCpnt, sgpnt, SCpnt->use_sg, i);
 			any2scsi(cptr[i].datalen, sgpnt[i].length);
 		};
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index b678ced..e61e731 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -136,7 +136,6 @@
 lasi700_driver_callback(struct parisc_device *dev)
 {
 	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
-	int irq = busdevice_alloc_irq(dev);
 	char *driver_name;
 	struct Scsi_Host *host;
 	struct NCR_700_Host_Parameters *hostdata =
@@ -170,14 +169,15 @@
 		hostdata->chip710 = 1;
 		hostdata->dmode_extra = DMODE_FC2;
 	}
+	hostdata->pci_dev = ccio_get_fake(dev);
 	if((host = NCR_700_detect(host_tpnt, hostdata)) == NULL) {
 		kfree(hostdata);
 		release_mem_region(host->base, 64);
 		return 1;
 	}
-	host->irq = irq;
-	if(request_irq(irq, NCR_700_intr, SA_SHIRQ, driver_name, host)) {
-		printk(KERN_ERR "%s: irq problem, detatching\n",
+	host->irq = dev->irq;
+	if(request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, driver_name, host)) {
+		printk(KERN_ERR "%s: irq problem, detaching\n",
 		       driver_name);
 		scsi_unregister(host);
 		NCR_700_release(host);
@@ -197,6 +197,7 @@
 	kfree(hostdata);
 	free_irq(host->irq, host);
 	release_mem_region(host->base, 64);
+	unregister_parisc_driver(&lasi700_driver);
 	return 1;
 }
 
diff --git a/drivers/sound/cs4281/cs4281m.c b/drivers/sound/cs4281/cs4281m.c
index 6854d70..c67291e 100644
--- a/drivers/sound/cs4281/cs4281m.c
+++ b/drivers/sound/cs4281/cs4281m.c
@@ -75,6 +75,7 @@
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
 #include <linux/wrapper.h>
+#include <linux/fs.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
 //#include "cs_dm.h"
diff --git a/drivers/sound/opl3sa2.c b/drivers/sound/opl3sa2.c
index d8b25ed..bd52c74 100644
--- a/drivers/sound/opl3sa2.c
+++ b/drivers/sound/opl3sa2.c
@@ -63,6 +63,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/isapnp.h>
+#include <linux/delay.h>
 #include <linux/pm.h>
 #include "sound_config.h"
 
diff --git a/drivers/sound/ymfpci.c b/drivers/sound/ymfpci.c
index 0b372c8..8614108 100644
--- a/drivers/sound/ymfpci.c
+++ b/drivers/sound/ymfpci.c
@@ -55,6 +55,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
index c8eb8d1..d58a377 100644
--- a/drivers/telephony/phonedev.c
+++ b/drivers/telephony/phonedev.c
@@ -18,7 +18,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/errno.h>
diff --git a/drivers/usb/acm.c b/drivers/usb/acm.c
index 77c42d8..381b4be 100644
--- a/drivers/usb/acm.c
+++ b/drivers/usb/acm.c
@@ -57,6 +57,7 @@
 #include <linux/smp_lock.h>
 #undef DEBUG
 #include <linux/usb.h>
+#include <asm/byteorder.h>
 
 /*
  * Version Information
diff --git a/drivers/usb/auerswald.c b/drivers/usb/auerswald.c
index 4c4ef04..cd1c936 100644
--- a/drivers/usb/auerswald.c
+++ b/drivers/usb/auerswald.c
@@ -25,6 +25,7 @@
 
 /* Standard Linux module include files */
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/usb/devio.c b/drivers/usb/devio.c
index eeb8667..96cbc98 100644
--- a/drivers/usb/devio.c
+++ b/drivers/usb/devio.c
@@ -44,6 +44,7 @@
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
 
 struct async {
diff --git a/drivers/usb/hcd.c b/drivers/usb/hcd.c
index 2f97c96..265143a 100644
--- a/drivers/usb/hcd.c
+++ b/drivers/usb/hcd.c
@@ -50,6 +50,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
+#include <asm/byteorder.h>
 
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/hcd/ehci-hub.c b/drivers/usb/hcd/ehci-hub.c
index 798fd60..4a78956 100644
--- a/drivers/usb/hcd/ehci-hub.c
+++ b/drivers/usb/hcd/ehci-hub.c
@@ -18,6 +18,8 @@
 
 /* this file is part of ehci-hcd.c */
 
+#include <asm/byteorder.h>
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff --git a/drivers/usb/hcd/ehci-mem.c b/drivers/usb/hcd/ehci-mem.c
index b2ee617..94fd675 100644
--- a/drivers/usb/hcd/ehci-mem.c
+++ b/drivers/usb/hcd/ehci-mem.c
@@ -18,6 +18,8 @@
 
 /* this file is part of ehci-hcd.c */
 
+#include <asm/byteorder.h>
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff --git a/drivers/usb/hcd/ehci-q.c b/drivers/usb/hcd/ehci-q.c
index df6c07d..1837e8b 100644
--- a/drivers/usb/hcd/ehci-q.c
+++ b/drivers/usb/hcd/ehci-q.c
@@ -18,6 +18,8 @@
 
 /* this file is part of ehci-hcd.c */
 
+#include <asm/byteorder.h>
+
 /*-------------------------------------------------------------------------*/
 
 /*
diff --git a/drivers/usb/hcd/ehci-sched.c b/drivers/usb/hcd/ehci-sched.c
index 62754b5..5030320 100644
--- a/drivers/usb/hcd/ehci-sched.c
+++ b/drivers/usb/hcd/ehci-sched.c
@@ -20,6 +20,8 @@
 
 /*-------------------------------------------------------------------------*/
 
+#include "ehci.h"
+
 /*
  * EHCI scheduled transaction support:  interrupt, iso, split iso
  * These are called "periodic" transactions in the EHCI spec.
diff --git a/drivers/usb/hcd/ohci-hcd.c b/drivers/usb/hcd/ohci-hcd.c
index 9dbceb3..9a05081 100644
--- a/drivers/usb/hcd/ohci-hcd.c
+++ b/drivers/usb/hcd/ohci-hcd.c
@@ -87,6 +87,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
+#include <asm/byteorder.h>
 
 #ifdef CONFIG_PMAC_PBOOK
 #include <asm/machdep.h>
diff --git a/drivers/usb/hcd/ohci-q.c b/drivers/usb/hcd/ohci-q.c
index 642e84b..ba17a66 100644
--- a/drivers/usb/hcd/ohci-q.c
+++ b/drivers/usb/hcd/ohci-q.c
@@ -7,6 +7,8 @@
  * This file is licenced under the GPL.
  * $Id: ohci-q.c,v 1.6 2002/01/19 00:23:15 dbrownell Exp $
  */
+
+#include <asm/byteorder.h>
  
 static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
 {
diff --git a/drivers/usb/hid-core.c b/drivers/usb/hid-core.c
index f9ebfa1..670bcfc 100644
--- a/drivers/usb/hid-core.c
+++ b/drivers/usb/hid-core.c
@@ -39,6 +39,7 @@
 #include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <asm/unaligned.h>
+#include <asm/byteorder.h>
 #include <linux/input.h>
 
 #undef DEBUG
diff --git a/drivers/usb/inode.c b/drivers/usb/inode.c
index a541dd5..ad11474 100644
--- a/drivers/usb/inode.c
+++ b/drivers/usb/inode.c
@@ -37,6 +37,7 @@
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/smp_lock.h>
+#include <asm/byteorder.h>
 
 static struct super_operations usbfs_ops;
 static struct address_space_operations usbfs_aops;
diff --git a/drivers/usb/kaweth.c b/drivers/usb/kaweth.c
index 65cb2b1..19f04a6 100644
--- a/drivers/usb/kaweth.c
+++ b/drivers/usb/kaweth.c
@@ -55,6 +55,7 @@
 #include <linux/usb.h>
 #include <linux/types.h>
 #include <asm/semaphore.h>
+#include <asm/byteorder.h>
 
 #define DEBUG
 
diff --git a/drivers/usb/mdc800.c b/drivers/usb/mdc800.c
index eb3d1df..542d56c 100644
--- a/drivers/usb/mdc800.c
+++ b/drivers/usb/mdc800.c
@@ -98,6 +98,7 @@
 #include <linux/smp_lock.h>
 
 #include <linux/usb.h>
+#include <linux/fs.h>
 
 /*
  * Version Information
diff --git a/drivers/usb/pegasus.c b/drivers/usb/pegasus.c
index 02e1a8e..7e04aaf 100644
--- a/drivers/usb/pegasus.c
+++ b/drivers/usb/pegasus.c
@@ -48,6 +48,7 @@
 #include <linux/etherdevice.h>
 #include <linux/usb.h>
 #include <linux/module.h>
+#include <asm/byteorder.h>
 #include "pegasus.h"
 
 /*
diff --git a/drivers/usb/scanner.c b/drivers/usb/scanner.c
index 8b262b8..f9ad345 100644
--- a/drivers/usb/scanner.c
+++ b/drivers/usb/scanner.c
@@ -328,6 +328,8 @@
  *      24 Bit Color ~ 70 secs - 3.6 Mbit/sec
  *       8 Bit Gray ~ 17 secs - 4.2 Mbit/sec */
 
+#include <asm/byteorder.h>
+
 /* 
  * Scanner definitions, macros, module info, 
  * debug/ioctl/data_dump enable, and other constants.
diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
index 29384b4..63fb3a7 100644
--- a/drivers/usb/usb-ohci.c
+++ b/drivers/usb/usb-ohci.c
@@ -68,6 +68,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
+#include <asm/byteorder.h>
 
 #define OHCI_USE_NPS		// force NoPowerSwitching mode
 // #define OHCI_VERBOSE_DEBUG	/* not always helpful */
diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
index 6d332d3..2f38a19 100644
--- a/drivers/usb/usb-uhci.c
+++ b/drivers/usb/usb-uhci.c
@@ -40,6 +40,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
+#include <asm/byteorder.h>
 
 /* This enables more detailed sanity checks in submit_iso */
 //#define ISO_SANITY_CHECK
diff --git a/drivers/usb/usb.c b/drivers/usb/usb.c
index be9fa8a..d6d446e 100644
--- a/drivers/usb/usb.c
+++ b/drivers/usb/usb.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/spinlock.h>
+#include <asm/byteorder.h>
 
 #ifdef CONFIG_USB_DEBUG
 	#define DEBUG
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 07a3ae8..2a10b08 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -24,6 +24,7 @@
 {
 	loff_t new = -1;
 
+	lock_kernel();
 	switch (whence) {
 	case 0:
 		new = off;
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index cb6304a..f41160b 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -14,7 +14,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/adfs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/spinlock.h>
 
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
index 66a0c36..7ca21e1 100644
--- a/fs/adfs/dir_f.c
+++ b/fs/adfs/dir_f.c
@@ -13,7 +13,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/adfs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/spinlock.h>
 
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c
index 71064bc..ff90116 100644
--- a/fs/adfs/dir_fplus.c
+++ b/fs/adfs/dir_fplus.c
@@ -11,7 +11,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/adfs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/spinlock.h>
 
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index c00ebea..9ab958b 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -23,7 +23,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/fcntl.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 
 #include "adfs.h"
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index f757844..660dc4b 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -11,7 +11,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/adfs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 8a0ce05..58912a4 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -13,7 +13,7 @@
 #include <linux/fs.h>
 #include <linux/adfs_fs.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index bf53d87..d0532a6 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -10,7 +10,7 @@
 
 #include <stdarg.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/affs_fs.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c
index 919309b..1726db8 100644
--- a/fs/affs/bitmap.c
+++ b/fs/affs/bitmap.c
@@ -7,7 +7,7 @@
  *  block allocation, deallocation, calculation of free space.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/affs_fs.h>
 #include <linux/stat.h>
 #include <linux/kernel.h>
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 510dffa..de3d019 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -15,7 +15,7 @@
 #include <asm/div64.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/affs_fs.h>
 #include <linux/fcntl.h>
 #include <linux/kernel.h>
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index b804256..83e4ce9 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -15,7 +15,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/affs_fs.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index cd32c3b..b5eb611 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -8,7 +8,7 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/affs_fs.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff --git a/fs/affs/super.c b/fs/affs/super.c
index ecf11f3..f526b3f 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -15,7 +15,7 @@
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/affs_fs.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -270,9 +270,8 @@
 	struct buffer_head	*root_bh = NULL;
 	struct buffer_head	*boot_bh;
 	struct inode		*root_inode = NULL;
-	kdev_t			 dev = sb->s_dev;
 	s32			 root_block;
-	int			 blocks, size, blocksize;
+	int			 size, blocksize;
 	u32			 chksum;
 	int			 num_bm;
 	int			 i, j;
@@ -308,12 +307,7 @@
 	 * blocks, we will have to change it.
 	 */
 
-	blocks = blk_size[major(dev)] ? blk_size[major(dev)][minor(dev)] : 0;
-	if (!blocks) {
-		printk(KERN_ERR "AFFS: Could not determine device size\n");
-		goto out_error;
-	}
-	size = (BLOCK_SIZE / 512) * blocks;
+	size = sb->s_bdev->bd_inode->i_size >> 9;
 	pr_debug("AFFS: initial blksize=%d, blocks=%d\n", 512, blocks);
 
 	affs_set_blocksize(sb, PAGE_SIZE);
diff --git a/fs/attr.c b/fs/attr.c
index eccf21e..acd18b0 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -5,7 +5,7 @@
  *  changes by Thomas Schoebel-Theuer
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 354af83..51e754d 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -20,7 +20,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <asm/uaccess.h>
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index fe3db57..66512c8 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -13,7 +13,7 @@
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/param.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/smp_lock.h>
 #include "autofs_i.h"
 
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c
index c7da7f5..b70b72d 100644
--- a/fs/autofs/waitq.c
+++ b/fs/autofs/waitq.c
@@ -11,7 +11,7 @@
  * ------------------------------------------------------------------------- */
 
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/signal.h>
 #include <linux/file.h>
 #include "autofs_i.h"
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 7e43620..e1c4fb9 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -21,7 +21,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/wait.h>
 #include <asm/uaccess.h>
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 2a1a29b..09423a1 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -14,7 +14,7 @@
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/param.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/smp_lock.h>
 #include "autofs_i.h"
 
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 9e5fe90..74c0109 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -11,7 +11,7 @@
  * ------------------------------------------------------------------------- */
 
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/signal.h>
 #include <linux/file.h>
 #include "autofs_i.h"
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index 2ff8ae8..e44c02a 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -8,7 +8,7 @@
 
 #include <linux/fs.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 
 /*
  * The follow_link operation is special: it must behave as a no-op
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c
index cc46c91..6445ca7 100644
--- a/fs/bfs/dir.c
+++ b/fs/bfs/dir.c
@@ -4,7 +4,7 @@
  *	Copyright (C) 1999,2000  Tigran Aivazian <tigran@veritas.com>
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/bfs_fs.h>
 #include <linux/locks.h>
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
index 9f8a585..018cfc1 100644
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -6,7 +6,7 @@
 
 #include <linux/module.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b73559d..0083038 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -13,7 +13,7 @@
 
 #include <linux/fs.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/a.out.h>
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 2348332..5121800 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -13,6 +13,8 @@
 #include <linux/init.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
+#include <linux/err.h>
+#include <linux/fs.h>
 
 static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
diff --git a/fs/buffer.c b/fs/buffer.c
index 866a5a4..0aef10b 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -29,7 +29,7 @@
 /* async buffer flushing, 1999 Andrea Arcangeli <andrea@suse.de> */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/locks.h>
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 03ab04d..2b2d3fb 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -9,7 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c
index 837072a..935fc18 100644
--- a/fs/coda/coda_linux.c
+++ b/fs/coda/coda_linux.c
@@ -10,7 +10,7 @@
 #include <linux/version.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 782f017..bd9acec 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -10,7 +10,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/stat.h>
diff --git a/fs/coda/file.c b/fs/coda/file.c
index d3bc9a2..eeee82f 100644
--- a/fs/coda/file.c
+++ b/fs/coda/file.c
@@ -9,7 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/file.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c
index 861a877..cc29c5e 100644
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -9,7 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index add25fd..0866221 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -21,7 +21,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/lp.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c
index f3318b8..15dc80a 100644
--- a/fs/coda/symlink.c
+++ b/fs/coda/symlink.c
@@ -9,7 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c
index 231b771..9491772 100644
--- a/fs/coda/sysctl.c
+++ b/fs/coda/sysctl.c
@@ -12,7 +12,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
 #include <linux/swapctl.h>
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 9c87ee4..ea22075 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -21,7 +21,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/stat.h>
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 6372557..0d59566 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -615,7 +615,7 @@
 */
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/tty.h>
 #include <linux/timer.h>
 #include <linux/config.h>
diff --git a/fs/devices.c b/fs/devices.c
index e859ba7..0447d80 100644
--- a/fs/devices.c
+++ b/fs/devices.c
@@ -13,7 +13,7 @@
 #include <linux/fs.h>
 #include <linux/major.h>
 #include <linux/string.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <linux/errno.h>
diff --git a/fs/dquot.c b/fs/dquot.c
index a9a697a..ff2326a 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -51,7 +51,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
@@ -289,7 +289,7 @@
 					sizeof(struct dqblk), &offset);
 	if (ret != sizeof(struct dqblk))
 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
-			kdevname(dquot->dq_sb->s_dev));
+			dquot->dq_sb->s_id);
 
 	set_fs(fs);
 	up(sem);
@@ -440,7 +440,7 @@
 	if (!dquot->dq_count) {
 		printk("VFS: dqput: trying to free free dquot\n");
 		printk("VFS: device %s, dquot of %s %d\n",
-			kdevname(dquot->dq_sb->s_dev),
+			dquot->dq_sb->s_id,
 			quotatypes[dquot->dq_type],
 			dquot->dq_id);
 		return;
@@ -715,7 +715,7 @@
 	if (!need_print_warning(dquot, flag))
 		return;
 	dquot->dq_flags |= flag;
-	tty_write_message(current->tty, (char *)bdevname(dquot->dq_sb->s_dev));
+	tty_write_message(current->tty, dquot->dq_sb->s_id);
 	if (warntype == ISOFTWARN || warntype == BSOFTWARN)
 		tty_write_message(current->tty, ": warning, ");
 	else
diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c
index 9502dc7..94d8b0d 100644
--- a/fs/driverfs/inode.c
+++ b/fs/driverfs/inode.c
@@ -701,7 +701,8 @@
 
 	vfs_unlink(dentry->d_parent->d_inode,dentry);
 
-	unlock_dir(dentry);
+	up(&dentry->d_inode->i_sem);
+	dput(dentry);
 
 	/* remove reference count from when file was created */
 	dput(dentry);
@@ -741,7 +742,8 @@
 		}
 		node = node->next;
 	}
-	unlock_dir(dentry);
+	up(&dentry->d_inode->i_sem);
+	dput(dentry);
 }
 
 /**
@@ -760,8 +762,9 @@
 	if (!dir->dentry)
 		goto done;
 
-	/* lock the directory while we remove the files */
 	dentry = dget(dir->dentry);
+	dget(dentry->d_parent);
+	down(&dentry->d_parent->d_inode->i_sem);
 	down(&dentry->d_inode->i_sem);
 
 	node = dir->files.next;
@@ -776,11 +779,9 @@
 		node = dir->files.next;
 	}
 
-	/* now lock the parent, so we can remove this directory */
-	lock_parent(dentry);
-
 	vfs_rmdir(dentry->d_parent->d_inode,dentry);
-	double_unlock(dentry,dentry->d_parent);
+	up(&dentry->d_parent->d_inode->i_sem);
+	up(&dentry->d_inode->i_sem);
 
 	/* remove reference count from when directory was created */
 	dput(dentry);
diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index 67d050f..4af8ea9 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -10,6 +10,7 @@
 #include <linux/efs_fs.h>
 #include <linux/efs_fs_sb.h>
 #include <linux/module.h>
+#include <linux/fs.h>
 
 
 extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff --git a/fs/exec.c b/fs/exec.c
index 3e34704..26f9df8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -35,6 +35,7 @@
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/personality.h>
+#include <linux/binfmts.h>
 #define __NO_VERSION__
 #include <linux/module.h>
 
@@ -420,8 +421,8 @@
 		active_mm = current->active_mm;
 		current->mm = mm;
 		current->active_mm = mm;
-		task_unlock(current);
 		activate_mm(active_mm, mm);
+		task_unlock(current);
 		mm_release();
 		if (old_mm) {
 			if (active_mm != old_mm) BUG();
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 5d3f148..cc6c621 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -32,15 +32,15 @@
  */
 
 
-#define in_range(b, first, len)		((b) >= (first) && (b) <= (first) + (len) - 1)
+#define in_range(b, first, len)	((b) >= (first) && (b) <= (first) + (len) - 1)
 
 struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
 					     unsigned int block_group,
 					     struct buffer_head ** bh)
 {
 	unsigned long group_desc;
-	unsigned long desc;
-	struct ext2_group_desc * gdp;
+	unsigned long offset;
+	struct ext2_group_desc * desc;
 	struct ext2_sb_info *sbi = &sb->u.ext2_sb;
 
 	if (block_group >= sbi->s_groups_count) {
@@ -53,19 +53,19 @@
 	}
 	
 	group_desc = block_group / EXT2_DESC_PER_BLOCK(sb);
-	desc = block_group % EXT2_DESC_PER_BLOCK(sb);
+	offset = block_group % EXT2_DESC_PER_BLOCK(sb);
 	if (!sbi->s_group_desc[group_desc]) {
 		ext2_error (sb, "ext2_get_group_desc",
 			    "Group descriptor not loaded - "
 			    "block_group = %d, group_desc = %lu, desc = %lu",
-			     block_group, group_desc, desc);
+			     block_group, group_desc, offset);
 		return NULL;
 	}
 	
-	gdp = (struct ext2_group_desc *) sbi->s_group_desc[group_desc]->b_data;
+	desc = (struct ext2_group_desc *) sbi->s_group_desc[group_desc]->b_data;
 	if (bh)
 		*bh = sbi->s_group_desc[group_desc];
-	return gdp + desc;
+	return desc + offset;
 }
 
 /*
@@ -78,18 +78,18 @@
 static struct buffer_head *read_block_bitmap(struct super_block *sb,
 						unsigned int block_group)
 {
-	struct ext2_group_desc * gdp;
+	struct ext2_group_desc * desc;
 	struct buffer_head * bh = NULL;
 	
-	gdp = ext2_get_group_desc (sb, block_group, NULL);
-	if (!gdp)
+	desc = ext2_get_group_desc (sb, block_group, NULL);
+	if (!desc)
 		goto error_out;
-	bh = sb_bread(sb, le32_to_cpu(gdp->bg_block_bitmap));
+	bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
 	if (!bh)
 		ext2_error (sb, "read_block_bitmap",
 			    "Cannot read block bitmap - "
 			    "block_group = %d, block_bitmap = %lu",
-			    block_group, (unsigned long) gdp->bg_block_bitmap);
+			    block_group, (unsigned long) desc->bg_block_bitmap);
 error_out:
 	return bh;
 }
@@ -135,7 +135,7 @@
 			goto read_it;
 		if (sbi->s_block_bitmap_number[slot] == slot)
 			goto found;
-		ext2_panic (sb, "__load_block_bitmap",
+		ext2_panic (sb, "load_block_bitmap",
 			    "block_group != block_bitmap_number");
 	}
 
@@ -166,6 +166,73 @@
 	return bh;
 }
 
+static inline int reserve_blocks(struct super_block *sb, int count)
+{
+	struct ext2_sb_info * sbi = EXT2_SB(sb);
+	struct ext2_super_block * es = sbi->s_es;
+	unsigned free_blocks = le32_to_cpu(es->s_free_blocks_count);
+	unsigned root_blocks = le32_to_cpu(es->s_r_blocks_count);
+
+	if (free_blocks < count)
+		count = free_blocks;
+
+	if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
+	    sbi->s_resuid != current->fsuid &&
+	    (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
+		/*
+		 * We are too close to reserve and we are not privileged.
+		 * Can we allocate anything at all?
+		 */
+		if (free_blocks > root_blocks)
+			count = free_blocks - root_blocks;
+		else
+			return 0;
+	}
+
+	es->s_free_blocks_count = cpu_to_le32(free_blocks - count);
+	mark_buffer_dirty(sbi->s_sbh);
+	sb->s_dirt = 1;
+	return count;
+}
+
+static inline void release_blocks(struct super_block *sb, int count)
+{
+	if (count) {
+		struct ext2_sb_info * sbi = EXT2_SB(sb);
+		struct ext2_super_block * es = sbi->s_es;
+		unsigned free_blocks = le32_to_cpu(es->s_free_blocks_count);
+		es->s_free_blocks_count = cpu_to_le32(free_blocks + count);
+		mark_buffer_dirty(sbi->s_sbh);
+		sb->s_dirt = 1;
+	}
+}
+
+static inline int group_reserve_blocks(struct ext2_group_desc *desc,
+				    struct buffer_head *bh, int count)
+{
+	unsigned free_blocks;
+
+	if (!desc->bg_free_blocks_count)
+		return 0;
+
+	free_blocks = le16_to_cpu(desc->bg_free_blocks_count);
+	if (free_blocks < count)
+		count = free_blocks;
+	desc->bg_free_blocks_count = cpu_to_le16(free_blocks - count);
+	mark_buffer_dirty(bh);
+	return count;
+}
+
+static inline void group_release_blocks(struct ext2_group_desc *desc,
+				    struct buffer_head *bh, int count)
+{
+	if (count) {
+		unsigned free_blocks = le16_to_cpu(desc->bg_free_blocks_count);
+		desc->bg_free_blocks_count = cpu_to_le16(free_blocks + count);
+		mark_buffer_dirty(bh);
+	}
+}
+
 /* Free given blocks, update quota and i_blocks field */
 void ext2_free_blocks (struct inode * inode, unsigned long block,
 		       unsigned long count)
@@ -176,15 +243,11 @@
 	unsigned long bit;
 	unsigned long i;
 	unsigned long overflow;
-	struct super_block * sb;
-	struct ext2_group_desc * gdp;
+	struct super_block * sb = inode->i_sb;
+	struct ext2_group_desc * desc;
 	struct ext2_super_block * es;
+	unsigned freed = 0, group_freed;
 
-	sb = inode->i_sb;
-	if (!sb) {
-		printk ("ext2_free_blocks: nonexistent device");
-		return;
-	}
 	lock_super (sb);
 	es = sb->u.ext2_sb.s_es;
 	if (block < le32_to_cpu(es->s_first_data_block) || 
@@ -214,53 +277,99 @@
 	bh = load_block_bitmap (sb, block_group);
 	if (IS_ERR(bh))
 		goto error_return;
-	
-	gdp = ext2_get_group_desc (sb, block_group, &bh2);
-	if (!gdp)
+
+	desc = ext2_get_group_desc (sb, block_group, &bh2);
+	if (!desc)
 		goto error_return;
 
-	if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) ||
-	    in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) ||
-	    in_range (block, le32_to_cpu(gdp->bg_inode_table),
+	if (in_range (le32_to_cpu(desc->bg_block_bitmap), block, count) ||
+	    in_range (le32_to_cpu(desc->bg_inode_bitmap), block, count) ||
+	    in_range (block, le32_to_cpu(desc->bg_inode_table),
 		      sb->u.ext2_sb.s_itb_per_group) ||
-	    in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
+	    in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table),
 		      sb->u.ext2_sb.s_itb_per_group))
 		ext2_error (sb, "ext2_free_blocks",
 			    "Freeing blocks in system zones - "
 			    "Block = %lu, count = %lu",
 			    block, count);
 
-	for (i = 0; i < count; i++) {
+	for (i = 0, group_freed = 0; i < count; i++) {
 		if (!ext2_clear_bit (bit + i, bh->b_data))
 			ext2_error (sb, "ext2_free_blocks",
 				      "bit already cleared for block %lu",
 				      block + i);
-		else {
-			DQUOT_FREE_BLOCK(inode, 1);
-			gdp->bg_free_blocks_count =
-				cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)+1);
-			es->s_free_blocks_count =
-				cpu_to_le32(le32_to_cpu(es->s_free_blocks_count)+1);
-		}
+		else
+			group_freed++;
 	}
-	
-	mark_buffer_dirty(bh2);
-	mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
 
 	mark_buffer_dirty(bh);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
 		ll_rw_block (WRITE, 1, &bh);
 		wait_on_buffer (bh);
 	}
+
+	group_release_blocks(desc, bh2, group_freed);
+	freed += group_freed;
+
 	if (overflow) {
 		block += count;
 		count = overflow;
 		goto do_more;
 	}
-	sb->s_dirt = 1;
 error_return:
+	release_blocks(sb, freed);
 	unlock_super (sb);
-	return;
+	DQUOT_FREE_BLOCK(inode, freed);
+}
+
+static int grab_block(char *map, unsigned size, int goal)
+{
+	int k;
+	char *p, *r;
+
+	if (!ext2_test_bit(goal, map))
+		goto got_it;
+	if (goal) {
+		/*
+		 * The goal was occupied; search forward for a free 
+		 * block within the next XX blocks.
+		 *
+		 * end_goal is more or less random, but it has to be
+		 * less than EXT2_BLOCKS_PER_GROUP. Aligning up to the
+		 * next 64-bit boundary is simple..
+		 */
+		k = (goal + 63) & ~63;
+		goal = ext2_find_next_zero_bit(map, k, goal);
+		if (goal < k)
+			goto got_it;
+		/*
+		 * Search in the remainder of the current group.
+		 */
+	}
+
+	p = map + (goal >> 3);
+	r = memscan(p, 0, (size - goal + 7) >> 3);
+	k = (r - map) << 3;
+	if (k < size) {
+		/* 
+		 * We have succeeded in finding a free byte in the block
+		 * bitmap.  Now search backwards to find the start of this
+		 * group of free blocks - won't take more than 7 iterations.
+		 */
+		for (goal = k; goal && !ext2_test_bit (goal - 1, map); goal--)
+			;
+		goto got_it;
+	}
+
+	k = ext2_find_next_zero_bit ((u32 *)map, size, goal);
+	if (k < size) {
+		goal = k;
+		goto got_it;
+	}
+	return -1;
+got_it:
+	ext2_set_bit(goal, map);
+	return goal;
 }
 
 /*
@@ -274,224 +383,148 @@
 int ext2_new_block (struct inode * inode, unsigned long goal,
     u32 * prealloc_count, u32 * prealloc_block, int * err)
 {
-	struct buffer_head * bh;
-	struct buffer_head * bh2;
-	char * p, * r;
+	struct buffer_head *bh;
+	struct buffer_head *bh2;
+	struct ext2_group_desc *desc;
 	int i, j, k, tmp;
-	struct super_block * sb;
-	struct ext2_group_desc * gdp;
-	struct ext2_super_block * es;
-#ifdef EXT2FS_DEBUG
-	static int goal_hits = 0, goal_attempts = 0;
-#endif
+	int block = 0;
+	struct super_block *sb = inode->i_sb;
+	struct ext2_sb_info *sbi = EXT2_SB(sb);
+	struct ext2_super_block *es = sbi->s_es;
+	unsigned group_size = EXT2_BLOCKS_PER_GROUP(sb);
+	unsigned prealloc_goal = es->s_prealloc_blocks;
+	unsigned group_alloc = 0, es_alloc, dq_alloc;
+
+	if (!prealloc_goal--)
+		prealloc_goal = EXT2_DEFAULT_PREALLOC_BLOCKS - 1;
+	if (!prealloc_count || *prealloc_count)
+		prealloc_goal = 0;
+
+	*err = -EDQUOT;
+	if (DQUOT_ALLOC_BLOCK(inode, 1))
+		goto out;
+
+	while (prealloc_goal && DQUOT_PREALLOC_BLOCK(inode, prealloc_goal))
+		prealloc_goal--;
+
+	dq_alloc = prealloc_goal + 1;
+
 	*err = -ENOSPC;
-	sb = inode->i_sb;
-	if (!sb) {
-		printk ("ext2_new_block: nonexistent device");
-		return 0;
-	}
 
 	lock_super (sb);
-	es = sb->u.ext2_sb.s_es;
-	if (le32_to_cpu(es->s_free_blocks_count) <= le32_to_cpu(es->s_r_blocks_count) &&
-	    ((sb->u.ext2_sb.s_resuid != current->fsuid) &&
-	     (sb->u.ext2_sb.s_resgid == 0 ||
-	      !in_group_p (sb->u.ext2_sb.s_resgid)) && 
-	     !capable(CAP_SYS_RESOURCE)))
-		goto out;
+
+	es_alloc = reserve_blocks(sb, dq_alloc);
+	if (!es_alloc)
+		goto out_unlock;
 
 	ext2_debug ("goal=%lu.\n", goal);
 
-repeat:
-	/*
-	 * First, test whether the goal block is free.
-	 */
 	if (goal < le32_to_cpu(es->s_first_data_block) ||
 	    goal >= le32_to_cpu(es->s_blocks_count))
 		goal = le32_to_cpu(es->s_first_data_block);
-	i = (goal - le32_to_cpu(es->s_first_data_block)) / EXT2_BLOCKS_PER_GROUP(sb);
-	gdp = ext2_get_group_desc (sb, i, &bh2);
-	if (!gdp)
+	i = (goal - le32_to_cpu(es->s_first_data_block)) / group_size;
+	desc = ext2_get_group_desc (sb, i, &bh2);
+	if (!desc)
 		goto io_error;
 
-	if (le16_to_cpu(gdp->bg_free_blocks_count) > 0) {
-		j = ((goal - le32_to_cpu(es->s_first_data_block)) % EXT2_BLOCKS_PER_GROUP(sb));
-#ifdef EXT2FS_DEBUG
-		if (j)
-			goal_attempts++;
-#endif
+	group_alloc = group_reserve_blocks(desc, bh2, es_alloc);
+	if (group_alloc) {
+		j = ((goal - le32_to_cpu(es->s_first_data_block)) % group_size);
 		bh = load_block_bitmap (sb, i);
 		if (IS_ERR(bh))
 			goto io_error;
 		
 		ext2_debug ("goal is at %d:%d.\n", i, j);
 
-		if (!ext2_test_bit(j, bh->b_data)) {
-			ext2_debug("goal bit allocated, %d hits\n",++goal_hits);
+		j = grab_block(bh->b_data, group_size, j);
+		if (j >= 0)
 			goto got_block;
-		}
-		if (j) {
-			/*
-			 * The goal was occupied; search forward for a free 
-			 * block within the next XX blocks.
-			 *
-			 * end_goal is more or less random, but it has to be
-			 * less than EXT2_BLOCKS_PER_GROUP. Aligning up to the
-			 * next 64-bit boundary is simple..
-			 */
-			int end_goal = (j + 63) & ~63;
-			j = ext2_find_next_zero_bit(bh->b_data, end_goal, j);
-			if (j < end_goal)
-				goto got_block;
-		}
-	
-		ext2_debug ("Bit not found near goal\n");
-
-		/*
-		 * There has been no free block found in the near vicinity
-		 * of the goal: do a search forward through the block groups,
-		 * searching in each group first for an entire free byte in
-		 * the bitmap and then for any free bit.
-		 * 
-		 * Search first in the remainder of the current group; then,
-		 * cyclicly search through the rest of the groups.
-		 */
-		p = ((char *) bh->b_data) + (j >> 3);
-		r = memscan(p, 0, (EXT2_BLOCKS_PER_GROUP(sb) - j + 7) >> 3);
-		k = (r - ((char *) bh->b_data)) << 3;
-		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
-			j = k;
-			goto search_back;
-		}
-
-		k = ext2_find_next_zero_bit ((unsigned long *) bh->b_data, 
-					EXT2_BLOCKS_PER_GROUP(sb),
-					j);
-		if (k < EXT2_BLOCKS_PER_GROUP(sb)) {
-			j = k;
-			goto got_block;
-		}
+		group_release_blocks(desc, bh2, group_alloc);
+		group_alloc = 0;
 	}
 
 	ext2_debug ("Bit not found in block group %d.\n", i);
 
 	/*
 	 * Now search the rest of the groups.  We assume that 
-	 * i and gdp correctly point to the last group visited.
+	 * i and desc correctly point to the last group visited.
 	 */
-	for (k = 0; k < sb->u.ext2_sb.s_groups_count; k++) {
+	for (k = 0; !group_alloc && k < sbi->s_groups_count; k++) {
 		i++;
-		if (i >= sb->u.ext2_sb.s_groups_count)
+		if (i >= sbi->s_groups_count)
 			i = 0;
-		gdp = ext2_get_group_desc (sb, i, &bh2);
-		if (!gdp)
+		desc = ext2_get_group_desc (sb, i, &bh2);
+		if (!desc)
 			goto io_error;
-		if (le16_to_cpu(gdp->bg_free_blocks_count) > 0)
-			break;
+		group_alloc = group_reserve_blocks(desc, bh2, es_alloc);
 	}
-	if (k >= sb->u.ext2_sb.s_groups_count)
-		goto out;
+	if (k >= sbi->s_groups_count)
+		goto out_release;
 	bh = load_block_bitmap (sb, i);
 	if (IS_ERR(bh))
 		goto io_error;
 	
-	r = memscan(bh->b_data, 0, EXT2_BLOCKS_PER_GROUP(sb) >> 3);
-	j = (r - bh->b_data) << 3;
-	if (j < EXT2_BLOCKS_PER_GROUP(sb))
-		goto search_back;
-	else
-		j = ext2_find_first_zero_bit ((unsigned long *) bh->b_data,
-					 EXT2_BLOCKS_PER_GROUP(sb));
-	if (j >= EXT2_BLOCKS_PER_GROUP(sb)) {
+	j = grab_block(bh->b_data, group_size, 0);
+	if (j < 0) {
 		ext2_error (sb, "ext2_new_block",
 			    "Free blocks count corrupted for block group %d", i);
-		goto out;
+		group_alloc = 0;
+		goto out_release;
 	}
 
-search_back:
-	/* 
-	 * We have succeeded in finding a free byte in the block
-	 * bitmap.  Now search backwards up to 7 bits to find the
-	 * start of this group of free blocks.
-	 */
-	for (k = 0; k < 7 && j > 0 && !ext2_test_bit (j - 1, bh->b_data); k++, j--);
-	
 got_block:
+	ext2_debug("using block group %d(%d)\n", i, desc->bg_free_blocks_count);
 
-	ext2_debug ("using block group %d(%d)\n", i, gdp->bg_free_blocks_count);
+	tmp = j + i * group_size + le32_to_cpu(es->s_first_data_block);
 
-	/*
-	 * Check quota for allocation of this block.
-	 */
-	if(DQUOT_ALLOC_BLOCK(inode, 1)) {
-		*err = -EDQUOT;
-		goto out;
-	}
-
-	tmp = j + i * EXT2_BLOCKS_PER_GROUP(sb) + le32_to_cpu(es->s_first_data_block);
-
-	if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||
-	    tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||
-	    in_range (tmp, le32_to_cpu(gdp->bg_inode_table),
-		      sb->u.ext2_sb.s_itb_per_group))
+	if (tmp == le32_to_cpu(desc->bg_block_bitmap) ||
+	    tmp == le32_to_cpu(desc->bg_inode_bitmap) ||
+	    in_range (tmp, le32_to_cpu(desc->bg_inode_table),
+		      sbi->s_itb_per_group))
 		ext2_error (sb, "ext2_new_block",
 			    "Allocating block in system zone - "
 			    "block = %u", tmp);
 
-	if (ext2_set_bit (j, bh->b_data)) {
-		ext2_warning (sb, "ext2_new_block",
-			      "bit already set for block %d", j);
-		DQUOT_FREE_BLOCK(inode, 1);
-		goto repeat;
+	if (tmp >= le32_to_cpu(es->s_blocks_count)) {
+		ext2_error (sb, "ext2_new_block",
+			    "block(%d) >= blocks count(%d) - "
+			    "block_group = %d, es == %p ",j,
+			le32_to_cpu(es->s_blocks_count), i, es);
+		goto out_release;
 	}
+	block = tmp;
 
+	/* OK, we _had_ allocated something */
 	ext2_debug ("found bit %d\n", j);
 
+	dq_alloc--;
+	es_alloc--;
+	group_alloc--;
+
 	/*
 	 * Do block preallocation now if required.
 	 */
-#ifdef EXT2_PREALLOCATE
 	/* Writer: ->i_prealloc* */
-	if (prealloc_count && !*prealloc_count) {
-		int	prealloc_goal;
-		unsigned long next_block = tmp + 1;
-
-		prealloc_goal = es->s_prealloc_blocks ?
-			es->s_prealloc_blocks : EXT2_DEFAULT_PREALLOC_BLOCKS;
+	if (group_alloc && !*prealloc_count) {
+		unsigned long next_block = block + 1;
 
 		*prealloc_block = next_block;
 		/* Writer: end */
-		for (k = 1;
-		     k < prealloc_goal && (j + k) < EXT2_BLOCKS_PER_GROUP(sb);
-		     k++, next_block++) {
-			if (DQUOT_PREALLOC_BLOCK(inode, 1))
-				break;
+		while (group_alloc && ++j < group_size) {
 			/* Writer: ->i_prealloc* */
 			if (*prealloc_block + *prealloc_count != next_block ||
-			    ext2_set_bit (j + k, bh->b_data)) {
+			    ext2_set_bit (j, bh->b_data)) {
 				/* Writer: end */
-				DQUOT_FREE_BLOCK(inode, 1);
  				break;
 			}
 			(*prealloc_count)++;
 			/* Writer: end */
+			next_block++;
+			es_alloc--;
+			dq_alloc--;
+			group_alloc--;
 		}	
-		/*
-		 * As soon as we go for per-group spinlocks we'll need these
-		 * done inside the loop above.
-		 */
-		gdp->bg_free_blocks_count =
-			cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) -
-			       (k - 1));
-		es->s_free_blocks_count =
-			cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) -
-			       (k - 1));
-		ext2_debug ("Preallocated a further %lu bits.\n",
-			       (k - 1));
 	}
-#endif
-
-	j = tmp;
 
 	mark_buffer_dirty(bh);
 	if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -499,32 +532,21 @@
 		wait_on_buffer (bh);
 	}
 
-	if (j >= le32_to_cpu(es->s_blocks_count)) {
-		ext2_error (sb, "ext2_new_block",
-			    "block(%d) >= blocks count(%d) - "
-			    "block_group = %d, es == %p ",j,
-			le32_to_cpu(es->s_blocks_count), i, es);
-		goto out;
-	}
+	ext2_debug ("allocating block %d. ", block);
 
-	ext2_debug ("allocating block %d. "
-		    "Goal hits %d of %d.\n", j, goal_hits, goal_attempts);
-
-	gdp->bg_free_blocks_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - 1);
-	mark_buffer_dirty(bh2);
-	es->s_free_blocks_count = cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) - 1);
-	mark_buffer_dirty(sb->u.ext2_sb.s_sbh);
-	sb->s_dirt = 1;
-	unlock_super (sb);
+out_release:
+	group_release_blocks(desc, bh2, group_alloc);
+	release_blocks(sb, es_alloc);
 	*err = 0;
-	return j;
-	
+out_unlock:
+	unlock_super (sb);
+	DQUOT_FREE_BLOCK(inode, dq_alloc);
+out:
+	return block;
+
 io_error:
 	*err = -EIO;
-out:
-	unlock_super (sb);
-	return 0;
-	
+	goto out_release;
 }
 
 unsigned long ext2_count_free_blocks (struct super_block * sb)
@@ -532,27 +554,27 @@
 #ifdef EXT2FS_DEBUG
 	struct ext2_super_block * es;
 	unsigned long desc_count, bitmap_count, x;
-	struct ext2_group_desc * gdp;
+	struct ext2_group_desc * desc;
 	int i;
 	
 	lock_super (sb);
 	es = sb->u.ext2_sb.s_es;
 	desc_count = 0;
 	bitmap_count = 0;
-	gdp = NULL;
+	desc = NULL;
 	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
 		struct buffer_head *bh;
-		gdp = ext2_get_group_desc (sb, i, NULL);
-		if (!gdp)
+		desc = ext2_get_group_desc (sb, i, NULL);
+		if (!desc)
 			continue;
-		desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
+		desc_count += le16_to_cpu(desc->bg_free_blocks_count);
 		bh = load_block_bitmap (sb, i);
 		if (IS_ERR(bh))
 			continue;
 		
 		x = ext2_count_free (bh, sb->s_blocksize);
 		printk ("group %d: stored = %d, counted = %lu\n",
-			i, le16_to_cpu(gdp->bg_free_blocks_count), x);
+			i, le16_to_cpu(desc->bg_free_blocks_count), x);
 		bitmap_count += x;
 	}
 	printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n",
@@ -632,18 +654,18 @@
 	struct ext2_super_block * es;
 	unsigned long desc_count, bitmap_count, x, j;
 	unsigned long desc_blocks;
-	struct ext2_group_desc * gdp;
+	struct ext2_group_desc * desc;
 	int i;
 
 	es = sb->u.ext2_sb.s_es;
 	desc_count = 0;
 	bitmap_count = 0;
-	gdp = NULL;
+	desc = NULL;
 	for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) {
-		gdp = ext2_get_group_desc (sb, i, NULL);
-		if (!gdp)
+		desc = ext2_get_group_desc (sb, i, NULL);
+		if (!desc)
 			continue;
-		desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
+		desc_count += le16_to_cpu(desc->bg_free_blocks_count);
 		bh = load_block_bitmap (sb, i);
 		if (IS_ERR(bh))
 			continue;
@@ -659,28 +681,28 @@
 					   "Descriptor block #%ld in group "
 					   "%d is marked free", j, i);
 
-		if (!block_in_use (le32_to_cpu(gdp->bg_block_bitmap), sb, bh->b_data))
+		if (!block_in_use (le32_to_cpu(desc->bg_block_bitmap), sb, bh->b_data))
 			ext2_error (sb, "ext2_check_blocks_bitmap",
 				    "Block bitmap for group %d is marked free",
 				    i);
 
-		if (!block_in_use (le32_to_cpu(gdp->bg_inode_bitmap), sb, bh->b_data))
+		if (!block_in_use (le32_to_cpu(desc->bg_inode_bitmap), sb, bh->b_data))
 			ext2_error (sb, "ext2_check_blocks_bitmap",
 				    "Inode bitmap for group %d is marked free",
 				    i);
 
 		for (j = 0; j < sb->u.ext2_sb.s_itb_per_group; j++)
-			if (!block_in_use (le32_to_cpu(gdp->bg_inode_table) + j, sb, bh->b_data))
+			if (!block_in_use (le32_to_cpu(desc->bg_inode_table) + j, sb, bh->b_data))
 				ext2_error (sb, "ext2_check_blocks_bitmap",
 					    "Block #%ld of the inode table in "
 					    "group %d is marked free", j, i);
 
 		x = ext2_count_free (bh, sb->s_blocksize);
-		if (le16_to_cpu(gdp->bg_free_blocks_count) != x)
+		if (le16_to_cpu(desc->bg_free_blocks_count) != x)
 			ext2_error (sb, "ext2_check_blocks_bitmap",
 				    "Wrong free blocks count for group %d, "
 				    "stored = %d, counted = %lu", i,
-				    le16_to_cpu(gdp->bg_free_blocks_count), x);
+				    le16_to_cpu(desc->bg_free_blocks_count), x);
 		bitmap_count += x;
 	}
 	if (le32_to_cpu(es->s_free_blocks_count) != bitmap_count)
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 9843deb..e005965 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -19,7 +19,7 @@
  */
 
 #include "ext2.h"
-#include <linux/sched.h>
+#include <linux/time.h>
 
 /*
  * Called when an inode is released. Note that this is different
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index c355f6c..76074e9 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -25,7 +25,7 @@
 #include "ext2.h"
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/highuid.h>
 #include <linux/quotaops.h>
 #include <linux/module.h>
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c
index 07e9aaf..680eb33 100644
--- a/fs/ext2/ioctl.c
+++ b/fs/ext2/ioctl.c
@@ -8,7 +8,7 @@
  */
 
 #include "ext2.h"
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <asm/uaccess.h>
 
 
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index f4f87da..24336e4 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -12,7 +12,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 65ee4b2..3ed85a1 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -18,7 +18,7 @@
  *	(jj@sunsite.ms.mff.cuni.cz)
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/jbd.h>
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index 79f4f83..e474547 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -22,7 +22,7 @@
  * we can depend on generic_block_fdatasync() to sync the data blocks.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 20e8aea..2febb54 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -12,7 +12,7 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 4398759..83cc128 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -23,7 +23,7 @@
  */
 
 #include <linux/fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/ext3_jbd.h>
 #include <linux/jbd.h>
 #include <linux/locks.h>
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 07f7fdd..beca674 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -11,7 +11,7 @@
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <asm/uaccess.h>
 
 
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index ca49f46..7b9e7c9 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -20,7 +20,7 @@
 
 #include <linux/fs.h>
 #include <linux/jbd.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
 #include <linux/fcntl.h>
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 24ddd1d..009ee46 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -20,7 +20,7 @@
 #include <linux/module.h>
 #include <linux/string.h>
 #include <linux/fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/jbd.h>
 #include <linux/ext3_fs.h>
 #include <linux/ext3_jbd.h>
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index a1ee11a..6a81b82 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -14,7 +14,7 @@
  */
 
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/msdos_fs.h>
 #include <linux/dirent.h>
 
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 27911fb..942fdeb 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -6,7 +6,7 @@
  *  regular file handling primitives for fat-based filesystems
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/locks.h>
 #include <linux/msdos_fs.h>
 #include <linux/fat_cvf.h>
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 8755a71..9e3b7ec 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -11,7 +11,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/locks.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
diff --git a/fs/fifo.c b/fs/fifo.c
index f5738c1..46eb3ca 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
+#include <linux/fs.h>
 
 static void wait_for_partner(struct inode* inode, unsigned int* cnt)
 {
diff --git a/fs/file.c b/fs/file.c
index 200d7b1..d89c8a6 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -8,7 +8,7 @@
 
 #include <linux/fs.h>
 #include <linux/mm.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/file.h>
diff --git a/fs/file_table.c b/fs/file_table.c
index e724873..d9e8a5b 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/iobuf.h>
+#include <linux/fs.h>
 
 /* sysctl tunables... */
 struct files_stat_struct files_stat = {0, 0, NR_FILE};
diff --git a/fs/filesystems.c b/fs/filesystems.c
index 98be56d..beb785f 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -8,10 +8,11 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/smp_lock.h>
 #include <linux/kmod.h>
 #include <linux/nfsd/interface.h>
+#include <linux/linkage.h>
 
 #if defined(CONFIG_NFSD_MODULE)
 struct nfsd_linkage *nfsd_linkage = NULL;
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 2942766..9d52234 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -33,7 +33,7 @@
  * Veritas filesystem driver - lookup and other directory related code.
  */
 #include <linux/fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
 #include <linux/kernel.h>
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c
index 8943d6d..513f2bd 100644
--- a/fs/hpfs/dir.c
+++ b/fs/hpfs/dir.c
@@ -7,7 +7,7 @@
  */
 
 #include "hpfs_fn.h"
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/smp_lock.h>
 
 int hpfs_dir_release(struct inode *inode, struct file *filp)
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index d841654..10bc9d8 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/string.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index ce0c2b0..a6cb5a5 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -15,7 +15,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/locks.h>
 #include <linux/stat.h>
 #include <linux/string.h>
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index a45a330..c141192 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -6,7 +6,7 @@
  *  inode VFS functions
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
diff --git a/fs/intermezzo/cache.c b/fs/intermezzo/cache.c
index b7ef2eb..0526fd3 100644
--- a/fs/intermezzo/cache.c
+++ b/fs/intermezzo/cache.c
@@ -19,7 +19,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/intermezzo/dcache.c b/fs/intermezzo/dcache.c
index 4b94a8e..eca114a 100644
--- a/fs/intermezzo/dcache.c
+++ b/fs/intermezzo/dcache.c
@@ -10,7 +10,7 @@
 #define __NO_VERSION__
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/intermezzo/dir.c b/fs/intermezzo/dir.c
index 25f7f18..de2d4af 100644
--- a/fs/intermezzo/dir.c
+++ b/fs/intermezzo/dir.c
@@ -21,7 +21,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/intermezzo/file.c b/fs/intermezzo/file.c
index 8464b26..68084e5 100644
--- a/fs/intermezzo/file.c
+++ b/fs/intermezzo/file.c
@@ -28,7 +28,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/intermezzo/journal_ext2.c b/fs/intermezzo/journal_ext2.c
index ceeb9f9..dfe97bb 100644
--- a/fs/intermezzo/journal_ext2.c
+++ b/fs/intermezzo/journal_ext2.c
@@ -5,7 +5,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/fs/intermezzo/journal_ext3.c b/fs/intermezzo/journal_ext3.c
index eadd1d8..58ab5f5 100644
--- a/fs/intermezzo/journal_ext3.c
+++ b/fs/intermezzo/journal_ext3.c
@@ -10,7 +10,7 @@
 #include <linux/types.h>
 #include <linux/param.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/fs/intermezzo/journal_obdfs.c b/fs/intermezzo/journal_obdfs.c
index bda86f3..c6d239b 100644
--- a/fs/intermezzo/journal_obdfs.c
+++ b/fs/intermezzo/journal_obdfs.c
@@ -10,7 +10,7 @@
 #include <linux/types.h>
 #include <linux/param.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/fs/intermezzo/journal_reiserfs.c b/fs/intermezzo/journal_reiserfs.c
index 780d9da..6531887 100644
--- a/fs/intermezzo/journal_reiserfs.c
+++ b/fs/intermezzo/journal_reiserfs.c
@@ -9,7 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/param.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/fs/intermezzo/journal_xfs.c b/fs/intermezzo/journal_xfs.c
index fed141f..0ec4372 100644
--- a/fs/intermezzo/journal_xfs.c
+++ b/fs/intermezzo/journal_xfs.c
@@ -5,7 +5,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
diff --git a/fs/intermezzo/methods.c b/fs/intermezzo/methods.c
index 09496b3..05af7f2 100644
--- a/fs/intermezzo/methods.c
+++ b/fs/intermezzo/methods.c
@@ -20,7 +20,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/intermezzo/presto.c b/fs/intermezzo/presto.c
index 1eba374..ad89030 100644
--- a/fs/intermezzo/presto.c
+++ b/fs/intermezzo/presto.c
@@ -10,7 +10,7 @@
  */
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/intermezzo/psdev.c b/fs/intermezzo/psdev.c
index 0384ab5..b7501c1 100644
--- a/fs/intermezzo/psdev.c
+++ b/fs/intermezzo/psdev.c
@@ -32,7 +32,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/lp.h>
 #include <linux/slab.h>
 #include <asm/ioctls.h>
diff --git a/fs/intermezzo/super.c b/fs/intermezzo/super.c
index 2b011f1..7081dbd 100644
--- a/fs/intermezzo/super.c
+++ b/fs/intermezzo/super.c
@@ -20,7 +20,7 @@
 #include <linux/ext2_fs.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/intermezzo/sysctl.c b/fs/intermezzo/sysctl.c
index 212e4c1..ec438c4 100644
--- a/fs/intermezzo/sysctl.c
+++ b/fs/intermezzo/sysctl.c
@@ -5,7 +5,7 @@
 #define __NO_VERSION__
 #include <linux/config.h> /* for CONFIG_PROC_FS */
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
 #include <linux/swapctl.h>
diff --git a/fs/intermezzo/upcall.c b/fs/intermezzo/upcall.c
index 95ecdef..37491a4 100644
--- a/fs/intermezzo/upcall.c
+++ b/fs/intermezzo/upcall.c
@@ -28,7 +28,7 @@
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
diff --git a/fs/ioctl.c b/fs/ioctl.c
index f46bdb1..a36c61f 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -7,6 +7,7 @@
 #include <linux/mm.h>
 #include <linux/smp_lock.h>
 #include <linux/file.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
index 5955991..bc97733 100644
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -20,7 +20,7 @@
 #include <linux/module.h>
 
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/iso_fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index 29db6b6..9c7ff0c 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -18,7 +18,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/locks.h>
 #include <linux/config.h>
 
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 66ea867..eca947c 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/iso_fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index a9aa148..0b952b3 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -6,7 +6,7 @@
  *  (C) 1991  Linus Torvalds - minix filesystem
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/iso_fs.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index 08a6c8a..5065d2f 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/iso_fs.h>
 #include <linux/string.h>
 #include <linux/mm.h>
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index e682155..895bd40 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -17,7 +17,7 @@
  * reused.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index ee8f224..94900b3 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -13,7 +13,7 @@
  * part of the ext2fs journaling system.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 92388ce..3280147 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -23,14 +23,13 @@
  */
 
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
-#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index b4f2cd8..68b2137 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -16,7 +16,7 @@
 #ifndef __KERNEL__
 #include "jfs_user.h"
 #else
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index 43987b6..77efb35 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -60,7 +60,7 @@
 #ifndef __KERNEL__
 #include "jfs_user.h"
 #else
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 1b11394..859c453 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -17,7 +17,7 @@
  * filesystem).
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/jbd.h>
 #include <linux/errno.h>
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 2bc47cf..dd23515 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -32,7 +32,7 @@
    dwmw2
 */
 #define __KERNEL_SYSCALLS__
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/unistd.h>
 
 #include <linux/module.h>
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 64b5898..39b6c37 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -68,7 +68,7 @@
 #include <asm/byteorder.h>
 #include <linux/version.h>
 #include <linux/smp_lock.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/ctype.h>
 
 #include "intrep.h"
diff --git a/fs/jffs/jffs_proc.c b/fs/jffs/jffs_proc.c
index 2210795..b100bff 100644
--- a/fs/jffs/jffs_proc.c
+++ b/fs/jffs/jffs_proc.c
@@ -26,7 +26,7 @@
 #include <linux/jffs.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/types.h>
 #include "jffs_fm.h"
 #include "jffs_proc.h"
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index be5f8be..ac1a66b 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -38,7 +38,7 @@
 #define __KERNEL_SYSCALLS__
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/unistd.h>
 #include <linux/jffs2.h>
 #include <linux/mtd/mtd.h>
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 4712eb7..8d5c142 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -42,7 +42,7 @@
 #include <linux/jffs2.h>
 #include <linux/jffs2_fs_i.h>
 #include <linux/jffs2_fs_sb.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include "nodelist.h"
 
 static int jffs2_readdir (struct file *, void *, filldir_t);
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 9294e58..fc4ab75 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -39,7 +39,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/jffs2.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/pagemap.h>
 #include <linux/crc32.h>
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index f092bfa..f38a040 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -10,7 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/nfs_fs.h>
 #include <linux/unistd.h>
 #include <linux/sunrpc/clnt.h>
diff --git a/fs/lockd/lockd_syms.c b/fs/lockd/lockd_syms.c
index 2de24bb..c8c4a60 100644
--- a/fs/lockd/lockd_syms.c
+++ b/fs/lockd/lockd_syms.c
@@ -16,7 +16,7 @@
 
 #include <linux/types.h>
 #include <linux/socket.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/uio.h>
 #include <linux/unistd.h>
 
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 28d8cbf..6ef8cb8 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -8,7 +8,7 @@
  */
 
 #include <linux/types.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/sunrpc/svc.h>
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index db4be6f..67c4743 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -306,9 +306,8 @@
 	struct nlm_block	*block;
 	int			error;
 
-	dprintk("lockd: nlmsvc_lock(%02x:%02x/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
-				major(file->f_file.f_dentry->d_inode->i_dev),
-				minor(file->f_file.f_dentry->d_inode->i_dev),
+	dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
+				file->f_file.f_dentry->d_inode->i_sb->s_id,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_type, lock->fl.fl_pid,
 				(long long)lock->fl.fl_start,
@@ -386,9 +385,8 @@
 {
 	struct file_lock	*fl;
 
-	dprintk("lockd: nlmsvc_testlock(%02x:%02x/%ld, ty=%d, %Ld-%Ld)\n",
-				major(file->f_file.f_dentry->d_inode->i_dev),
-				minor(file->f_file.f_dentry->d_inode->i_dev),
+	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
+				file->f_file.f_dentry->d_inode->i_sb->s_id,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_type,
 				(long long)lock->fl.fl_start,
@@ -419,9 +417,8 @@
 {
 	int	error;
 
-	dprintk("lockd: nlmsvc_unlock(%02x:%02x/%ld, pi=%d, %Ld-%Ld)\n",
-				major(file->f_file.f_dentry->d_inode->i_dev),
-				minor(file->f_file.f_dentry->d_inode->i_dev),
+	dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
+				file->f_file.f_dentry->d_inode->i_sb->s_id,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_pid,
 				(long long)lock->fl.fl_start,
@@ -448,9 +445,8 @@
 {
 	struct nlm_block	*block;
 
-	dprintk("lockd: nlmsvc_cancel(%02x:%02x/%ld, pi=%d, %Ld-%Ld)\n",
-				major(file->f_file.f_dentry->d_inode->i_dev),
-				minor(file->f_file.f_dentry->d_inode->i_dev),
+	dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
+				file->f_file.f_dentry->d_inode->i_sb->s_id,
 				file->f_file.f_dentry->d_inode->i_ino,
 				lock->fl.fl_pid,
 				(long long)lock->fl.fl_start,
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index a5283be..9eb5866 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -9,7 +9,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/in.h>
 #include <linux/sunrpc/svc.h>
diff --git a/fs/lockd/svcshare.c b/fs/lockd/svcshare.c
index 73fbb1b..ef24965 100644
--- a/fs/lockd/svcshare.c
+++ b/fs/lockd/svcshare.c
@@ -6,7 +6,7 @@
  * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/unistd.h>
 #include <linux/string.h>
 #include <linux/slab.h>
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index e7bcab7..6c07d3a 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -9,7 +9,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/in.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/clnt.h>
@@ -128,7 +128,7 @@
 	struct nlm_file	**fp, *f;
 
 	dprintk("lockd: closing file %s/%ld\n",
-		kdevname(inode->i_dev), inode->i_ino);
+		inode->i_sb->s_id, inode->i_ino);
 	fp = nlm_files + file->f_hash;
 	while ((f = *fp) != NULL) {
 		if (f == file) {
diff --git a/fs/locks.c b/fs/locks.c
index eeaa45b..2c6d2d3 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -120,7 +120,8 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/capability.h>
-#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/fs.h>
 
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 6b136aa..77ec25b 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -10,7 +10,7 @@
 #define __NO_VERSION__
 #include <linux/module.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/msdos_fs.h>
 
 #define MSDOS_DEBUG 0
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 25ac483..929d6df 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -11,7 +11,7 @@
 
 #include <linux/config.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/kernel.h>
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index bc7b38e..0b5f437 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -9,7 +9,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 4e79dcb..b3882c7 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -15,7 +15,7 @@
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/string.h>
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index f10cb81..d923de4 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -13,7 +13,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/ioctl.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/highuid.h>
 #include <linux/vmalloc.h>
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 7d9bc34..57573ef 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/shm.h>
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index 095498a..a9c4a4c 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -10,7 +10,7 @@
 
 #include <linux/config.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/socket.h>
 #include <linux/fcntl.h>
diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c
index 843aed0..c1eb6d3 100644
--- a/fs/ncpfs/symlink.c
+++ b/fs/ncpfs/symlink.c
@@ -25,7 +25,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/ncp_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include "ncplib_kernel.h"
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index bc19363..72b052b 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -17,7 +17,7 @@
  *  6 Jun 1999	Cache readdir lookups in the page cache. -DaveM
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index d25cb49..f7fa8ac 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -16,7 +16,7 @@
  *  nfs regular file handling functions
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
diff --git a/fs/nfs/flushd.c b/fs/nfs/flushd.c
index 8dca7b9..c1e64de 100644
--- a/fs/nfs/flushd.c
+++ b/fs/nfs/flushd.c
@@ -28,7 +28,7 @@
 #include <linux/pagemap.h>
 #include <linux/file.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 
 #include <linux/sunrpc/auth.h>
 #include <linux/sunrpc/clnt.h>
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 28d57bf..e2821e8 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -17,7 +17,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/string.h>
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 30ab0b8..9f9b72b 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -10,7 +10,7 @@
  */
 
 #include <linux/param.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/utsname.h>
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 1936438..a89441e 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/param.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/utsname.h>
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 51fbb9b..5541efe 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -70,7 +70,7 @@
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/sunrpc/clnt.h>
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index e19009e..5cd3459 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -30,7 +30,7 @@
 #include <linux/types.h>
 #include <linux/param.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/utsname.h>
 #include <linux/errno.h>
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 909f447..87fe738 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -16,7 +16,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 4350cf8..82203f1 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -11,7 +11,7 @@
  */
 
 #define NFS_NEED_XDR_TYPES
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs.h>
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 03c7735..6f725d3 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -375,7 +375,6 @@
 	struct nameidata	nd;
 	struct inode		*inode;
 	struct svc_fh		fh;
-	kdev_t			dev;
 	int			err;
 
 	err = -EPERM;
@@ -386,11 +385,10 @@
 		return err;
 	}
 	inode = nd.dentry->d_inode;
-	dev = inode->i_dev;
 
-	dprintk("nfsd: exp_rootfh(%s [%p] %s:%02x:%02x/%ld)\n",
+	dprintk("nfsd: exp_rootfh(%s [%p] %s:%s/%ld)\n",
 		 path, nd.dentry, clp->cl_ident,
-		 major(dev), minor(dev), (long) inode->i_ino);
+		 inode->i_sb->s_id, inode->i_ino);
 	exp = exp_parent(clp, inode->i_sb, nd.dentry);
 	if (!exp) {
 		dprintk("nfsd: exp_rootfh export not found.\n");
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index c5253b5..d117b4f 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/linkage.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
 #include <linux/fs.h>
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 8349746..7101328 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/types.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/nfs3.h>
 
 #include <linux/sunrpc/xdr.h>
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index 2157f62..1329160 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -11,7 +11,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index aad14fb..d19e5ce 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -11,7 +11,7 @@
 #include <linux/version.h>
 
 #include <linux/linkage.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/fcntl.h>
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 952e012..82152dc 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -424,8 +424,7 @@
 	/* It's a directory, or we are required to confirm the file's
 	 * location in the tree.
 	 */
-	dprintk("nfs_fh: need to look harder for %02x:%02x/%d\n",
-		major(sb->s_dev), minor(sb->s_dev), datap[0]);
+	dprintk("nfs_fh: need to look harder for %s/%d\n", sb->s_id, datap[0]);
 
 	if (!S_ISDIR(result->d_inode->i_mode)) {
 		nfsdstats.fh_nocache_nondir++;
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 8c4599d..3e481a0 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -8,7 +8,7 @@
  */
 
 #include <linux/linkage.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
 #include <linux/fs.h>
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index a4d9a98..cade5f6 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -12,7 +12,7 @@
 #include <linux/config.h>
 #include <linux/module.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/nfs.h>
 #include <linux/in.h>
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index d557f95..4611beb 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -7,7 +7,7 @@
  */
 
 #include <linux/types.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/nfs.h>
 
 #include <linux/sunrpc/xdr.h>
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c
index 2bcffc4..166c3e8 100644
--- a/fs/nfsd/stats.c
+++ b/fs/nfsd/stats.c
@@ -24,7 +24,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #define __NO_VERSION__
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 2455606..55a29ad 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -18,7 +18,7 @@
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/string.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/locks.h>
 #include <linux/fs.h>
@@ -1410,8 +1410,8 @@
 		oldlen = cd.buflen;
 
 		/*
-		dprintk("nfsd: f_op->readdir(%x/%ld @ %d) buflen = %d (%d)\n",
-			file.f_inode->i_dev, file.f_inode->i_ino,
+		dprintk("nfsd: f_op->readdir(%s/%ld @ %d) buflen = %d (%d)\n",
+			file.f_inode->i_sb->s_id, file.f_inode->i_ino,
 			(int) file.f_pos, (int) oldlen, (int) cd.buflen);
 		 */
 		err = file.f_op->readdir(&file, &cd, (filldir_t) func);
diff --git a/fs/pipe.c b/fs/pipe.c
index 9073473..596188f 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 08993e3..d1e5d9e 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -55,7 +55,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/kernel_stat.h>
 #include <linux/tty.h>
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 47c5cfd..8358560 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -17,7 +17,7 @@
 
 #include <linux/config.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/init.h>
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index f50b130..cf45ec0 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -11,7 +11,7 @@
 #include <asm/uaccess.h>
 
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #define __NO_VERSION__
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 5e6b476..c184990 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -4,7 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index 69aeddd..a2d8499 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -7,9 +7,10 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/poll.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index c64166f..18917b6 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -4,7 +4,7 @@
  * Copyright 1997 Paul Mackerras
  */
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/string.h>
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5dc1a8f..b176467 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -17,7 +17,7 @@
 
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/kernel_stat.h>
 #include <linux/tty.h>
@@ -50,9 +50,6 @@
  * have a way to deal with that gracefully. Right now I used straightforward
  * wrappers, but this needs further analysis wrt potential overflows.
  */
-#ifdef CONFIG_MODULES
-extern int get_module_list(char *);
-#endif
 extern int get_device_list(char *);
 extern int get_partition_list(char *, char **, off_t, int);
 extern int get_filesystem_list(char *);
@@ -203,13 +200,17 @@
 };
 
 #ifdef CONFIG_MODULES
-static int modules_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+extern struct seq_operations modules_op;
+static int modules_open(struct inode *inode, struct file *file)
 {
-	int len = get_module_list(page);
-	return proc_calc_metrics(page, start, off, count, eof, len);
+	return seq_open(file, &modules_op);
 }
-
+static struct file_operations proc_modules_operations = {
+	open:		modules_open,
+	read:		seq_read,
+	llseek:		seq_lseek,
+	release:	seq_release,
+};
 extern struct seq_operations ksyms_op;
 static int ksyms_open(struct inode *inode, struct file *file)
 {
@@ -223,6 +224,20 @@
 };
 #endif
 
+extern struct seq_operations slabinfo_op;
+extern ssize_t slabinfo_write(struct file *, const char *, size_t, loff_t *);
+static int slabinfo_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &slabinfo_op);
+}
+static struct file_operations proc_slabinfo_operations = {
+	open:		slabinfo_open,
+	read:		seq_read,
+	write:		slabinfo_write,
+	llseek:		seq_lseek,
+	release:	seq_release,
+};
+
 static int kstat_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -521,9 +536,6 @@
 		{"uptime",	uptime_read_proc},
 		{"meminfo",	meminfo_read_proc},
 		{"version",	version_read_proc},
-#ifdef CONFIG_MODULES
-		{"modules",	modules_read_proc},
-#endif
 		{"stat",	kstat_read_proc},
 		{"devices",	devices_read_proc},
 		{"partitions",	partitions_read_proc},
@@ -551,7 +563,9 @@
 		entry->proc_fops = &proc_kmsg_operations;
 	create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
 	create_seq_entry("interrupts", 0, &proc_interrupts_operations);
+	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
 #ifdef CONFIG_MODULES
+	create_seq_entry("modules", 0, &proc_modules_operations);
 	create_seq_entry("ksyms", 0, &proc_ksyms_operations);
 #endif
 	proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
@@ -575,8 +589,4 @@
 			entry->proc_fops = &ppc_htab_operations;
 	}
 #endif
-	entry = create_proc_read_entry("slabinfo", S_IWUSR | S_IRUGO, NULL,
-				       slabinfo_read_proc, NULL);
-	if (entry)
-		entry->write_proc = slabinfo_write_proc;
 }
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index 1d55d49..9de90ed 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -8,7 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/tty.h>
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 666166b..98e089b 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -9,7 +9,7 @@
 #include <asm/uaccess.h>
 
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/config.h>
diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c
index b06d5c1..f45c43d 100644
--- a/fs/qnx4/bitmap.c
+++ b/fs/qnx4/bitmap.c
@@ -14,7 +14,8 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/fs.h>
 #include <linux/qnx4_fs.h>
 #include <linux/stat.h>
 #include <linux/kernel.h>
diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c
index ab5856a..ecf6d05 100644
--- a/fs/qnx4/file.c
+++ b/fs/qnx4/file.c
@@ -15,7 +15,7 @@
 #include <linux/config.h>
 #include <linux/types.h>
 #include <linux/fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/qnx4_fs.h>
 
 /*
diff --git a/fs/qnx4/fsync.c b/fs/qnx4/fsync.c
index f3d2301..56136f1 100644
--- a/fs/qnx4/fsync.c
+++ b/fs/qnx4/fsync.c
@@ -12,7 +12,7 @@
 
 #include <linux/config.h>
 #include <linux/errno.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/fcntl.h>
 #include <linux/locks.h>
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index f282935..6af2f77 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -13,7 +13,8 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/fs.h>
 #include <linux/qnx4_fs.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
diff --git a/fs/readdir.c b/fs/readdir.c
index 7ec20be..083165f 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -4,12 +4,13 @@
  *  Copyright (C) 1995  Linus Torvalds
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/stat.h>
 #include <linux/file.h>
 #include <linux/smp_lock.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 427a003..1130f91 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -3,7 +3,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/locks.h>
 #include <asm/bitops.h>
diff --git a/fs/reiserfs/buffer2.c b/fs/reiserfs/buffer2.c
index 2d0b29a..b702525 100644
--- a/fs/reiserfs/buffer2.c
+++ b/fs/reiserfs/buffer2.c
@@ -3,7 +3,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/locks.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
index 1c9e1bc..0ae4d34 100644
--- a/fs/reiserfs/do_balan.c
+++ b/fs/reiserfs/do_balan.c
@@ -18,7 +18,7 @@
 
 #include <linux/config.h>
 #include <asm/uaccess.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 
 #ifdef CONFIG_REISERFS_CHECK
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index f967d46..91e51da 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -3,7 +3,7 @@
  */
 
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
 
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 5444f25..5a8f9f6 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -36,7 +36,7 @@
 
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/reiserfs_fs.h>
diff --git a/fs/reiserfs/ibalance.c b/fs/reiserfs/ibalance.c
index c77948e..b4a4b2d 100644
--- a/fs/reiserfs/ibalance.c
+++ b/fs/reiserfs/ibalance.c
@@ -5,7 +5,7 @@
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 
 /* this is one and only function that is used outside (do_balance.c) */
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index c35cb51..3446271 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3,7 +3,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index dccd1c3..a3c2d85 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -4,7 +4,7 @@
 
 #include <linux/fs.h>
 #include <linux/reiserfs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
 #include <linux/locks.h>
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
index 74305fa..9881a26 100644
--- a/fs/reiserfs/item_ops.c
+++ b/fs/reiserfs/item_ops.c
@@ -2,7 +2,7 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 
 // this contains item handlers for old item types: sd, direct,
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 1996782..3bb9474 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -45,7 +45,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <asm/semaphore.h>
 
 #include <linux/vmalloc.h>
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c
index 64f2dba..f39feaf 100644
--- a/fs/reiserfs/lbalance.c
+++ b/fs/reiserfs/lbalance.c
@@ -5,7 +5,7 @@
 #include <linux/config.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 
 /* these are used in do_balance.c */
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 9d2d24b..ed3c0aa 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -12,7 +12,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/bitops.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c
index 45c2537..503ef62 100644
--- a/fs/reiserfs/objectid.c
+++ b/fs/reiserfs/objectid.c
@@ -6,7 +6,7 @@
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/random.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_fs_sb.h>
 
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index c7c18e3..16bf7ce 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -3,7 +3,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/string.h>
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index b6ef3e5..2b6a8ad 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -12,7 +12,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <asm/uaccess.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_fs_sb.h>
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 5d3eee7..5ab2d7e 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -54,7 +54,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/pagemap.h>
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index a9ae97d..5051b81 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -13,7 +13,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <asm/uaccess.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/smp_lock.h>
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index 18f1bda..98106be 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -3,7 +3,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/pagemap.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/locks.h>
diff --git a/fs/select.c b/fs/select.c
index b059b90..30c29f1 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -19,6 +19,7 @@
 #include <linux/poll.h>
 #include <linux/personality.h> /* for STICKY_TIMEOUTS */
 #include <linux/file.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c
index 3e98f83..369c139 100644
--- a/fs/smbfs/cache.c
+++ b/fs/smbfs/cache.c
@@ -9,7 +9,7 @@
  * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c
index 53bedfd..4ef7212 100644
--- a/fs/smbfs/dir.c
+++ b/fs/smbfs/dir.c
@@ -7,7 +7,7 @@
  *  Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/smp_lock.h>
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index 39badd7..63f6aaa 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -7,7 +7,7 @@
  *  Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 688ba2d..7c964fe 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -9,7 +9,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/string.h>
diff --git a/fs/smbfs/ioctl.c b/fs/smbfs/ioctl.c
index afc45b4..e68ebd7 100644
--- a/fs/smbfs/ioctl.c
+++ b/fs/smbfs/ioctl.c
@@ -10,7 +10,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/ioctl.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/highuid.h>
 
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c
index 8c66f4c..78ea221 100644
--- a/fs/smbfs/sock.c
+++ b/fs/smbfs/sock.c
@@ -7,7 +7,8 @@
  *  Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
-#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/socket.h>
 #include <linux/fcntl.h>
diff --git a/fs/stat.c b/fs/stat.c
index 20bd373..3431914 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -10,6 +10,7 @@
 #include <linux/file.h>
 #include <linux/smp_lock.h>
 #include <linux/highuid.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 3254e53..7a0eebe 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -29,7 +29,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/udf_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/stat.h>
 #include <linux/slab.h>
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 8f82baf..861593a 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -9,7 +9,7 @@
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 #include <linux/stat.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
diff --git a/fs/ufs/cylinder.c b/fs/ufs/cylinder.c
index 97391b4..a0729fe 100644
--- a/fs/ufs/cylinder.c
+++ b/fs/ufs/cylinder.c
@@ -10,7 +10,7 @@
 
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 3dca14b..1171261 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -13,7 +13,7 @@
  * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/locks.h>
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 819e694..fd63321 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -30,7 +30,7 @@
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 #include <linux/fcntl.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
 #include <linux/mm.h>
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index d1eea1f..c0a435a 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -22,7 +22,7 @@
 
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index cc08c9f..e114383 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -31,7 +31,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 0a95f62..3742b3e 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -24,7 +24,7 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index ef84557..d079056 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -74,7 +74,7 @@
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 #include <linux/slab.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 448466b..2cec5fe 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -33,7 +33,7 @@
 #include <linux/fs.h>
 #include <linux/ufs_fs.h>
 #include <linux/fcntl.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
 #include <linux/string.h>
diff --git a/fs/umsdos/dir.c b/fs/umsdos/dir.c
index 8d797bb..4586fc6 100644
--- a/fs/umsdos/dir.c
+++ b/fs/umsdos/dir.c
@@ -7,7 +7,7 @@
  *  Extended MS-DOS directory handling functions
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
diff --git a/fs/umsdos/emd.c b/fs/umsdos/emd.c
index 51d76ca..2b64394 100644
--- a/fs/umsdos/emd.c
+++ b/fs/umsdos/emd.c
@@ -9,7 +9,7 @@
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/msdos_fs.h>
diff --git a/fs/umsdos/inode.c b/fs/umsdos/inode.c
index befdd47..ad0104d 100644
--- a/fs/umsdos/inode.c
+++ b/fs/umsdos/inode.c
@@ -11,7 +11,7 @@
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
 #include <linux/string.h>
diff --git a/fs/umsdos/ioctl.c b/fs/umsdos/ioctl.c
index 13cd83d..722581c 100644
--- a/fs/umsdos/ioctl.c
+++ b/fs/umsdos/ioctl.c
@@ -10,7 +10,7 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
 #include <linux/umsdos_fs.h>
diff --git a/fs/umsdos/namei.c b/fs/umsdos/namei.c
index 1e40fd8..f7640db 100644
--- a/fs/umsdos/namei.c
+++ b/fs/umsdos/namei.c
@@ -13,7 +13,7 @@
 
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/stat.h>
diff --git a/fs/umsdos/rdir.c b/fs/umsdos/rdir.c
index 372454a..edd41d9 100644
--- a/fs/umsdos/rdir.c
+++ b/fs/umsdos/rdir.c
@@ -7,7 +7,7 @@
  *  (For directory without EMD file).
  */
 
-#include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
 #include <linux/errno.h>
diff --git a/include/asm-i386/hardirq.h b/include/asm-i386/hardirq.h
index 4acb4b0..64ef2bc 100644
--- a/include/asm-i386/hardirq.h
+++ b/include/asm-i386/hardirq.h
@@ -36,6 +36,8 @@
 
 #define synchronize_irq()	barrier()
 
+#define release_irqlock(cpu)	do { } while (0)
+
 #else
 
 #include <asm/atomic.h>
diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h
index 42f3242..e8d4f37 100644
--- a/include/asm-i386/highmem.h
+++ b/include/asm-i386/highmem.h
@@ -88,6 +88,7 @@
 	enum fixed_addresses idx;
 	unsigned long vaddr;
 
+	preempt_disable();
 	if (page < highmem_start_page)
 		return page_address(page);
 
@@ -109,8 +110,10 @@
 	unsigned long vaddr = (unsigned long) kvaddr;
 	enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
 
-	if (vaddr < FIXADDR_START) // FIXME
+	if (vaddr < FIXADDR_START) { // FIXME
+		preempt_enable();
 		return;
+	}
 
 	if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
 		BUG();
@@ -122,6 +125,8 @@
 	pte_clear(kmap_pte-idx);
 	__flush_tlb_one(vaddr);
 #endif
+
+	preempt_enable();
 }
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 5b43b7c..b572c28 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -96,6 +96,18 @@
 #define __STR(x) #x
 #define STR(x) __STR(x)
 
+#define GET_THREAD_INFO \
+	"movl $-8192, %ebx\n\t" \
+	"andl %esp, %ebx\n\t"
+
+#ifdef CONFIG_PREEMPT
+#define BUMP_LOCK_COUNT \
+	GET_THREAD_INFO \
+	"incl 16(%ebx)\n\t"
+#else
+#define BUMP_LOCK_COUNT
+#endif
+
 #define SAVE_ALL \
 	"cld\n\t" \
 	"pushl %es\n\t" \
@@ -109,7 +121,8 @@
 	"pushl %ebx\n\t" \
 	"movl $" STR(__KERNEL_DS) ",%edx\n\t" \
 	"movl %edx,%ds\n\t" \
-	"movl %edx,%es\n\t"
+	"movl %edx,%es\n\t" \
+	BUMP_LOCK_COUNT
 
 #define IRQ_NAME2(nr) nr##_interrupt(void)
 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 462ec5a..b8b60c2 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -12,6 +12,7 @@
 #define __ASM_I386_I387_H
 
 #include <linux/sched.h>
+#include <linux/spinlock.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
 #include <asm/user.h>
@@ -24,7 +25,7 @@
 extern void restore_fpu( struct task_struct *tsk );
 
 extern void kernel_fpu_begin(void);
-#define kernel_fpu_end() stts()
+#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
 
 
 #define unlazy_fpu( tsk ) do { \
diff --git a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h
index b132819..3e90f19 100644
--- a/include/asm-i386/io_apic.h
+++ b/include/asm-i386/io_apic.h
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <asm/types.h>
+#include <asm/mpspec.h>
 
 /*
  * Intel IO-APIC support for SMP and UP systems.
diff --git a/include/asm-i386/pgalloc.h b/include/asm-i386/pgalloc.h
index 090573f..67773c0 100644
--- a/include/asm-i386/pgalloc.h
+++ b/include/asm-i386/pgalloc.h
@@ -75,20 +75,26 @@
 {
 	unsigned long *ret;
 
+	preempt_disable();
 	if ((ret = pgd_quicklist) != NULL) {
 		pgd_quicklist = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
-	} else
+		preempt_enable();
+	} else {
+		preempt_enable();
 		ret = (unsigned long *)get_pgd_slow();
+	}
 	return (pgd_t *)ret;
 }
 
 static inline void free_pgd_fast(pgd_t *pgd)
 {
+	preempt_disable();
 	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
 	pgd_quicklist = (unsigned long *) pgd;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 static inline void free_pgd_slow(pgd_t *pgd)
@@ -119,19 +125,23 @@
 {
 	unsigned long *ret;
 
+	preempt_disable();
 	if ((ret = (unsigned long *)pte_quicklist) != NULL) {
 		pte_quicklist = (unsigned long *)(*ret);
 		ret[0] = ret[1];
 		pgtable_cache_size--;
 	}
+	preempt_enable();
 	return (pte_t *)ret;
 }
 
 static inline void pte_free_fast(pte_t *pte)
 {
+	preempt_disable();
 	*(unsigned long *)pte = (unsigned long) pte_quicklist;
 	pte_quicklist = (unsigned long *) pte;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 static __inline__ void pte_free_slow(pte_t *pte)
diff --git a/include/asm-i386/smplock.h b/include/asm-i386/smplock.h
index c270def..e1d5925 100644
--- a/include/asm-i386/smplock.h
+++ b/include/asm-i386/smplock.h
@@ -10,7 +10,16 @@
 
 extern spinlock_t kernel_flag;
 
+#ifdef CONFIG_SMP
 #define kernel_locked()		spin_is_locked(&kernel_flag)
+#else
+#ifdef CONFIG_PREEMPT
+#define kernel_locked()		preempt_get_count()
+#define global_irq_holder	0
+#else
+#define kernel_locked()		1
+#endif
+#endif
 
 /*
  * Release global kernel lock and global interrupt lock
@@ -43,6 +52,11 @@
  */
 static __inline__ void lock_kernel(void)
 {
+#ifdef CONFIG_PREEMPT
+	if (current->lock_depth == -1)
+		spin_lock(&kernel_flag);
+	++current->lock_depth;
+#else
 #if 1
 	if (!++current->lock_depth)
 		spin_lock(&kernel_flag);
@@ -55,6 +69,7 @@
 		:"=m" (__dummy_lock(&kernel_flag)),
 		 "=m" (current->lock_depth));
 #endif
+#endif
 }
 
 static __inline__ void unlock_kernel(void)
diff --git a/include/asm-i386/softirq.h b/include/asm-i386/softirq.h
index b9f7796..c62cbec 100644
--- a/include/asm-i386/softirq.h
+++ b/include/asm-i386/softirq.h
@@ -5,9 +5,9 @@
 #include <asm/hardirq.h>
 
 #define __cpu_bh_enable(cpu) \
-		do { barrier(); local_bh_count(cpu)--; } while (0)
+		do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0)
 #define cpu_bh_disable(cpu) \
-		do { local_bh_count(cpu)++; barrier(); } while (0)
+		do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0)
 
 #define local_bh_disable()	cpu_bh_disable(smp_processor_id())
 #define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
@@ -22,7 +22,7 @@
  * If you change the offsets in irq_stat then you have to
  * update this code as well.
  */
-#define local_bh_enable()						\
+#define _local_bh_enable()						\
 do {									\
 	unsigned int *ptr = &local_bh_count(smp_processor_id());	\
 									\
@@ -45,4 +45,6 @@
 		/* no registers clobbered */ );				\
 } while (0)
 
+#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0)
+
 #endif	/* __ASM_SOFTIRQ_H */
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index 89118fc..1a4b487 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -77,7 +77,7 @@
 		:"=m" (lock->lock) : : "memory"
 
 
-static inline void spin_unlock(spinlock_t *lock)
+static inline void _raw_spin_unlock(spinlock_t *lock)
 {
 #if SPINLOCK_DEBUG
 	if (lock->magic != SPINLOCK_MAGIC)
@@ -97,7 +97,7 @@
 		:"=q" (oldval), "=m" (lock->lock) \
 		:"0" (oldval) : "memory"
 
-static inline void spin_unlock(spinlock_t *lock)
+static inline void _raw_spin_unlock(spinlock_t *lock)
 {
 	char oldval = 1;
 #if SPINLOCK_DEBUG
@@ -113,7 +113,7 @@
 
 #endif
 
-static inline int spin_trylock(spinlock_t *lock)
+static inline int _raw_spin_trylock(spinlock_t *lock)
 {
 	char oldval;
 	__asm__ __volatile__(
@@ -123,7 +123,7 @@
 	return oldval > 0;
 }
 
-static inline void spin_lock(spinlock_t *lock)
+static inline void _raw_spin_lock(spinlock_t *lock)
 {
 #if SPINLOCK_DEBUG
 	__label__ here;
@@ -179,7 +179,7 @@
  */
 /* the spinlock helpers are in arch/i386/kernel/semaphore.c */
 
-static inline void read_lock(rwlock_t *rw)
+static inline void _raw_read_lock(rwlock_t *rw)
 {
 #if SPINLOCK_DEBUG
 	if (rw->magic != RWLOCK_MAGIC)
@@ -188,7 +188,7 @@
 	__build_read_lock(rw, "__read_lock_failed");
 }
 
-static inline void write_lock(rwlock_t *rw)
+static inline void _raw_write_lock(rwlock_t *rw)
 {
 #if SPINLOCK_DEBUG
 	if (rw->magic != RWLOCK_MAGIC)
@@ -197,10 +197,10 @@
 	__build_write_lock(rw, "__write_lock_failed");
 }
 
-#define read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
-#define write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
+#define _raw_read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
+#define _raw_write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
 
-static inline int write_trylock(rwlock_t *lock)
+static inline int _raw_write_trylock(rwlock_t *lock)
 {
 	atomic_t *count = (atomic_t *)lock;
 	if (atomic_sub_and_test(RW_LOCK_BIAS, count))
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
index 61c7b42..55bca60 100644
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -25,6 +25,7 @@
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	__u32			cpu;		/* current CPU */
+	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
@@ -41,7 +42,8 @@
 #define TI_EXEC_DOMAIN	0x00000004
 #define TI_FLAGS	0x00000008
 #define TI_CPU		0x0000000C
-#define TI_ADDR_LIMIT	0x00000010
+#define TI_PRE_COUNT	0x00000010
+#define TI_ADDR_LIMIT	0x00000014
 
 #endif
 
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
index c932a69..7143971 100644
--- a/include/asm-i386/uaccess.h
+++ b/include/asm-i386/uaccess.h
@@ -5,6 +5,7 @@
  * User space memory access functions
  */
 #include <linux/config.h>
+#include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/prefetch.h>
 #include <asm/page.h>
diff --git a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
index 62bfae5..d55bd01 100644
--- a/include/asm-sparc64/hardirq.h
+++ b/include/asm-sparc64/hardirq.h
@@ -56,6 +56,8 @@
 
 #define synchronize_irq()	barrier()
 
+#define release_irqlock(cpu)	do { } while (0)
+
 #else /* (CONFIG_SMP) */
 
 static __inline__ int irqs_running(void)
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
index f8f85d3..1d8b25d 100644
--- a/include/asm-sparc64/pgalloc.h
+++ b/include/asm-sparc64/pgalloc.h
@@ -1,4 +1,4 @@
-/* $Id: pgalloc.h,v 1.30 2001-12-21 04:56:17 davem Exp $ */
+/* $Id: pgalloc.h,v 1.31 2002-02-11 06:42:10 davem Exp $ */
 #ifndef _SPARC64_PGALLOC_H
 #define _SPARC64_PGALLOC_H
 
@@ -158,6 +158,7 @@
 {
 	struct page *page = virt_to_page(pgd);
 
+	preempt_disable();
 	if (!page->pprev_hash) {
 		(unsigned long *)page->next_hash = pgd_quicklist;
 		pgd_quicklist = (unsigned long *)page;
@@ -165,12 +166,14 @@
 	(unsigned long)page->pprev_hash |=
 		(((unsigned long)pgd & (PAGE_SIZE / 2)) ? 2 : 1);
 	pgd_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ pgd_t *get_pgd_fast(void)
 {
         struct page *ret;
 
+	preempt_disable();
         if ((ret = (struct page *)pgd_quicklist) != NULL) {
                 unsigned long mask = (unsigned long)ret->pprev_hash;
 		unsigned long off = 0;
@@ -186,16 +189,22 @@
 			pgd_quicklist = (unsigned long *)ret->next_hash;
                 ret = (struct page *)(__page_address(ret) + off);
                 pgd_cache_size--;
+		preempt_enable();
         } else {
-		struct page *page = alloc_page(GFP_KERNEL);
+		struct page *page;
 
+		preempt_enable();
+		page = alloc_page(GFP_KERNEL);
 		if (page) {
 			ret = (struct page *)page_address(page);
 			clear_page(ret);
 			(unsigned long)page->pprev_hash = 2;
+
+			preempt_disable();
 			(unsigned long *)page->next_hash = pgd_quicklist;
 			pgd_quicklist = (unsigned long *)page;
 			pgd_cache_size++;
+			preempt_enable();
 		}
         }
         return (pgd_t *)ret;
@@ -205,20 +214,25 @@
 
 extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
+	preempt_disable();
 	*(unsigned long *)pgd = (unsigned long) pgd_quicklist;
 	pgd_quicklist = (unsigned long *) pgd;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ pgd_t *get_pgd_fast(void)
 {
 	unsigned long *ret;
 
+	preempt_disable();
 	if((ret = pgd_quicklist) != NULL) {
 		pgd_quicklist = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
+		preempt_enable();
 	} else {
+		preempt_enable();
 		ret = (unsigned long *) __get_free_page(GFP_KERNEL);
 		if(ret)
 			memset(ret, 0, PAGE_SIZE);
@@ -258,20 +272,27 @@
 
 	if (pte_quicklist[color] == NULL)
 		color = 1;
+
+	preempt_disable();
 	if((ret = (unsigned long *)pte_quicklist[color]) != NULL) {
 		pte_quicklist[color] = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
 	}
+	preempt_enable();
+
 	return (pmd_t *)ret;
 }
 
 extern __inline__ void free_pmd_fast(pmd_t *pmd)
 {
 	unsigned long color = DCACHE_COLOR((unsigned long)pmd);
+
+	preempt_disable();
 	*(unsigned long *)pmd = (unsigned long) pte_quicklist[color];
 	pte_quicklist[color] = (unsigned long *) pmd;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ void free_pmd_slow(pmd_t *pmd)
@@ -288,20 +309,25 @@
 	unsigned long color = VPTE_COLOR(address);
 	unsigned long *ret;
 
+	preempt_disable();
 	if((ret = (unsigned long *)pte_quicklist[color]) != NULL) {
 		pte_quicklist[color] = (unsigned long *)(*ret);
 		ret[0] = 0;
 		pgtable_cache_size--;
 	}
+	preempt_enable();
 	return (pte_t *)ret;
 }
 
 extern __inline__ void free_pte_fast(pte_t *pte)
 {
 	unsigned long color = DCACHE_COLOR((unsigned long)pte);
+
+	preempt_disable();
 	*(unsigned long *)pte = (unsigned long) pte_quicklist[color];
 	pte_quicklist[color] = (unsigned long *) pte;
 	pgtable_cache_size++;
+	preempt_enable();
 }
 
 extern __inline__ void free_pte_slow(pte_t *pte)
diff --git a/include/asm-sparc64/smplock.h b/include/asm-sparc64/smplock.h
index dd2cc2b..d9c8754 100644
--- a/include/asm-sparc64/smplock.h
+++ b/include/asm-sparc64/smplock.h
@@ -9,9 +9,17 @@
 
 extern spinlock_t kernel_flag;
 
+#ifdef CONFIG_SMP
 #define kernel_locked()			\
 	(spin_is_locked(&kernel_flag) &&\
 	 (current->lock_depth >= 0))
+#else
+#ifdef CONFIG_PREEMPT
+#define kernel_locked()			preempt_get_count()
+#else
+#define kernel_locked()			1
+#endif
+#endif
 
 /*
  * Release global kernel lock and global interrupt lock
diff --git a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h
index e97b25e..0239b72 100644
--- a/include/asm-sparc64/softirq.h
+++ b/include/asm-sparc64/softirq.h
@@ -10,14 +10,15 @@
 #include <asm/hardirq.h>
 #include <asm/system.h>		/* for membar() */
 
-#define local_bh_disable()	(local_bh_count(smp_processor_id())++)
-#define __local_bh_enable()	(local_bh_count(smp_processor_id())--)
+#define local_bh_disable()	do { barrier(); preempt_disable(); local_bh_count(smp_processor_id())++; } while (0)
+#define __local_bh_enable()	do { local_bh_count(smp_processor_id())--; preempt_enable(); barrier(); } while (0)
 #define local_bh_enable()			  \
 do { if (!--local_bh_count(smp_processor_id()) && \
 	 softirq_pending(smp_processor_id())) {   \
 		do_softirq();			  \
 		__sti();			  \
      }						  \
+     preempt_enable();				  \
 } while (0)
 
 #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
index ce905b4..55fef65 100644
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -40,7 +40,7 @@
 do {	membar("#LoadLoad");	\
 } while(*((volatile unsigned char *)lock))
 
-extern __inline__ void spin_lock(spinlock_t *lock)
+extern __inline__ void _raw_spin_lock(spinlock_t *lock)
 {
 	__asm__ __volatile__(
 "1:	ldstub		[%0], %%g7\n"
@@ -57,7 +57,7 @@
 	: "g7", "memory");
 }
 
-extern __inline__ int spin_trylock(spinlock_t *lock)
+extern __inline__ int _raw_spin_trylock(spinlock_t *lock)
 {
 	unsigned int result;
 	__asm__ __volatile__("ldstub [%1], %0\n\t"
@@ -68,7 +68,7 @@
 	return (result == 0);
 }
 
-extern __inline__ void spin_unlock(spinlock_t *lock)
+extern __inline__ void _raw_spin_unlock(spinlock_t *lock)
 {
 	__asm__ __volatile__("membar	#StoreStore | #LoadStore\n\t"
 			     "stb	%%g0, [%0]"
@@ -99,9 +99,9 @@
 extern void _do_spin_unlock (spinlock_t *lock);
 extern int _spin_trylock (spinlock_t *lock);
 
-#define spin_trylock(lp)	_spin_trylock(lp)
-#define spin_lock(lock)		_do_spin_lock(lock, "spin_lock")
-#define spin_unlock(lock)	_do_spin_unlock(lock)
+#define _raw_spin_trylock(lp)	_spin_trylock(lp)
+#define _raw_spin_lock(lock)	_do_spin_lock(lock, "spin_lock")
+#define _raw_spin_unlock(lock)	_do_spin_unlock(lock)
 
 #endif /* CONFIG_DEBUG_SPINLOCK */
 
@@ -118,10 +118,10 @@
 extern void __write_lock(rwlock_t *);
 extern void __write_unlock(rwlock_t *);
 
-#define read_lock(p)	__read_lock(p)
-#define read_unlock(p)	__read_unlock(p)
-#define write_lock(p)	__write_lock(p)
-#define write_unlock(p)	__write_unlock(p)
+#define _raw_read_lock(p)	__read_lock(p)
+#define _raw_read_unlock(p)	__read_unlock(p)
+#define _raw_write_lock(p)	__write_lock(p)
+#define _raw_write_unlock(p)	__write_unlock(p)
 
 #else /* !(CONFIG_DEBUG_SPINLOCK) */
 
@@ -138,28 +138,28 @@
 extern void _do_write_lock(rwlock_t *rw, char *str);
 extern void _do_write_unlock(rwlock_t *rw);
 
-#define read_lock(lock)	\
+#define _raw_read_lock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_read_lock(lock, "read_lock"); \
 	__restore_flags(flags); \
 } while(0)
 
-#define read_unlock(lock) \
+#define _raw_read_unlock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_read_unlock(lock, "read_unlock"); \
 	__restore_flags(flags); \
 } while(0)
 
-#define write_lock(lock) \
+#define _raw_write_lock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_write_lock(lock, "write_lock"); \
 	__restore_flags(flags); \
 } while(0)
 
-#define write_unlock(lock) \
+#define _raw_write_unlock(lock) \
 do {	unsigned long flags; \
 	__save_and_cli(flags); \
 	_do_write_unlock(lock); \
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
index 35d2e00..35d2a9e 100644
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -1,4 +1,4 @@
-/* $Id: thread_info.h,v 1.1 2002-02-10 00:00:58 davem Exp $
+/* $Id: thread_info.h,v 1.2 2002-02-11 06:42:10 davem Exp $
  * thread_info.h: sparc64 low-level thread information
  *
  * Copyright (C) 2002  David S. Miller (davem@redhat.com)
@@ -27,6 +27,7 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/ptrace.h>
+#include <asm/types.h>
 
 struct task_struct;
 struct exec_domain;
@@ -42,8 +43,10 @@
 	/* D$ line 2 */
 	unsigned long		fault_address;
 	struct pt_regs		*kregs;
-	unsigned long		*utraps;
 	struct exec_domain	*exec_domain;
+	int			preempt_count;
+
+	unsigned long		*utraps;
 
 	struct reg_window 	reg_window[NSWINS];
 	unsigned long 		rwbuf_stkptrs[NSWINS];
@@ -76,18 +79,19 @@
 #define TI_KSP		0x00000018
 #define TI_FAULT_ADDR	0x00000020
 #define TI_KREGS	0x00000028
-#define TI_UTRAPS	0x00000030
-#define TI_EXEC_DOMAIN	0x00000038
-#define TI_REG_WINDOW	0x00000040
-#define TI_RWIN_SPTRS	0x000003c0	
-#define TI_GSR		0x000003f8
-#define TI_XFSR		0x00000430
-#define TI_USER_CNTD0	0x00000468
-#define TI_USER_CNTD1	0x00000470
-#define TI_KERN_CNTD0	0x00000478
-#define TI_KERN_CNTD1	0x00000480
-#define TI_PCR		0x00000488
-#define TI_CEE_STUFF	0x00000490
+#define TI_EXEC_DOMAIN	0x00000030
+#define TI_PRE_COUNT	0x00000038
+#define TI_UTRAPS	0x00000040
+#define TI_REG_WINDOW	0x00000048
+#define TI_RWIN_SPTRS	0x000003c8	
+#define TI_GSR		0x00000400
+#define TI_XFSR		0x00000438
+#define TI_USER_CNTD0	0x00000470
+#define TI_USER_CNTD1	0x00000478
+#define TI_KERN_CNTD0	0x00000480
+#define TI_KERN_CNTD1	0x00000488
+#define TI_PCR		0x00000490
+#define TI_CEE_STUFF	0x00000498
 #define TI_FPREGS	0x000004c0
 
 /* We embed this in the uppermost byte of thread_info->flags */
diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
index a302515..3c3fa2e 100644
--- a/include/asm-sparc64/ttable.h
+++ b/include/asm-sparc64/ttable.h
@@ -1,4 +1,4 @@
-/* $Id: ttable.h,v 1.18 2002-02-09 19:49:32 davem Exp $ */
+/* $Id: ttable.h,v 1.19 2002-02-11 06:42:10 davem Exp $ */
 #ifndef _SPARC64_TTABLE_H
 #define _SPARC64_TTABLE_H
 
@@ -140,7 +140,7 @@
 	mov	level, %o0;				\
 	call	routine;				\
 	 add	%sp, STACK_BIAS + REGWIN_SZ, %o1;	\
-	ba,a,pt	%xcc, rtrap_clr_l6;
+	ba,a,pt	%xcc, rtrap_irq;
 	
 #define TICK_SMP_IRQ					\
 	rdpr	%pil, %g2;				\
@@ -150,7 +150,7 @@
 109:	 or	%g7, %lo(109b), %g7;			\
 	call	smp_percpu_timer_interrupt;		\
 	 add	%sp, STACK_BIAS + REGWIN_SZ, %o0;	\
-	ba,a,pt	%xcc, rtrap_clr_l6;
+	ba,a,pt	%xcc, rtrap_irq;
 
 #define TRAP_IVEC TRAP_NOSAVE(do_ivec)
 
diff --git a/include/linux/affs_fs_i.h b/include/linux/affs_fs_i.h
index c32f69c..89872f7 100644
--- a/include/linux/affs_fs_i.h
+++ b/include/linux/affs_fs_i.h
@@ -2,6 +2,8 @@
 #define _AFFS_FS_I
 
 #include <linux/a.out.h>
+#include <linux/fs.h>
+#include <asm/semaphore.h>
 
 #define AFFS_CACHE_SIZE		PAGE_SIZE
 //#define AFFS_CACHE_SIZE		(4*4)
diff --git a/include/linux/ax25.h b/include/linux/ax25.h
index 9191445..6dfc8fc 100644
--- a/include/linux/ax25.h
+++ b/include/linux/ax25.h
@@ -6,6 +6,8 @@
 #ifndef	AX25_KERNEL_H
 #define	AX25_KERNEL_H
 
+#include <linux/socket.h>
+
 #define AX25_MTU	256
 #define AX25_MAX_DIGIS  8
 
diff --git a/include/linux/bfs_fs_i.h b/include/linux/bfs_fs_i.h
index ca1432a..5a85f1d 100644
--- a/include/linux/bfs_fs_i.h
+++ b/include/linux/bfs_fs_i.h
@@ -6,6 +6,8 @@
 #ifndef _LINUX_BFS_FS_I
 #define _LINUX_BFS_FS_I
 
+#include <linux/fs.h>
+
 /*
  * BFS file system in-core inode info
  */
diff --git a/include/linux/brlock.h b/include/linux/brlock.h
index 208c457..e36492e 100644
--- a/include/linux/brlock.h
+++ b/include/linux/brlock.h
@@ -171,11 +171,11 @@
 }
 
 #else
-# define br_read_lock(idx)	((void)(idx))
-# define br_read_unlock(idx)	((void)(idx))
-# define br_write_lock(idx)	((void)(idx))
-# define br_write_unlock(idx)	((void)(idx))
-#endif
+# define br_read_lock(idx)	({ (void)(idx); preempt_disable(); })
+# define br_read_unlock(idx)	({ (void)(idx); preempt_enable(); })
+# define br_write_lock(idx)	({ (void)(idx); preempt_disable(); })
+# define br_write_unlock(idx)	({ (void)(idx); preempt_enable(); })
+#endif	/* CONFIG_SMP */
 
 /*
  * Now enumerate all of the possible sw/hw IRQ protected
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 73e9728..1cccb9d 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -14,7 +14,6 @@
 #define _LINUX_CAPABILITY_H
 
 #include <linux/types.h>
-#include <linux/fs.h>
 
 /* User-level do most of the mapping between kernel and user
    capabilities based on the version tag given by the kernel. The
diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h
index c5cbc10..2f55b03 100644
--- a/include/linux/efs_fs.h
+++ b/include/linux/efs_fs.h
@@ -27,6 +27,7 @@
 #define	EFS_BLOCKSIZE_BITS	9
 #define	EFS_BLOCKSIZE		(1 << EFS_BLOCKSIZE_BITS)
 
+#include <linux/fs.h>
 #include <linux/efs_fs_i.h>
 #include <linux/efs_dir.h>
 
diff --git a/include/linux/err.h b/include/linux/err.h
new file mode 100644
index 0000000..92cab64
--- /dev/null
+++ b/include/linux/err.h
@@ -0,0 +1,29 @@
+#ifndef _LINUX_ERR_H
+#define _LINUX_ERR_H
+
+#include <asm/errno.h>
+
+/*
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a dentry
+ * pointer with the same return value.
+ *
+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ */
+static inline void *ERR_PTR(long error)
+{
+	return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+	return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+	return (unsigned long)ptr > (unsigned long)-1000L;
+}
+
+#endif /* _LINUX_ERR_H */
diff --git a/include/linux/file.h b/include/linux/file.h
index 5e006ad..067ca77 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -8,6 +8,7 @@
 #include <asm/atomic.h>
 #include <linux/posix_types.h>
 #include <linux/compiler.h>
+#include <linux/spinlock.h>
 
 /*
  * The default fd array needs to be at least BITS_PER_LONG,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 28027aa..cc874fa 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1257,28 +1257,7 @@
 extern int is_subdir(struct dentry *, struct dentry *);
 extern ino_t find_inode_number(struct dentry *, struct qstr *);
 
-/*
- * Kernel pointers have redundant information, so we can use a
- * scheme where we can return either an error code or a dentry
- * pointer with the same return value.
- *
- * This should be a per-architecture thing, to allow different
- * error and pointer decisions.
- */
-static inline void *ERR_PTR(long error)
-{
-	return (void *) error;
-}
-
-static inline long PTR_ERR(const void *ptr)
-{
-	return (long) ptr;
-}
-
-static inline long IS_ERR(const void *ptr)
-{
-	return (unsigned long)ptr > (unsigned long)-1000L;
-}
+#include <linux/err.h>
 
 /*
  * The bitmask for a lookup event:
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index 3d2df3c..1082b5b 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -2,6 +2,9 @@
 #define _LINUX_FS_STRUCT_H
 #ifdef __KERNEL__
 
+#include <linux/mount.h>
+#include <linux/dcache.h>
+
 struct fs_struct {
 	atomic_t count;
 	rwlock_t lock;
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h
index 1d8b041..5c30fc9 100644
--- a/include/linux/generic_serial.h
+++ b/include/linux/generic_serial.h
@@ -12,9 +12,6 @@
 #ifndef GENERIC_SERIAL_H
 #define GENERIC_SERIAL_H
 
-
-
-
 struct real_driver {
   void                    (*disable_tx_interrupts) (void *);
   void                    (*enable_tx_interrupts) (void *);
@@ -98,7 +95,7 @@
                      struct termios * old_termios);
 int  gs_init_port(struct gs_port *port);
 int  gs_setserial(struct gs_port *port, struct serial_struct *sp);
-void gs_getserial(struct gs_port *port, struct serial_struct *sp);
+int  gs_getserial(struct gs_port *port, struct serial_struct *sp);
 void gs_got_break(struct gs_port *port);
 
 extern int gs_debug;
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 118afad..c7651b4 100644
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/bio.h>
+#include <linux/fs.h>
 #include <asm/pgalloc.h>
 
 #ifdef CONFIG_HIGHMEM
diff --git a/include/linux/in.h b/include/linux/in.h
index 1d5f14a..f41a61d 100644
--- a/include/linux/in.h
+++ b/include/linux/in.h
@@ -19,6 +19,7 @@
 #define _LINUX_IN_H
 
 #include <linux/types.h>
+#include <linux/socket.h>
 
 /* Standard well-defined IP protocols.  */
 enum {
diff --git a/include/linux/inet.h b/include/linux/inet.h
index acb9376..940f320 100644
--- a/include/linux/inet.h
+++ b/include/linux/inet.h
@@ -44,6 +44,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/net.h>
+
 extern void		inet_proto_init(struct net_proto *pro);
 extern char		*in_ntoa(__u32 in);
 extern __u32		in_aton(const char *str);
diff --git a/include/linux/iso_fs_i.h b/include/linux/iso_fs_i.h
index e4fc9d8..01a1ae2 100644
--- a/include/linux/iso_fs_i.h
+++ b/include/linux/iso_fs_i.h
@@ -1,6 +1,8 @@
 #ifndef _ISO_FS_I
 #define _ISO_FS_I
 
+#include <linux/fs.h>
+
 enum isofs_file_format {
 	isofs_file_normal = 0,
 	isofs_file_sparse = 1,
diff --git a/include/linux/lp.h b/include/linux/lp.h
index 9b04225..521bcd2 100644
--- a/include/linux/lp.h
+++ b/include/linux/lp.h
@@ -98,6 +98,9 @@
 
 #ifdef __KERNEL__
 
+#include <linux/wait.h>
+#include <asm/semaphore.h>
+
 /* Magic numbers for defining port-device mappings */
 #define LP_PARPORT_UNSPEC -4
 #define LP_PARPORT_AUTO -3
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ba87022..5377dd7 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -13,6 +13,7 @@
 #include <linux/mmzone.h>
 #include <linux/swap.h>
 #include <linux/rbtree.h>
+#include <linux/fs.h>
 
 extern unsigned long max_mapnr;
 extern unsigned long num_physpages;
diff --git a/include/linux/msdos_fs_i.h b/include/linux/msdos_fs_i.h
index 7b102ea..438afd8 100644
--- a/include/linux/msdos_fs_i.h
+++ b/include/linux/msdos_fs_i.h
@@ -1,6 +1,8 @@
 #ifndef _MSDOS_FS_I
 #define _MSDOS_FS_I
 
+#include <linux/fs.h>
+
 /*
  * MS-DOS file system inode data in memory
  */
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
index 8695e5f..da92ede 100644
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -9,6 +9,8 @@
 	struct rw_semaphore	sem;
 };
 
+void umount_tree(struct vfsmount *mnt);
+
 static inline void put_namespace(struct namespace *namespace)
 {
 	if (atomic_dec_and_test(&namespace->count)) {
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index c22d9f3..0a1df9e 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -13,10 +13,10 @@
 #include <linux/config.h>
 #include <linux/smp_lock.h>
 
-#if defined(CONFIG_QUOTA)
-
 #include <linux/fs.h>
 
+#if defined(CONFIG_QUOTA)
+
 /*
  * declaration of quota_function calls in kernel.
  */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 78a5834..dd6dc69 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -6,7 +6,8 @@
 extern unsigned long event;
 
 #include <linux/config.h>
-#include <linux/binfmts.h>
+#include <linux/capability.h>
+#include <linux/tqueue.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -91,6 +92,7 @@
 #define TASK_UNINTERRUPTIBLE	2
 #define TASK_ZOMBIE		4
 #define TASK_STOPPED		8
+#define PREEMPT_ACTIVE		0x4000000
 
 #define __set_task_state(tsk, state_value)		\
 	do { (tsk)->state = (state_value); } while (0)
@@ -508,15 +510,12 @@
 extern unsigned long volatile jiffies;
 extern unsigned long itimer_ticks;
 extern unsigned long itimer_next;
-extern struct timeval xtime;
 extern void do_timer(struct pt_regs *);
 
 extern unsigned int * prof_buffer;
 extern unsigned long prof_len;
 extern unsigned long prof_shift;
 
-#define CURRENT_TIME (xtime.tv_sec)
-
 extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr));
 extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
 extern void FASTCALL(sleep_on(wait_queue_head_t *q));
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 183b1e4..46b6b67 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -1,22 +1,12 @@
 #ifndef __SHMEM_FS_H
 #define __SHMEM_FS_H
 
+#include <linux/swap.h>
+
 /* inode in-kernel data */
 
 #define SHMEM_NR_DIRECT 16
 
-/*
- * A swap entry has to fit into a "unsigned long", as
- * the entry is hidden in the "index" field of the
- * swapper address space.
- *
- * We have to move it here, since not every user of fs.h is including
- * mm.h, but mm.h is including fs.h via sched .h :-/
- */
-typedef struct {
-	unsigned long val;
-} swp_entry_t;
-
 extern atomic_t shmem_nrpages;
 
 struct shmem_inode_info {
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a1d9d4e..2bec5fa 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -25,6 +25,8 @@
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/poll.h>
+#include <linux/net.h>
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
diff --git a/include/linux/slab.h b/include/linux/slab.h
index ceff350..50cefbb 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -62,11 +62,6 @@
 extern void kfree(const void *);
 
 extern int FASTCALL(kmem_cache_reap(int));
-extern int slabinfo_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data);
-struct file;
-extern int slabinfo_write_proc(struct file *file, const char *buffer,
-			   unsigned long count, void *data);
 
 /* System wide caches */
 extern kmem_cache_t	*vm_area_cachep;
diff --git a/include/linux/smb.h b/include/linux/smb.h
index 9cf2d06..d47f28f 100644
--- a/include/linux/smb.h
+++ b/include/linux/smb.h
@@ -10,6 +10,7 @@
 #define _LINUX_SMB_H
 
 #include <linux/types.h>
+#include <linux/kdev_t.h>
 
 enum smb_protocol { 
 	SMB_PROTOCOL_NONE, 
diff --git a/include/linux/smb_fs_i.h b/include/linux/smb_fs_i.h
index 309e8b9..8516954 100644
--- a/include/linux/smb_fs_i.h
+++ b/include/linux/smb_fs_i.h
@@ -11,6 +11,7 @@
 
 #ifdef __KERNEL__
 #include <linux/types.h>
+#include <linux/fs.h>
 
 /*
  * smb fs inode data (in memory only)
diff --git a/include/linux/smp.h b/include/linux/smp.h
index bb1ff5c..43bef90 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -81,7 +81,9 @@
 #define smp_processor_id()			0
 #define hard_smp_processor_id()			0
 #define smp_threads_ready			1
+#ifndef CONFIG_PREEMPT
 #define kernel_lock()
+#endif
 #define cpu_logical_map(cpu)			0
 #define cpu_number_map(cpu)			0
 #define smp_call_function(func,info,retry,wait)	({ 0; })
diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h
index d1bb038..13d8c7a 100644
--- a/include/linux/smp_lock.h
+++ b/include/linux/smp_lock.h
@@ -3,7 +3,7 @@
 
 #include <linux/config.h>
 
-#ifndef CONFIG_SMP
+#if !defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT)
 
 #define lock_kernel()				do { } while(0)
 #define unlock_kernel()				do { } while(0)
diff --git a/include/linux/sound.h b/include/linux/sound.h
index 18a6733..428f597 100644
--- a/include/linux/sound.h
+++ b/include/linux/sound.h
@@ -3,6 +3,8 @@
  * Minor numbers for the sound driver.
  */
 
+#include <linux/fs.h>
+
 #define SND_DEV_CTL		0	/* Control port /dev/mixer */
 #define SND_DEV_SEQ		1	/* Sequencer output /dev/sequencer (FM
 						synthesizer and MIDI output) */
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index dc27910..6e3ef75 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -2,6 +2,10 @@
 #define __LINUX_SPINLOCK_H
 
 #include <linux/config.h>
+#include <linux/linkage.h>
+#include <linux/compiler.h>
+#include <linux/thread_info.h>
+#include <linux/kernel.h>
 
 /*
  * These are the generic versions of the spinlocks and read-write
@@ -62,8 +66,10 @@
 
 #if (DEBUG_SPINLOCKS < 1)
 
+#ifndef CONFIG_PREEMPT
 #define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
 #define ATOMIC_DEC_AND_LOCK
+#endif
 
 /*
  * Your basic spinlocks, allowing only a single CPU anywhere
@@ -79,11 +85,11 @@
 #endif
 
 #define spin_lock_init(lock)	do { } while(0)
-#define spin_lock(lock)		(void)(lock) /* Not "unused variable". */
+#define _raw_spin_lock(lock)	(void)(lock) /* Not "unused variable". */
 #define spin_is_locked(lock)	(0)
-#define spin_trylock(lock)	({1; })
+#define _raw_spin_trylock(lock)	({1; })
 #define spin_unlock_wait(lock)	do { } while(0)
-#define spin_unlock(lock)	do { } while(0)
+#define _raw_spin_unlock(lock)	do { } while(0)
 
 #elif (DEBUG_SPINLOCKS < 2)
 
@@ -142,13 +148,79 @@
 #endif
 
 #define rwlock_init(lock)	do { } while(0)
-#define read_lock(lock)		(void)(lock) /* Not "unused variable". */
-#define read_unlock(lock)	do { } while(0)
-#define write_lock(lock)	(void)(lock) /* Not "unused variable". */
-#define write_unlock(lock)	do { } while(0)
+#define _raw_read_lock(lock)	(void)(lock) /* Not "unused variable". */
+#define _raw_read_unlock(lock)	do { } while(0)
+#define _raw_write_lock(lock)	(void)(lock) /* Not "unused variable". */
+#define _raw_write_unlock(lock)	do { } while(0)
 
 #endif /* !SMP */
 
+#ifdef CONFIG_PREEMPT
+
+asmlinkage void preempt_schedule(void);
+
+#define preempt_get_count() (current_thread_info()->preempt_count)
+
+#define preempt_disable() \
+do { \
+	++current_thread_info()->preempt_count; \
+	barrier(); \
+} while (0)
+
+#define preempt_enable_no_resched() \
+do { \
+	--current_thread_info()->preempt_count; \
+	barrier(); \
+} while (0)
+
+#define preempt_enable() \
+do { \
+	--current_thread_info()->preempt_count; \
+	barrier(); \
+	if (unlikely(!(current_thread_info()->preempt_count) && \
+		test_thread_flag(TIF_NEED_RESCHED))) \
+			preempt_schedule(); \
+} while (0)
+
+#define spin_lock(lock)	\
+do { \
+	preempt_disable(); \
+	_raw_spin_lock(lock); \
+} while(0)
+
+#define spin_trylock(lock)	({preempt_disable(); _raw_spin_trylock(lock) ? \
+				1 : ({preempt_enable(); 0;});})
+#define spin_unlock(lock) \
+do { \
+	_raw_spin_unlock(lock); \
+	preempt_enable(); \
+} while (0)
+
+#define read_lock(lock)		({preempt_disable(); _raw_read_lock(lock);})
+#define read_unlock(lock)	({_raw_read_unlock(lock); preempt_enable();})
+#define write_lock(lock)	({preempt_disable(); _raw_write_lock(lock);})
+#define write_unlock(lock)	({_raw_write_unlock(lock); preempt_enable();})
+#define write_trylock(lock)	({preempt_disable();_raw_write_trylock(lock) ? \
+				1 : ({preempt_enable(); 0;});})
+
+#else
+
+#define preempt_get_count()	do { } while (0)
+#define preempt_disable()	do { } while (0)
+#define preempt_enable_no_resched()	do {} while(0)
+#define preempt_enable()	do { } while (0)
+
+#define spin_lock(lock)		_raw_spin_lock(lock)
+#define spin_trylock(lock)	_raw_spin_trylock(lock)
+#define spin_unlock(lock)	_raw_spin_unlock(lock)
+
+#define read_lock(lock)		_raw_read_lock(lock)
+#define read_unlock(lock)	_raw_read_unlock(lock)
+#define write_lock(lock)	_raw_write_lock(lock)
+#define write_unlock(lock)	_raw_write_unlock(lock)
+#define write_trylock(lock)	_raw_write_trylock(lock)
+#endif
+
 /* "lock on reference count zero" */
 #ifndef ATOMIC_DEC_AND_LOCK
 #include <asm/atomic.h>
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index fb33c6b..f6439cb 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -14,6 +14,7 @@
 #include <linux/sunrpc/types.h>
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcauth.h>
+#include <linux/wait.h>
 
 /*
  * RPC service.
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index facaddc..69827d8 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -10,6 +10,7 @@
 #ifdef __KERNEL__
 
 #include <linux/uio.h>
+#include <asm/byteorder.h>
 
 /*
  * Buffer adjustment
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 3535d0d..6c149d1 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -2,6 +2,9 @@
 #define _LINUX_SWAP_H
 
 #include <linux/spinlock.h>
+#include <linux/kdev_t.h>
+#include <linux/linkage.h>
+#include <linux/mmzone.h>
 #include <asm/page.h>
 
 #define SWAP_FLAG_PREFER	0x8000	/* set if swap priority specified */
@@ -39,6 +42,14 @@
 	} info;
 };
 
+ /* A swap entry has to fit into a "unsigned long", as
+  * the entry is hidden in the "index" field of the
+  * swapper address space.
+  */
+typedef struct {
+	unsigned long val;
+} swp_entry_t;
+
 #ifdef __KERNEL__
 
 /*
diff --git a/include/linux/time.h b/include/linux/time.h
index 15ba838..e744795 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -82,6 +82,10 @@
 	)*60 + sec; /* finally seconds */
 }
 
+extern struct timeval xtime;
+
+#define CURRENT_TIME (xtime.tv_sec)
+
 #endif /* __KERNEL__ */
 
 
diff --git a/include/linux/timex.h b/include/linux/timex.h
index 3a00a26..b82cbdc 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -51,6 +51,7 @@
 #ifndef _LINUX_TIMEX_H
 #define _LINUX_TIMEX_H
 
+#include <linux/time.h>
 #include <asm/param.h>
 
 /*
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index f87bd85..e08fcf8 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -1,7 +1,6 @@
 #ifndef __LINUX_VMALLOC_H
 #define __LINUX_VMALLOC_H
 
-#include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
 
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 1a60139..bfcc2fa 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -46,6 +46,8 @@
 #include <asm/atomic.h>
 #include <linux/skbuff.h>
 
+#include <linux/err.h>
+
 #define NUD_IN_TIMER	(NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE)
 #define NUD_VALID	(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
 #define NUD_CONNECTED	(NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
diff --git a/include/net/scm.h b/include/net/scm.h
index e26b43f..2147074 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -1,6 +1,8 @@
 #ifndef __LINUX_NET_SCM_H
 #define __LINUX_NET_SCM_H
 
+#include <linux/limits.h>
+
 /* Well, we should have at least one descriptor open
  * to accept passed FDs 8)
  */
diff --git a/include/net/sock.h b/include/net/sock.h
index 77dcd26..898193d 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -301,6 +301,8 @@
 #define SOCK_BINDADDR_LOCK	4
 #define SOCK_BINDPORT_LOCK	8
 
+#include <linux/fs.h>	/* just for inode - yeuch.*/
+
 
 /* Used by processes to "lock" a socket state, so that
  * interrupts and bottom half handlers won't change it
diff --git a/kernel/exit.c b/kernel/exit.c
index 6b5a7cb..2566c5c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -18,6 +18,7 @@
 #include <linux/acct.h>
 #endif
 #include <linux/file.h>
+#include <linux/binfmts.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -390,8 +391,8 @@
 		/* more a memory barrier than a real lock */
 		task_lock(tsk);
 		tsk->mm = NULL;
-		task_unlock(tsk);
 		enter_lazy_tlb(mm, current, smp_processor_id());
+		task_unlock(tsk);
 		mmput(mm);
 	}
 }
diff --git a/kernel/fork.c b/kernel/fork.c
index 3e49ad5..94ccd2a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -22,6 +22,8 @@
 #include <linux/namespace.h>
 #include <linux/personality.h>
 #include <linux/file.h>
+#include <linux/binfmts.h>
+#include <linux/fs.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -650,6 +652,13 @@
 	if (p->binfmt && p->binfmt->module)
 		__MOD_INC_USE_COUNT(p->binfmt->module);
 
+#ifdef CONFIG_PREEMPT
+	/*
+	 * schedule_tail drops this_rq()->lock so we compensate with a count
+	 * of 1.  Also, we want to start with kernel preemption disabled.
+	 */
+	p->thread_info->preempt_count = 1;
+#endif
 	p->did_exec = 0;
 	p->swappable = 0;
 	p->state = TASK_UNINTERRUPTIBLE;
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 57e60f0..3f0b16c 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -47,6 +47,7 @@
 #include <linux/in6.h>
 #include <linux/completion.h>
 #include <linux/seq_file.h>
+#include <linux/binfmts.h>
 #include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
@@ -448,6 +449,9 @@
 EXPORT_SYMBOL(interruptible_sleep_on);
 EXPORT_SYMBOL(interruptible_sleep_on_timeout);
 EXPORT_SYMBOL(schedule);
+#ifdef CONFIG_PREEMPT
+EXPORT_SYMBOL(preempt_schedule);
+#endif
 EXPORT_SYMBOL(schedule_timeout);
 EXPORT_SYMBOL(sys_sched_yield);
 EXPORT_SYMBOL(set_user_nice);
diff --git a/kernel/module.c b/kernel/module.c
index 34bb9ed..d0ed467 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/seq_file.h>
+#include <linux/fs.h>
 
 /*
  * Originally by Anonymous (as far as I know...)
@@ -1074,84 +1075,67 @@
 /*
  * Called by the /proc file system to return a current list of modules.
  */
-
-int get_module_list(char *p)
+static void *m_start(struct seq_file *m, loff_t *pos)
 {
-	size_t left = PAGE_SIZE;
-	struct module *mod;
-	char tmpstr[64];
-	struct module_ref *ref;
-
-	for (mod = module_list; mod != &kernel_module; mod = mod->next) {
-		long len;
-		const char *q;
-
-#define safe_copy_str(str, len)						\
-		do {							\
-			if (left < len)					\
-				goto fini;				\
-			memcpy(p, str, len); p += len, left -= len;	\
-		} while (0)
-#define safe_copy_cstr(str)	safe_copy_str(str, sizeof(str)-1)
-
-		len = strlen(mod->name);
-		safe_copy_str(mod->name, len);
-
-		if ((len = 20 - len) > 0) {
-			if (left < len)
-				goto fini;
-			memset(p, ' ', len);
-			p += len;
-			left -= len;
-		}
-
-		len = sprintf(tmpstr, "%8lu", mod->size);
-		safe_copy_str(tmpstr, len);
-
-		if (mod->flags & MOD_RUNNING) {
-			len = sprintf(tmpstr, "%4ld",
-				      (mod_member_present(mod, can_unload)
-				       && mod->can_unload
-				       ? -1L : (long)atomic_read(&mod->uc.usecount)));
-			safe_copy_str(tmpstr, len);
-		}
-
-		if (mod->flags & MOD_DELETED)
-			safe_copy_cstr(" (deleted)");
-		else if (mod->flags & MOD_RUNNING) {
-			if (mod->flags & MOD_AUTOCLEAN)
-				safe_copy_cstr(" (autoclean)");
-			if (!(mod->flags & MOD_USED_ONCE))
-				safe_copy_cstr(" (unused)");
-		}
-		else if (mod->flags & MOD_INITIALIZING)
-			safe_copy_cstr(" (initializing)");
-		else
-			safe_copy_cstr(" (uninitialized)");
-
-		if ((ref = mod->refs) != NULL) {
-			safe_copy_cstr(" [");
-			while (1) {
-				q = ref->ref->name;
-				len = strlen(q);
-				safe_copy_str(q, len);
-
-				if ((ref = ref->next_ref) != NULL)
-					safe_copy_cstr(" ");
-				else
-					break;
-			}
-			safe_copy_cstr("]");
-		}
-		safe_copy_cstr("\n");
-
-#undef safe_copy_str
-#undef safe_copy_cstr
-	}
-
-fini:
-	return PAGE_SIZE - left;
+	struct module *v;
+	loff_t n = *pos;
+	lock_kernel();
+	for (v = module_list; v && n--; v = v->next)
+		;
+	return v;
 }
+static void *m_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	struct module *v = p;
+	(*pos)++;
+	return v->next;
+}
+static void m_stop(struct seq_file *m, void *p)
+{
+	unlock_kernel();
+}
+static int m_show(struct seq_file *m, void *p)
+{
+	struct module *mod = p;
+	struct module_ref *ref = mod->refs;
+
+	if (mod == &kernel_module)
+		return 0;
+
+	seq_printf(m, "%-20s%8lu", mod->name, mod->size);
+	if (mod->flags & MOD_RUNNING)
+		seq_printf(m, "%4ld",
+			      (mod_member_present(mod, can_unload)
+			       && mod->can_unload
+			       ? -1L : (long)atomic_read(&mod->uc.usecount)));
+
+	if (mod->flags & MOD_DELETED)
+		seq_puts(m, " (deleted)");
+	else if (mod->flags & MOD_RUNNING) {
+		if (mod->flags & MOD_AUTOCLEAN)
+			seq_puts(m, " (autoclean)");
+		if (!(mod->flags & MOD_USED_ONCE))
+			seq_puts(m, " (unused)");
+	} else if (mod->flags & MOD_INITIALIZING)
+		seq_puts(m, " (initializing)");
+	else
+		seq_puts(m, " (uninitialized)");
+	if (ref) {
+		char c;
+		seq_putc(m, ' ');
+		for (c = '[' ; ref; c = ' ', ref = ref->next_ref)
+			seq_printf(m, "%c%s", c, ref->ref->name);
+		seq_putc(m, ']');
+	}
+	seq_putc(m, '\n');
+	return 0;
+}
+struct seq_operations modules_op = {
+	start:	m_start,
+	next:	m_next,
+	stop:	m_stop,
+	show:	m_show
+};
 
 /*
  * Called by the /proc file system to return a current list of ksyms.
diff --git a/kernel/sched.c b/kernel/sched.c
index 6fc59ef..c8b0115 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -18,6 +18,7 @@
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/completion.h>
 #include <asm/mmu_context.h>
 
 #define BITMAP_SIZE ((((MAX_PRIO+7)/8)+sizeof(long)-1)/sizeof(long))
@@ -61,10 +62,12 @@
 	struct runqueue *__rq;
 
 repeat_lock_task:
+	preempt_disable();
 	__rq = task_rq(p);
 	spin_lock_irqsave(&__rq->lock, *flags);
 	if (unlikely(__rq != task_rq(p))) {
 		spin_unlock_irqrestore(&__rq->lock, *flags);
+		preempt_enable();
 		goto repeat_lock_task;
 	}
 	return __rq;
@@ -73,6 +76,7 @@
 static inline void unlock_task_rq(runqueue_t *rq, unsigned long *flags)
 {
 	spin_unlock_irqrestore(&rq->lock, *flags);
+	preempt_enable();
 }
 /*
  * Adding/removing a task to/from a priority array:
@@ -195,6 +199,7 @@
 #ifdef CONFIG_SMP
 	int need_resched, nrpolling;
 
+	preempt_disable();
 	/* minimise the chance of sending an interrupt to poll_idle() */
 	nrpolling = test_tsk_thread_flag(p,TIF_POLLING_NRFLAG);
 	need_resched = test_and_set_tsk_thread_flag(p,TIF_NEED_RESCHED);
@@ -202,6 +207,7 @@
 
 	if (!need_resched && !nrpolling && (p->thread_info->cpu != smp_processor_id()))
 		smp_send_reschedule(p->thread_info->cpu);
+	preempt_enable();
 #else
 	set_tsk_need_resched(p);
 #endif
@@ -219,6 +225,7 @@
 	runqueue_t *rq;
 
 repeat:
+	preempt_disable();
 	rq = task_rq(p);
 	while (unlikely(rq->curr == p)) {
 		cpu_relax();
@@ -227,9 +234,11 @@
 	rq = lock_task_rq(p, &flags);
 	if (unlikely(rq->curr == p)) {
 		unlock_task_rq(rq, &flags);
+		preempt_enable();
 		goto repeat;
 	}
 	unlock_task_rq(rq, &flags);
+	preempt_enable();
 }
 
 /*
@@ -295,7 +304,10 @@
 
 void wake_up_forked_process(task_t * p)
 {
-	runqueue_t *rq = this_rq();
+	runqueue_t *rq;
+	
+	preempt_disable();
+	rq = this_rq();
 
 	p->state = TASK_RUNNING;
 	if (!rt_task(p)) {
@@ -308,6 +320,7 @@
 	p->thread_info->cpu = smp_processor_id();
 	activate_task(p, rq);
 	spin_unlock_irq(&rq->lock);
+	preempt_enable();
 }
 
 asmlinkage void schedule_tail(task_t *prev)
@@ -635,17 +648,31 @@
  */
 asmlinkage void schedule(void)
 {
-	task_t *prev = current, *next;
-	runqueue_t *rq = this_rq();
+	task_t *prev, *next;
+	runqueue_t *rq;
 	prio_array_t *array;
 	list_t *queue;
 	int idx;
 
 	if (unlikely(in_interrupt()))
 		BUG();
+
+	preempt_disable();
+	prev = current;
+	rq = this_rq();
+	
 	release_kernel_lock(prev, smp_processor_id());
 	spin_lock_irq(&rq->lock);
 
+#ifdef CONFIG_PREEMPT
+	/*
+	 * if entering from preempt_schedule, off a kernel preemption,
+	 * go straight to picking the next task.
+	 */
+	if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
+		goto pick_next_task;
+#endif
+	
 	switch (prev->state) {
 	case TASK_RUNNING:
 		prev->sleep_timestamp = jiffies;
@@ -659,7 +686,7 @@
 	default:
 		deactivate_task(prev, rq);
 	}
-#if CONFIG_SMP
+#if CONFIG_SMP || CONFIG_PREEMPT
 pick_next_task:
 #endif
 	if (unlikely(!rq->nr_running)) {
@@ -707,9 +734,25 @@
 	spin_unlock_irq(&rq->lock);
 
 	reacquire_kernel_lock(current);
+	preempt_enable_no_resched();
 	return;
 }
 
+#ifdef CONFIG_PREEMPT
+/*
+ * this is is the entry point to schedule() from in-kernel preemption.
+ */
+asmlinkage void preempt_schedule(void)
+{
+	do {
+		current_thread_info()->preempt_count += PREEMPT_ACTIVE;
+		schedule();
+		current_thread_info()->preempt_count -= PREEMPT_ACTIVE;
+		barrier();
+	} while (test_thread_flag(TIF_NEED_RESCHED));
+}
+#endif /* CONFIG_PREEMPT */
+
 /*
  * The core wakeup function.  Non-exclusive wakeups (nr_exclusive == 0) just
  * wake everything up.  If it's an exclusive wakeup (nr_exclusive == small +ve
@@ -1105,9 +1148,12 @@
 
 asmlinkage long sys_sched_yield(void)
 {
-	runqueue_t *rq = this_rq();
+	runqueue_t *rq;
 	prio_array_t *array;
 
+	preempt_disable();
+	rq = this_rq();
+
 	/*
 	 * Decrease the yielding task's priority by one, to avoid
 	 * livelocks. This priority loss is temporary, it's recovered
@@ -1134,6 +1180,7 @@
 		__set_bit(current->prio, array->bitmap);
 	}
 	spin_unlock(&rq->lock);
+	preempt_enable_no_resched();
 
 	schedule();
 
diff --git a/kernel/signal.c b/kernel/signal.c
index 74d7835..78a9be2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -13,6 +13,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/sched.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 
diff --git a/kernel/sys.c b/kernel/sys.c
index 21c21ca..15e7e34 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -14,6 +14,7 @@
 #include <linux/prctl.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff --git a/kernel/time.c b/kernel/time.c
index 461a87d..8c5450d 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -24,7 +24,6 @@
  *	(Even though the technical memorandum forbids it)
  */
 
-#include <linux/mm.h>
 #include <linux/timex.h>
 #include <linux/smp_lock.h>
 
diff --git a/mm/filemap.c b/mm/filemap.c
index 7fdfbdf..16b924b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -24,6 +24,7 @@
 #include <linux/mm.h>
 #include <linux/iobuf.h>
 #include <linux/compiler.h>
+#include <linux/fs.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 895ba46..d6cd10d 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -8,6 +8,7 @@
 #include <linux/smp_lock.h>
 #include <linux/shm.h>
 #include <linux/mman.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
diff --git a/mm/mremap.c b/mm/mremap.c
index 0a42e05..055cdfa 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -10,6 +10,7 @@
 #include <linux/shm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
diff --git a/mm/slab.c b/mm/slab.c
index 9835c23..dfa8401 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -49,7 +49,8 @@
  *  constructors and destructors are called without any locking.
  *  Several members in kmem_cache_t and slab_t never change, they
  *	are accessed without any locking.
- *  The per-cpu arrays are never accessed from the wrong cpu, no locking.
+ *  The per-cpu arrays are never accessed from the wrong cpu, no locking,
+ *  	and local interrupts are disabled so slab code is preempt-safe.
  *  The non-constant members are protected with a per-cache irq spinlock.
  *
  * Further notes from the original documentation:
@@ -75,6 +76,7 @@
 #include	<linux/interrupt.h>
 #include	<linux/init.h>
 #include	<linux/compiler.h>
+#include	<linux/seq_file.h>
 #include	<asm/uaccess.h>
 
 /*
@@ -1869,31 +1871,56 @@
 }
 
 #ifdef CONFIG_PROC_FS
-/* /proc/slabinfo
- *	cache-name num-active-objs total-objs
- *	obj-size num-active-slabs total-slabs
- *	num-pages-per-slab
- */
-#define FIXUP(t)				\
-	do {					\
-		if (len <= off) {		\
-			off -= len;		\
-			len = 0;		\
-		} else {			\
-			if (len-off > count)	\
-				goto t;		\
-		}				\
-	} while (0)
 
-static int proc_getdata (char*page, char**start, off_t off, int count)
+static void *s_start(struct seq_file *m, loff_t *pos)
 {
+	loff_t n = *pos;
 	struct list_head *p;
-	int len = 0;
 
-	/* Output format version, so at least we can change it without _too_
-	 * many complaints.
-	 */
-	len += sprintf(page+len, "slabinfo - version: 1.1"
+	down(&cache_chain_sem);
+	if (!n)
+		return (void *)1;
+	p = &cache_cache.next;
+	while (--n) {
+		p = p->next;
+		if (p == &cache_cache.next)
+			return NULL;
+	}
+	return list_entry(p, kmem_cache_t, next);
+}
+
+static void *s_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	kmem_cache_t *cachep = p;
+	++*pos;
+	if (p == (void *)1)
+		return &cache_cache;
+	cachep = list_entry(cachep->next.next, kmem_cache_t, next);
+	return cachep == &cache_cache ? NULL : cachep;
+}
+
+static void s_stop(struct seq_file *m, void *p)
+{
+	up(&cache_chain_sem);
+}
+
+static int s_show(struct seq_file *m, void *p)
+{
+	kmem_cache_t *cachep = p;
+	struct list_head *q;
+	slab_t		*slabp;
+	unsigned long	active_objs;
+	unsigned long	num_objs;
+	unsigned long	active_slabs = 0;
+	unsigned long	num_slabs;
+	const char *name; 
+
+	if (p == (void*)1) {
+		/*
+		 * Output format version, so at least we can change it
+		 * without _too_ many complaints.
+		 */
+		seq_puts(m, "slabinfo - version: 1.1"
 #if STATS
 				" (statistics)"
 #endif
@@ -1901,116 +1928,89 @@
 				" (SMP)"
 #endif
 				"\n");
-	FIXUP(got_data);
+		return 0;
+	}
 
-	down(&cache_chain_sem);
-	p = &cache_cache.next;
-	do {
-		kmem_cache_t	*cachep;
-		struct list_head *q;
-		slab_t		*slabp;
-		unsigned long	active_objs;
-		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);
+	active_objs = 0;
+	num_slabs = 0;
+	list_for_each(q,&cachep->slabs_full) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse != cachep->num)
+			BUG();
+		active_objs += cachep->num;
+		active_slabs++;
+	}
+	list_for_each(q,&cachep->slabs_partial) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse == cachep->num || !slabp->inuse)
+			BUG();
+		active_objs += slabp->inuse;
+		active_slabs++;
+	}
+	list_for_each(q,&cachep->slabs_free) {
+		slabp = list_entry(q, slab_t, list);
+		if (slabp->inuse)
+			BUG();
+		num_slabs++;
+	}
+	num_slabs+=active_slabs;
+	num_objs = num_slabs*cachep->num;
 
-		spin_lock_irq(&cachep->spinlock);
-		active_objs = 0;
-		num_slabs = 0;
-		list_for_each(q,&cachep->slabs_full) {
-			slabp = list_entry(q, slab_t, list);
-			if (slabp->inuse != cachep->num)
-				BUG();
-			active_objs += cachep->num;
-			active_slabs++;
-		}
-		list_for_each(q,&cachep->slabs_partial) {
-			slabp = list_entry(q, slab_t, list);
-			if (slabp->inuse == cachep->num || !slabp->inuse)
-				BUG();
-			active_objs += slabp->inuse;
-			active_slabs++;
-		}
-		list_for_each(q,&cachep->slabs_free) {
-			slabp = list_entry(q, slab_t, list);
-			if (slabp->inuse)
-				BUG();
-			num_slabs++;
-		}
-		num_slabs+=active_slabs;
-		num_objs = num_slabs*cachep->num;
+	name = cachep->name; 
+	{
+	char tmp; 
+	if (__get_user(tmp, name)) 
+		name = "broken"; 
+	} 	
 
-		name = cachep->name; 
-		{
-		char tmp; 
-		if (__get_user(tmp, name)) 
-			name = "broken"; 
-		} 	
-
-		len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
-			name, active_objs, num_objs, cachep->objsize,
-			active_slabs, num_slabs, (1<<cachep->gfporder));
+	seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
+		name, active_objs, num_objs, cachep->objsize,
+		active_slabs, num_slabs, (1<<cachep->gfporder));
 
 #if STATS
-		{
-			unsigned long errors = cachep->errors;
-			unsigned long high = cachep->high_mark;
-			unsigned long grown = cachep->grown;
-			unsigned long reaped = cachep->reaped;
-			unsigned long allocs = cachep->num_allocations;
+	{
+		unsigned long errors = cachep->errors;
+		unsigned long high = cachep->high_mark;
+		unsigned long grown = cachep->grown;
+		unsigned long reaped = cachep->reaped;
+		unsigned long allocs = cachep->num_allocations;
 
-			len += sprintf(page+len, " : %6lu %7lu %5lu %4lu %4lu",
-					high, allocs, grown, reaped, errors);
-		}
+		seq_printf(m, " : %6lu %7lu %5lu %4lu %4lu",
+				high, allocs, grown, reaped, errors);
+	}
 #endif
 #ifdef CONFIG_SMP
-		{
-			unsigned int batchcount = cachep->batchcount;
-			unsigned int limit;
+	{
+		unsigned int batchcount = cachep->batchcount;
+		unsigned int limit;
 
-			if (cc_data(cachep))
-				limit = cc_data(cachep)->limit;
-			 else
-				limit = 0;
-			len += sprintf(page+len, " : %4u %4u",
-					limit, batchcount);
-		}
+		if (cc_data(cachep))
+			limit = cc_data(cachep)->limit;
+		 else
+			limit = 0;
+		seq_printf(m, " : %4u %4u", limit, batchcount);
+	}
 #endif
 #if STATS && defined(CONFIG_SMP)
-		{
-			unsigned long allochit = atomic_read(&cachep->allochit);
-			unsigned long allocmiss = atomic_read(&cachep->allocmiss);
-			unsigned long freehit = atomic_read(&cachep->freehit);
-			unsigned long freemiss = atomic_read(&cachep->freemiss);
-			len += sprintf(page+len, " : %6lu %6lu %6lu %6lu",
-					allochit, allocmiss, freehit, freemiss);
-		}
+	{
+		unsigned long allochit = atomic_read(&cachep->allochit);
+		unsigned long allocmiss = atomic_read(&cachep->allocmiss);
+		unsigned long freehit = atomic_read(&cachep->freehit);
+		unsigned long freemiss = atomic_read(&cachep->freemiss);
+		seq_printf(m, " : %6lu %6lu %6lu %6lu",
+				allochit, allocmiss, freehit, freemiss);
+	}
 #endif
-		len += sprintf(page+len,"\n");
-		spin_unlock_irq(&cachep->spinlock);
-		FIXUP(got_data_up);
-		p = cachep->next.next;
-	} while (p != &cache_cache.next);
-got_data_up:
-	up(&cache_chain_sem);
-
-got_data:
-	*start = page+off;
-	return len;
+	spin_unlock_irq(&cachep->spinlock);
+	seq_putc(m, '\n');
+	return 0;
 }
 
 /**
- * slabinfo_read_proc - generates /proc/slabinfo
- * @page: scratch area, one page long
- * @start: pointer to the pointer to the output buffer
- * @off: offset within /proc/slabinfo the caller is interested in
- * @count: requested len in bytes
- * @eof: eof marker
- * @data: unused
+ * slabinfo_op - iterator that generates /proc/slabinfo
  *
- * The contents of the buffer are
+ * Output layout:
  * cache-name
  * num-active-objs
  * total-objs
@@ -2020,28 +2020,24 @@
  * num-pages-per-slab
  * + further values on SMP and with statistics enabled
  */
-int slabinfo_read_proc (char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = proc_getdata(page, start, off, count);
-	len -= (*start-page);
-	if (len <= count)
-		*eof = 1;
-	if (len>count) len = count;
-	if (len<0) len = 0;
-	return len;
-}
+
+struct seq_operations slabinfo_op = {
+	start:	s_start,
+	next:	s_next,
+	stop:	s_stop,
+	show:	s_show
+};
 
 #define MAX_SLABINFO_WRITE 128
 /**
- * slabinfo_write_proc - SMP tuning for the slab allocator
+ * slabinfo_write - SMP tuning for the slab allocator
  * @file: unused
  * @buffer: user buffer
  * @count: data len
  * @data: unused
  */
-int slabinfo_write_proc (struct file *file, const char *buffer,
-				unsigned long count, void *data)
+ssize_t slabinfo_write(struct file *file, const char *buffer,
+				size_t count, loff_t *ppos)
 {
 #ifdef CONFIG_SMP
 	char kbuf[MAX_SLABINFO_WRITE+1], *tmp;
diff --git a/net/socket.c b/net/socket.c
index 2965aa8..588328c 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -132,7 +132,7 @@
 
 static struct net_proto_family *net_families[NPROTO];
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 static atomic_t net_family_lockct = ATOMIC_INIT(0);
 static spinlock_t net_family_lock = SPIN_LOCK_UNLOCKED;
 
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 42813ac..3b0c400 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -15,6 +15,7 @@
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/svcauth.h>
 #include <linux/sunrpc/svcsock.h>
+#include <linux/err.h>
 
 #define RPCDBG_FACILITY	RPCDBG_AUTH