## Automatically generated incremental diff
## From:   linux-2.4.27-pre6
## To:     linux-2.4.27-rc1
## Robot:  $Id: make-incremental-diff,v 1.12 2004/01/06 07:19:36 hpa Exp $

diff -urN linux-2.4.27-pre6/Documentation/filesystems/hpfs.txt linux-2.4.27-rc1/Documentation/filesystems/hpfs.txt
--- linux-2.4.27-pre6/Documentation/filesystems/hpfs.txt	2001-06-11 19:15:27.000000000 -0700
+++ linux-2.4.27-rc1/Documentation/filesystems/hpfs.txt	2004-06-19 17:51:29.751466791 -0700
@@ -1,5 +1,5 @@
-Read/Write HPFS 2.05
-1998-2001, Mikulas Patocka
+Read/Write HPFS 2.09
+1998-2004, Mikulas Patocka
 
 email: mikulas@artax.karlin.mff.cuni.cz
 homepage: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
@@ -283,6 +283,14 @@
 2.05 Fixed crash when got mount parameters without =
      Fixed crash when allocation of anode failed due to full disk
      Fixed some crashes when block io or inode allocation failed
+2.06 Fixed some crash on corrupted disk structures
+     Better allocation strategy
+     Reschedule points added so that it doesn't lock CPU long time
+     It should work in read-only mode on Warp Server
+2.07 More fixes for Warp Server. Now it really works
+2.08 Creating new files is not so slow on large disks
+     An attempt to sync deleted file does not generate filesystem error
+2.09 Fixed error on extremly fragmented files
 
 
  vim: set textwidth=80:
diff -urN linux-2.4.27-pre6/Makefile linux-2.4.27-rc1/Makefile
--- linux-2.4.27-pre6/Makefile	2004-06-19 17:51:28.085397125 -0700
+++ linux-2.4.27-rc1/Makefile	2004-06-19 17:51:29.771467628 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 27
-EXTRAVERSION = -pre6
+EXTRAVERSION = -rc1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -urN linux-2.4.27-pre6/arch/i386/kernel/acpi.c linux-2.4.27-rc1/arch/i386/kernel/acpi.c
--- linux-2.4.27-pre6/arch/i386/kernel/acpi.c	2004-06-19 17:51:28.087397209 -0700
+++ linux-2.4.27-rc1/arch/i386/kernel/acpi.c	2004-06-19 17:51:29.773467711 -0700
@@ -532,6 +532,11 @@
 		return 1;
         }
 
+	result = mp_irqs_alloc();	/* Dynamically allocate mp_irqs[] */
+	if (result < 0)  {
+		acpi_noirq = 1;
+		return result;
+	}
 
 	result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
 	if (!result) { 
diff -urN linux-2.4.27-pre6/arch/i386/kernel/mpparse.c linux-2.4.27-rc1/arch/i386/kernel/mpparse.c
--- linux-2.4.27-pre6/arch/i386/kernel/mpparse.c	2004-06-19 17:51:28.089397292 -0700
+++ linux-2.4.27-rc1/arch/i386/kernel/mpparse.c	2004-06-19 17:51:29.775467795 -0700
@@ -1104,6 +1104,20 @@
 }
 
 
+/* allocate mp_irqs[] for ACPI parsing table parsing */
+int __init mp_irqs_alloc()
+{
+	int size = (MAX_IRQ_SOURCES * sizeof(int)) * 4;
+
+	mp_irqs = (struct mpc_config_intsrc *)alloc_bootmem(size);
+	if (!mp_irqs) {
+		printk(KERN_ERR "mp_irqs_alloc(): alloc_bootmem(%d) failed!\n", size);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+
 void __init mp_override_legacy_irq (
 	u8			bus_irq,
 	u8			polarity, 
@@ -1163,7 +1177,6 @@
 	int count;
 
 	count = (MAX_MP_BUSSES * sizeof(int)) * 4;
-	count += (MAX_IRQ_SOURCES * sizeof(int)) * 4;
 	bus_data = alloc_bootmem(count);
 	if (!bus_data) {
 		panic("Fatal: can't allocate bus memory for ACPI legacy IRQ!");
@@ -1172,7 +1185,7 @@
 	mp_bus_id_to_node = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int))];
 	mp_bus_id_to_local = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 2];
 	mp_bus_id_to_pci_bus = (int *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 3];
-	mp_irqs = (struct mpc_config_intsrc *)&bus_data[(MAX_MP_BUSSES * sizeof(int)) * 4];
+
 	for (i = 0; i < MAX_MP_BUSSES; ++i)
 	  mp_bus_id_to_pci_bus[i] = -1;
 
@@ -1198,6 +1211,7 @@
 
 		for (idx = 0; idx < mp_irq_entries; idx++)
 			if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+				(mp_irqs[idx].mpc_dstapic == ioapic) &&
 				(mp_irqs[idx].mpc_srcbusirq == i ||
 				mp_irqs[idx].mpc_dstirq == i))
 					break;
diff -urN linux-2.4.27-pre6/arch/x86_64/kernel/bluesmoke.c linux-2.4.27-rc1/arch/x86_64/kernel/bluesmoke.c
--- linux-2.4.27-pre6/arch/x86_64/kernel/bluesmoke.c	2004-06-19 17:51:28.132399090 -0700
+++ linux-2.4.27-rc1/arch/x86_64/kernel/bluesmoke.c	2004-06-19 17:51:29.842470597 -0700
@@ -19,6 +19,7 @@
 #include <asm/processor.h> 
 #include <asm/msr.h>
 #include <asm/kdebug.h>
+#include <asm/smp.h>
 
 static int mce_disabled __initdata;
 static unsigned long mce_cpus; 
@@ -30,13 +31,6 @@
 static int banks;
 static unsigned long ignored_banks, disabled_banks;
 
-/* Machine Check on everything dubious. This is a good setting
-   for device driver testing. */
-#define K8_DRIVER_DEBUG ((1<<13)-1)
-/* Report RAM errors and Hyper Transport Problems, but ignore Device
-   aborts and GART errors. */
-#define K8_NORMAL_OP    0xff
-static u32 k8_nb_flags __initdata = K8_NORMAL_OP;
 struct notifier_block *mc_notifier_list = NULL;
 EXPORT_SYMBOL(mc_notifier_list);
 
@@ -525,8 +519,6 @@
 	banks = cap&0xff; 
 	for (i = 0; i < banks; i++) { 
 		u64 val = ((1UL<<i) & disabled_banks) ? 0 : ~0UL; 
-		if (val && i == 4)
-			val = k8_nb_flags;
 		wrmsrl(MSR_IA32_MC0_STATUS+4*i,0UL);
 		wrmsrl(MSR_IA32_MC0_ADDR+4*i,0UL);
 		wrmsrl(MSR_IA32_MC0_CTL+4*i, val);
@@ -637,7 +629,6 @@
    mce=nok8 disable k8 specific features
    mce=disable<NUMBER> disable bank NUMBER
    mce=enable<NUMBER> enable bank number
-   mce=device	Enable device driver test reporting in NB
    mce=NUMBER mcheck timer interval number seconds. 
    Can be also comma separated in a single mce= */
 static int __init mcheck_enable(char *str)
@@ -654,8 +645,6 @@
 			disabled_banks |= 1UL << simple_strtol(p+7,NULL,0);
 		else if (!strcmp(p,"nok8"))
 			nok8 = 1;
-		else if (!strcmp(p,"device"))
-			k8_nb_flags = K8_DRIVER_DEBUG;
 	}
 	return 0;
 }
diff -urN linux-2.4.27-pre6/arch/x86_64/kernel/mpparse.c linux-2.4.27-rc1/arch/x86_64/kernel/mpparse.c
--- linux-2.4.27-pre6/arch/x86_64/kernel/mpparse.c	2004-06-19 17:51:28.135399216 -0700
+++ linux-2.4.27-rc1/arch/x86_64/kernel/mpparse.c	2004-06-19 17:51:29.844470680 -0700
@@ -866,6 +866,7 @@
 
 		for (idx = 0; idx < mp_irq_entries; idx++)
 			if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+				(mp_irqs[idx].mpc_dstapic == ioapic) &&
 				(mp_irqs[idx].mpc_srcbusirq == i ||
 				mp_irqs[idx].mpc_dstirq == i))
 					break;
diff -urN linux-2.4.27-pre6/drivers/acpi/asus_acpi.c linux-2.4.27-rc1/drivers/acpi/asus_acpi.c
--- linux-2.4.27-pre6/drivers/acpi/asus_acpi.c	2004-06-19 17:51:28.142399508 -0700
+++ linux-2.4.27-rc1/drivers/acpi/asus_acpi.c	2004-06-19 17:51:29.852471015 -0700
@@ -1086,8 +1086,8 @@
 	memset(hotk, 0, sizeof(struct asus_hotk));
 
 	hotk->handle = device->handle;
-	sprintf(acpi_device_name(device), "%s", ACPI_HOTK_DEVICE_NAME);
-	sprintf(acpi_device_class(device), "%s", ACPI_HOTK_CLASS);
+	strcpy(acpi_device_name(device), ACPI_HOTK_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_HOTK_CLASS);
 	acpi_driver_data(device) = hotk;
 	hotk->device = device;
 
diff -urN linux-2.4.27-pre6/drivers/acpi/pci_link.c linux-2.4.27-rc1/drivers/acpi/pci_link.c
--- linux-2.4.27-pre6/drivers/acpi/pci_link.c	2004-06-19 17:51:28.147399718 -0700
+++ linux-2.4.27-rc1/drivers/acpi/pci_link.c	2004-06-19 17:51:29.857471224 -0700
@@ -304,31 +304,12 @@
 		struct acpi_resource	end;
 	}                       resource;
 	struct acpi_buffer	buffer = {sizeof(resource)+1, &resource};
-	int			i = 0;
-	int			valid = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_set");
 
 	if (!link || !irq)
 		return_VALUE(-EINVAL);
 
-	/* We don't check irqs the first time around */
-	if (link->irq.setonboot) {
-		/* See if we're already at the target IRQ. */
-		if (irq == link->irq.active)
-			return_VALUE(0);
-
-		/* Make sure the target IRQ in the list of possible IRQs. */
-		for (i=0; i<link->irq.possible_count; i++) {
-			if (irq == link->irq.possible[i])
-				valid = 1;
-		}
-		if (!valid) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Target IRQ %d invalid\n", irq));
-			return_VALUE(-EINVAL);
-		}
-	}
-
 	memset(&resource, 0, sizeof(resource));
 
 	switch(link->irq.resource_type) {
@@ -698,6 +679,9 @@
 	acpi_link.count++;
 
 end:
+	/* disable all links -- to be activated on use */
+	acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+
 	if (result)
 		kfree(link);
 
diff -urN linux-2.4.27-pre6/drivers/acpi/pci_root.c linux-2.4.27-rc1/drivers/acpi/pci_root.c
--- linux-2.4.27-pre6/drivers/acpi/pci_root.c	2004-06-19 17:51:28.148399759 -0700
+++ linux-2.4.27-rc1/drivers/acpi/pci_root.c	2004-06-19 17:51:29.857471224 -0700
@@ -112,6 +112,40 @@
 	}
 }
 
+static acpi_status
+get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
+{
+	int *busnr = (int *)data;
+	struct acpi_resource_address64 address;
+
+	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS64)
+		return AE_OK;
+
+	acpi_resource_to_address64(resource, &address);
+	if ((address.address_length > 0) && 
+	   (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+		*busnr = address.min_address_range;
+
+	return AE_OK;
+}
+
+static acpi_status 
+try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
+{
+	acpi_status status;
+
+	*busnum = -1;
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum);
+	if (ACPI_FAILURE(status))
+		return status;
+	/* Check if we really get a bus number from _CRS */
+	if (*busnum == -1)
+		return AE_ERROR;
+	return AE_OK;
+}
+
 static int
 acpi_pci_root_add (
 	struct acpi_device	*device)
@@ -189,9 +223,22 @@
 	/* Some systems have wrong _BBN */
 	list_for_each_entry(tmp, &acpi_pci_roots, node) {
 		if ((tmp->id.segment == root->id.segment)
-				&& (tmp->id.bus == root->id.bus))
+				&& (tmp->id.bus == root->id.bus)) {
+			int bus = 0;
+			acpi_status status;
+
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
 				"Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
+
+			status = try_get_root_bridge_busnr(root->handle, &bus);
+			if (ACPI_FAILURE(status))
+				break;
+			if (bus != root->id.bus) {
+				printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus);
+				root->id.bus = bus;
+			}
+			break;
+		}
 	}
 
 	/*
diff -urN linux-2.4.27-pre6/drivers/acpi/thermal.c linux-2.4.27-rc1/drivers/acpi/thermal.c
--- linux-2.4.27-pre6/drivers/acpi/thermal.c	2004-06-19 17:51:28.151399885 -0700
+++ linux-2.4.27-rc1/drivers/acpi/thermal.c	2004-06-19 17:51:29.860471349 -0700
@@ -227,6 +227,13 @@
 	status = acpi_get_handle(tz->handle, "_SCP", &handle);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
+		status = acpi_get_handle(tz->handle, "_PSV", &handle);
+		if(!ACPI_FAILURE(status)) {
+			tz->cooling_mode = 1;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", 
+				mode?"passive":"active"));
+			return_VALUE(0);
+		}
 		return_VALUE(-ENODEV);
 	}
 
diff -urN linux-2.4.27-pre6/drivers/hotplug/Config.in linux-2.4.27-rc1/drivers/hotplug/Config.in
--- linux-2.4.27-pre6/drivers/hotplug/Config.in	2004-06-19 17:51:28.184401265 -0700
+++ linux-2.4.27-rc1/drivers/hotplug/Config.in	2004-06-19 17:51:30.093481093 -0700
@@ -17,7 +17,7 @@
 dep_tristate '  SHPC PCI Hotplug driver' CONFIG_HOTPLUG_PCI_SHPC $CONFIG_HOTPLUG_PCI
 dep_mbool '    Use polling mechanism for hot-plug events (for testing purpose)' CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE $CONFIG_HOTPLUG_PCI_SHPC
 if [ "$CONFIG_ACPI" = "n" ]; then
-dep_mbool '    For AMD SHPC only: Use $HRT for resource/configuration' CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY $CONFIG_HOTPLUG_PCI_SHPC 
+dep_mbool '    For AMD SHPC only: Use HRT for resource/configuration' CONFIG_HOTPLUG_PCI_SHPC_PHPRM_LEGACY $CONFIG_HOTPLUG_PCI_SHPC 
 fi
 dep_tristate '  PCI Express Hotplug driver' CONFIG_HOTPLUG_PCI_PCIE $CONFIG_HOTPLUG_PCI
 dep_mbool '    Use polling mechanism for hot-plug events (for testing purpose)' CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE $CONFIG_HOTPLUG_PCI_PCIE
diff -urN linux-2.4.27-pre6/drivers/usb/serial/visor.c linux-2.4.27-rc1/drivers/usb/serial/visor.c
--- linux-2.4.27-pre6/drivers/usb/serial/visor.c	2004-06-19 17:51:28.432411635 -0700
+++ linux-2.4.27-rc1/drivers/usb/serial/visor.c	2004-06-19 17:51:30.885514212 -0700
@@ -890,14 +890,13 @@
 {
 	int response;
 	unsigned char *transfer_buffer;
+	struct palm_ext_connection_info *connection_info;
 
 	dbg("%s", __FUNCTION__);
 
 	dbg("%s - Set config to 1", __FUNCTION__);
 	usb_set_configuration(serial->dev, 1);
 
-	struct palm_ext_connection_info *connection_info;
-
 	transfer_buffer = kmalloc(sizeof (*connection_info),
 					GFP_KERNEL);
 	if (!transfer_buffer) {
diff -urN linux-2.4.27-pre6/drivers/usb/storage/jumpshot.c linux-2.4.27-rc1/drivers/usb/storage/jumpshot.c
--- linux-2.4.27-pre6/drivers/usb/storage/jumpshot.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.27-rc1/drivers/usb/storage/jumpshot.c	2004-06-19 17:51:30.937516386 -0700
@@ -710,15 +710,8 @@
 
 		// build the reply
 		//
-		ptr[0] = (info->sectors >> 24) & 0xFF;
-		ptr[1] = (info->sectors >> 16) & 0xFF;
-		ptr[2] = (info->sectors >> 8) & 0xFF;
-		ptr[3] = (info->sectors) & 0xFF;
-
-		ptr[4] = (info->ssize >> 24) & 0xFF;
-		ptr[5] = (info->ssize >> 16) & 0xFF;
-		ptr[6] = (info->ssize >> 8) & 0xFF;
-		ptr[7] = (info->ssize) & 0xFF;
+		((u32 *) ptr)[0] = cpu_to_be32(info->sectors - 1);
+		((u32 *) ptr)[1] = cpu_to_be32(info->ssize);
 
 		return USB_STOR_TRANSPORT_GOOD;
 	}
diff -urN linux-2.4.27-pre6/fs/hpfs/alloc.c linux-2.4.27-rc1/fs/hpfs/alloc.c
--- linux-2.4.27-pre6/fs/hpfs/alloc.c	1999-06-04 01:06:29.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/alloc.c	2004-06-19 17:51:31.253529600 -0700
@@ -79,11 +79,11 @@
 	} else {
 		if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto uls;
 	}
-	/*if (!tstbits(bmp, nr + n, n + forward)) {
+	if (!tstbits(bmp, nr, n + forward)) {
 		ret = bs + nr;
 		goto rt;
 	}
-	if (!tstbits(bmp, nr + 2*n, n + forward)) {
+	/*if (!tstbits(bmp, nr + n, n + forward)) {
 		ret = bs + nr + n;
 		goto rt;
 	}*/
@@ -103,9 +103,11 @@
 		goto rt;
 	}
 	nr >>= 5;
-	for (i = nr + 1; i != nr; i++, i &= 0x1ff) {
-		if (!bmp[i]) continue;
-		if (n + forward >= 0x3f && bmp[i] != -1) continue;
+	/*for (i = nr + 1; i != nr; i++, i &= 0x1ff) {*/
+	i = nr;
+	do {
+		if (!bmp[i]) goto cont;
+		if (n + forward >= 0x3f && bmp[i] != -1) goto cont;
 		q = i<<5;
 		if (i > 0) {
 			unsigned k = bmp[i-1];
@@ -123,7 +125,9 @@
 			ret = bs + q;
 			goto rt;
 		}
-	}
+		cont:
+		i++, i &= 0x1ff;
+	} while (i != nr);
 	rt:
 	if (ret) {
 		if (s->s_hpfs_chk && ((ret >> 14) != (bs >> 14) || (bmp[(ret & 0x3fff) >> 5] | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) {
@@ -152,45 +156,57 @@
 secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward, int lock)
 {
 	secno sec;
-	unsigned i;
+	int i;
 	unsigned n_bmps;
-	int b = s->s_hpfs_c_bitmap;
 	int f_p = 0;
+	int near_bmp;
 	if (forward < 0) {
 		forward = -forward;
 		f_p = 1;
 	}
 	if (lock) hpfs_lock_creation(s);
-	if (near && near < s->s_hpfs_fs_size)
+	n_bmps = (s->s_hpfs_fs_size + 0x4000 - 1) >> 14;
+	if (near && near < s->s_hpfs_fs_size) {
 		if ((sec = alloc_in_bmp(s, near, n, f_p ? forward : forward/4))) goto ret;
+		near_bmp = near >> 14;
+	} else near_bmp = n_bmps / 2;
+	/*
 	if (b != -1) {
 		if ((sec = alloc_in_bmp(s, b<<14, n, f_p ? forward : forward/2))) {
 			b &= 0x0fffffff;
 			goto ret;
 		}
 		if (b > 0x10000000) if ((sec = alloc_in_bmp(s, (b&0xfffffff)<<14, n, f_p ? forward : 0))) goto ret;
-	}	
-	n_bmps = (s->s_hpfs_fs_size + 0x4000 - 1) >> 14;
-	for (i = 0; i < n_bmps / 2; i++) {
-		if ((sec = alloc_in_bmp(s, (n_bmps/2+i) << 14, n, forward))) {
-			s->s_hpfs_c_bitmap = n_bmps/2+i;
+	}
+	*/
+	if (!f_p) if (forward > s->s_hpfs_max_fwd_alloc) forward = s->s_hpfs_max_fwd_alloc;
+	less_fwd:
+	for (i = 0; i < n_bmps; i++) {
+		if (near_bmp+i < n_bmps && ((sec = alloc_in_bmp(s, (near_bmp+i) << 14, n, forward)))) {
+			s->s_hpfs_c_bitmap = near_bmp+i;
 			goto ret;
 		}	
-		if ((sec = alloc_in_bmp(s, (n_bmps/2-i-1) << 14, n, forward))) {
-			s->s_hpfs_c_bitmap = n_bmps/2-i-1;
+		if (!forward) {
+			if (near_bmp-i-1 >= 0 && ((sec = alloc_in_bmp(s, (near_bmp-i-1) << 14, n, forward)))) {
+				s->s_hpfs_c_bitmap = near_bmp-i-1;
+				goto ret;
+			}
+		} else {
+			if (near_bmp+i >= n_bmps && ((sec = alloc_in_bmp(s, (near_bmp+i-n_bmps) << 14, n, forward)))) {
+				s->s_hpfs_c_bitmap = near_bmp+i-n_bmps;
+				goto ret;
+			}
+		}
+		if (i == 1 && s->s_hpfs_c_bitmap != -1 && ((sec = alloc_in_bmp(s, (s->s_hpfs_c_bitmap) << 14, n, forward)))) {
 			goto ret;
 		}
 	}
-	if ((sec = alloc_in_bmp(s, (n_bmps-1) << 14, n, forward))) {
-		s->s_hpfs_c_bitmap = n_bmps-1;
-		goto ret;
-	}
 	if (!f_p) {
-		for (i = 0; i < n_bmps; i++)
-			if ((sec = alloc_in_bmp(s, i << 14, n, 0))) {
-				s->s_hpfs_c_bitmap = 0x10000000 + i;
-				goto ret;
-			}
+		if (forward) {
+			s->s_hpfs_max_fwd_alloc = forward * 3 / 4;
+			forward /= 2;
+			goto less_fwd;
+		}
 	}
 	sec = 0;
 	ret:
@@ -267,6 +283,8 @@
 		return;
 	}
 	lock_super(s);
+	s->s_hpfs_max_fwd_alloc += n > 0xffff ? 0xffff : n;
+	if (s->s_hpfs_max_fwd_alloc > 0xffffff) s->s_hpfs_max_fwd_alloc = 0xffffff;
 	new_map:
 	if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) {
 		unlock_super(s);
@@ -319,7 +337,7 @@
 	}
 	hpfs_brelse4(&qbh);
 	i = 0;
-	if (s->s_hpfs_c_bitmap != -1 ) {
+	if (s->s_hpfs_c_bitmap != -1) {
 		bmp = hpfs_map_bitmap(s, b, &qbh, "chkdn1");
 		goto chk_bmp;
 	}
diff -urN linux-2.4.27-pre6/fs/hpfs/anode.c linux-2.4.27-rc1/fs/hpfs/anode.c
--- linux-2.4.27-pre6/fs/hpfs/anode.c	2001-06-11 19:15:27.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/anode.c	2004-06-19 17:51:31.253529600 -0700
@@ -112,7 +112,7 @@
 			brelse(bh);
 			return -1;
 		}
-		se = node;
+		se = !fnod ? node : (node + 16384) & ~16383;
 	}	
 	if (!(se = hpfs_alloc_sector(s, se, 1, fsecno*ALLOC_M>ALLOC_FWD_MAX ? ALLOC_FWD_MAX : fsecno*ALLOC_M<ALLOC_FWD_MIN ? ALLOC_FWD_MIN : fsecno*ALLOC_M, 1))) {
 		brelse(bh);
@@ -191,7 +191,6 @@
 		}
 		up = up != node ? anode->up : -1;
 		btree->u.internal[btree->n_used_nodes - 1].file_secno = /*fs*/-1;
-		if (up == -1) anode->up = ra;
 		mark_buffer_dirty(bh);
 		brelse(bh);
 		a = na;
diff -urN linux-2.4.27-pre6/fs/hpfs/buffer.c linux-2.4.27-rc1/fs/hpfs/buffer.c
--- linux-2.4.27-pre6/fs/hpfs/buffer.c	2002-02-25 11:38:08.000000000 -0800
+++ linux-2.4.27-rc1/fs/hpfs/buffer.c	2004-06-19 17:51:31.253529600 -0700
@@ -124,6 +124,8 @@
 {
 	struct buffer_head *bh;
 
+	cond_resched();
+
 	*bhp = bh = sb_bread(s, secno);
 	if (bh != NULL)
 		return bh->b_data;
@@ -140,6 +142,8 @@
 	struct buffer_head *bh;
 	/*return hpfs_map_sector(s, secno, bhp, 0);*/
 
+	cond_resched();
+
 	if ((*bhp = bh = sb_getblk(s, secno)) != NULL) {
 		if (!buffer_uptodate(bh)) wait_on_buffer(bh);
 		mark_buffer_uptodate(bh, 1);
@@ -158,6 +162,8 @@
 	struct buffer_head *bh;
 	char *data;
 
+	cond_resched();
+
 	if (secno & 3) {
 		printk("HPFS: hpfs_map_4sectors: unaligned read\n");
 		return 0;
@@ -209,6 +215,8 @@
 void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
                           struct quad_buffer_head *qbh)
 {
+	cond_resched();
+
 	if (secno & 3) {
 		printk("HPFS: hpfs_get_4sectors: unaligned read\n");
 		return 0;
diff -urN linux-2.4.27-pre6/fs/hpfs/ea.c linux-2.4.27-rc1/fs/hpfs/ea.c
--- linux-2.4.27-pre6/fs/hpfs/ea.c	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/ea.c	2004-06-19 17:51:31.254529642 -0700
@@ -235,7 +235,7 @@
 		}
 		pos += ea->namelen + ea->valuelen + 5;
 	}
-	if (!fnode->ea_size_s) {
+	if (!fnode->ea_offs) {
 		/*if (fnode->ea_size_s) {
 			hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
 				inode->i_ino, fnode->ea_size_s);
@@ -243,15 +243,13 @@
 		}*/
 		fnode->ea_offs = 0xc4;
 	}
-	if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->ea_size_s > 0x200) {
+	if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) {
 		hpfs_error(s, "fnode %08x: ea_offs == %03x, ea_size_s == %03x",
 			inode->i_ino, fnode->ea_offs, fnode->ea_size_s);
 		return;
 	}
 	if ((fnode->ea_size_s || !fnode->ea_size_l) &&
-	     fnode->ea_offs + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) {
-		/* I'm not sure ... maybe we overwrite ACL here. I have no info
-		   on it right now :-( */
+	     fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) {
 		ea = fnode_end_ea(fnode);
 		*(char *)ea = 0;
 		ea->namelen = strlen(key);
diff -urN linux-2.4.27-pre6/fs/hpfs/hpfs.h linux-2.4.27-rc1/fs/hpfs/hpfs.h
--- linux-2.4.27-pre6/fs/hpfs/hpfs.h	2000-08-13 10:22:47.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/hpfs.h	2004-06-19 17:51:31.254529642 -0700
@@ -408,7 +408,7 @@
   unsigned file_size;			/* file length, bytes */
   unsigned n_needea;			/* number of EA's with NEEDEA set */
   char user_id[16];			/* unused */
-  unsigned ea_offs;			/* offset from start of fnode
+  unsigned short ea_offs;		/* offset from start of fnode
 					   to first fnode-resident ea */
   char dasd_limit_treshhold;
   char dasd_limit_delta;
diff -urN linux-2.4.27-pre6/fs/hpfs/hpfs_fn.h linux-2.4.27-rc1/fs/hpfs/hpfs_fn.h
--- linux-2.4.27-pre6/fs/hpfs/hpfs_fn.h	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/hpfs_fn.h	2004-06-19 17:51:31.255529684 -0700
@@ -27,9 +27,6 @@
 
 #include "hpfs.h"
 
-#define memcpy_tofs memcpy
-#define memcpy_fromfs memcpy
-
 #define EIOERROR  EIO
 #define EFSERROR  EPERM
 #define EMEMERROR ENOMEM
@@ -121,12 +118,12 @@
 
 extern inline struct extended_attribute *fnode_ea(struct fnode *fnode)
 {
-	return (struct extended_attribute *)((char *)fnode + fnode->ea_offs);
+	return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->acl_size_s);
 }
 
 extern inline struct extended_attribute *fnode_end_ea(struct fnode *fnode)
 {
-	return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->ea_size_s);
+	return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s);
 }
 
 extern inline struct extended_attribute *next_ea(struct extended_attribute *ea)
diff -urN linux-2.4.27-pre6/fs/hpfs/inode.c linux-2.4.27-rc1/fs/hpfs/inode.c
--- linux-2.4.27-pre6/fs/hpfs/inode.c	2001-09-10 07:31:25.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/inode.c	2004-06-19 17:51:31.255529684 -0700
@@ -192,11 +192,11 @@
 
 void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
 {
-	if (fnode->acl_size_l || fnode->acl_size_s) {
-		/* Some unknown structures like ACL may be in fnode,
-		   we'd better not overwrite them */
+	/*if (fnode->acl_size_l || fnode->acl_size_s) {
+		   Some unknown structures like ACL may be in fnode,
+		   we'd better not overwrite them
 		hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino);
-	} else if (i->i_sb->s_hpfs_eas >= 2) {
+	} else*/ if (i->i_sb->s_hpfs_eas >= 2) {
 		unsigned char ea[4];
 		if ((i->i_uid != i->i_sb->s_hpfs_uid) || i->i_hpfs_ea_uid) {
 			ea[0] = i->i_uid & 0xff;
@@ -259,16 +259,18 @@
 	struct hpfs_dirent *de;
 	if (i->i_ino == i->i_sb->s_hpfs_root) return;
 	if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) return;
-	if (i->i_ino != i->i_sb->s_hpfs_root) {
+	if (i->i_ino != i->i_sb->s_hpfs_root && i->i_nlink) {
 		if (!(de = map_fnode_dirent(i->i_sb, i->i_ino, fnode, &qbh))) {
 			brelse(bh);
 			return;
 		}
 	} else de = NULL;
 	if (S_ISREG(i->i_mode)) {
-		fnode->file_size = de->file_size = i->i_size;
+		fnode->file_size = i->i_size;
+		if (de) de->file_size = i->i_size;
 	} else if (S_ISDIR(i->i_mode)) {
-		fnode->file_size = de->file_size = 0;
+		fnode->file_size = 0;
+		if (de) de->file_size = 0;
 	}
 	hpfs_write_inode_ea(i, fnode);
 	if (de) {
diff -urN linux-2.4.27-pre6/fs/hpfs/map.c linux-2.4.27-rc1/fs/hpfs/map.c
--- linux-2.4.27-pre6/fs/hpfs/map.c	2000-08-13 10:22:47.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/map.c	2004-06-19 17:51:31.255529684 -0700
@@ -142,7 +142,7 @@
 				}
 			}
 			if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 ||
-			   (signed int)fnode->ea_offs + fnode->ea_size_s > 0x200)) {
+			   (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) {
 				hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x",
 					ino, fnode->ea_offs, fnode->ea_size_s);
 				goto bail;
@@ -225,14 +225,16 @@
 			}
 			for (p = 20; p < dnode->first_free; p += d[p] + (d[p+1] << 8)) {
 				struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p);
-				if (de->length > 292 || (de->length < 32) || (de->length & 3)) {
+				if (de->length > 292 || (de->length < 32) || (de->length & 3) || p + de->length > 2048) {
 					hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
 					goto bail;
 				}
 				if (((31 + de->namelen + de->down*4 + 3) & ~3) != de->length) {
+					if (((31 + de->namelen + de->down*4 + 3) & ~3) < de->length && s->s_flags & MS_RDONLY) goto ok;
 					hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
 					goto bail;
 				}
+				ok:
 				if (s->s_hpfs_chk >= 2) b |= 1 << de->down;
 				if (de->down) if (de_down_pointer(de) < 0x10) {
 					hpfs_error(s, "bad down pointer in dnode %08x, dirent %03x, last %03x", secno, p, pp);
diff -urN linux-2.4.27-pre6/fs/hpfs/super.c linux-2.4.27-rc1/fs/hpfs/super.c
--- linux-2.4.27-pre6/fs/hpfs/super.c	2002-08-02 17:39:45.000000000 -0700
+++ linux-2.4.27-rc1/fs/hpfs/super.c	2004-06-19 17:51:31.256529726 -0700
@@ -461,6 +461,7 @@
 	s->s_hpfs_was_error = 0;
 	s->s_hpfs_cp_table = NULL;
 	s->s_hpfs_c_bitmap = -1;
+	s->s_hpfs_max_fwd_alloc = 0xffffff;
 	
 	/* Load bitmap directory */
 	if (!(s->s_hpfs_bmp_dir = hpfs_load_bitmap_directory(s, superblock->bitmaps)))
diff -urN linux-2.4.27-pre6/fs/jbd/transaction.c linux-2.4.27-rc1/fs/jbd/transaction.c
--- linux-2.4.27-pre6/fs/jbd/transaction.c	2004-02-18 05:36:31.000000000 -0800
+++ linux-2.4.27-rc1/fs/jbd/transaction.c	2004-06-19 17:51:31.257529767 -0700
@@ -1694,6 +1694,23 @@
 	return 0;
 }
 
+void debug_page(struct page *p)
+{
+	struct buffer_head *bh;
+
+	bh = p->buffers;
+
+	printk(KERN_ERR "%s: page index:%u count:%d flags:%x\n", __FUNCTION__,
+		 p->index, atomic_read(&p->count), p->flags);
+
+	while (bh) {
+		printk(KERN_ERR "%s: bh b_next:%p blocknr:%u b_list:%u state:%x\n",
+			__FUNCTION__, bh->b_next, bh->b_blocknr, bh->b_list,
+				bh->b_state);
+		bh = bh->b_this_page;
+	} 
+}
+
 
 /** 
  * int journal_try_to_free_buffers() - try to free page buffers.
@@ -1752,6 +1769,11 @@
 	do {
 		struct buffer_head *p = tmp;
 
+		if (!unlikely(tmp)) {
+			debug_page(page);
+			BUG();
+		}
+			
 		tmp = tmp->b_this_page;
 		if (buffer_jbd(p))
 			if (!__journal_try_to_free_buffer(p, &locked_or_dirty))
diff -urN linux-2.4.27-pre6/fs/stat.c linux-2.4.27-rc1/fs/stat.c
--- linux-2.4.27-pre6/fs/stat.c	2004-02-18 05:36:31.000000000 -0800
+++ linux-2.4.27-rc1/fs/stat.c	2004-06-19 17:51:31.275530520 -0700
@@ -52,6 +52,8 @@
 	tmp.st_ino = inode->i_ino;
 	tmp.st_mode = inode->i_mode;
 	tmp.st_nlink = inode->i_nlink;
+	if (tmp.st_nlink != inode->i_nlink)
+		return -EOVERFLOW;
 	SET_OLDSTAT_UID(tmp, inode->i_uid);
 	SET_OLDSTAT_GID(tmp, inode->i_gid);
 	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
@@ -78,6 +80,8 @@
 	tmp.st_ino = inode->i_ino;
 	tmp.st_mode = inode->i_mode;
 	tmp.st_nlink = inode->i_nlink;
+	if (tmp.st_nlink != inode->i_nlink)
+		return -EOVERFLOW;
 	SET_STAT_UID(tmp, inode->i_uid);
 	SET_STAT_GID(tmp, inode->i_gid);
 	tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
diff -urN linux-2.4.27-pre6/include/linux/fs.h linux-2.4.27-rc1/include/linux/fs.h
--- linux-2.4.27-pre6/include/linux/fs.h	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.27-rc1/include/linux/fs.h	2004-06-19 17:51:31.382534994 -0700
@@ -449,7 +449,7 @@
 	atomic_t		i_count;
 	kdev_t			i_dev;
 	umode_t			i_mode;
-	nlink_t			i_nlink;
+	unsigned int		i_nlink;
 	uid_t			i_uid;
 	gid_t			i_gid;
 	kdev_t			i_rdev;
diff -urN linux-2.4.27-pre6/include/linux/hpfs_fs_sb.h linux-2.4.27-rc1/include/linux/hpfs_fs_sb.h
--- linux-2.4.27-pre6/include/linux/hpfs_fs_sb.h	1999-05-16 10:33:30.000000000 -0700
+++ linux-2.4.27-rc1/include/linux/hpfs_fs_sb.h	2004-06-19 17:51:31.382534994 -0700
@@ -30,6 +30,7 @@
 					/*	128 bytes lowercasing table */
 	unsigned *sb_bmp_dir;		/* main bitmap directory */
 	unsigned sb_c_bitmap;		/* current bitmap */
+	unsigned sb_max_fwd_alloc;	/* max forwad allocation */
 	wait_queue_head_t sb_creation_de;/* when creating dirents, nobody else
 					   can alloc blocks */
 	unsigned sb_creation_de_lock : 1;
@@ -60,6 +61,7 @@
 #define s_hpfs_cp_table u.hpfs_sb.sb_cp_table
 #define s_hpfs_bmp_dir u.hpfs_sb.sb_bmp_dir
 #define s_hpfs_c_bitmap u.hpfs_sb.sb_c_bitmap
+#define s_hpfs_max_fwd_alloc u.hpfs_sb.sb_max_fwd_alloc
 #define s_hpfs_creation_de u.hpfs_sb.sb_creation_de
 #define s_hpfs_creation_de_lock u.hpfs_sb.sb_creation_de_lock
 #define s_hpfs_iget_q u.hpfs_sb.sb_iget_q
diff -urN linux-2.4.27-pre6/lib/rwsem-spinlock.c linux-2.4.27-rc1/lib/rwsem-spinlock.c
--- linux-2.4.27-pre6/lib/rwsem-spinlock.c	2004-06-19 17:51:28.648420668 -0700
+++ linux-2.4.27-rc1/lib/rwsem-spinlock.c	2004-06-19 17:51:31.403535873 -0700
@@ -102,6 +102,7 @@
 static inline struct rw_semaphore *__rwsem_wake_one_writer(struct rw_semaphore *sem)
 {
 	struct rwsem_waiter *waiter;
+	struct task_struct *tsk;
 
 	sem->activity = -1;
 
diff -urN linux-2.4.27-pre6/net/ipv4/igmp.c linux-2.4.27-rc1/net/ipv4/igmp.c
--- linux-2.4.27-pre6/net/ipv4/igmp.c	2004-06-19 17:51:28.654420919 -0700
+++ linux-2.4.27-rc1/net/ipv4/igmp.c	2004-06-19 17:51:31.408536082 -0700
@@ -286,7 +286,6 @@
 	if (ip_route_output(&rt, dst, 0, 0, dev->ifindex))
 		return 0;
 	if (rt->rt_src == 0) {
-		kfree_skb(skb);
 		ip_rt_put(rt);
 		return 0;
 	}
diff -urN linux-2.4.27-pre6/net/ipv4/ip_sockglue.c linux-2.4.27-rc1/net/ipv4/ip_sockglue.c
--- linux-2.4.27-pre6/net/ipv4/ip_sockglue.c	2004-06-19 17:51:28.655420960 -0700
+++ linux-2.4.27-rc1/net/ipv4/ip_sockglue.c	2004-06-19 17:51:31.409536123 -0700
@@ -750,6 +750,7 @@
 				err = ip_mc_join_group(sk, &mreq);
 				if (err)
 					break;
+				greqs.gsr_interface = mreq.imr_ifindex;
 				omode = MCAST_INCLUDE;
 				add = 1;
 			} else /* MCAST_LEAVE_SOURCE_GROUP */ {
diff -urN linux-2.4.27-pre6/net/ipv6/netfilter/ip6_tables.c linux-2.4.27-rc1/net/ipv6/netfilter/ip6_tables.c
--- linux-2.4.27-pre6/net/ipv6/netfilter/ip6_tables.c	2004-06-19 17:51:28.669421546 -0700
+++ linux-2.4.27-rc1/net/ipv6/netfilter/ip6_tables.c	2004-06-19 17:51:31.423536709 -0700
@@ -20,6 +20,7 @@
 #include <linux/udp.h>
 #include <linux/icmpv6.h>
 #include <net/ip.h>
+#include <net/ipv6.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <linux/proc_fs.h>
diff -urN linux-2.4.27-pre6/net/ipv6/udp.c linux-2.4.27-rc1/net/ipv6/udp.c
--- linux-2.4.27-pre6/net/ipv6/udp.c	2004-04-14 06:05:41.000000000 -0700
+++ linux-2.4.27-rc1/net/ipv6/udp.c	2004-06-19 17:51:31.426536834 -0700
@@ -521,8 +521,7 @@
 
 static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
-#if defined(CONFIG_FILTER)
-	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
 		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
 			UDP6_INC_STATS_BH(UdpInErrors);
 			IP6_INC_STATS_BH(Ip6InDiscards);
@@ -531,7 +530,6 @@
 		}
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
-#endif
 	if (sock_queue_rcv_skb(sk,skb)<0) {
 		UDP6_INC_STATS_BH(UdpInErrors);
 		IP6_INC_STATS_BH(Ip6InDiscards);
@@ -586,34 +584,26 @@
 				struct sk_buff *skb)
 {
 	struct sock *sk, *sk2;
-	struct sk_buff *buff;
 	int dif;
 
 	read_lock(&udp_hash_lock);
 	sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)];
 	dif = skb->dev->ifindex;
 	sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
-	if (!sk)
-		goto free_skb;
+	if (!sk) {
+		kfree_skb(skb);
+		goto out;
+	}
 
-	buff = NULL;
 	sk2 = sk;
 	while((sk2 = udp_v6_mcast_next(sk2->next, uh->dest, daddr,
 						  uh->source, saddr, dif))) {
-		if (!buff) {
-			buff = skb_clone(skb, GFP_ATOMIC);
-			if (!buff)
-				continue;
-		}
-		if (sock_queue_rcv_skb(sk2, buff) >= 0)
-			buff = NULL;
-	}
-	if (buff)
-		kfree_skb(buff);
-	if (sock_queue_rcv_skb(sk, skb) < 0) {
-free_skb:
-		kfree_skb(skb);
+		struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
+		if (buff)
+			udpv6_queue_rcv_skb(sk2, buff);
 	}
+	udpv6_queue_rcv_skb(sk, skb);
+out:
 	read_unlock(&udp_hash_lock);
 }
 
