From 20f1405b13f312a985a1e66141b7766127fa5c98 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:09:15 -0500 Subject: [PATCH] Import 0.99.14b --- Makefile | 14 +++-- README | 21 ++----- drivers/sound/sb_dsp.c | 2 + fs/block_dev.c | 2 +- fs/fifo.c | 36 ++++++------ fs/inode.c | 11 ++-- fs/pipe.c | 112 +++++++++++++++++++++++--------------- include/linux/delay.h | 2 +- include/linux/fs.h | 2 + include/linux/in.h | 40 +++++++------- include/linux/limits.h | 2 +- include/linux/net.h | 8 +-- include/linux/pipe_fs_i.h | 28 ++++++---- kernel/ptrace.c | 2 +- net/inet/ip.c | 63 +++++++++++---------- net/socket.c | 15 ++++- 16 files changed, 199 insertions(+), 161 deletions(-) diff --git a/Makefile b/Makefile index e8a32672839d..8e94fff9fa98 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 0.99 PATCHLEVEL = 14 -ALPHA = a +ALPHA = b all: Version zImage @@ -149,12 +149,14 @@ init/main.o: $(CONFIGURE) init/main.c $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $< tools/system: boot/head.o init/main.o tools/version.o linuxsubdirs - $(LD) $(LDFLAGS) -T 1000 -M boot/head.o init/main.o tools/version.o \ + $(LD) $(LDFLAGS) -T 1000 boot/head.o init/main.o tools/version.o \ $(ARCHIVES) \ $(FILESYSTEMS) \ $(DRIVERS) \ $(LIBS) \ - -o tools/system > System.map + -o tools/system + nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \ + sort > System.map boot/setup: boot/setup.s $(AS86) -o boot/setup.o boot/setup.s @@ -187,12 +189,14 @@ zlilo: $(CONFIGURE) zImage tools/zSystem: boot/head.o init/main.o tools/version.o linuxsubdirs - $(LD) $(LDFLAGS) -T 100000 -M boot/head.o init/main.o tools/version.o \ + $(LD) $(LDFLAGS) -T 100000 boot/head.o init/main.o tools/version.o \ $(ARCHIVES) \ $(FILESYSTEMS) \ $(DRIVERS) \ $(LIBS) \ - -o tools/zSystem > zSystem.map + -o tools/zSystem + nm tools/zSystem | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | \ + sort > zSystem.map fs: dummy $(MAKE) linuxsubdirs SUBDIRS=fs diff --git a/README b/README index db5e5254b854..0929c2c22d3b 100644 --- a/README +++ b/README @@ -1,29 +1,18 @@ - Linux kernel release 0.99 patchlevel 13 + Linux kernel release 0.99 patchlevel 14 -[ Just to show everybody that I have no personal integrity at all, this -release is dedicated to Martin Mueller and Sebastian Hetze just because -they wrote the German Linux Anwenderhandbuch. The fact that they sent -me some of the money they made on selling it has nothing at all to do -with the dedication. Oh, no. That would be crass. ] - -These are the release notes for linux version 0.99.13. Read them +These are the release notes for linux version 0.99.14. Read them carefully, as they tell you what's new, explain how to install the kernel, and what to do if something goes wrong. -NOTE! There has been some indication that gcc versions older than 2.4.5 -result in bad kernels being built: 2.3.3 will fail even to build the -kernel, and I have at least one report of trouble with a 2.4.3-built -kernel that went away when the kernel was recompiled with 2.4.5. - INSTALLING the kernel: - - if you install by patching, you need a *clean* 0.99.12 source tree, + - if you install by patching, you need a *clean* 0.99.13 source tree, which presumably exists in /usr/src/linux. If so, to get the kernel patched, just do a cd /usr/src - patch -p0 < linux-0.99.patch13 + patch -p0 < linux-0.99.patch14 and you should be ok. You may want to remove the backup files (xxx~ or xxx.orig), and make sure that there are no failed patches (xxx# or @@ -32,7 +21,7 @@ INSTALLING the kernel: - If you install the full sources, do a cd /usr/src - tar xvf linux-0.99.13.tar + tar xvf linux-0.99.14.tar to get it all put in place. diff --git a/drivers/sound/sb_dsp.c b/drivers/sound/sb_dsp.c index a5e52d3b0dc7..2bcee0e20637 100644 --- a/drivers/sound/sb_dsp.c +++ b/drivers/sound/sb_dsp.c @@ -433,12 +433,14 @@ sb_dsp_prepare_for_output (int dev, int bsize, int bcount) dsp_cleanup (); dsp_speaker (ON); +#ifndef EXCLUDE_SBPRO if (major == 3) /* SB Pro */ { sb_mixer_set_stereo(dsp_stereo); dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels * changes */ } +#endif return 0; } diff --git a/fs/block_dev.c b/fs/block_dev.c index 9a839c69ec41..22ffc2154525 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -82,7 +82,7 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count) int blocksize; int blocksize_bits, i; unsigned int left; - int blocks; + unsigned int blocks; int bhrequest, uptodate; struct buffer_head ** bhb, ** bhe; struct buffer_head * buflist[NBUF]; diff --git a/fs/fifo.c b/fs/fifo.c index 2589457c6cdf..50e0b8cb2117 100644 --- a/fs/fifo.c +++ b/fs/fifo.c @@ -24,7 +24,7 @@ static int fifo_open(struct inode * inode,struct file * filp) */ filp->f_op = &connecting_fifo_fops; if (!PIPE_READERS(*inode)++) - wake_up(&PIPE_WRITE_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) { PIPE_RD_OPENERS(*inode)++; while (!PIPE_WRITERS(*inode)) { @@ -32,17 +32,17 @@ static int fifo_open(struct inode * inode,struct file * filp) retval = -ERESTARTSYS; break; } - interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); + interruptible_sleep_on(&PIPE_WAIT(*inode)); } if (!--PIPE_RD_OPENERS(*inode)) - wake_up(&PIPE_WRITE_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); } while (PIPE_WR_OPENERS(*inode)) - interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); + interruptible_sleep_on(&PIPE_WAIT(*inode)); if (PIPE_WRITERS(*inode)) filp->f_op = &read_fifo_fops; if (retval && !--PIPE_READERS(*inode)) - wake_up(&PIPE_WRITE_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); break; case 2: @@ -57,7 +57,7 @@ static int fifo_open(struct inode * inode,struct file * filp) } filp->f_op = &write_fifo_fops; if (!PIPE_WRITERS(*inode)++) - wake_up(&PIPE_READ_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); if (!PIPE_READERS(*inode)) { PIPE_WR_OPENERS(*inode)++; while (!PIPE_READERS(*inode)) { @@ -65,15 +65,15 @@ static int fifo_open(struct inode * inode,struct file * filp) retval = -ERESTARTSYS; break; } - interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); + interruptible_sleep_on(&PIPE_WAIT(*inode)); } if (!--PIPE_WR_OPENERS(*inode)) - wake_up(&PIPE_READ_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); } while (PIPE_RD_OPENERS(*inode)) - interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); + interruptible_sleep_on(&PIPE_WAIT(*inode)); if (retval && !--PIPE_WRITERS(*inode)) - wake_up(&PIPE_READ_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); break; case 3: @@ -85,13 +85,13 @@ static int fifo_open(struct inode * inode,struct file * filp) */ filp->f_op = &rdwr_fifo_fops; if (!PIPE_READERS(*inode)++) - wake_up(&PIPE_WRITE_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); while (PIPE_WR_OPENERS(*inode)) - interruptible_sleep_on(&PIPE_READ_WAIT(*inode)); + interruptible_sleep_on(&PIPE_WAIT(*inode)); if (!PIPE_WRITERS(*inode)++) - wake_up(&PIPE_READ_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); while (PIPE_RD_OPENERS(*inode)) - interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); + interruptible_sleep_on(&PIPE_WAIT(*inode)); break; default: @@ -106,7 +106,8 @@ static int fifo_open(struct inode * inode,struct file * filp) } if (!page) return -ENOMEM; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; + PIPE_LOCK(*inode) = 0; + PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_BASE(*inode) = (char *) page; return 0; } @@ -151,9 +152,10 @@ void init_fifo(struct inode * inode) { inode->i_op = &fifo_inode_operations; inode->i_pipe = 1; + PIPE_LOCK(*inode) = 0; PIPE_BASE(*inode) = NULL; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; + PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; - PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL; + PIPE_WAIT(*inode) = NULL; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; } diff --git a/fs/inode.c b/fs/inode.c index db0425f5831c..d8437b1fc42f 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -308,10 +308,8 @@ void iput(struct inode * inode) inode->i_ino, inode->i_mode); return; } - if (inode->i_pipe) { - wake_up(&PIPE_READ_WAIT(*inode)); - wake_up(&PIPE_WRITE_WAIT(*inode)); - } + if (inode->i_pipe) + wake_up(&PIPE_WAIT(*inode)); repeat: if (inode->i_count>1) { inode->i_count--; @@ -403,10 +401,11 @@ struct inode * get_pipe_inode(void) } inode->i_op = &pipe_inode_operations; inode->i_count = 2; /* sum of readers/writers */ - PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL; - PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; + PIPE_WAIT(*inode) = NULL; + PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; + PIPE_LOCK(*inode) = 0; inode->i_pipe = 1; inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR; inode->i_uid = current->euid; diff --git a/fs/pipe.c b/fs/pipe.c index f8289ea05add..2e94ba154cf6 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -13,33 +13,54 @@ #include #include + +/* We don't use the head/tail construction any more. Now we use the start/len*/ +/* contruction providing full use of PIPE_BUF (multiple of PAGE_SIZE) */ +/* Florian Coosmann (FGC) ^ current = 1 */ +/* Additionally, we now use locking technique. This prevents race condition */ +/* in case of paging and multiple read/write on the same pipe. (FGC) */ + + static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count) { - int chars, size, read = 0; + int chars = 0, size = 0, read = 0; + char *pipebuf; - if (!(filp->f_flags & O_NONBLOCK)) - while (!PIPE_SIZE(*inode)) { - wake_up(& PIPE_WRITE_WAIT(*inode)); - if (!PIPE_WRITERS(*inode)) /* are there any writers? */ + if (filp->f_flags & O_NONBLOCK) { + if (PIPE_LOCK(*inode)) + return -EAGAIN; + if (PIPE_EMPTY(*inode)) + if (PIPE_WRITERS(*inode)) + return -EAGAIN; + else + return 0; + } else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) { + if (PIPE_EMPTY(*inode)) { + if (!PIPE_WRITERS(*inode)) return 0; - if (current->signal & ~current->blocked) - return -ERESTARTSYS; - interruptible_sleep_on(& PIPE_READ_WAIT(*inode)); } + if (current->signal & ~current->blocked) + return -ERESTARTSYS; + interruptible_sleep_on(&PIPE_WAIT(*inode)); + } + PIPE_LOCK(*inode)++; while (count>0 && (size = PIPE_SIZE(*inode))) { - chars = PAGE_SIZE-PIPE_TAIL(*inode); + chars = PIPE_MAX_RCHUNK(*inode); if (chars > count) chars = count; if (chars > size) chars = size; - memcpy_tofs(buf, PIPE_BASE(*inode)+PIPE_TAIL(*inode), chars ); read += chars; - PIPE_TAIL(*inode) += chars; - PIPE_TAIL(*inode) &= (PAGE_SIZE-1); + pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode); + PIPE_START(*inode) += chars; + PIPE_START(*inode) &= (PIPE_BUF-1); + PIPE_LEN(*inode) -= chars; count -= chars; + memcpy_tofs(buf, pipebuf, chars ); buf += chars; } - wake_up(& PIPE_WRITE_WAIT(*inode)); + PIPE_LOCK(*inode)--; + wake_up(&PIPE_WAIT(*inode)); if (read) return read; if (PIPE_WRITERS(*inode)) @@ -49,45 +70,47 @@ static int pipe_read(struct inode * inode, struct file * filp, char * buf, int c static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count) { - int chars, size, written = 0; + int chars = 0, free = 0, written = 0; + char *pipebuf; if (!PIPE_READERS(*inode)) { /* no readers */ send_sig(SIGPIPE,current,0); return -EPIPE; } -/* if count < PAGE_SIZE, we have to make it atomic */ - if (count < PAGE_SIZE) - size = PAGE_SIZE-count; +/* if count <= PIPE_BUF, we have to make it atomic */ + if (count <= PIPE_BUF) + free = count; else - size = PAGE_SIZE-1; + free = 1; /* can't do it atomically, wait for any free space */ while (count>0) { - while (PIPE_SIZE(*inode) >= size) { + while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) { if (!PIPE_READERS(*inode)) { /* no readers */ send_sig(SIGPIPE,current,0); - return written?written:-EPIPE; + return written? :-EPIPE; } if (current->signal & ~current->blocked) - return written?written:-ERESTARTSYS; + return written? :-ERESTARTSYS; if (filp->f_flags & O_NONBLOCK) - return written?written:-EAGAIN; - else - interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode)); + return written? :-EAGAIN; + interruptible_sleep_on(&PIPE_WAIT(*inode)); } - while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) { - chars = PAGE_SIZE-PIPE_HEAD(*inode); + PIPE_LOCK(*inode)++; + while (count>0 && (free = PIPE_FREE(*inode))) { + chars = PIPE_MAX_WCHUNK(*inode); if (chars > count) chars = count; - if (chars > size) - chars = size; - memcpy_fromfs(PIPE_BASE(*inode)+PIPE_HEAD(*inode), buf, chars ); + if (chars > free) + chars = free; + pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode); written += chars; - PIPE_HEAD(*inode) += chars; - PIPE_HEAD(*inode) &= (PAGE_SIZE-1); + PIPE_LEN(*inode) += chars; count -= chars; + memcpy_fromfs(pipebuf, buf, chars ); buf += chars; } - wake_up(& PIPE_READ_WAIT(*inode)); - size = PAGE_SIZE-1; + PIPE_LOCK(*inode)--; + wake_up(&PIPE_WAIT(*inode)); + free = 1; } return written; } @@ -129,12 +152,12 @@ static int pipe_select(struct inode * inode, struct file * filp, int sel_type, s case SEL_IN: if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode)) return 1; - select_wait(&PIPE_READ_WAIT(*inode), wait); + select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_OUT: if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode)) return 1; - select_wait(&PIPE_WRITE_WAIT(*inode), wait); + select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_EX: if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) @@ -155,12 +178,12 @@ static int fifo_select(struct inode * inode, struct file * filp, int sel_type, s case SEL_IN: if (!PIPE_EMPTY(*inode)) return 1; - select_wait(&PIPE_READ_WAIT(*inode), wait); + select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_OUT: if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode)) return 1; - select_wait(&PIPE_WRITE_WAIT(*inode), wait); + select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_EX: if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) @@ -183,10 +206,10 @@ static int connect_read(struct inode * inode, struct file * filp, char * buf, in break; if (filp->f_flags & O_NONBLOCK) return -EAGAIN; - wake_up(& PIPE_WRITE_WAIT(*inode)); + wake_up(& PIPE_WAIT(*inode)); if (current->signal & ~current->blocked) return -ERESTARTSYS; - interruptible_sleep_on(& PIPE_READ_WAIT(*inode)); + interruptible_sleep_on(& PIPE_WAIT(*inode)); } filp->f_op = &read_fifo_fops; return pipe_read(inode,filp,buf,count); @@ -200,12 +223,12 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type filp->f_op = &read_fifo_fops; return 1; } - select_wait(&PIPE_READ_WAIT(*inode), wait); + select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_OUT: if (!PIPE_FULL(*inode)) return 1; - select_wait(&PIPE_WRITE_WAIT(*inode), wait); + select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_EX: if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) @@ -223,21 +246,20 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type static void pipe_read_release(struct inode * inode, struct file * filp) { PIPE_READERS(*inode)--; - wake_up(&PIPE_WRITE_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); } static void pipe_write_release(struct inode * inode, struct file * filp) { PIPE_WRITERS(*inode)--; - wake_up(&PIPE_READ_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); } static void pipe_rdwr_release(struct inode * inode, struct file * filp) { PIPE_READERS(*inode)--; PIPE_WRITERS(*inode)--; - wake_up(&PIPE_READ_WAIT(*inode)); - wake_up(&PIPE_WRITE_WAIT(*inode)); + wake_up(&PIPE_WAIT(*inode)); } /* diff --git a/include/linux/delay.h b/include/linux/delay.h index 92508f376285..e3621a2f98f1 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -11,7 +11,7 @@ extern unsigned long loops_per_sec; extern __inline__ void __delay(int loops) { - __asm__("\n1:\tdecl %0\n\tjns 1b\n": :"a" (loops):"ax"); + __asm__(".align 2,0x90\n1:\tdecl %0\n\tjns 1b": :"a" (loops):"ax"); } /* diff --git a/include/linux/fs.h b/include/linux/fs.h index 201baad18d6e..b8e4c6266e25 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -12,6 +12,7 @@ #include #include #include +#include /* * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix @@ -177,6 +178,7 @@ struct inode { struct inode * i_hash_next, * i_hash_prev; struct inode * i_bound_to, * i_bound_by; struct inode * i_mount; + struct socket * i_socket; unsigned short i_count; unsigned short i_flags; unsigned char i_lock; diff --git a/include/linux/in.h b/include/linux/in.h index 5ec599127cd3..c3c656b9ee77 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -124,41 +124,41 @@ extern unsigned short int htons(unsigned short int); static __inline__ unsigned long int __ntohl(unsigned long int x) { - register unsigned long int tmp __asm__ ("ax") = x; - __asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap lower bytes */ - "rorl $16,%%eax\n\t" /* swap words */ - "xchgb %%al,%%ah\n\t" /* swap higher bytes */ - : "=a" (tmp) : "a" (tmp) ); - return(tmp); + __asm__("xchgb %l0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %l0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); + return x; } static __inline__ unsigned short int __ntohs(unsigned short int x) { - register unsigned short int tmp __asm__ ("ax") = x; - __asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap bytes */ - : "=a" (tmp) : "a" (tmp)); - return(tmp); + __asm__("xchgb %b0,%h0" /* swap bytes */ + : "=q" (x) + : "0" (x)); + return x; } static __inline__ unsigned long int __htonl(unsigned long int x) { - register unsigned long int tmp __asm__ ("ax") = x; - __asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap lower bytes */ - "rorl $16,%%eax\n\t" /* swap words */ - "xchgb %%al,%%ah\n\t" /* swap higher bytes */ - : "=a" (tmp) : "a" (tmp)); - return(tmp); + __asm__("xchgb %l0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %l0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); + return x; } static __inline__ unsigned short int __htons(unsigned short int x) { - register unsigned short int tmp __asm__ ("ax") = x; - __asm__ __volatile__ ("xchgb %%al,%%ah\n\t" /* swap bytes */ - : "=a" (tmp) : "a" (tmp)); - return(tmp); + __asm__("xchgb %b0,%h0" /* swap bytes */ + : "=q" (x) + : "0" (x)); + return x; } #ifdef __OPTIMIZE__ diff --git a/include/linux/limits.h b/include/linux/limits.h index 4163ab72aabe..d0f300c4f860 100644 --- a/include/linux/limits.h +++ b/include/linux/limits.h @@ -12,6 +12,6 @@ #define MAX_INPUT 255 /* size of the type-ahead buffer */ #define NAME_MAX 255 /* # chars in a file name */ #define PATH_MAX 1024 /* # chars in a path name */ -#define PIPE_BUF 4095 /* # bytes in atomic write to a pipe */ +#define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */ #endif diff --git a/include/linux/net.h b/include/linux/net.h index 2f6d08eabc9d..01e0633dff34 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -20,6 +20,7 @@ #include +#include #define NSOCKETS 128 /* should be dynamic, later... */ @@ -75,13 +76,10 @@ struct socket { struct socket *iconn; /* incomplete client conn.s */ struct socket *next; struct wait_queue **wait; /* ptr to place to wait on */ - void *dummy; + struct inode *inode; }; -#define SOCK_INODE(S) ((struct inode *)(S)->dummy) -extern struct socket sockets[NSOCKETS]; -#define last_socket (sockets + NSOCKETS - 1) - +#define SOCK_INODE(S) ((S)->inode) struct proto_ops { int family; diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index fc5c4e6c7ed0..21b39d628a37 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -2,28 +2,34 @@ #define _LINUX_PIPE_FS_I_H struct pipe_inode_info { - struct wait_queue * read_wait; - struct wait_queue * write_wait; + struct wait_queue * wait; char * base; - unsigned int head; - unsigned int tail; + unsigned int start; + unsigned int len; + unsigned int lock; unsigned int rd_openers; unsigned int wr_openers; unsigned int readers; unsigned int writers; }; -#define PIPE_READ_WAIT(inode) ((inode).u.pipe_i.read_wait) -#define PIPE_WRITE_WAIT(inode) ((inode).u.pipe_i.write_wait) +#define PIPE_WAIT(inode) ((inode).u.pipe_i.wait) #define PIPE_BASE(inode) ((inode).u.pipe_i.base) -#define PIPE_HEAD(inode) ((inode).u.pipe_i.head) -#define PIPE_TAIL(inode) ((inode).u.pipe_i.tail) +#define PIPE_START(inode) ((inode).u.pipe_i.start) +#define PIPE_LEN(inode) ((inode).u.pipe_i.len) #define PIPE_RD_OPENERS(inode) ((inode).u.pipe_i.rd_openers) #define PIPE_WR_OPENERS(inode) ((inode).u.pipe_i.wr_openers) #define PIPE_READERS(inode) ((inode).u.pipe_i.readers) #define PIPE_WRITERS(inode) ((inode).u.pipe_i.writers) -#define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1)) -#define PIPE_EMPTY(inode) (PIPE_HEAD(inode)==PIPE_TAIL(inode)) -#define PIPE_FULL(inode) (PIPE_SIZE(inode)==(PAGE_SIZE-1)) +#define PIPE_LOCK(inode) ((inode).u.pipe_i.lock) +#define PIPE_SIZE(inode) PIPE_LEN(inode) + +#define PIPE_EMPTY(inode) (PIPE_SIZE(inode)==0) +#define PIPE_FULL(inode) (PIPE_SIZE(inode)==PIPE_BUF) +#define PIPE_FREE(inode) (PIPE_BUF - PIPE_LEN(inode)) +#define PIPE_END(inode) ((PIPE_START(inode)+PIPE_LEN(inode))&\ + (PIPE_BUF-1)) +#define PIPE_MAX_RCHUNK(inode) (PIPE_BUF - PIPE_START(inode)) +#define PIPE_MAX_WCHUNK(inode) (PIPE_BUF - PIPE_END(inode)) #endif diff --git a/kernel/ptrace.c b/kernel/ptrace.c index b6a673bcf53c..42d330b2a66b 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -269,7 +269,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if (!(child->flags & PF_PTRACED)) return -ESRCH; if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL && request != PTRACE_DETACH) + if (request != PTRACE_KILL) return -ESRCH; } if (child->p_pptr != current) diff --git a/net/inet/ip.c b/net/inet/ip.c index c22f111c6764..de901cf700e5 100644 --- a/net/inet/ip.c +++ b/net/inet/ip.c @@ -425,19 +425,22 @@ static inline unsigned short ip_fast_csum(unsigned char * buff, int wlen) { unsigned long sum = 0; - __asm__("\t clc\n" - "1:\n" - "\t lodsl\n" - "\t adcl %%eax, %%ebx\n" - "\t loop 1b\n" - "\t adcl $0, %%ebx\n" - "\t movl %%ebx, %%eax\n" - "\t shrl $16, %%eax\n" - "\t addw %%ax, %%bx\n" - "\t adcw $0, %%bx\n" - : "=b" (sum) , "=S" (buff) - : "0" (sum), "c" (wlen) ,"1" (buff) - : "ax", "cx", "si", "bx" ); + + if (wlen) + __asm__("clc\n" + "1:\t" + "lodsl\n\t" + "adcl %%eax, %0\n\t" + "decl %2\n\t" + "jne 1b\n\t" + "adcl $0, %0\n\t" + "movl %0, %%eax\n\t" + "shrl $16, %%eax\n\t" + "addw %%ax, %w0\n\t" + "adcw $0, %w0" + : "=r" (sum), "=S" (buff), "=r" (wlen) + : "0" (sum), "1" (buff), "2" (wlen) + : "ax" ); return (~sum) & 0xffff; } @@ -452,33 +455,33 @@ ip_compute_csum(unsigned char * buff, int len) /* Do the first multiple of 4 bytes and convert to 16 bits. */ if (len > 3) { - __asm__("\t clc\n" - "1:\n" - "\t lodsl\n" - "\t adcl %%eax, %%ebx\n" - "\t loop 1b\n" - "\t adcl $0, %%ebx\n" - "\t movl %%ebx, %%eax\n" - "\t shrl $16, %%eax\n" - "\t addw %%ax, %%bx\n" - "\t adcw $0, %%bx\n" + __asm__("clc\n" + "1:\t" + "lodsl\n\t" + "adcl %%eax, %%ebx\n\t" + "loop 1b\n\t" + "adcl $0, %%ebx\n\t" + "movl %%ebx, %%eax\n\t" + "shrl $16, %%eax\n\t" + "addw %%ax, %%bx\n\t" + "adcw $0, %%bx" : "=b" (sum) , "=S" (buff) : "0" (sum), "c" (len >> 2) ,"1" (buff) : "ax", "cx", "si", "bx" ); } if (len & 2) { - __asm__("\t lodsw\n" - "\t addw %%ax, %%bx\n" - "\t adcw $0, %%bx\n" + __asm__("lodsw\n\t" + "addw %%ax, %%bx\n\t" + "adcw $0, %%bx" : "=b" (sum), "=S" (buff) : "0" (sum), "1" (buff) : "bx", "ax", "si"); } if (len & 1) { - __asm__("\t lodsb\n" - "\t movb $0, %%ah\n" - "\t addw %%ax, %%bx\n" - "\t adcw $0, %%bx\n" + __asm__("lodsb\n\t" + "movb $0, %%ah\n\t" + "addw %%ax, %%bx\n\t" + "adcw $0, %%bx" : "=b" (sum), "=S" (buff) : "0" (sum), "1" (buff) : "bx", "ax", "si"); diff --git a/net/socket.c b/net/socket.c index 412a7f4cfd47..6885fe7c232b 100644 --- a/net/socket.c +++ b/net/socket.c @@ -69,11 +69,13 @@ static struct file_operations socket_file_ops = { NULL, /* no special open code... */ sock_close }; -struct socket sockets[NSOCKETS]; + +static struct socket sockets[NSOCKETS]; static struct wait_queue *socket_wait_free = NULL; static struct proto_ops *pops[NPROTO]; static int net_debug = 0; +#define last_socket (sockets + NSOCKETS - 1) #ifdef SOCK_DEBUG /* Module debugging. */ @@ -138,8 +140,16 @@ socki_lookup(struct inode *inode) { struct socket *sock; + if ((sock = inode->i_socket) != NULL) { + if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) + return sock; + printk("socket.c: uhhuh. stale inode->i_socket pointer\n"); + } for (sock = sockets; sock <= last_socket; ++sock) - if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) return(sock); + if (sock->state != SS_FREE && SOCK_INODE(sock) == inode) { + printk("socket.c: uhhuh. Found socket despite no inode->i_socket pointer\n"); + return(sock); + } return(NULL); } @@ -187,6 +197,7 @@ sock_alloc(int wait) SOCK_INODE(sock)->i_mode = S_IFSOCK; SOCK_INODE(sock)->i_uid = current->euid; SOCK_INODE(sock)->i_gid = current->egid; + SOCK_INODE(sock)->i_socket = sock; sock->wait = &SOCK_INODE(sock)->i_wait; DPRINTF((net_debug, -- 2.39.5