aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@cc.helsinki.fi>1994-02-07 14:58:39 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:31 -0400
commitd5a0671f4362f508274b5d32a5cdf222e8dae5ec (patch)
tree8151d96fcd458e2da336cfb18aac0f1512673f80
parente2778b587aa9fb80b1ce6bf12ff05ab1f7520dde (diff)
downloadarchive-d5a0671f4362f508274b5d32a5cdf222e8dae5ec.tar.gz
ALPHA-pl15a
[ Message-ID: <2jaihl$21l@klaava.Helsinki.FI> ] - pl15a fixes the buffer cache growing problem, adds emulation for a few unimportant floating point instructions (i287 instructions that are No-Ops on the i387, so "emulating" them is easy :^) and fixes a silly bug when mmap'ing stuff write-only. It also fixes a buggy lock in the networking.
-rw-r--r--Makefile2
-rw-r--r--drivers/FPU-emu/fpu_aux.c19
-rw-r--r--drivers/char/console.c5
-rw-r--r--drivers/char/tty_ioctl.c3
-rw-r--r--drivers/scsi/scsi.c2
-rw-r--r--fs/buffer.c29
-rw-r--r--fs/ext2/inode.c5
-rw-r--r--include/asm/io.h13
-rw-r--r--init/main.c13
-rw-r--r--mm/memory.c4
-rw-r--r--mm/mmap.c4
-rw-r--r--net/inet/dev.c102
-rw-r--r--net/inet/ip.c1
-rw-r--r--net/inet/ip.h1
-rw-r--r--net/inet/raw.c2
-rw-r--r--net/inet/tcp.h1
16 files changed, 117 insertions, 89 deletions
diff --git a/Makefile b/Makefile
index 06a544e..b15808f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 0.99
PATCHLEVEL = 15
-ALPHA =
+ALPHA = a
all: Version zImage
diff --git a/drivers/FPU-emu/fpu_aux.c b/drivers/FPU-emu/fpu_aux.c
index c1835d4..d9f3a22 100644
--- a/drivers/FPU-emu/fpu_aux.c
+++ b/drivers/FPU-emu/fpu_aux.c
@@ -17,6 +17,9 @@
#include "control_w.h"
+static void fnop(void)
+{
+}
void fclex(void)
{
@@ -47,9 +50,16 @@ void finit()
FPU_entry_eip = ip_offset = 0;
}
+/*
+ * These are nops on the i387..
+ */
+#define feni fnop
+#define fdisi fnop
+#define fsetpm fnop
+
static FUNC const finit_table[] = {
- Un_impl, Un_impl, fclex, finit,
- Un_impl, FPU_illegal, FPU_illegal, FPU_illegal
+ feni, fdisi, fclex, finit,
+ fsetpm, FPU_illegal, FPU_illegal, FPU_illegal
};
void finit_()
@@ -75,11 +85,6 @@ void fstsw_()
}
-
-static void fnop(void)
-{
-}
-
static FUNC const fp_nop_table[] = {
fnop, FPU_illegal, FPU_illegal, FPU_illegal,
FPU_illegal, FPU_illegal, FPU_illegal, FPU_illegal
diff --git a/drivers/char/console.c b/drivers/char/console.c
index a228898..cfd1e0c 100644
--- a/drivers/char/console.c
+++ b/drivers/char/console.c
@@ -1800,12 +1800,11 @@ int paste_selection(struct tty_struct *tty)
if (! *bp)
return 0;
unblank_screen();
- while (*bp)
- {
+ while (*bp) {
put_tty_queue(*bp, &tty->read_q);
bp++;
+ TTY_READ_FLUSH(tty);
}
- TTY_READ_FLUSH(tty);
return 0;
}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 1f4b50e..bb9474d 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -550,6 +550,9 @@ int tty_ioctl(struct inode * inode, struct file * file,
return set_selection(arg);
case 3:
return paste_selection(tty);
+ case 4:
+ unblank_screen();
+ return 0;
#endif /* CONFIG_SELECTION */
default:
return -EINVAL;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a2083b8..6025755 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -136,6 +136,8 @@ static struct blist blacklist[] =
{"SEAGATE", "ST296","921"}, /* Responds to all lun */
{"SONY","CD-ROM CDU-541","4.3d"},
{"TANDBERG","TDC 3600","U07"}, /* Locks up if polled for lun != 0 */
+ {"TEAC","CD-ROM","1.06"}, /* causes failed REQUEST SENSE on lun 1 for seagate
+ * controller, which causes SCSI code to reset bus.*/
{"TEXEL","CD-ROM","1.06"}, /* causes failed REQUEST SENSE on lun 1 for seagate
* controller, which causes SCSI code to reset bus.*/
{NULL, NULL, NULL}};
diff --git a/fs/buffer.c b/fs/buffer.c
index 1d00868..31c203d 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -956,7 +956,11 @@ int shrink_buffers(unsigned int priority)
bh = free_list;
i = nr_buffers >> priority;
for ( ; i-- > 0 ; bh = bh->b_next_free) {
- if (bh->b_count || !bh->b_this_page)
+ if (bh->b_count) {
+ put_last_free(bh);
+ continue;
+ }
+ if (!bh->b_this_page)
continue;
if (bh->b_lock)
if (priority)
@@ -975,6 +979,29 @@ int shrink_buffers(unsigned int priority)
return 0;
}
+void show_buffers(void)
+{
+ struct buffer_head * bh;
+ int found = 0, locked = 0, dirty = 0, used = 0, lastused = 0;
+
+ printk("Buffer memory: %6dkB\n",buffermem>>10);
+ printk("Buffer heads: %6d\n",nr_buffer_heads);
+ printk("Buffer blocks: %6d\n",nr_buffers);
+ bh = free_list;
+ do {
+ found++;
+ if (bh->b_lock)
+ locked++;
+ if (bh->b_dirt)
+ dirty++;
+ if (bh->b_count)
+ used++, lastused = found;
+ bh = bh->b_next_free;
+ } while (bh != free_list);
+ printk("Buffer mem: %d buffers, %d used (last=%d), %d locked, %d dirty\n",
+ found, used, lastused, locked, dirty);
+}
+
/*
* This initializes the initial buffer free list. nr_buffers is set
* to one less the actual number of buffers, as a sop to backwards
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 3f0230e..050b0f2 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -69,10 +69,11 @@ void ext2_discard_prealloc (struct inode * inode)
{
#ifdef EXT2_PREALLOCATE
if (inode->u.ext2_i.i_prealloc_count) {
+ int i = inode->u.ext2_i.i_prealloc_count;
+ inode->u.ext2_i.i_prealloc_count = 0;
ext2_free_blocks (inode->i_sb,
inode->u.ext2_i.i_prealloc_block,
- inode->u.ext2_i.i_prealloc_count);
- inode->u.ext2_i.i_prealloc_count = 0;
+ i);
}
#endif
}
diff --git a/include/asm/io.h b/include/asm/io.h
index a2527c1..09c494c 100644
--- a/include/asm/io.h
+++ b/include/asm/io.h
@@ -2,6 +2,19 @@
#define _ASM_IO_H
/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
+ * versions of the single-IO instructions (inb_p/inw_p/..).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
diff --git a/init/main.c b/init/main.c
index 41309a4..f86cf12 100644
--- a/init/main.c
+++ b/init/main.c
@@ -326,6 +326,17 @@ static void parse_options(char *line)
envp_init[envs+1] = NULL;
}
+static void copy_options(char * to, char * from)
+{
+ char c = ' ';
+
+ do {
+ if (c == ' ' && !memcmp("mem=", from, 4))
+ memory_end = simple_strtoul(from+4, &from, 0);
+ c = *(to++) = *(from++);
+ } while (c);
+}
+
static void copro_timeout(void)
{
fpu_error = 1;
@@ -351,7 +362,7 @@ asmlinkage void start_kernel(void)
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= PAGE_MASK;
ramdisk_size = RAMDISK_SIZE;
- strcpy(command_line,COMMAND_LINE);
+ copy_options(command_line,COMMAND_LINE);
#ifdef CONFIG_MAX_16M
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
diff --git a/mm/memory.c b/mm/memory.c
index 57cee25..0168a8d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -981,9 +981,6 @@ void show_mem(void)
printk("Free pages: %6dkB\n",nr_free_pages<<(PAGE_SHIFT-10));
printk("Secondary pages: %6dkB\n",nr_secondary_pages<<(PAGE_SHIFT-10));
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- printk("Buffer memory: %6dkB\n",buffermem>>10);
- printk("Buffer heads: %6d\n",nr_buffer_heads);
- printk("Buffer blocks: %6d\n",nr_buffers);
i = high_memory >> PAGE_SHIFT;
while (i-- > 0) {
total++;
@@ -998,6 +995,7 @@ void show_mem(void)
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
+ show_buffers();
}
/*
diff --git a/mm/mmap.c b/mm/mmap.c
index 5fea243..794ad23 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -113,9 +113,9 @@ int do_mmap(struct file * file, unsigned long addr, unsigned long len,
mask |= PAGE_READONLY;
if (prot & PROT_WRITE)
if ((flags & MAP_TYPE) == MAP_PRIVATE)
- mask |= PAGE_COW;
+ mask |= PAGE_COPY;
else
- mask |= PAGE_RW;
+ mask |= PAGE_SHARED;
if (!mask)
return -EINVAL;
diff --git a/net/inet/dev.c b/net/inet/dev.c
index 22002f0..e5bc513 100644
--- a/net/inet/dev.c
+++ b/net/inet/dev.c
@@ -193,81 +193,49 @@ ip_addr_match(unsigned long me, unsigned long him)
/* Check the address for our address, broadcasts, etc. */
-int
-chk_addr(unsigned long addr)
+int chk_addr(unsigned long addr)
{
- struct device *dev;
- unsigned long dst;
-
- DPRINTF((DBG_DEV, "chk_addr(%s) --> ", in_ntoa(addr)));
- dst = ntohl(addr);
-
- /* Accept both `all ones' and `all zeros' as BROADCAST. */
- if (dst == INADDR_ANY || dst == INADDR_BROADCAST) {
- DPRINTF((DBG_DEV, "BROADCAST\n"));
- return(IS_BROADCAST);
- }
+ struct device *dev;
+ unsigned long mask;
- /* Accept all of the `loopback' class A net. */
- if ((dst & IN_CLASSA_NET) == 0x7F000000L) {
- DPRINTF((DBG_DEV, "LOOPBACK\n"));
+ /* Accept both `all ones' and `all zeros' as BROADCAST. */
+ if (addr == INADDR_ANY || addr == INADDR_BROADCAST)
+ return IS_BROADCAST;
- /*
- * We force `loopback' to be equal to MY_ADDR.
- */
- return(IS_MYADDR);
- /* return(IS_LOOPBACK); */
- }
+ mask = get_mask(addr);
- /* OK, now check the interface addresses. */
- for (dev = dev_base; dev != NULL; dev = dev->next) {
- if (!(dev->flags&IFF_UP))
- continue;
- if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
- return(IS_MYADDR);
- /* Is it the exact IP address? */
- if (addr == dev->pa_addr) {
- DPRINTF((DBG_DEV, "MYADDR\n"));
- return(IS_MYADDR);
- }
+ /* Accept all of the `loopback' class A net. */
+ if ((addr & mask) == htonl(0x7F000000L))
+ return IS_MYADDR;
- /* Nope. Check for a subnetwork broadcast. */
- if ((addr & dev->pa_mask) == (dev->pa_addr & dev->pa_mask)) {
- if ((addr & ~dev->pa_mask) == 0) {
- DPRINTF((DBG_DEV, "SUBBROADCAST-0\n"));
- return(IS_BROADCAST);
+ /* OK, now check the interface addresses. */
+ for (dev = dev_base; dev != NULL; dev = dev->next) {
+ if (!(dev->flags & IFF_UP))
+ continue;
+ if ((dev->pa_addr == 0)/* || (dev->flags&IFF_PROMISC)*/)
+ return IS_MYADDR;
+ /* Is it the exact IP address? */
+ if (addr == dev->pa_addr)
+ return IS_MYADDR;
+ /* Is it our broadcast address? */
+ if ((dev->flags & IFF_BROADCAST) && addr == dev->pa_brdaddr)
+ return IS_BROADCAST;
+ /* Nope. Check for a subnetwork broadcast. */
+ if (((addr ^ dev->pa_addr) & dev->pa_mask) == 0) {
+ if ((addr & ~dev->pa_mask) == 0)
+ return IS_BROADCAST;
+ if ((addr & ~dev->pa_mask) == ~dev->pa_mask)
+ return IS_BROADCAST;
}
- if (((addr & ~dev->pa_mask) | dev->pa_mask)
- == INADDR_BROADCAST) {
- DPRINTF((DBG_DEV, "SUBBROADCAST-1\n"));
- return(IS_BROADCAST);
+ /* Nope. Check for Network broadcast. */
+ if (((addr ^ dev->pa_addr) & mask) == 0) {
+ if ((addr & ~mask) == 0)
+ return IS_BROADCAST;
+ if ((addr & ~mask) == ~mask)
+ return IS_BROADCAST;
}
}
-
- /* Nope. Check for Network broadcast. */
- if(IN_CLASSA(dst)) {
- if( addr == (dev->pa_addr | 0xffffff00)) {
- DPRINTF((DBG_DEV, "CLASS A BROADCAST-1\n"));
- return(IS_BROADCAST);
- }
- }
- else if(IN_CLASSB(dst)) {
- if( addr == (dev->pa_addr | 0xffff0000)) {
- DPRINTF((DBG_DEV, "CLASS B BROADCAST-1\n"));
- return(IS_BROADCAST);
- }
- }
- else { /* IN_CLASSC */
- if( addr == (dev->pa_addr | 0xff000000)) {
- DPRINTF((DBG_DEV, "CLASS C BROADCAST-1\n"));
- return(IS_BROADCAST);
- }
- }
- }
-
- DPRINTF((DBG_DEV, "NONE\n"));
-
- return(0); /* no match at all */
+ return 0; /* no match at all */
}
diff --git a/net/inet/ip.c b/net/inet/ip.c
index fdef4c6..d95e4cd 100644
--- a/net/inet/ip.c
+++ b/net/inet/ip.c
@@ -764,7 +764,6 @@ static struct sk_buff *ip_glue(struct ipq *qp)
skb->len = (len - qp->maclen);
skb->h.raw = skb->data;
skb->free = 1;
- skb->lock = 1;
/* Copy the original MAC and IP headers into the new buffer. */
ptr = (unsigned char *) skb->h.raw;
diff --git a/net/inet/ip.h b/net/inet/ip.h
index 7f2ecc0..31035bb 100644
--- a/net/inet/ip.h
+++ b/net/inet/ip.h
@@ -78,6 +78,7 @@ extern void ip_queue_xmit(struct sock *sk,
struct device *dev, struct sk_buff *skb,
int free);
extern void ip_retransmit(struct sock *sk, int all);
+extern void ip_do_retransmit(struct sock *sk, int all);
extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen);
extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen);
diff --git a/net/inet/raw.c b/net/inet/raw.c
index 91563d7..24f1da0 100644
--- a/net/inet/raw.c
+++ b/net/inet/raw.c
@@ -115,7 +115,7 @@ raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* Now we need to copy this into memory. */
skb->sk = sk;
skb->len = len + skb->ip_hdr->ihl*sizeof(long);
- skb->h.raw = skb->ip_hdr;
+ skb->h.raw = (unsigned char *) skb->ip_hdr;
skb->dev = dev;
skb->saddr = daddr;
skb->daddr = saddr;
diff --git a/net/inet/tcp.h b/net/inet/tcp.h
index 007f3ee..e154d5e 100644
--- a/net/inet/tcp.h
+++ b/net/inet/tcp.h
@@ -124,6 +124,7 @@ extern int tcp_rcv(struct sk_buff *skb, struct device *dev,
extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
+extern void tcp_send_probe0(struct sock *sk);
extern void tcp_enqueue_partial(struct sk_buff *, struct sock *);
extern struct sk_buff * tcp_dequeue_partial(struct sock *);