home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 31
/
CDASC_31_1996_juillet_aout.iso
/
vrac
/
prept209.zip
/
PREPT209.GZ
/
PREPT209
Wrap
Text File
|
1996-05-29
|
40KB
|
1,363 lines
diff -u --recursive --new-file pre2.0.8/linux/Documentation/ioctl-number.txt linux/Documentation/ioctl-number.txt
--- pre2.0.8/linux/Documentation/ioctl-number.txt Fri May 17 15:32:10 1996
+++ linux/Documentation/ioctl-number.txt Tue May 28 07:39:18 1996
@@ -55,7 +55,6 @@
Ioctl Include File Comments
========================================================
0x00 linux/fs.h only FIBMAP, FIGETBSZ
-0x00 linux/mc146818rtc.h conflict!
0x02 linux/fd.h
0x03 linux/hdreg.h
0x04 linux/umsdos_fs.h
@@ -90,6 +89,7 @@
'm' linux/mtio.h conflict!
'm' linux/soundcard.h conflict!
'n' linux/ncp_fs.h
+'p' linux/mc146818rtc.h
'r' linux/msdos_fs.h
's' linux/cdk.h
't' linux/if_ppp.h no conflict
diff -u --recursive --new-file pre2.0.8/linux/MAINTAINERS linux/MAINTAINERS
--- pre2.0.8/linux/MAINTAINERS Sun May 12 22:54:22 1996
+++ linux/MAINTAINERS Wed May 29 09:51:41 1996
@@ -68,6 +68,12 @@
it has been replaced by a better system and you
should be using that.
+EXT2 FILE SYSTEM
+P: Remy Card
+M: Remy.Card@linux.org
+L: linux-kernel@vger.rutgers.edu
+S: Maintained
+
3C501 NETWORK DRIVER
P: Alan Cox
M: net-patches@lxorguk.ukuu.org.uk
diff -u --recursive --new-file pre2.0.8/linux/Makefile linux/Makefile
--- pre2.0.8/linux/Makefile Tue May 28 08:09:54 1996
+++ linux/Makefile Tue May 28 07:39:47 1996
@@ -1,6 +1,6 @@
VERSION = 1
PATCHLEVEL = 99
-SUBLEVEL = 8
+SUBLEVEL = 9
ARCH = i386
diff -u --recursive --new-file pre2.0.8/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- pre2.0.8/linux/arch/i386/kernel/time.c Tue May 7 16:22:17 1996
+++ linux/arch/i386/kernel/time.c Tue May 28 10:14:17 1996
@@ -10,6 +10,8 @@
* 1995-03-26 Markus Kuhn
* fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
* precision CMOS clock update
+ * 1996-05-03 Ingo Molnar
+ * fixed time warps in do_[slow|fast]_gettimeoffset()
*/
#include <linux/errno.h>
#include <linux/sched.h>
@@ -31,57 +33,102 @@
#ifndef CONFIG_APM /* cycle counter may be unreliable */
/* Cycle counter value at the previous timer interrupt.. */
-static unsigned long long last_timer_cc = 0;
-static unsigned long long init_timer_cc = 0;
+static struct {
+ unsigned long low;
+ unsigned long high;
+} init_timer_cc, last_timer_cc;
+/*
+ * This is more assembly than C, but it's also rather
+ * timing-critical and we have to use assembler to get
+ * reasonable 64-bit arithmetic
+ */
static unsigned long do_fast_gettimeoffset(void)
{
- unsigned long time_low, time_high;
- unsigned long quotient, remainder;
+ register unsigned long eax asm("ax");
+ register unsigned long edx asm("dx");
+ unsigned long tmp, quotient, low_timer, missing_time;
+
+ /* Last jiffie when do_fast_gettimeoffset() was called.. */
+ static unsigned long last_jiffies=0;
+
+ /* Cached "clocks per usec" value.. */
+ static unsigned long cached_quotient=0;
+
+ /* The "clocks per usec" value is calculated once each jiffie */
+ tmp = jiffies;
+ quotient = cached_quotient;
+ low_timer = last_timer_cc.low;
+ missing_time = 0;
+ if (last_jiffies != tmp) {
+ last_jiffies = tmp;
+ /*
+ * test for hanging bottom handler (this means xtime is not
+ * updated yet)
+ */
+ if (test_bit(TIMER_BH, &bh_active) )
+ {
+ missing_time = 997670/HZ;
+ }
- /* Get last timer tick in absolute kernel time */
- __asm__("subl %2,%0\n\t"
- "sbbl %3,%1"
- :"=r" (time_low), "=r" (time_high)
- :"m" (*(0+(long *)&init_timer_cc)),
- "m" (*(1+(long *)&init_timer_cc)),
- "0" (*(0+(long *)&last_timer_cc)),
- "1" (*(1+(long *)&last_timer_cc)));
- /*
- * Divide the 64-bit time with the 32-bit jiffy counter,
- * getting the quotient in clocks.
- *
- * Giving quotient = "average internal clocks per jiffy"
- */
- __asm__("divl %2"
- :"=a" (quotient), "=d" (remainder)
- :"r" (jiffies),
- "0" (time_low), "1" (time_high));
+ /* Get last timer tick in absolute kernel time */
+ eax = low_timer;
+ edx = last_timer_cc.high;
+ __asm__("subl "SYMBOL_NAME_STR(init_timer_cc)",%0\n\t"
+ "sbbl "SYMBOL_NAME_STR(init_timer_cc)"+4,%1"
+ :"=a" (eax), "=d" (edx)
+ :"0" (eax), "1" (edx));
+
+ /*
+ * Divide the 64-bit time with the 32-bit jiffy counter,
+ * getting the quotient in clocks.
+ *
+ * Giving quotient = "average internal clocks per usec"
+ */
+ __asm__("divl %2"
+ :"=a" (eax), "=d" (edx)
+ :"r" (tmp),
+ "0" (eax), "1" (edx));
+
+ edx = 997670/HZ;
+ tmp = eax;
+ eax = 0;
+
+ __asm__("divl %2"
+ :"=a" (eax), "=d" (edx)
+ :"r" (tmp),
+ "0" (eax), "1" (edx));
+ cached_quotient = eax;
+ quotient = eax;
+ }
/* Read the time counter */
__asm__(".byte 0x0f,0x31"
- :"=a" (time_low), "=d" (time_high));
+ :"=a" (eax), "=d" (edx));
/* .. relative to previous jiffy (32 bits is enough) */
- time_low -= (unsigned long) last_timer_cc;
+ edx = 0;
+ eax -= low_timer;
/*
- * Time offset = (1000000/HZ * remainder) / quotient.
+ * Time offset = (997670/HZ * time_low) / quotient.
*/
- __asm__("mull %1\n\t"
- "divl %2"
- :"=a" (quotient), "=d" (remainder)
+
+ __asm__("mull %2"
+ :"=a" (eax), "=d" (edx)
:"r" (quotient),
- "0" (time_low), "1" (1000000/HZ));
+ "0" (eax), "1" (edx));
/*
- * Due to rounding errors (and jiffies inconsistencies),
+ * Due to rounding errors (and jiffies inconsistencies),
* we need to check the result so that we'll get a timer
* that is monotonous.
*/
- if (quotient >= 1000000/HZ)
- quotient = 1000000/HZ-1;
- return quotient;
+ if (edx >= 997670/HZ)
+ edx = 997670/HZ-1;
+
+ eax = edx + missing_time;
+ return eax;
}
#endif
@@ -122,21 +169,63 @@
static unsigned long do_slow_gettimeoffset(void)
{
int count;
+ static int count_p = 0;
unsigned long offset = 0;
+ static unsigned long jiffies_p = 0;
+
+ /*
+ * cache volatile jiffies temporaly, we have IRQs turned off.
+ */
+ unsigned long jiffies_t;
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
- /* we know probability of underflow is always MUCH less than 1% */
- if (count > (LATCH - LATCH/100)) {
- /* check for pending timer interrupt */
- outb_p(0x0a, 0x20);
- if (inb(0x20) & 1)
- offset = TICK_SIZE;
- }
+
+ jiffies_t = jiffies;
+
+ /*
+ * avoiding timer inconsistencies (they are rare, but they happen)...
+ * there are three kinds of problems that must be avoided here:
+ * 1. the timer counter underflows
+ * 2. hardware problem with the timer, not giving us continuous time,
+ * the counter does small "jumps" upwards on some Pentium systems,
+ * thus causes time warps
+ * 3. we are after the timer interrupt, but the bottom half handler
+ * hasn't executed yet.
+ */
+ if( count > count_p ) {
+ if( jiffies_t == jiffies_p ) {
+ if( count > LATCH-LATCH/100 )
+ offset = TICK_SIZE;
+ else
+ /*
+ * argh, the timer is bugging we cant do nothing
+ * but to give the previous clock value.
+ */
+ count = count_p;
+ } else {
+ if( test_bit(TIMER_BH, &bh_active) ) {
+ /*
+ * we have detected a counter underflow.
+ */
+ offset = TICK_SIZE;
+ count_p = count;
+ } else {
+ count_p = count;
+ jiffies_p = jiffies_t;
+ }
+ }
+ } else {
+ count_p = count;
+ jiffies_p = jiffies_t;
+ }
+
+
count = ((LATCH-1) - count) * TICK_SIZE;
count = (count + LATCH/2) / LATCH;
+
return offset + count;
}
@@ -283,8 +372,8 @@
{
/* read Pentium cycle counter */
__asm__(".byte 0x0f,0x31"
- :"=a" (((unsigned long *) &last_timer_cc)[0]),
- "=d" (((unsigned long *) &last_timer_cc)[1]));
+ :"=a" (last_timer_cc.low),
+ "=d" (last_timer_cc.high));
timer_interrupt(irq, NULL, regs);
}
#endif
@@ -375,8 +464,8 @@
do_gettimeoffset = do_fast_gettimeoffset;
/* read Pentium cycle counter */
__asm__(".byte 0x0f,0x31"
- :"=a" (((unsigned long *) &init_timer_cc)[0]),
- "=d" (((unsigned long *) &init_timer_cc)[1]));
+ :"=a" (init_timer_cc.low),
+ "=d" (init_timer_cc.high));
irq0.handler = pentium_timer_interrupt;
}
#endif
diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/boot/mk_type41.c linux/arch/ppc/boot/mk_type41.c
--- pre2.0.8/linux/arch/ppc/boot/mk_type41.c Tue May 28 08:09:54 1996
+++ linux/arch/ppc/boot/mk_type41.c Tue May 28 07:46:04 1996
@@ -40,7 +40,7 @@
}
if ((out_fd = creat(argv[2], 0666)) < 0)
{
- fprintf(stderr, "Can't create outpue file: '%s': %s\n", argv[2], strerror(errno));
+ fprintf(stderr, "Can't create output file: '%s': %s\n", argv[2], strerror(errno));
exit(2);
}
if (fstat(in_fd, &info) < 0)
@@ -185,7 +185,7 @@
* the next two.
* - size of the diskette is (assumed to be)
* (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
- * - unlike the above sector nunbers, the beginning sector is zero-based!
+ * - unlike the above sector numbers, the beginning sector is zero-based!
*/
#if 0
pe->beginning_sector = LeDword(1);
diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/include/elf/ChangeLog linux/arch/ppc/kernel/include/elf/ChangeLog
--- pre2.0.8/linux/arch/ppc/kernel/include/elf/ChangeLog Tue May 28 08:09:55 1996
+++ linux/arch/ppc/kernel/include/elf/ChangeLog Tue May 28 07:46:04 1996
@@ -9,7 +9,7 @@
Tue Feb 14 13:59:13 1995 Michael Meissner <meissner@tiktok.cygnus.com>
- * common.h (EM_PPC): Use offical value of 20, not 17.
+ * common.h (EM_PPC): Use official value of 20, not 17.
(EM_PPC_OLD): Define this to be the old value of EM_PPC.
@@ -108,7 +108,7 @@
* common.h (EM_HPPA, NT_VERSION, STN_UNDEF, DT_*): New macros.
* external.h (Elf_External_Dyn): New type.
- * internal.h (Elf_Intenral_Shdr): New field `size'.
+ * internal.h (Elf_Internal_Shdr): New field `size'.
(Elf_Internal_Dyn): New type.
Tue Apr 20 16:03:45 1993 Fred Fish (fnf@cygnus.com)
diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/ppc_machine.h linux/arch/ppc/kernel/ppc_machine.h
--- pre2.0.8/linux/arch/ppc/kernel/ppc_machine.h Tue May 28 08:09:55 1996
+++ linux/arch/ppc/kernel/ppc_machine.h Tue May 28 07:46:04 1996
@@ -10,7 +10,7 @@
#define MSR_TGPR (1<<17) /* TLB Update registers in use */
#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */
#define MSR_EE (1<<15) /* External Interrupt enable */
-#define MSR_PR (1<<14) /* Supervisor/User privelege */
+#define MSR_PR (1<<14) /* Supervisor/User privilege */
#define MSR_FP (1<<13) /* Floating Point enable */
#define MSR_ME (1<<12) /* Machine Check enable */
#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- pre2.0.8/linux/arch/ppc/kernel/process.c Tue May 28 08:09:55 1996
+++ linux/arch/ppc/kernel/process.c Tue May 28 07:46:04 1996
@@ -2,7 +2,7 @@
* linux/arch/ppc/kernel/process.c
*
* Copyright (C) 1995 Linus Torvalds
- * Adapted for PowerPC by Gary THomas
+ * Adapted for PowerPC by Gary Thomas
*/
/*
diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/support.c linux/arch/ppc/kernel/support.c
--- pre2.0.8/linux/arch/ppc/kernel/support.c Tue May 28 08:09:55 1996
+++ linux/arch/ppc/kernel/support.c Tue May 28 07:46:04 1996
@@ -1,5 +1,5 @@
/*
- * Miscallaneous support routines
+ * Miscellaneous support routines
*/
#include <asm/bitops.h>
diff -u --recursive --new-file pre2.0.8/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- pre2.0.8/linux/arch/ppc/kernel/syscalls.c Tue May 28 08:09:55 1996
+++ linux/arch/ppc/kernel/syscalls.c Tue May 28 07:46:04 1996
@@ -19,7 +19,7 @@
/*
* sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix tranditionally does this, though.
+ * a pipe. It's not the way unix traditionally does this, though.
*/
asmlinkage int sys_pipe(unsigned long * fildes)
{
diff -u --recursive --new-file pre2.0.8/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- pre2.0.8/linux/drivers/char/rtc.c Sun May 12 10:16:07 1996
+++ linux/drivers/char/rtc.c Tue May 28 07:39:18 1996
@@ -30,11 +30,10 @@
*
*/
-#define RTC_VERSION "1.06"
+#define RTC_VERSION "1.07"
#define RTC_IRQ 8 /* Can't see this changing soon. */
-#define RTC_IO_BASE 0x70 /* Or this... */
-#define RTC_IO_EXTENT 0x10 /* Only really 0x70 to 0x71, but... */
+#define RTC_IO_EXTENT 0x10 /* Only really two ports, but... */
/*
* Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
@@ -539,7 +538,7 @@
}
misc_register(&rtc_dev);
/* Check region? Naaah! Just snarf it up. */
- request_region(RTC_IO_BASE, RTC_IO_EXTENT, "rtc");
+ request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
init_timer(&rtc_irq_timer);
rtc_irq_timer.function = rtc_dropped_irq;
rtc_wait = NULL;
diff -u --recursive --new-file pre2.0.8/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- pre2.0.8/linux/drivers/net/eexpress.c Tue May 7 16:22:27 1996
+++ linux/drivers/net/eexpress.c Wed May 29 09:49:25 1996
@@ -1,4 +1,4 @@
-/* $Id: eexpress.c,v 1.12 1996/04/15 17:27:30 phil Exp $
+/* $Id: eexpress.c,v 1.13 1996/05/19 15:59:51 phil Exp $
*
* Intel EtherExpress device driver for Linux
*
@@ -86,7 +86,7 @@
static char version[] =
"eexpress.c: v0.10 04-May-95 John Sullivan <js10039@cam.ac.uk>\n"
-" v0.13 10-Apr-96 Philip Blundell <phil@tazenda.demon.co.uk>\n";
+" v0.14 19-May-96 Philip Blundell <phil@tazenda.demon.co.uk>\n";
#include <linux/module.h>
@@ -103,6 +103,7 @@
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
+#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
@@ -1060,15 +1061,25 @@
printk("%s: eexp_hw_init586()\n", dev->name);
#endif
- PRIV(dev)->started = 0;
+ lp->started = 0;
set_loopback;
outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);
outb_p(i586_RST,ioaddr+EEPROM_Ctrl);
+ udelay(2000); /* delay 20ms */
+ {
+ unsigned short ofs, i;
+ for (ofs = 0; ofs < lp->rx_buf_end; ofs += 32) {
+ outw_p(ofs, ioaddr+SM_PTR);
+ for (i = 0; i < 16; i++) {
+ outw_p(0, ioaddr+SM_ADDR(i<<1));
+ }
+ }
+ }
outw_p(lp->rx_buf_end,ioaddr+WRITE_PTR);
start_code[28] = (dev->flags & IFF_PROMISC)?(start_code[28] | 1):(start_code[28] & ~1);
- PRIV(dev)->promisc = dev->flags & IFF_PROMISC;
+ lp->promisc = dev->flags & IFF_PROMISC;
/* We may die here */
outsw(ioaddr, start_code, sizeof(start_code)>>1);
outw(CONF_HW_ADDR,ioaddr+WRITE_PTR);
@@ -1205,8 +1216,8 @@
static struct device dev_eexp[EEXP_MAX_CARDS] =
{
- NULL, /* will allocate dynamically */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe
+ { NULL, /* will allocate dynamically */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, express_probe },
};
int irq[EEXP_MAX_CARDS] = {0, };
diff -u --recursive --new-file pre2.0.8/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- pre2.0.8/linux/drivers/net/ne.c Tue May 7 16:22:29 1996
+++ linux/drivers/net/ne.c Tue May 28 07:39:18 1996
@@ -229,6 +229,12 @@
}
}
+ /* We should have a "dev" from Space.c or the static module table. */
+ if (dev == NULL) {
+ printk(KERN_ERR "ne.c: Passed a NULL device.\n");
+ dev = init_etherdev(0, 0);
+ }
+
if (ei_debug && version_printed++ == 0)
printk(version);
@@ -344,12 +350,6 @@
return ENXIO;
#endif
- }
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("ne.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
}
if (pci_irq_line) {
diff -u --recursive --new-file pre2.0.8/linux/drivers/net/ppp.c linux/drivers/net/ppp.c
--- pre2.0.8/linux/drivers/net/ppp.c Mon May 20 08:21:01 1996
+++ linux/drivers/net/ppp.c Wed May 29 07:32:38 1996
@@ -6,7 +6,7 @@
* Dynamic PPP devices by Jim Freeman <jfree@caldera.com>.
* ppp_tty_receive ``noisy-raise-bug'' fixed by Ove Ewerlid <ewerlid@syscon.uu.se>
*
- * ==FILEVERSION 960303==
+ * ==FILEVERSION 960528==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
diff -u --recursive --new-file pre2.0.8/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- pre2.0.8/linux/drivers/scsi/scsi.c Wed May 15 11:01:15 1996
+++ linux/drivers/scsi/scsi.c Wed May 29 09:49:26 1996
@@ -580,7 +580,7 @@
printk("\n");
#endif
-if (host_byte(SCpnt->result) != DID_OK) {
+ if (SCpnt->result) {
if (((driver_byte (SCpnt->result) & DRIVER_SENSE) ||
(status_byte (SCpnt->result) & CHECK_CONDITION)) &&
((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
@@ -1569,9 +1569,15 @@
case SUGGEST_IS_OK:
break;
case SUGGEST_REMAP:
+#ifdef DEBUG
+ printk("SENSE SUGGEST REMAP - status = FINISHED\n");
+#endif
+ status = FINISHED;
+ exit = DRIVER_SENSE | SUGGEST_ABORT;
+ break;
case SUGGEST_RETRY:
#ifdef DEBUG
- printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n");
+ printk("SENSE SUGGEST RETRY - status = MAYREDO\n");
#endif
status = MAYREDO;
exit = DRIVER_SENSE | SUGGEST_RETRY;
@@ -1606,6 +1612,9 @@
status = REDO;
break;
case SUGGEST_REMAP:
+ status = FINISHED;
+ exit = DRIVER_SENSE | SUGGEST_ABORT;
+ break;
case SUGGEST_RETRY:
status = MAYREDO;
exit = DRIVER_SENSE | SUGGEST_RETRY;
diff -u --recursive --new-file pre2.0.8/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- pre2.0.8/linux/drivers/scsi/scsi_ioctl.c Mon May 20 08:21:02 1996
+++ linux/drivers/scsi/scsi_ioctl.c Wed May 29 09:49:25 1996
@@ -150,7 +150,7 @@
result = SCpnt->result;
SCpnt->request.rq_status = RQ_INACTIVE;
- if(SCpnt->device->scsi_request_fn)
+ if (!SCpnt->device->was_reset && SCpnt->device->scsi_request_fn)
(*SCpnt->device->scsi_request_fn)();
wake_up(&SCpnt->device->device_wait);
diff -u --recursive --new-file pre2.0.8/linux/fs/isofs/util.c linux/fs/isofs/util.c
--- pre2.0.8/linux/fs/isofs/util.c Wed Nov 8 12:26:10 1995
+++ linux/fs/isofs/util.c Wed May 29 07:26:48 1996
@@ -6,7 +6,7 @@
* convert numbers according to section 7.3.3, etc.
*
* isofs special functions. This file was lifted in its entirety from
- * the bsd386 iso9660 filesystem, by Pace Williamson.
+ * the 386bsd iso9660 filesystem, by Pace Willisson <pace@blitz.com>.
*/
int
diff -u --recursive --new-file pre2.0.8/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- pre2.0.8/linux/fs/nfs/dir.c Sat Apr 27 15:19:58 1996
+++ linux/fs/nfs/dir.c Tue May 28 07:45:19 1996
@@ -476,8 +476,12 @@
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
name, &sattr, &fhandle, &fattr);
- if (!error)
- nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
+ if (!error) {
+ if (fattr.fileid == dir->i_ino)
+ printk("Sony NewsOS 4.1R buggy nfs server?\n");
+ else
+ nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
+ }
iput(dir);
return error;
}
diff -u --recursive --new-file pre2.0.8/linux/fs/read_write.c linux/fs/read_write.c
--- pre2.0.8/linux/fs/read_write.c Fri May 17 15:32:18 1996
+++ linux/fs/read_write.c Wed May 29 15:43:55 1996
@@ -100,7 +100,7 @@
return 0;
}
-asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
+asmlinkage int sys_read(unsigned int fd,char * buf,int count)
{
int error;
struct file * file;
@@ -112,7 +112,7 @@
return -EBADF;
if (!file->f_op || !file->f_op->read)
return -EINVAL;
- if (!count)
+ if (count <= 0)
return 0;
error = locks_verify_area(FLOCK_VERIFY_READ,inode,file,file->f_pos,count);
if (error)
diff -u --recursive --new-file pre2.0.8/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
--- pre2.0.8/linux/include/asm-alpha/bitops.h Sun Apr 21 12:39:02 1996
+++ linux/include/asm-alpha/bitops.h Wed May 29 18:47:38 1996
@@ -31,7 +31,7 @@
:"=&r" (temp),
"=m" (*m),
"=&r" (oldbit)
- :"r" (1UL << (nr & 31)),
+ :"Ir" (1UL << (nr & 31)),
"m" (*m));
return oldbit != 0;
}
@@ -54,7 +54,7 @@
:"=&r" (temp),
"=m" (*m),
"=&r" (oldbit)
- :"r" (1UL << (nr & 31)),
+ :"Ir" (1UL << (nr & 31)),
"m" (*m));
return oldbit != 0;
}
@@ -75,7 +75,7 @@
:"=&r" (temp),
"=m" (*m),
"=&r" (oldbit)
- :"r" (1UL << (nr & 31)),
+ :"Ir" (1UL << (nr & 31)),
"m" (*m));
return oldbit != 0;
}
diff -u --recursive --new-file pre2.0.8/linux/include/asm-i386/checksum.h linux/include/asm-i386/checksum.h
--- pre2.0.8/linux/include/asm-i386/checksum.h Sun May 5 08:52:04 1996
+++ linux/include/asm-i386/checksum.h Tue May 28 12:27:59 1996
@@ -46,7 +46,7 @@
unsigned int ihl) {
unsigned int sum;
- __asm__("
+ __asm__ __volatile__("
movl (%1), %0
subl $4, %2
jbe 2f
diff -u --recursive --new-file pre2.0.8/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- pre2.0.8/linux/include/asm-i386/system.h Fri Apr 5 13:35:28 1996
+++ linux/include/asm-i386/system.h Wed May 29 18:06:39 1996
@@ -199,18 +199,21 @@
switch (size) {
case 1:
__asm__("xchgb %b0,%1"
- :"=&q" (x), "=m" (*__xg(ptr))
- :"0" (x), "m" (*__xg(ptr)));
+ :"=q" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
break;
case 2:
__asm__("xchgw %w0,%1"
- :"=&r" (x), "=m" (*__xg(ptr))
- :"0" (x), "m" (*__xg(ptr)));
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
break;
case 4:
__asm__("xchgl %0,%1"
- :"=&r" (x), "=m" (*__xg(ptr))
- :"0" (x), "m" (*__xg(ptr)));
+ :"=r" (x)
+ :"m" (*__xg(ptr)), "0" (x)
+ :"memory");
break;
}
return x;
diff -u --recursive --new-file pre2.0.8/linux/include/asm-ppc/posix_types.h linux/include/asm-ppc/posix_types.h
--- pre2.0.8/linux/include/asm-ppc/posix_types.h Tue May 28 08:09:57 1996
+++ linux/include/asm-ppc/posix_types.h Tue May 28 07:46:04 1996
@@ -1,5 +1,5 @@
#ifndef _PPC_POSIX_TYPES_H
-#define _PPc_POSIX_TYPES_H
+#define _PPC_POSIX_TYPES_H
/*
* This file is generally used by user-level software, so you need to
@@ -95,4 +95,4 @@
#endif /* __GNUC__ */
-#endif /* _PPc_POSIX_TYPES_H */
+#endif /* _PPC_POSIX_TYPES_H */
diff -u --recursive --new-file pre2.0.8/linux/include/linux/mc146818rtc.h linux/include/linux/mc146818rtc.h
--- pre2.0.8/linux/include/linux/mc146818rtc.h Tue May 7 16:22:38 1996
+++ linux/include/linux/mc146818rtc.h Tue May 28 07:39:19 1996
@@ -107,25 +107,7 @@
#endif
/*
- * ioctl calls that are permitted to the /dev/rtc interface, if
- * CONFIG_RTC was enabled.
- */
-
-#define RTC_AIE_ON 0x01 /* Alarm int. enable on */
-#define RTC_AIE_OFF 0x02 /* ... off */
-#define RTC_UIE_ON 0x03 /* Update int. enable on */
-#define RTC_UIE_OFF 0x04 /* ... off */
-#define RTC_PIE_ON 0x05 /* Periodic int. enable on */
-#define RTC_PIE_OFF 0x06 /* ... off */
-#define RTC_ALM_SET 0x07 /* Set alarm (struct tm) */
-#define RTC_ALM_READ 0x08 /* Read alarm (struct tm) */
-#define RTC_RD_TIME 0x09 /* Read RTC time (struct tm) */
-#define RTC_SET_TIME 0x0a /* Set time of RTC (not used) */
-#define RTC_IRQP_READ 0x0b /* Read periodic IRQ rate (Hz) */
-#define RTC_IRQP_SET 0x0c /* Set periodic IRQ rate (Hz) */
-
-/*
- * The struct used to pass data via the above ioctl. Similar to the
+ * The struct used to pass data via the following ioctl. Similar to the
* struct tm in <time.h>, but it needs to be here so that the kernel
* source is self contained, allowing cross-compiles, etc. etc.
*/
@@ -141,5 +123,25 @@
int tm_yday;
int tm_isdst;
};
+
+/*
+ * ioctl calls that are permitted to the /dev/rtc interface, if
+ * CONFIG_RTC was enabled.
+ */
+
+#define RTC_AIE_ON _IO('p', 0x01) /* Alarm int. enable on */
+#define RTC_AIE_OFF _IO('p', 0x02) /* ... off */
+#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
+#define RTC_UIE_OFF _IO('p', 0x04) /* ... off */
+#define RTC_PIE_ON _IO('p', 0x05) /* Periodic int. enable on */
+#define RTC_PIE_OFF _IO('p', 0x06) /* ... off */
+
+#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
+#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
+#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */
+#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
+#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
+#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
+
#endif /* _MC146818RTC_H */
diff -u --recursive --new-file pre2.0.8/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- pre2.0.8/linux/kernel/ksyms.c Tue May 21 19:52:39 1996
+++ linux/kernel/ksyms.c Wed May 29 16:42:27 1996
@@ -163,7 +163,6 @@
X(__bforget),
X(ll_rw_block),
X(__wait_on_buffer),
- X(__wait_on_page),
X(mark_buffer_uptodate),
X(unlock_buffer),
X(dcache_lookup),
diff -u --recursive --new-file pre2.0.8/linux/mm/filemap.c linux/mm/filemap.c
--- pre2.0.8/linux/mm/filemap.c Tue May 21 19:52:39 1996
+++ linux/mm/filemap.c Wed May 29 16:44:11 1996
@@ -42,6 +42,19 @@
*/
/*
+ * This is a special fast page-free routine that _only_ works
+ * on page-cache pages that we are currently using. We can
+ * just decrement the page count, because we know that the page
+ * has a count > 1 (the page cache itself counts as one, and
+ * we're currently using it counts as one). So we don't need
+ * the full free_page() stuff..
+ */
+static inline void release_page(struct page * page)
+{
+ atomic_dec(&page->count);
+}
+
+/*
* Invalidate the pages of an inode, removing all pages that aren't
* locked down (those are sure to be up-to-date anyway, so we shouldn't
* invalidate them).
@@ -228,12 +241,9 @@
len = count;
page = find_page(inode, pos);
if (page) {
- unsigned long addr;
-
wait_on_page(page);
- addr = page_address(page);
- memcpy((void *) (offset + addr), buf, len);
- free_page(addr);
+ memcpy((void *) (offset + page_address(page)), buf, len);
+ release_page(page);
}
count -= len;
buf += len;
@@ -273,7 +283,7 @@
#if 1
page = find_page(inode, offset);
if (page) {
- page->count--;
+ release_page(page);
return page_cache;
}
/*
@@ -291,12 +301,15 @@
/*
* Wait for IO to complete on a locked page.
+ *
+ * This must be called with the caller "holding" the page,
+ * ie with increased "page->count" so that the page won't
+ * go away during the wait..
*/
void __wait_on_page(struct page *page)
{
struct wait_queue wait = { current, NULL };
- page->count++;
add_wait_queue(&page->wait, &wait);
repeat:
run_task_queue(&tq_disk);
@@ -306,7 +319,6 @@
goto repeat;
}
remove_wait_queue(&page->wait, &wait);
- page->count--;
current->state = TASK_RUNNING;
}
@@ -558,9 +570,6 @@
unsigned long pos, ppos, page_cache;
int reada_ok;
- if (count <= 0)
- return 0;
-
error = 0;
read = 0;
page_cache = 0;
@@ -608,45 +617,18 @@
for (;;) {
struct page *page;
- unsigned long offset, addr, nr;
if (pos >= inode->i_size)
break;
- offset = pos & ~PAGE_MASK;
- nr = PAGE_SIZE - offset;
- /*
- * Try to find the data in the page cache..
- */
- page = find_page(inode, pos & PAGE_MASK);
- if (page)
- goto found_page;
/*
- * Ok, it wasn't cached, so we need to create a new
- * page..
- */
- if (page_cache)
- goto new_page;
-
- error = -ENOMEM;
- page_cache = __get_free_page(GFP_KERNEL);
- if (!page_cache)
- break;
- error = 0;
-
- /*
- * That could have slept, so we need to check again..
+ * Try to find the data in the page cache..
*/
- if (pos >= inode->i_size)
- break;
page = find_page(inode, pos & PAGE_MASK);
if (!page)
- goto new_page;
+ goto no_cached_page;
found_page:
- addr = page_address(page);
- if (nr > count)
- nr = count;
/*
* Try to read ahead only if the current page is filled or being filled.
* Otherwise, if we were reading ahead, decrease max read ahead size to
@@ -659,15 +641,27 @@
else if (reada_ok && filp->f_ramax > MIN_READAHEAD)
filp->f_ramax = MIN_READAHEAD;
- if (PageLocked(page))
- __wait_on_page(page);
+ wait_on_page(page);
if (!PageUptodate(page))
- goto read_page;
+ goto page_read_error;
+
+success:
+ /*
+ * Ok, we have the page, it's up-to-date and ok,
+ * so now we can finally copy it to user space...
+ */
+ {
+ unsigned long offset, nr;
+ offset = pos & ~PAGE_MASK;
+ nr = PAGE_SIZE - offset;
+ if (nr > count)
+ nr = count;
+
if (nr > inode->i_size - pos)
nr = inode->i_size - pos;
- memcpy_tofs(buf, (void *) (addr + offset), nr);
- free_page(addr);
+ memcpy_tofs(buf, (void *) (page_address(page) + offset), nr);
+ release_page(page);
buf += nr;
pos += nr;
read += nr;
@@ -675,13 +669,28 @@
if (count)
continue;
break;
-
+ }
+
+no_cached_page:
+ /*
+ * Ok, it wasn't cached, so we need to create a new
+ * page..
+ */
+ if (!page_cache) {
+ page_cache = __get_free_page(GFP_KERNEL);
+ /*
+ * That could have slept, so go around to the
+ * very beginning..
+ */
+ if (page_cache)
+ continue;
+ error = -ENOMEM;
+ break;
+ }
-new_page:
/*
* Ok, add the new page to the hash-queues...
*/
- addr = page_cache;
page = mem_map + MAP_NR(page_cache);
page_cache = 0;
add_to_page_cache(page, inode, pos & PAGE_MASK);
@@ -694,7 +703,6 @@
* identity of the reader can decide if we can read the
* page or not..
*/
-read_page:
/*
* We have to read the page.
* If we were reading ahead, we had previously tried to read this page,
@@ -706,12 +714,25 @@
filp->f_ramax = MIN_READAHEAD;
error = inode->i_op->readpage(inode, page);
+ if (!error)
+ goto found_page;
+ release_page(page);
+ break;
+
+page_read_error:
+ /*
+ * We found the page, but it wasn't up-to-date.
+ * Try to re-read it _once_. We do this synchronously,
+ * because this happens only if there were errors.
+ */
+ error = inode->i_op->readpage(inode, page);
if (!error) {
- if (!PageError(page))
- goto found_page;
- error = -EIO;
+ wait_on_page(page);
+ if (PageUptodate(page) && !PageError(page))
+ goto success;
+ error = -EIO; /* Some unspecified error occurred.. */
}
- free_page(addr);
+ release_page(page);
break;
}
@@ -729,78 +750,125 @@
}
/*
- * Find a cached page and wait for it to become up-to-date, return
- * the page address. Increments the page count.
+ * Semantics for shared and private memory areas are different past the end
+ * of the file. A shared mapping past the last page of the file is an error
+ * and results in a SIGBUS, while a private mapping just maps in a zero page.
+ *
+ * The goto's are kind of ugly, but this streamlines the normal case of having
+ * it in the page cache, and handles the special cases reasonably without
+ * having a lot of duplicated code.
*/
-static inline unsigned long fill_page(struct inode * inode, unsigned long offset)
+static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
{
+ unsigned long offset;
struct page * page;
- unsigned long new_page;
+ struct inode * inode = area->vm_inode;
+ unsigned long old_page, new_page;
+
+ new_page = 0;
+ offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
+ if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
+ goto no_page;
+ /*
+ * Do we have something in the page cache already?
+ */
page = find_page(inode, offset);
- if (page)
- goto found_page_dont_free;
+ if (!page)
+ goto no_cached_page;
+
+found_page:
+ /*
+ * Ok, found a page in the page cache, now we need to check
+ * that it's up-to-date
+ */
+ wait_on_page(page);
+ if (!PageUptodate(page))
+ goto page_read_error;
+
+success:
+ /*
+ * Found the page, need to check sharing and possibly
+ * copy it over to another page..
+ */
+ old_page = page_address(page);
+ if (!no_share) {
+ /*
+ * Ok, we can share the cached page directly.. Get rid
+ * of any potential extra pages.
+ */
+ if (new_page)
+ free_page(new_page);
+
+ flush_page_to_ram(old_page);
+ return old_page;
+ }
+
+ /*
+ * Check that we have another page to copy it over to..
+ */
+ if (!new_page) {
+ new_page = __get_free_page(GFP_KERNEL);
+ if (!new_page)
+ goto failure;
+ }
+ memcpy((void *) new_page, (void *) old_page, PAGE_SIZE);
+ flush_page_to_ram(new_page);
+ release_page(page);
+ return new_page;
+
+no_cached_page:
new_page = __get_free_page(GFP_KERNEL);
+ if (!new_page)
+ goto no_page;
+
+ /*
+ * During getting the above page we might have slept,
+ * so we need to re-check the situation with the page
+ * cache.. The page we just got may be useful if we
+ * can't share, so don't get rid of it here.
+ */
page = find_page(inode, offset);
if (page)
goto found_page;
- if (!new_page)
- goto failure;
+
+ /*
+ * Now, create a new page-cache page from the page we got
+ */
page = mem_map + MAP_NR(new_page);
new_page = 0;
add_to_page_cache(page, inode, offset);
- inode->i_op->readpage(inode, page);
+
+ if (inode->i_op->readpage(inode, page) != 0)
+ goto failure;
+
+ /*
+ * Do a very limited read-ahead if appropriate
+ */
if (PageLocked(page))
new_page = try_to_read_ahead(inode, offset + PAGE_SIZE, 0);
-found_page:
- if (new_page)
- free_page(new_page);
-found_page_dont_free:
- wait_on_page(page);
- if (PageUptodate(page)) {
-success:
- return page_address(page);
- }
- /* If not marked as error, try _once_ to read it again */
- if (!PageError(page)) {
- inode->i_op->readpage(inode, page);
- wait_on_page(page);
- if (PageUptodate(page))
- goto success;
- }
- page->count--;
-failure:
- return 0;
-}
-
-/*
- * Semantics for shared and private memory areas are different past the end
- * of the file. A shared mapping past the last page of the file is an error
- * and results in a SIGBUS, while a private mapping just maps in a zero page.
- */
-static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
-{
- unsigned long offset;
- struct inode * inode = area->vm_inode;
- unsigned long page;
+ goto found_page;
- offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
- if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
- return 0;
+page_read_error:
+ /*
+ * Umm, take care of errors if the page isn't up-to-date.
+ * Try to re-read it _once_.
+ */
+ if (inode->i_op->readpage(inode, page) != 0)
+ goto failure;
+ if (PageError(page))
+ goto failure;
+ if (PageUptodate(page))
+ goto success;
- page = fill_page(inode, offset);
- if (page && no_share) {
- unsigned long new_page = __get_free_page(GFP_KERNEL);
- if (new_page) {
- memcpy((void *) new_page, (void *) page, PAGE_SIZE);
- flush_page_to_ram(new_page);
- }
- free_page(page);
- return new_page;
- }
- if (page)
- flush_page_to_ram(page);
- return page;
+ /*
+ * Uhhuh.. Things didn't work out. Return zero to tell the
+ * mm layer so, possibly freeing the page cache page first.
+ */
+failure:
+ release_page(page);
+no_page:
+ return 0;
}
/*
diff -u --recursive --new-file pre2.0.8/linux/mm/kmalloc.c linux/mm/kmalloc.c
--- pre2.0.8/linux/mm/kmalloc.c Fri Apr 5 13:35:28 1996
+++ linux/mm/kmalloc.c Wed May 29 17:59:34 1996
@@ -171,6 +171,38 @@
#define BLOCKSIZE(order) (blocksize[order])
#define AREASIZE(order) (PAGE_SIZE<<(sizes[order].gfporder))
+/*
+ * Create a small cache of page allocations: this helps a bit with
+ * those pesky 8kB+ allocations for NFS when we're temporarily
+ * out of memory..
+ *
+ * This is a _truly_ small cache, we just cache one single page
+ * order (for orders 0, 1 and 2, that is 4, 8 and 16kB on x86).
+ */
+#define MAX_CACHE_ORDER 3
+struct page_descriptor * kmalloc_cache[MAX_CACHE_ORDER];
+
+static inline struct page_descriptor * get_kmalloc_pages(unsigned long priority,
+ unsigned long order, int dma)
+{
+ struct page_descriptor * tmp;
+
+ tmp = (struct page_descriptor *) __get_free_pages(priority, order, dma);
+ if (!tmp && !dma && order < MAX_CACHE_ORDER)
+ tmp = xchg(kmalloc_cache+order, tmp);
+ return tmp;
+}
+
+static inline void free_kmalloc_pages(struct page_descriptor * page,
+ unsigned long order, int dma)
+{
+ if (!dma && order < MAX_CACHE_ORDER) {
+ page = xchg(kmalloc_cache+order, page);
+ if (!page)
+ return;
+ }
+ free_pages((unsigned long) page, order);
+}
long kmalloc_init(long start_mem, long end_mem)
{
@@ -260,8 +292,7 @@
/* sz is the size of the blocks we're dealing with */
sz = BLOCKSIZE(order);
- page = (struct page_descriptor *) __get_free_pages(priority,
- sizes[order].gfporder, dma);
+ page = get_kmalloc_pages(priority, sizes[order].gfporder, dma);
if (!page)
goto no_free_page;
@@ -322,7 +353,7 @@
void kfree(void *ptr)
{
- int size;
+ int size, dma;
unsigned long flags;
int order;
register struct block_header *p;
@@ -331,10 +362,12 @@
if (!ptr)
return;
p = ((struct block_header *) ptr) - 1;
+ dma = 0;
page = PAGE_DESC(p);
order = page->order;
pg = &sizes[order].firstfree;
if (p->bh_flags == MF_DMA) {
+ dma = 1;
p->bh_flags = MF_USED;
pg = &sizes[order].dmafree;
}
@@ -378,7 +411,7 @@
pg = &tmp->next;
}
sizes[order].npages--;
- free_pages((long) page, sizes[order].gfporder);
+ free_kmalloc_pages(page, sizes[order].gfporder, dma);
}
sizes[order].nfrees++;
sizes[order].nbytesmalloced -= size;
diff -u --recursive --new-file pre2.0.8/linux/mm/page_io.c linux/mm/page_io.c
--- pre2.0.8/linux/mm/page_io.c Tue Apr 23 13:57:14 1996
+++ linux/mm/page_io.c Wed May 29 16:52:31 1996
@@ -76,10 +76,10 @@
else
kstat.pswpout++;
page = mem_map + MAP_NR(buf);
+ atomic_inc(&page->count);
wait_on_page(page);
if (p->swap_device) {
if (!wait) {
- page->count++;
set_bit(PG_free_after, &page->flags);
set_bit(PG_decr_after, &page->flags);
set_bit(PG_swap_unlock_after, &page->flags);
@@ -87,6 +87,11 @@
nr_async_pages++;
}
ll_rw_page(rw,p->swap_device,offset,buf);
+ /*
+ * NOTE! We don't decrement the page count if we
+ * don't wait - that will happen asynchronously
+ * when the IO completes.
+ */
if (!wait)
return;
wait_on_page(page);
@@ -130,6 +135,7 @@
ll_rw_swap_file(rw,swapf->i_dev, zones, i,buf);
} else
printk("rw_swap_page: no swap file or device\n");
+ atomic_dec(&page->count);
if (offset && !clear_bit(offset,p->swap_lockmap))
printk("rw_swap_page: lock already cleared\n");
wake_up(&lock_queue);
diff -u --recursive --new-file pre2.0.8/linux/mm/swapfile.c linux/mm/swapfile.c
--- pre2.0.8/linux/mm/swapfile.c Tue May 7 16:22:40 1996
+++ linux/mm/swapfile.c Tue May 28 07:39:18 1996
@@ -318,12 +318,13 @@
struct inode * inode;
struct file filp;
int i, type, prev;
+ int err;
if (!suser())
return -EPERM;
- i = namei(specialfile,&inode);
- if (i)
- return i;
+ err = namei(specialfile,&inode);
+ if (err)
+ return err;
prev = -1;
for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
p = swap_info + type;
@@ -353,13 +354,21 @@
swap_list.next = swap_list.head;
}
p->flags = SWP_USED;
- i = try_to_unuse(type);
- if (i) {
+ err = try_to_unuse(type);
+ if (err) {
iput(inode);
+ /* re-insert swap space back into swap_list */
+ for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
+ if (p->prio >= swap_info[i].prio)
+ break;
+ p->next = i;
+ if (prev < 0)
+ swap_list.head = swap_list.next = p - swap_info;
+ else
+ swap_info[prev].next = p - swap_info;
p->flags = SWP_WRITEOK;
- return i;
+ return err;
}
-
if(p->swap_device){
memset(&filp, 0, sizeof(filp));
filp.f_inode = inode;
diff -u --recursive --new-file pre2.0.8/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- pre2.0.8/linux/net/ipv4/ip_fw.c Tue May 28 08:10:01 1996
+++ linux/net/ipv4/ip_fw.c Wed May 29 14:24:12 1996
@@ -541,7 +541,13 @@
#ifdef CONFIG_IP_TRANSPARENT_PROXY
if (policy&IP_FW_F_REDIR) {
if (redirport)
- *redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp]);
+ if ((*redirport = htons(f->fw_pts[f->fw_nsp+f->fw_ndp])) == 0) {
+ /* Wildcard redirection.
+ * Note that redirport will become
+ * 0xFFFF for non-TCP/UDP packets.
+ */
+ *redirport = dst_port;
+ }
answer = FW_REDIRECT;
} else
#endif