diff -u --recursive --new-file v2.1.118/linux/CREDITS linux/CREDITS
--- v2.1.118/linux/CREDITS	Wed Aug 26 11:37:32 1998
+++ linux/CREDITS	Thu Aug 27 12:00:25 1998
@@ -68,6 +68,7 @@
 D: Implemented a workaround for some interrupt buggy printers
 D: Author of pscan that helps to fix lp/parport bug
 D: Author of lil (Linux Interrupt Latency benchmark)
+D: Fixed the shm swap deallocation at swapoff time (try_to_unuse message)
 D: Various other kernel hacks
 S: Via Ciaclini 26
 S: Imola 40026
@@ -288,8 +289,8 @@
 E: chaffee@cs.berkeley.edu
 W: http://bmrc.berkeley.edu/people/chaffee/
 D: vfat, fat32, joliet, native language support
-S: 3674 Oakwood Terrace #201
-S: Fremont, California 94536
+S: 3700 Warwick Road
+S: Fremont, California 94555
 S: USA
 
 N: Chih-Jen Chang
@@ -708,8 +709,8 @@
 E: rth@cygnus.com
 E: richard@gnu.org
 D: Alpha/ELF, gcc, binutils, and glibc
-S: 50 E. Middlefield #10
-S: Mountain View, California 94043-3822
+S: 5450 Mayme #25
+S: San Jose, California 95129
 S: USA
 
 N: Sebastian Hetze
diff -u --recursive --new-file v2.1.118/linux/Documentation/Changes linux/Documentation/Changes
--- v2.1.118/linux/Documentation/Changes	Wed Jun 24 22:54:01 1998
+++ linux/Documentation/Changes	Thu Aug 27 12:01:47 1998
@@ -190,12 +190,6 @@
 of /proc/net/dev changed; as a result, an older ifconfig will
 incorrectly report errors.
 
-   As of 2.1.102, the firewalling code has been replaced with
-firewalling chains.  See
-http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html for
-more information.  Among other things, you'll now need to use ipchains
-instead of ipfwadm to configure your filters.
-
    The IP firewalling code has been replaced: ipfwadm will no longer
 work.  You need to obtain `ipchains', available from
 http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html
diff -u --recursive --new-file v2.1.118/linux/Makefile linux/Makefile
--- v2.1.118/linux/Makefile	Wed Aug 26 11:37:33 1998
+++ linux/Makefile	Thu Aug 27 11:45:04 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 118
+SUBLEVEL = 119
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -73,6 +73,12 @@
 #INSTALL_PATH=/boot
 
 #
+# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory 
+# relocations required by build roots.  This is not defined in the
+# makefile but the arguement can be passed to make if needed.
+#
+
+#
 # If you want to preset the SVGA mode, uncomment the next line and
 # set SVGA_MODE to whatever number you want.
 # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
@@ -289,7 +295,7 @@
 
 modules_install:
 	@( \
-	MODLIB=/lib/modules/$(VERSION).$(PATCHLEVEL).$(SUBLEVEL); \
+	MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(VERSION).$(PATCHLEVEL).$(SUBLEVEL); \
 	cd modules; \
 	MODULES=""; \
 	inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
diff -u --recursive --new-file v2.1.118/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.118/linux/arch/i386/kernel/irq.c	Thu Aug  6 14:06:28 1998
+++ linux/arch/i386/kernel/irq.c	Wed Aug 26 15:40:08 1998
@@ -450,12 +450,12 @@
  * no other CPU is executing any bottom half handler.
  *
  * Don't wait if we're already running in an interrupt
- * context or are inside a bh handler.
+ * context or are inside a bh handler. 
  */
 void synchronize_bh(void)
 {
 	if (atomic_read(&global_bh_count) && !in_interrupt())
-			wait_on_bh();
+		wait_on_bh();
 }
 
 /*
diff -u --recursive --new-file v2.1.118/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.1.118/linux/arch/i386/kernel/smp.c	Tue Aug 18 22:02:02 1998
+++ linux/arch/i386/kernel/smp.c	Wed Aug 26 10:00:31 1998
@@ -245,7 +245,7 @@
 {
 	char str[16];
 	int count=sizeof(*mpc);
-	int apics=0;
+	int ioapics = 0;
 	unsigned char *mpt=((unsigned char *)mpc)+count;
 
 	if(memcmp(mpc->mpc_signature,MPC_SIGNATURE,4))
@@ -364,11 +364,15 @@
 					(struct mpc_config_ioapic *)mpt;
 				if(m->mpc_flags&MPC_APIC_USABLE)
 				{
-					apics++;
+					ioapics++;
 					printk("I/O APIC #%d Version %d at 0x%lX.\n",
 						m->mpc_apicid,m->mpc_apicver,
 						m->mpc_apicaddr);
-					mp_ioapic_addr = m->mpc_apicaddr;
+					/*
+					 * we use the first one only currently
+					 */
+					if (!ioapics)
+						mp_ioapic_addr = m->mpc_apicaddr;
 				}
 				mpt+=sizeof(*m);
 				count+=sizeof(*m);
@@ -400,8 +404,8 @@
 			}
 		}
 	}
-	if(apics>1)
-		printk("Warning: Multiple APICs not supported.\n");
+	if (ioapics > 1)
+		printk("Warning: Multiple IO-APICs not yet supported.\n");
 	return num_processors;
 }
 
diff -u --recursive --new-file v2.1.118/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- v2.1.118/linux/arch/ppc/kernel/pmac_setup.c	Thu Aug  6 14:06:29 1998
+++ linux/arch/ppc/kernel/pmac_setup.c	Thu Aug 27 11:03:56 1998
@@ -44,7 +44,6 @@
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
-#include <asm/ide.h>
 #include <asm/pci-bridge.h>
 #include <asm/adb.h>
 #include <asm/cuda.h>
@@ -272,95 +271,4 @@
 		printk(" (root)");
 	}
 }
-
-#ifdef CONFIG_BLK_DEV_IDE
-int pmac_ide_ports_known;
-ide_ioreg_t pmac_ide_regbase[MAX_HWIFS];
-int pmac_ide_irq[MAX_HWIFS];
-
-__initfunc(void pmac_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq))
-{
-	int i;
-
-	*p = 0;
-	if (base == 0)
-		return;
-	if (base == mb_cd_base && !check_media_bay(MB_CD)) {
-		mb_cd_index = -1;
-		return;
-	}
-	for (i = 0; i < 8; ++i)
-		*p++ = base + i * 0x10;
-	*p = base + 0x160;
-	if (irq != NULL) {
-		*irq = 0;
-		for (i = 0; i < MAX_HWIFS; ++i) {
-			if (base == pmac_ide_regbase[i]) {
-				*irq = pmac_ide_irq[i];
-				break;
-			}
-		}
-	}
-}
-
-__initfunc(void pmac_ide_probe(void))
-{
-	struct device_node *np;
-	int i;
-	struct device_node *atas;
-	struct device_node *p, **pp, *removables, **rp;
-
-	pp = &atas;
-	rp = &removables;
-	p = find_devices("ATA");
-	if (p == NULL)
-		p = find_devices("IDE");
-	if (p == NULL)
-		p = find_type_devices("ide");
-	if (p == NULL)
-		p = find_type_devices("ata");
-	/* Move removable devices such as the media-bay CDROM
-	   on the PB3400 to the end of the list. */
-	for (; p != NULL; p = p->next) {
-		if (p->parent && p->parent->name
-		    && strcasecmp(p->parent->name, "media-bay") == 0) {
-			*rp = p;
-			rp = &p->next;
-		} else {
-			*pp = p;
-			pp = &p->next;
-		}
-	}
-	*rp = NULL;
-	*pp = removables;
-
-	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
-		if (np->n_addrs == 0) {
-			printk(KERN_WARNING "ide: no address for device %s\n",
-			       np->full_name);
-			continue;
-		}
-		pmac_ide_regbase[i] = (unsigned long)
-			ioremap(np->addrs[0].address, 0x200);
-		if (np->n_intrs == 0) {
-			printk("ide: no intrs for device %s, using 13\n",
-			       np->full_name);
-			pmac_ide_irq[i] = 13;
-		} else {
-			pmac_ide_irq[i] = np->intrs[0].line;
-		}
-
-		if (np->parent && np->parent->name
-		    && strcasecmp(np->parent->name, "media-bay") == 0) {
-			mb_cd_index = i;
-			mb_cd_base = pmac_ide_regbase[i];
-			mb_cd_irq = pmac_ide_irq[i];
-		}
-
-		++i;
-	}
-
-	pmac_ide_ports_known = 1;
-}
-#endif /* CONFIG_BLK_DEV_IDE */
 
diff -u --recursive --new-file v2.1.118/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.1.118/linux/drivers/block/Config.in	Tue Aug 18 22:02:03 1998
+++ linux/drivers/block/Config.in	Thu Aug 27 11:03:56 1998
@@ -48,6 +48,14 @@
           bool '   WInbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
       fi
     fi
+    if [ "$CONFIG_PMAC" = "y" ]; then
+      define_bool CONFIG_BLK_DEV_IDE_PMAC y
+      bool '   PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC
+      if [ "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" ]; then
+        define_bool CONFIG_BLK_DEV_IDEDMA y
+	bool '     Use DMA by default' CONFIG_PMAC_IDEDMA_AUTO
+      fi
+    fi
     bool '   Other IDE chipset support' CONFIG_IDE_CHIPSETS
     if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
       comment 'Note: most of these also require special kernel boot parameters'
diff -u --recursive --new-file v2.1.118/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v2.1.118/linux/drivers/block/Makefile	Wed Aug 26 11:37:34 1998
+++ linux/drivers/block/Makefile	Thu Aug 27 11:03:56 1998
@@ -106,6 +106,10 @@
 IDE_OBJS += cmd640.o
 endif
 
+ifeq ($(CONFIG_BLK_DEV_IDE_PMAC),y)
+IDE_OBJS += ide-pmac.o
+endif
+
 ifeq ($(CONFIG_BLK_DEV_IDEPCI),y)
 IDE_OBJS += ide-pci.o
 endif
diff -u --recursive --new-file v2.1.118/linux/drivers/block/ide-pmac.c linux/drivers/block/ide-pmac.c
--- v2.1.118/linux/drivers/block/ide-pmac.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/ide-pmac.c	Thu Aug 27 11:03:56 1998
@@ -0,0 +1,298 @@
+/*
+ * Support for IDE interfaces on PowerMacs.
+ * These IDE interfaces are memory-mapped and have a DBDMA channel
+ * for doing DMA.
+ *
+ *  Copyright (C) 1998 Paul Mackerras.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ * Some code taken from drivers/block/ide-dma.c:
+ *
+ *  Copyright (c) 1995-1998  Mark Lord
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/dbdma.h>
+#include <asm/ide.h>
+#include <asm/mediabay.h>
+#include "ide.h"
+
+ide_ioreg_t pmac_ide_regbase[MAX_HWIFS];
+int pmac_ide_irq[MAX_HWIFS];
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+#define MAX_DCMDS	256	/* allow up to 256 DBDMA commands per xfer */
+
+static void pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif);
+static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
+static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr);
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+
+__initfunc(void
+pmac_ide_init_hwif_ports(ide_ioreg_t *p, ide_ioreg_t base, int *irq))
+{
+	int i;
+
+	*p = 0;
+	if (base == 0)
+		return;
+	if (base == mb_cd_base && !check_media_bay(MB_CD)) {
+		mb_cd_index = -1;
+		return;
+	}
+	for (i = 0; i < 8; ++i)
+		*p++ = base + i * 0x10;
+	*p = base + 0x160;
+	if (irq != NULL) {
+		*irq = 0;
+		for (i = 0; i < MAX_HWIFS; ++i) {
+			if (base == pmac_ide_regbase[i]) {
+				*irq = pmac_ide_irq[i];
+				break;
+			}
+		}
+	}
+}
+
+__initfunc(void
+pmac_ide_probe(void))
+{
+	struct device_node *np;
+	int i;
+	struct device_node *atas;
+	struct device_node *p, **pp, *removables, **rp;
+	unsigned long base;
+	int irq;
+	ide_hwif_t *hwif;
+
+	if (_machine != _MACH_Pmac)
+		return;
+	pp = &atas;
+	rp = &removables;
+	p = find_devices("ATA");
+	if (p == NULL)
+		p = find_devices("IDE");
+	if (p == NULL)
+		p = find_type_devices("ide");
+	if (p == NULL)
+		p = find_type_devices("ata");
+	/* Move removable devices such as the media-bay CDROM
+	   on the PB3400 to the end of the list. */
+	for (; p != NULL; p = p->next) {
+		if (p->parent && p->parent->name
+		    && strcasecmp(p->parent->name, "media-bay") == 0) {
+			*rp = p;
+			rp = &p->next;
+		} else {
+			*pp = p;
+			pp = &p->next;
+		}
+	}
+	*rp = NULL;
+	*pp = removables;
+
+	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
+		if (np->n_addrs == 0) {
+			printk(KERN_WARNING "ide: no address for device %s\n",
+			       np->full_name);
+			continue;
+		}
+		base = (unsigned long) ioremap(np->addrs[0].address, 0x200);
+		if (np->n_intrs == 0) {
+			printk("ide: no intrs for device %s, using 13\n",
+			       np->full_name);
+			irq = 13;
+		} else {
+			irq = np->intrs[0].line;
+		}
+		pmac_ide_regbase[i] = base;
+		pmac_ide_irq[i] = irq;
+
+		if (np->parent && np->parent->name
+		    && strcasecmp(np->parent->name, "media-bay") == 0) {
+			mb_cd_index = i;
+			mb_cd_base = base;
+			mb_cd_irq = irq;
+		}
+
+		hwif = &ide_hwifs[i];
+		pmac_ide_init_hwif_ports(hwif->io_ports, base, &hwif->irq);
+		hwif->chipset = ide_generic;
+		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+		if (np->n_addrs >= 2 && np->n_intrs >= 2) {
+			/* has a DBDMA controller channel */
+			pmac_ide_setup_dma(np, hwif);
+		}
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+
+		++i;
+	}
+}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+
+__initfunc(static void
+pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif))
+{
+	hwif->dma_base = (unsigned long) ioremap(np->addrs[1].address, 0x200);
+
+	/*
+	 * Allocate space for the DBDMA commands.
+	 * The +2 is +1 for the stop command and +1 to allow for
+	 * aligning the start address to a multiple of 16 bytes.
+	 */
+	hwif->dmatable = (unsigned long *)
+	       kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);
+	if (hwif->dmatable == 0) {
+		printk(KERN_ERR "%s: unable to allocate DMA command list\n",
+		       hwif->name);
+		return;
+	}
+
+	hwif->dmaproc = &pmac_ide_dmaproc;
+#ifdef CONFIG_PMAC_IDEDMA_AUTO
+	hwif->autodma = 1;
+#endif
+}
+
+/*
+ * pmac_ide_build_dmatable builds the DBDMA command list
+ * for a transfer and sets the DBDMA channel to point to it.
+ */
+static int
+pmac_ide_build_dmatable(ide_drive_t *drive, int wr)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	struct dbdma_cmd *table, *tstart;
+	int count = 0;
+	struct request *rq = HWGROUP(drive)->rq;
+	struct buffer_head *bh = rq->bh;
+	unsigned int size, addr;
+	volatile struct dbdma_regs *dma
+		= (volatile struct dbdma_regs *) hwif->dma_base;
+
+	table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable);
+	out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
+
+	do {
+		/*
+		 * Determine addr and size of next buffer area.  We assume that
+		 * individual virtual buffers are always composed linearly in
+		 * physical memory.  For example, we assume that any 8kB buffer
+		 * is always composed of two adjacent physical 4kB pages rather
+		 * than two possibly non-adjacent physical 4kB pages.
+		 */
+		if (bh == NULL) {  /* paging requests have (rq->bh == NULL) */
+			addr = virt_to_bus(rq->buffer);
+			size = rq->nr_sectors << 9;
+		} else {
+			/* group sequential buffers into one large buffer */
+			addr = virt_to_bus(bh->b_data);
+			size = bh->b_size;
+			while ((bh = bh->b_reqnext) != NULL) {
+				if ((addr + size) != virt_to_bus(bh->b_data))
+					break;
+				size += bh->b_size;
+			}
+		}
+
+		/*
+		 * Fill in the next DBDMA command block.
+		 * Note that one DBDMA command can transfer
+		 * at most 65535 bytes.
+		 */
+		while (size) {
+			unsigned int tc = (size < 0xfe00)? size: 0xfe00;
+
+			if (++count >= MAX_DCMDS) {
+				printk("%s: DMA table too small\n",
+				       drive->name);
+				return 0; /* revert to PIO for this request */
+			}
+			st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
+			st_le16(&table->req_count, tc);
+			st_le32(&table->phy_addr, addr);
+			table->cmd_dep = 0;
+			table->xfer_status = 0;
+			table->res_count = 0;
+			addr += tc;
+			size -= tc;
+			++table;
+		}
+	} while (bh != NULL);
+
+	/* convert the last command to an input/output last command */
+	if (count)
+		st_le16(&table[-1].command, wr? OUTPUT_LAST: INPUT_LAST);
+	else
+		printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
+
+	/* add the stop command to the end of the list */
+	memset(table, 0, sizeof(struct dbdma_cmd));
+	out_le16(&table->command, DBDMA_STOP);
+
+	out_le32(&dma->cmdptr, virt_to_bus(tstart));
+	return 1;
+}
+
+int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	volatile struct dbdma_regs *dma
+		= (volatile struct dbdma_regs *) hwif->dma_base;
+	int dstat;
+
+	switch (func) {
+	case ide_dma_on:
+		/* ide-floppy DMA doesn't work yet... */
+		drive->using_dma = drive->media != ide_floppy;
+		break;
+	case ide_dma_off:
+		printk(KERN_INFO "%s: DMA disabled\n", drive->name);
+	case ide_dma_off_quietly:
+		drive->using_dma = 0;
+		break;
+	case ide_dma_check:
+		/* ide-floppy DMA doesn't work yet... */
+		drive->using_dma = hwif->autodma && drive->media != ide_floppy;
+		break;
+	case ide_dma_read:
+	case ide_dma_write:
+		if (!pmac_ide_build_dmatable(drive, func==ide_dma_write))
+			return 1;
+		drive->waiting_for_dma = 1;
+		if (drive->media != ide_disk)
+			return 0;
+		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
+		OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
+			 IDE_COMMAND_REG);
+	case ide_dma_begin:
+		out_le32(&dma->control, (RUN << 16) | RUN);
+		break;
+	case ide_dma_end:
+		drive->waiting_for_dma = 0;
+		dstat = in_le32(&dma->status);
+		out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
+		/* verify good dma status */
+		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
+	case ide_dma_test_irq:
+		return (in_le32(&dma->status) & (RUN|ACTIVE)) == RUN;
+	default:
+		printk(KERN_ERR "pmac_ide_dmaproc: bad func %d\n", func);
+	}
+	return 0;
+}
+
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
diff -u --recursive --new-file v2.1.118/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.1.118/linux/drivers/block/ide.c	Wed Aug 26 11:37:35 1998
+++ linux/drivers/block/ide.c	Thu Aug 27 11:03:56 1998
@@ -1104,8 +1104,7 @@
 			if (sleep) {
 				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) 
 					sleep = jiffies + WAIT_MIN_SLEEP;
-				hwgroup->timer.expires = sleep;
-				add_timer(&hwgroup->timer);
+				mod_timer(&hwgroup->timer, sleep);
 			} else {
 				/* Ugly, but how can we sleep for the lock otherwise? perhaps from tq_scheduler? */
 				ide_release_lock(&ide_lock);	/* for atari only */
@@ -2638,6 +2637,12 @@
 		(void) init_pdc4030();
 	}
 #endif /* CONFIG_BLK_DEV_PDC4030 */
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+	{
+		extern void pmac_ide_probe(void);
+		pmac_ide_probe();
+	}
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
 }
 
 __initfunc(void ide_init_builtin_drivers (void))
diff -u --recursive --new-file v2.1.118/linux/drivers/block/nbd.c linux/drivers/block/nbd.c
--- v2.1.118/linux/drivers/block/nbd.c	Wed Aug 26 11:37:35 1998
+++ linux/drivers/block/nbd.c	Thu Aug 27 11:52:04 1998
@@ -81,9 +81,18 @@
 	int result;
 	struct msghdr msg;
 	struct iovec iov;
+	unsigned long flags;
 
 	oldfs = get_fs();
 	set_fs(get_ds());
+
+	spin_lock_irqsave(&current->sigmask_lock, flags);
+	oldset = current->blocked;
+	sigfillset(&current->blocked);
+	recalc_sigpending(current);
+	spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
+
 	do {
 		sigset_t oldset;
 
@@ -98,22 +107,11 @@
 		msg.msg_namelen = 0;
 		msg.msg_flags = 0;
 
-		spin_lock_irq(&current->sigmask_lock);
-		oldset = current->blocked;
-		sigfillset(&current->blocked);
-		recalc_sigpending(current);
-		spin_unlock_irq(&current->sigmask_lock);
-
 		if (send)
 			result = sock_sendmsg(sock, &msg, size);
 		else
 			result = sock_recvmsg(sock, &msg, size, 0);
 
-		spin_lock_irq(&current->sigmask_lock);
-		current->blocked = oldset;
-		recalc_sigpending(current);
-		spin_unlock_irq(&current->sigmask_lock);
-
 		if (result <= 0) {
 #ifdef PARANOIA
 			printk(KERN_ERR "NBD: %s - sock=%ld at buf=%ld, size=%d returned %d.\n",
@@ -124,6 +122,12 @@
 		size -= result;
 		buf += result;
 	} while (size > 0);
+
+	spin_lock_irqsave(&current->sigmask_lock, flags);
+	current->blocked = oldset;
+	recalc_sigpending(current);
+	spin_unlock_irqrestore(&current->sigmask_lock, flags);
+
 	set_fs(oldfs);
 	return result;
 }
@@ -295,8 +299,6 @@
 		requests_in++;
 #endif
 		req->errors = 0;
-
-		nbd_send_req(lo->sock, req);	/* Why does this block?         */
 		CURRENT = CURRENT->next;
 		req->next = NULL;
 		if (lo->head == NULL) {
@@ -306,6 +308,10 @@
 			lo->head->next = req;
 			lo->head = req;
 		}
+
+		spin_unlock_irq(&io_request_lock);
+		nbd_send_req(lo->sock, req);	/* Why does this block?         */
+		spin_lock_irq(&io_request_lock);
 		continue;
 
 	      error_out:
diff -u --recursive --new-file v2.1.118/linux/drivers/char/joystick.c linux/drivers/char/joystick.c
--- v2.1.118/linux/drivers/char/joystick.c	Thu May 14 19:47:39 1998
+++ linux/drivers/char/joystick.c	Wed Aug 26 10:27:55 1998
@@ -771,6 +771,7 @@
 	js_ioctl,		/* js_ioctl */
 	NULL,			/* js_mmap */
 	js_open,		/* js_open */
+	NULL,			/* js_flush */
 	js_release,		/* js_release */
 	NULL			/* js_sync */
 };
diff -u --recursive --new-file v2.1.118/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.1.118/linux/drivers/isdn/isdn_common.c	Wed Apr  1 20:11:51 1998
+++ linux/drivers/isdn/isdn_common.c	Thu Aug 27 12:00:06 1998
@@ -1787,6 +1787,7 @@
 	isdn_ioctl,             /* isdn_ioctl */
 	NULL,                   /* isdn_mmap */
 	isdn_open,
+	NULL,			/* flush */
 	isdn_close,
 	NULL                    /* fsync */
 };
diff -u --recursive --new-file v2.1.118/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v2.1.118/linux/drivers/scsi/hosts.c	Thu Aug  6 14:06:33 1998
+++ linux/drivers/scsi/hosts.c	Thu Aug 27 12:01:00 1998
@@ -518,10 +518,18 @@
     
     /* If we are removing the last host registered, it is safe to reuse
      * its host number (this avoids "holes" at boot time) (DB) 
+     * It is also safe to reuse those of numbers directly below which have
+     * been released earlier (to avoid some holes in numbering).
      */
-    if (max_scsi_hosts == next_scsi_host)
-	max_scsi_hosts--;
-    
+    if(sh->host_no == max_scsi_hosts - 1) {
+	while(--max_scsi_hosts >= next_scsi_host) {
+	    shpnt = scsi_hostlist;
+	    while(shpnt && shpnt->host_no != max_scsi_hosts - 1)
+		shpnt = shpnt->next;
+	    if(shpnt)
+		break;
+	}
+    }
     next_scsi_host--;
     scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + sh->extra_bytes);
 }
diff -u --recursive --new-file v2.1.118/linux/fs/hfs/super.c linux/fs/hfs/super.c
--- v2.1.118/linux/fs/hfs/super.c	Sun Jun  7 11:16:36 1998
+++ linux/fs/hfs/super.c	Wed Aug 26 13:25:21 1998
@@ -396,9 +396,7 @@
 	struct hfs_mdb *mdb;
 	struct hfs_cat_key key;
 	kdev_t dev = s->s_dev;
-#ifndef CONFIG_MAC_PARTITION
 	hfs_s32 part_size, part_start;
-#endif
 	struct inode *root_inode;
 	int part;
 
@@ -415,16 +413,25 @@
 	/* set the device driver to 512-byte blocks */
 	set_blocksize(dev, HFS_SECTOR_SIZE);
 
-	/* look for a partition table and find the correct partition */
-#ifndef CONFIG_MAC_PARTITION
+#ifdef CONFIG_MAC_PARTITION
+	/* check to see if we're in a partition */
+	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0);
+
+	/* erk. try parsing the partition table ourselves */
+	if (!mdb) {
+		if (hfs_part_find(s, part, silent, &part_size, &part_start)) {
+	    		goto bail2;
+	  	}
+	  	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);
+	}
+#else
 	if (hfs_part_find(s, part, silent, &part_size, &part_start)) {
 		goto bail2;
 	}
 
 	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, part_start);
-#else
-	mdb = hfs_mdb_get(s, s->s_flags & MS_RDONLY, 0);
 #endif
+
 	if (!mdb) {
 		if (!silent) {
 			printk("VFS: Can't find a HFS filesystem on dev %s.\n",
diff -u --recursive --new-file v2.1.118/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v2.1.118/linux/fs/isofs/inode.c	Wed Jun 24 22:54:09 1998
+++ linux/fs/isofs/inode.c	Wed Aug 26 15:06:55 1998
@@ -25,6 +25,7 @@
 #include <linux/cdrom.h>
 #include <linux/init.h>
 #include <linux/nls.h>
+#include <linux/ctype.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -41,6 +42,18 @@
 static int check_bread = 0;
 #endif
 
+static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
+static int isofs_hash(struct dentry *parent, struct qstr *qstr);
+static int isofs_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int isofs_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
+
+#ifdef CONFIG_JOLIET
+static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
+static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
+static int isofs_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
+static int isofs_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
+#endif
+
 void isofs_put_super(struct super_block *sb)
 {
 #ifdef CONFIG_JOLIET
@@ -71,21 +84,213 @@
 	NULL
 };
 
+static struct dentry_operations isofs_dentry_ops[] = {
+	{
+		NULL,			/* d_revalidate */
+		isofs_hash,
+		isofs_cmp,
+		NULL			/* d_delete */
+	},
+	{
+		NULL,			/* d_revalidate */
+		isofs_hashi,
+		isofs_cmpi,
+		NULL			/* d_delete */
+	},
+#ifdef CONFIG_JOLIET
+	{
+		NULL,			/* d_revalidate */
+		isofs_hash_ms,
+		isofs_cmp_ms,
+		NULL			/* d_delete */
+	},
+	{
+		NULL,			/* d_revalidate */
+		isofs_hashi_ms,
+		isofs_cmpi_ms,
+		NULL			/* d_delete */
+	}
+#endif
+};
+
 struct iso9660_options{
-  char map;
-  char rock;
-  char joliet;
-  char cruft;
-  char unhide;
-  unsigned char check;
-  unsigned int blocksize;
-  mode_t mode;
-  gid_t gid;
-  uid_t uid;
-  char *iocharset;
-  unsigned char utf8;
+	char map;
+	char rock;
+	char joliet;
+	char cruft;
+	char unhide;
+	unsigned char check;
+	unsigned int blocksize;
+	mode_t mode;
+	gid_t gid;
+	uid_t uid;
+	char *iocharset;
+	unsigned char utf8;
 };
 
+static int strnicmp(const char *s1, const char *s2, int len)
+{
+	int n = 0;
+	while (*s1 && *s2 && (tolower(*s1) == tolower(*s2))) {
+		s1++; s2++; n++;
+		if (n == len) return 0;
+	}
+	if (*s1 == 0 && *s2 == 0) return 0;
+	if (*s1 && *s2) {
+		if (*s1 > *s2) return 1;
+		return -1;
+	}
+	if (*s1) return 1;
+	return -1;
+}
+
+/*
+ * Compute the hash for the isofs name corresponding to the dentry.
+ */
+static int
+isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
+{
+	const char *name;
+	int len;
+
+	len = qstr->len;
+	name = qstr->name;
+	if (ms) {
+		while (len && name[len-1] == '.')
+			len--;
+	}
+
+	qstr->hash = full_name_hash(name, len);
+
+	return 0;
+}
+
+/*
+ * Compute the hash for the isofs name corresponding to the dentry.
+ */
+static int
+isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
+{
+	const char *name;
+	int len;
+	char c;
+	unsigned long hash;
+
+	len = qstr->len;
+	name = qstr->name;
+	if (ms) {
+		while (len && name[len-1] == '.')
+			len--;
+	}
+
+	hash = init_name_hash();
+	while (len--) {
+		c = tolower(*name++);
+		hash = partial_name_hash(tolower(c), hash);
+	}
+	qstr->hash = end_name_hash(hash);
+
+	return 0;
+}
+
+/*
+ * Case insensitive compare of two isofs names.
+ */
+static int
+isofs_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms)
+{
+	int alen, blen;
+
+	/* A filename cannot end in '.' or we treat it like it has none */
+	alen = a->len;
+	blen = b->len;
+	if (ms) {
+		while (alen && a->name[alen-1] == '.')
+			alen--;
+		while (blen && b->name[blen-1] == '.')
+			blen--;
+	}
+	if (alen == blen) {
+		if (strnicmp(a->name, b->name, alen) == 0)
+			return 0;
+	}
+	return 1;
+}
+
+/*
+ * Case sensitive compare of two isofs names.
+ */
+static int
+isofs_cmp_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms)
+{
+	int alen, blen;
+
+	/* A filename cannot end in '.' or we treat it like it has none */
+	alen = a->len;
+	blen = b->len;
+	if (ms) {
+		while (alen && a->name[alen-1] == '.')
+			alen--;
+		while (blen && b->name[blen-1] == '.')
+			blen--;
+	}
+	if (alen == blen) {
+		if (strncmp(a->name, b->name, alen) == 0)
+			return 0;
+	}
+	return 1;
+}
+
+static int
+isofs_hash(struct dentry *dentry, struct qstr *qstr)
+{
+	return isofs_hash_common(dentry, qstr, 0);
+}
+
+static int
+isofs_hashi(struct dentry *dentry, struct qstr *qstr)
+{
+	return isofs_hashi_common(dentry, qstr, 0);
+}
+
+static int
+isofs_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b)
+{
+	return isofs_cmp_common(dentry, a, b, 0);
+}
+
+static int
+isofs_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b)
+{
+	return isofs_cmpi_common(dentry, a, b, 0);
+}
+
+#ifdef CONFIG_JOLIET
+static int
+isofs_hash_ms(struct dentry *dentry, struct qstr *qstr)
+{
+	return isofs_hash_common(dentry, qstr, 1);
+}
+
+static int
+isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr)
+{
+	return isofs_hashi_common(dentry, qstr, 1);
+}
+
+static int
+isofs_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
+{
+	return isofs_cmp_common(dentry, a, b, 1);
+}
+
+static int
+isofs_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
+{
+	return isofs_cmpi_common(dentry, a, b, 1);
+}
+#endif
+
 static int parse_options(char *options, struct iso9660_options * popt)
 {
 	char *this_char,*value;
@@ -95,7 +300,7 @@
 	popt->joliet = 'y';
 	popt->cruft = 'n';
 	popt->unhide = 'n';
-	popt->check = 's';		/* default: strict */
+	popt->check = 'u';		/* unset */
 	popt->blocksize = 1024;
 	popt->mode = S_IRUGO | S_IXUGO; /* r-x for all.  The disc could
 					   be shared with DOS machines so
@@ -274,6 +479,7 @@
 	unsigned int			vol_desc_start;
 	struct inode		      * inode;
 	struct iso9660_options		opt;
+	int				table;
 
 	MOD_INC_USE_COUNT;
 	/* lock before any blocking operations */
@@ -374,7 +580,7 @@
 			    } else if (sec->escape[2] == 0x45) {
 				joliet_level = 3;
 			    }
-			    printk("ISO 9660 Extensions: Microsoft Joliet Level %d\n",
+			    printk(KERN_DEBUG"ISO 9660 Extensions: Microsoft Joliet Level %d\n",
 				   joliet_level);
 			}
 			goto root_found;
@@ -532,7 +738,6 @@
 	s->s_op = &isofs_sops;
 	s->u.isofs_sb.s_mapping = opt.map;
 	s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 2 : 0);
-	s->u.isofs_sb.s_name_check = opt.check;
 	s->u.isofs_sb.s_cruft = opt.cruft;
 	s->u.isofs_sb.s_unhide = opt.unhide;
 	s->u.isofs_sb.s_uid = opt.uid;
@@ -555,7 +760,10 @@
 	 * CD with Unicode names.  Until someone sees such a beast, it
 	 * will not be supported.
 	 */
-	if (joliet_level && opt.rock == 'y' && s->u.isofs_sb.s_rock != 1) {
+	if (opt.rock == 'y' && s->u.isofs_sb.s_rock == 1) {
+		joliet_level = 0;
+	}
+	if (joliet_level) {
 		iput(inode);
 		pri = (struct iso_primary_descriptor *) sec;
 		rootp = (struct iso_directory_record *)
@@ -566,11 +774,22 @@
 			 << s -> u.isofs_sb.s_log_zone_size);
 		inode = iget(s, s->u.isofs_sb.s_firstdatazone);
 		s->u.isofs_sb.s_rock = 0;
+		opt.rock = 'n';
+	}
+
+	if (opt.check == 'u') {
+		/* Only Joliet is case insensitive by default */
+		if (joliet_level) opt.check = 'r';
+		else opt.check = 's';
 	}
 
 	s->s_root = d_alloc_root(inode, NULL);
 	if (!(s->s_root))
 		goto out_no_root;
+	table = 0;
+	if (joliet_level) table += 2;
+	if (opt.check == 'r') table++;
+	s->s_root->d_op = &isofs_dentry_ops[table];
 
 	if(!check_disk_change(dev)) {
 		brelse(bh);
@@ -694,34 +913,36 @@
 	size = inode->u.isofs_i.i_section_size;
 	nextino = inode->u.isofs_i.i_next_section_ino;
 #ifdef DEBUG
-	printk("first inode: inode=%lu nextino=%lu firstext=%u size=%lu\n",
+	printk("first inode: inode=%x nextino=%x firstext=%u size=%lu\n",
 		inode->i_ino, nextino, firstext, size);
 #endif
 	i = 0;
-	while(b_off >= offset + size) {
-		offset += size;
-
-		if(nextino == 0) return 0;
-		ino = iget(inode->i_sb, nextino);
-		if(!ino) return 0;
-		firstext = ino->u.isofs_i.i_first_extent;
-		size = ino->u.isofs_i.i_section_size;
+	if (nextino) {
+		while(b_off >= offset + size) {
+			offset += size;
+
+			if(nextino == 0) return 0;
+			ino = iget(inode->i_sb, nextino);
+			if(!ino) return 0;
+			firstext = ino->u.isofs_i.i_first_extent;
+			size = ino->u.isofs_i.i_section_size;
 #ifdef DEBUG
-		printk("read inode: inode=%lu ino=%lu nextino=%lu firstext=%u size=%lu\n",
-			inode->i_ino, nextino, ino->u.isofs_i.i_next_section_ino, firstext, size);
+			printk("read inode: inode=%lu ino=%lu nextino=%lu firstext=%u size=%lu\n",
+			       inode->i_ino, nextino, ino->u.isofs_i.i_next_section_ino, firstext, size);
 #endif
-		nextino = ino->u.isofs_i.i_next_section_ino;
-		iput(ino);
+			nextino = ino->u.isofs_i.i_next_section_ino;
+			iput(ino);
 		
-		if(++i > 100) {
-			printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n");
-			printk("isofs_bmap: ino=%lu block=%d firstext=%u size=%u nextino=%lu\n",
-				inode->i_ino, block, firstext, (unsigned)size, nextino);
-			return 0;
+			if(++i > 100) {
+				printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n");
+				printk("isofs_bmap: ino=%lu block=%d firstext=%u size=%u nextino=%lu\n",
+				       inode->i_ino, block, firstext, (unsigned)size, nextino);
+				return 0;
+			}
 		}
 	}
 #ifdef DEBUG
-	printk("isofs_bmap: mapped inode:block %lu:%d to block %lu\n",
+	printk("isofs_bmap: mapped inode:block %x:%d to block %lu\n",
 		inode->i_ino, block, (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode));
 #endif
 	return (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode);
@@ -905,7 +1126,7 @@
 #endif
 
 #ifdef DEBUG
-	printk("Get inode %d: %d %d: %d\n",inode->i_ino, block,
+	printk("Get inode %x: %d %d: %d\n",inode->i_ino, block,
 	       ((int)pnt) & 0x3ff, inode->i_size);
 #endif
 
diff -u --recursive --new-file v2.1.118/linux/fs/isofs/joliet.c linux/fs/isofs/joliet.c
--- v2.1.118/linux/fs/isofs/joliet.c	Wed Jun 24 22:54:09 1998
+++ linux/fs/isofs/joliet.c	Wed Aug 26 09:54:41 1998
@@ -79,8 +79,6 @@
 	unsigned char utf8;
 	struct nls_table *nls;
 	unsigned char len = 0;
-	int i;
-	char c;
 
 	utf8 = inode->i_sb->u.isofs_sb.s_utf8;
 	nls = inode->i_sb->u.isofs_sb.s_nls_iocharset;
@@ -96,14 +94,12 @@
 		len -= 2;
 	}
 
-        if (inode->i_sb->u.isofs_sb.s_name_check == 'r') {
-               for (i = 0; i < len; i++) {
-                       c = outname[i];
-                       /* lower case */
-                       if (c >= 'A' && c <= 'Z') c |= 0x20;
-                       if (c == ';') c = '.';
-                       outname[i] = c;
-               }
+	/*
+	 * Windows doesn't like periods at the end of a name,
+	 * so neither do we
+	 */
+	while (len >= 2 && (outname[len-1] == '.')) {
+		len--;
 	}
 
 	return len;
diff -u --recursive --new-file v2.1.118/linux/fs/isofs/namei.c linux/fs/isofs/namei.c
--- v2.1.118/linux/fs/isofs/namei.c	Wed Jun 24 22:54:09 1998
+++ linux/fs/isofs/namei.c	Wed Aug 26 09:54:41 1998
@@ -22,33 +22,31 @@
  * ok, we cannot use strncmp, as the name is not in our data space.
  * Thus we'll have to use isofs_match. No big problem. Match also makes
  * some sanity tests.
- *
- * NOTE! unlike strncmp, isofs_match returns 1 for success, 0 for failure.
  */
-static int isofs_match(int len,const char * name, const char * compare, int dlen)
+static int
+isofs_cmp(struct dentry * dentry, const char * compare, int dlen)
 {
+	struct qstr qstr;
+
 	if (!compare)
-		return 0;
+		return 1;
 
 	/* check special "." and ".." files */
 	if (dlen == 1) {
 		/* "." */
 		if (compare[0] == 0) {
-			if (!len)
-				return 1;
+			if (!dentry->d_name.len)
+				return 0;
 			compare = ".";
 		} else if (compare[0] == 1) {
 			compare = "..";
 			dlen = 2;
 		}
 	}
-#if 0
-	if (len <= 2) printk("Match: %d %d %s %d %d \n",len,dlen,compare,de->name[0], dlen);
-#endif
-	
-	if (dlen != len)
-		return 0;
-	return !memcmp(name, compare, len);
+
+	qstr.name = compare;
+	qstr.len = dlen;
+	return dentry->d_op->d_compare(dentry, &dentry->d_name, &qstr);
 }
 
 /*
@@ -59,8 +57,8 @@
  * itself (as an inode number). It does NOT read the inode of the
  * entry - you'll have to do that yourself if you want to.
  */
-static struct buffer_head * isofs_find_entry(struct inode * dir,
-	const char * name, int namelen, unsigned long * ino)
+static struct buffer_head *
+isofs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino)
 {
 	unsigned long bufsize = ISOFS_BUFFER_SIZE(dir);
 	unsigned char bufbits = ISOFS_BUFFER_BITS(dir);
@@ -195,7 +193,7 @@
 			}
 			/* This allows us to match with and without
 			 * a trailing period. */
-			if(dpnt[dlen-1] == '.' && namelen == dlen-1)
+			if(dpnt[dlen-1] == '.' && dentry->d_name.len == dlen-1)
 				dlen--;
 		}
 		/*
@@ -205,7 +203,7 @@
 		if(   !(de->flags[-dir->i_sb->u.isofs_sb.s_high_sierra] & 5)
 		   || dir->i_sb->u.isofs_sb.s_unhide == 'y' )
 		{
-			match = isofs_match(namelen,name,dpnt,dlen);
+			match = (isofs_cmp(dentry,dpnt,dlen) == 0);
 		}
 		if (match) {
 			if(inode_number == -1) {
@@ -231,11 +229,10 @@
 {
 	unsigned long ino;
 	struct buffer_head * bh;
-	char *lcname;
 	struct inode *inode;
 
 #ifdef DEBUG
-	printk("lookup: %x %d\n",dir->i_ino, dentry->d_name.len);
+	printk("lookup: %x %s\n",dir->i_ino, dentry->d_name.name);
 #endif
 	if (!dir)
 		return -ENOENT;
@@ -243,23 +240,9 @@
 	if (!S_ISDIR(dir->i_mode))
 		return -ENOENT;
 
-	/* If mounted with check=relaxed (and most likely norock),
-	 * then first convert this name to lower case.
-	 */
-	if (dir->i_sb->u.isofs_sb.s_name_check == 'r' &&
-	    (lcname = kmalloc(dentry->d_name.len, GFP_KERNEL)) != NULL) {
-		int i;
-		char c;
-
-		for (i=0; i<dentry->d_name.len; i++) {
-			c = dentry->d_name.name[i];
-			if (c >= 'A' && c <= 'Z') c |= 0x20;
-			lcname[i] = c;
-		}
-		bh = isofs_find_entry(dir, lcname, dentry->d_name.len, &ino);
-		kfree(lcname);
-	} else
-		bh = isofs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &ino);
+	dentry->d_op = dir->i_sb->s_root->d_op;
+
+	bh = isofs_find_entry(dir, dentry, &ino);
 
 	inode = NULL;
 	if (bh) {
diff -u --recursive --new-file v2.1.118/linux/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c
--- v2.1.118/linux/fs/nfs/mount_clnt.c	Wed Aug 26 11:37:43 1998
+++ linux/fs/nfs/mount_clnt.c	Wed Aug 26 10:10:33 1998
@@ -78,6 +78,7 @@
 		clnt->cl_softrtry = 1;
 		clnt->cl_chatty   = 1;
 		clnt->cl_oneshot  = 1;
+		clnt->cl_intr = 1;
 	}
 	return clnt;
 }
diff -u --recursive --new-file v2.1.118/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.1.118/linux/fs/nfs/write.c	Wed Aug 26 11:37:43 1998
+++ linux/fs/nfs/write.c	Thu Aug 27 13:17:48 1998
@@ -56,18 +56,6 @@
 #include <linux/nfs_fs.h>
 #include <asm/uaccess.h>
 
-/*
- * NOTE! We must NOT default to soft-mounting: that breaks too many
- * programs that depend on POSIX behaviour of uninterruptible reads
- * and writes.
- *
- * Until we have a per-mount soft/hard mount policy that we can honour
- * we must default to hard mounting!
- *
- * And yes, this should be "interruptible", not soft.
- */
-#define IS_SOFT 0
-
 #define NFS_PARANOIA 1
 #define NFSDBG_FACILITY		NFSDBG_PAGECACHE
 
@@ -730,29 +718,21 @@
 nfs_flush_dirty_pages(struct inode *inode, pid_t pid, off_t offset, off_t len)
 {
 	struct nfs_wreq *last = NULL;
-	int result = 0, cancel = 0;
+	int result = 0;
 
 	dprintk("NFS:      flush_dirty_pages(%x/%ld for pid %d %ld/%ld)\n",
 		inode->i_dev, inode->i_ino, current->pid, offset, len);
 
-	if (IS_SOFT && signalled()) {
-		nfs_cancel_dirty(inode, pid);
-		cancel = 1;
-	}
-
 	for (;;) {
-		if (IS_SOFT && signalled()) {
-			if (!cancel)
-				nfs_cancel_dirty(inode, pid);
-			result = -ERESTARTSYS;
-			break;
-		}
-
 		/* Flush all pending writes for the pid and file region */
 		last = nfs_flush_pages(inode, pid, offset, len, 0);
 		if (last == NULL)
 			break;
-		wait_on_write_request(last);
+		result = wait_on_write_request(last);
+		if (result) {
+			nfs_cancel_dirty(inode,pid);
+			break;
+		}
 	}
 
 	return result;
diff -u --recursive --new-file v2.1.118/linux/fs/romfs/inode.c linux/fs/romfs/inode.c
--- v2.1.118/linux/fs/romfs/inode.c	Wed Jun 24 22:54:10 1998
+++ linux/fs/romfs/inode.c	Wed Aug 26 10:16:25 1998
@@ -30,17 +30,18 @@
  *					  correct namelen for statfs
  *					spotted by Bill Hawes:
  *					  readlink shouldn't iput()
+ *	Jun 1998	2.1.106		from Avery Pennarun: glibc scandir()
+ *					  exposed a problem in readdir
+ *			2.1.107		code-freeze spellchecker run
+ *	Aug 1998			2.1.118+ VFS changes
  */
 
 /* todo:
  *	- see Documentation/filesystems/romfs.txt
- *	- use malloced memory for file names?
- *	- quicklist routines from fs/namei.c, get_page is possibly not
- *	  intended to be used now
+ *	- use allocated, not stack memory for file names?
  *	- considering write access...
  *	- network (tftp) files?
- *	- in the ancient times something leaked to made umounts
- *	  impossible, but I've not seen it in the last months
+ *	- merge back some _op tables
  */
 
 /*
@@ -492,6 +493,7 @@
 	NULL,			/* ioctl */
 	generic_file_mmap,	/* mmap */
 	NULL,			/* open */
+	NULL,			/* flush */
 	NULL,			/* release */
 	NULL,			/* fsync */
 	NULL,			/* fasync */
@@ -529,6 +531,7 @@
 	NULL,			/* ioctl */
 	NULL,			/* mmap */
 	NULL,			/* open */
+	NULL,			/* flush */
 	NULL,			/* release */
 	NULL,			/* fsync */
 	NULL,			/* fasync */
diff -u --recursive --new-file v2.1.118/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
--- v2.1.118/linux/fs/smbfs/proc.c	Tue Aug 18 22:02:06 1998
+++ linux/fs/smbfs/proc.c	Thu Aug 27 10:58:23 1998
@@ -1961,11 +1961,13 @@
 	smb_init_dirent(server, fattr);
 
 	/*
-	 * Win 95 is painfully slow at returning trans2 getattr info,
-	 * so we provide the SMB_FIX_OLDATTR option switch.
+	 * Select whether to use core or trans2 getattr.
  	 */
 	if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) {
-		if (server->mnt->version & SMB_FIX_OLDATTR)
+		/*
+		 * Win 95 appears to break with the trans2 getattr.
+ 	 	 */
+		if (server->mnt->version & (SMB_FIX_OLDATTR|SMB_FIX_WIN95))
 			goto core_attr;
 		if (server->mnt->version & SMB_FIX_DIRATTR)
 			result = smb_proc_getattr_ff(server, dir, fattr);
diff -u --recursive --new-file v2.1.118/linux/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h
--- v2.1.118/linux/include/asm-i386/hardirq.h	Mon Aug  3 12:45:47 1998
+++ linux/include/asm-i386/hardirq.h	Wed Aug 26 14:59:12 1998
@@ -20,7 +20,7 @@
 #define hardirq_enter(cpu)	(local_irq_count[cpu]++)
 #define hardirq_exit(cpu)	(local_irq_count[cpu]--)
 
-#define synchronize_irq()	do { } while (0)
+#define synchronize_irq()	barrier()
 
 #else
 
diff -u --recursive --new-file v2.1.118/linux/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
--- v2.1.118/linux/include/asm-i386/softirq.h	Wed Jun 24 22:54:10 1998
+++ linux/include/asm-i386/softirq.h	Wed Aug 26 15:00:38 1998
@@ -86,7 +86,7 @@
 /* These are for the irq's testing the lock */
 #define softirq_trylock(cpu)	(local_bh_count[cpu] ? 0 : (local_bh_count[cpu]=1))
 #define softirq_endlock(cpu)	(local_bh_count[cpu] = 0)
-#define synchronize_bh()	do { } while (0)
+#define synchronize_bh()	barrier()
 
 #endif	/* SMP */
 
diff -u --recursive --new-file v2.1.118/linux/include/asm-ppc/ide.h linux/include/asm-ppc/ide.h
--- v2.1.118/linux/include/asm-ppc/ide.h	Thu Aug  6 14:06:33 1998
+++ linux/include/asm-ppc/ide.h	Thu Aug 27 11:03:56 1998
@@ -95,8 +95,6 @@
 static __inline__ ide_ioreg_t ide_default_io_base(int index)
 {
         if (_machine == _MACH_Pmac) {
-		if (!pmac_ide_ports_known)
-			pmac_ide_probe();
 		return pmac_ide_regbase[index];
 	}
 	if (_machine == _MACH_mbx) return index;
diff -u --recursive --new-file v2.1.118/linux/include/linux/iso_fs_sb.h linux/include/linux/iso_fs_sb.h
--- v2.1.118/linux/include/linux/iso_fs_sb.h	Tue Jun 23 10:01:29 1998
+++ linux/include/linux/iso_fs_sb.h	Wed Aug 26 09:54:41 1998
@@ -16,7 +16,6 @@
 	unsigned char s_rock;
 	unsigned char s_joliet_level;
 	unsigned char s_utf8;
-	unsigned char s_name_check; /* r = relaxed, s = strict */
 	unsigned char s_cruft; /* Broken disks with high
 				  byte of length containing
 				  junk */
diff -u --recursive --new-file v2.1.118/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h
--- v2.1.118/linux/include/linux/smb_fs.h	Fri Jul 31 17:10:57 1998
+++ linux/include/linux/smb_fs.h	Thu Aug 27 13:22:30 1998
@@ -9,7 +9,6 @@
 #ifndef _LINUX_SMB_FS_H
 #define _LINUX_SMB_FS_H
 
-#include <linux/dirent.h>
 #include <linux/smb.h>
 
 /*
diff -u --recursive --new-file v2.1.118/linux/include/linux/smb_mount.h linux/include/linux/smb_mount.h
--- v2.1.118/linux/include/linux/smb_mount.h	Wed Oct 29 14:49:18 1997
+++ linux/include/linux/smb_mount.h	Thu Aug 27 10:58:23 1998
@@ -15,12 +15,11 @@
 
 struct smb_mount_data {
 	int version;
-        uid_t mounted_uid;      /* Who may umount() this filesystem? */
-
-        uid_t uid;
-        gid_t gid;
-        mode_t file_mode;
-        mode_t dir_mode;
+	__kernel_uid_t mounted_uid; /* Who may umount() this filesystem? */
+	__kernel_uid_t uid;
+	__kernel_gid_t gid;
+	__kernel_mode_t file_mode;
+	__kernel_mode_t dir_mode;
 };
 
 #endif
diff -u --recursive --new-file v2.1.118/linux/include/net/sock.h linux/include/net/sock.h
--- v2.1.118/linux/include/net/sock.h	Fri Jul 31 17:07:32 1998
+++ linux/include/net/sock.h	Thu Aug 27 13:19:38 1998
@@ -350,7 +350,7 @@
 	unsigned char		reuse,		/* SO_REUSEADDR setting			*/
 				nonagle;	/* Disable Nagle algorithm?		*/
 
-	int			sock_readers;	/* User count				*/
+	atomic_t		sock_readers;	/* User count				*/
 	int			rcvbuf;		/* Size of receive buffer in bytes	*/
 
 	struct wait_queue	**sleep;	/* Sock wait queue			*/
@@ -643,42 +643,20 @@
 #if 0
 /* debugging code: the test isn't even 100% correct, but it can catch bugs */
 /* Note that a double lock is ok in theory - it's just _usually_ a bug */
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		__label__ here;
 		printk("double lock on socket at %p\n", &&here);
 here:
 	}
 #endif
-#ifdef __SMP__
-	/*
-	 * This is a very broken bottom half synchronization mechanism.
-	 * You don't want to know..
-	 */
-	{ unsigned long flags;
-	save_flags(flags);
-	cli();
-	sk->sock_readers++;
-	restore_flags(flags);
-	}
-#else
-	sk->sock_readers++;
-	barrier();
-#endif
+	atomic_inc(&sk->sock_readers);
+	synchronize_bh();
 }
 
 static inline void release_sock(struct sock *sk)
 {
 	barrier();
-#if 0
-/* debugging code: remove me when ok */
-	if (sk->sock_readers == 0) {
-		__label__ here;
-		sk->sock_readers = 1;
-		printk("trying to unlock unlocked socket at %p\n", &&here);
-here:
-	}
-#endif
-	if ((sk->sock_readers = sk->sock_readers-1) == 0)
+	if (atomic_dec_and_test(&sk->sock_readers))
 		__release_sock(sk);
 }
 
diff -u --recursive --new-file v2.1.118/linux/kernel/sched.c linux/kernel/sched.c
--- v2.1.118/linux/kernel/sched.c	Wed Aug 26 11:37:45 1998
+++ linux/kernel/sched.c	Wed Aug 26 15:06:00 1998
@@ -430,9 +430,6 @@
 	ret = detach_timer(timer);
 	timer->next = timer->prev = 0;
 	spin_unlock_irqrestore(&timerlist_lock, flags);
-
-	/* Make sure the timer isn't running in parallell.. */
-	synchronize_bh();
 	return ret;
 }
 
diff -u --recursive --new-file v2.1.118/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.1.118/linux/mm/swapfile.c	Wed Aug 26 11:37:45 1998
+++ linux/mm/swapfile.c	Wed Aug 26 16:01:57 1998
@@ -489,7 +489,7 @@
 	int swap_header_version;
 	int lock_map_size = PAGE_SIZE;
 	int nr_good_pages = 0;
-	char tmp_lock_map = 0;
+	unsigned long tmp_lock_map = 0;
 	
 	lock_kernel();
 	if (!capable(CAP_SYS_ADMIN))
@@ -558,9 +558,9 @@
 		goto bad_swap;
 	}
 
-	p->swap_lockmap = &tmp_lock_map;
+	p->swap_lockmap = (char *) &tmp_lock_map;
 	rw_swap_page_nocache(READ, SWP_ENTRY(type,0), (char *) swap_header);
-	p->swap_lockmap = 0;
+	p->swap_lockmap = NULL;
 
 	if (!memcmp("SWAP-SPACE",swap_header->magic.magic,10))
 		swap_header_version = 1;
diff -u --recursive --new-file v2.1.118/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- v2.1.118/linux/net/ipv4/raw.c	Thu May 14 19:47:44 1998
+++ linux/net/ipv4/raw.c	Wed Aug 26 15:53:08 1998
@@ -152,7 +152,7 @@
 	int type = skb->h.icmph->type;
 	int code = skb->h.icmph->code;
 
-	if (sk->ip_recverr && !sk->sock_readers) {
+	if (sk->ip_recverr && !atomic_read(&sk->sock_readers)) {
 		struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 		if (skb2 && sock_queue_err_skb(sk, skb2))
 			kfree_skb(skb);
@@ -194,7 +194,7 @@
 	
 	skb->h.raw = skb->nh.raw;
 
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		__skb_queue_tail(&sk->back_log, skb);
 		return 0;
 	}
diff -u --recursive --new-file v2.1.118/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.1.118/linux/net/ipv4/tcp.c	Tue Jul 28 14:21:10 1998
+++ linux/net/ipv4/tcp.c	Wed Aug 26 15:53:35 1998
@@ -707,7 +707,7 @@
 	int copied  = 0;
 
 	/* Verify that the socket is locked */
-	if (!sk->sock_readers)
+	if (!atomic_read(&sk->sock_readers))
 		printk("tcp_do_sendmsg: socket not locked!\n");
 
 	/* Wait for a connection to finish. */
@@ -1389,7 +1389,7 @@
 	 * Check whether the socket is locked ... supposedly
 	 * it's impossible to tcp_close() a locked socket.
 	 */
-	if (sk->sock_readers)
+	if (atomic_read(&sk->sock_readers))
 		printk("tcp_close: socket already locked!\n");
 
 	/* We need to grab some memory, and put together a FIN,
diff -u --recursive --new-file v2.1.118/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.1.118/linux/net/ipv4/tcp_ipv4.c	Mon Aug  3 12:45:48 1998
+++ linux/net/ipv4/tcp_ipv4.c	Wed Aug 26 15:52:37 1998
@@ -720,7 +720,7 @@
 			 * dropped. This is the new "fast" path mtu
 			 * discovery.
 			 */
-			if (!sk->sock_readers) {
+			if (!atomic_read(&sk->sock_readers)) {
 				lock_sock(sk); 
 				tcp_simple_retransmit(sk);
 				release_sock(sk);
@@ -813,7 +813,7 @@
 		/* Prevent race conditions with accept() - 
 		 * ICMP is unreliable. 
 		 */
-		if (sk->sock_readers) {
+		if (atomic_read(&sk->sock_readers)) {
 			/* XXX: add a counter here to profile this. 
 			 * If too many ICMPs get dropped on busy
 			 * servers this needs to be solved differently.
@@ -1175,7 +1175,7 @@
 		/* Clone the TCP header template */
 		newsk->dport = req->rmt_port;
 
-		newsk->sock_readers = 0;
+		atomic_set(&newsk->sock_readers, 0);
 		atomic_set(&newsk->rmem_alloc, 0);
 		skb_queue_head_init(&newsk->receive_queue);
 		atomic_set(&newsk->wmem_alloc, 0);
@@ -1543,7 +1543,7 @@
 
 	if (sk->state == TCP_TIME_WAIT)
 		goto do_time_wait;
-	if (!sk->sock_readers)
+	if (!atomic_read(&sk->sock_readers))
 		return tcp_v4_do_rcv(sk, skb);
 
 	__skb_queue_tail(&sk->back_log, skb);
diff -u --recursive --new-file v2.1.118/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.1.118/linux/net/ipv4/tcp_timer.c	Thu May  7 22:51:56 1998
+++ linux/net/ipv4/tcp_timer.c	Wed Aug 26 15:54:19 1998
@@ -182,7 +182,7 @@
 	if(sk->zapped) 
 		return;
 	
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		/* Try again in second. */
 		tcp_reset_xmit_timer(sk, TIME_PROBE0, HZ);
 		return;
@@ -432,7 +432,7 @@
 		return;
 	}
 
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		/* Try again in a second. */
 		tcp_reset_xmit_timer(sk, TIME_RETRANS, HZ);
 		return;
@@ -518,7 +518,7 @@
 			struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
 			
 			/* TCP_LISTEN is implied. */
-			if (!sk->sock_readers && tp->syn_wait_queue) {
+			if (!atomic_read(&sk->sock_readers) && tp->syn_wait_queue) {
 				struct open_request *prev = (struct open_request *)(&tp->syn_wait_queue);
 				struct open_request *req = tp->syn_wait_queue;
 				do {
diff -u --recursive --new-file v2.1.118/linux/net/ipv4/timer.c linux/net/ipv4/timer.c
--- v2.1.118/linux/net/ipv4/timer.c	Thu Mar 26 15:57:13 1998
+++ linux/net/ipv4/timer.c	Wed Aug 26 15:54:33 1998
@@ -73,7 +73,7 @@
 	int why = sk->timeout;
 
 	/* Only process if socket is not in use. */
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		sk->timer.expires = jiffies+HZ;
 		add_timer(&sk->timer);
 		return;
diff -u --recursive --new-file v2.1.118/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v2.1.118/linux/net/ipv4/udp.c	Tue Jun 23 10:01:31 1998
+++ linux/net/ipv4/udp.c	Wed Aug 26 15:54:54 1998
@@ -493,7 +493,7 @@
     	  	return;	/* No socket for error */
 	}
 
-	if (sk->ip_recverr && !sk->sock_readers) {
+	if (sk->ip_recverr && !atomic_read(&sk->sock_readers)) {
 		struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 		if (skb2 && sock_queue_err_skb(sk, skb2))
 			kfree_skb(skb2);
@@ -1026,7 +1026,7 @@
 
 static inline void udp_deliver(struct sock *sk, struct sk_buff *skb)
 {
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		__skb_queue_tail(&sk->back_log, skb);
 		return;
 	}
diff -u --recursive --new-file v2.1.118/linux/net/ipv6/raw.c linux/net/ipv6/raw.c
--- v2.1.118/linux/net/ipv6/raw.c	Tue Jul 28 14:21:10 1998
+++ linux/net/ipv6/raw.c	Wed Aug 26 15:55:32 1998
@@ -220,7 +220,7 @@
 	if (sk->ip_hdrincl)
 		skb->h.raw = skb->nh.raw;
 
-	if (sk->sock_readers) {
+	if (atomic_read(&sk->sock_readers)) {
 		__skb_queue_tail(&sk->back_log, skb);
 		return 0;
 	}
diff -u --recursive --new-file v2.1.118/linux/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- v2.1.118/linux/net/ipv6/tcp_ipv6.c	Tue Jun 23 10:01:31 1998
+++ linux/net/ipv6/tcp_ipv6.c	Wed Aug 26 15:56:01 1998
@@ -617,7 +617,7 @@
 			 */
 			sk->mtu = sk->dst_cache->pmtu;
 		}
-		if (sk->sock_readers) { /* remove later */
+		if (atomic_read(&sk->sock_readers)) { /* remove later */
 			printk(KERN_DEBUG "tcp_v6_err: pmtu disc: socket locked.\n");
 			return;
 		}
@@ -631,7 +631,7 @@
 		struct open_request *req, *prev;
 		struct ipv6hdr hd;
 	case TCP_LISTEN:
-		if (sk->sock_readers)
+		if (atomic_read(&sk->sock_readers))
 			return;
 
 		/* Grrrr - fix this later. */
@@ -1178,7 +1178,7 @@
 	if(sk->state == TCP_TIME_WAIT)
 		goto do_time_wait;
 
-	if (!sk->sock_readers)
+	if (!atomic_read(&sk->sock_readers))
 		return tcp_v6_do_rcv(sk, skb);
 
 	__skb_queue_tail(&sk->back_log, skb);
diff -u --recursive --new-file v2.1.118/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
--- v2.1.118/linux/net/ipv6/udp.c	Tue Jul 28 14:21:10 1998
+++ linux/net/ipv6/udp.c	Wed Aug 26 15:56:19 1998
@@ -569,7 +569,7 @@
 
 	/* deliver */
 
-	if (sk->sock_readers)
+	if (atomic_read(&sk->sock_readers))
 		__skb_queue_tail(&sk->back_log, skb);
 	else
 		udpv6_queue_rcv_skb(sk, skb);
diff -u --recursive --new-file v2.1.118/linux/net/unix/af_unix.c linux/net/unix/af_unix.c
--- v2.1.118/linux/net/unix/af_unix.c	Tue Jun 23 10:01:31 1998
+++ linux/net/unix/af_unix.c	Wed Aug 26 16:03:02 1998
@@ -125,17 +125,17 @@
 
 extern __inline__ void unix_lock(unix_socket *sk)
 {
-	sk->sock_readers++;
+	atomic_inc(&sk->sock_readers);
 }
 
 extern __inline__ int unix_unlock(unix_socket *sk)
 {
-	return --sk->sock_readers;
+	return atomic_dec_and_test(&sk->sock_readers);
 }
 
 extern __inline__ int unix_locked(unix_socket *sk)
 {
-	return sk->sock_readers;
+	return atomic_read(&sk->sock_readers);
 }
 
 extern __inline__ void unix_release_addr(struct unix_address *addr)
@@ -338,7 +338,7 @@
 		sk->protinfo.af_unix.dentry=NULL;
 	}
 	
-	if(!unix_unlock(sk) && atomic_read(&sk->wmem_alloc) == 0)
+	if(unix_unlock(sk) && atomic_read(&sk->wmem_alloc) == 0)
 	{
 		sk_free(sk);
 		unix_remove_socket(sk);
@@ -418,7 +418,7 @@
 	sk->destruct = unix_destruct_addr;
 	sk->protinfo.af_unix.family=PF_UNIX;
 	sk->protinfo.af_unix.dentry=NULL;
-	sk->sock_readers=1;			/* Us */
+	atomic_set(&sk->sock_readers, 1);	/* Us */
 	sk->protinfo.af_unix.readsem=MUTEX;	/* single task reading lock */
 	sk->mtu=4096;
 	sk->protinfo.af_unix.list=&unix_sockets_unbound;
@@ -1411,7 +1411,7 @@
 	{
 		len+=sprintf(buffer+len,"%p: %08X %08X %08lX %04X %02X %5ld",
 			s,
-			s->sock_readers,
+			atomic_read(&s->sock_readers),
 			0,
 			s->socket ? s->socket->flags : 0,
 			s->type,
