Commit a0ab4fe2 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.0.18

parent 4cb8ac91
......@@ -1273,11 +1273,11 @@ S: Batavia, Illinois 60510
S: USA
N: Leo Spiekman
E: spiekman@et.tudelft.nl
W: http://dutettk.et.tudelft.nl/~spiekman
E: leo@netlabs.net
W: http://www.netlabs.net/hp/leo/
D: Optics Storage 8000AT cdrom driver
S: Utrecht
S: The Netherlands
S: Cliffwood, NJ 07721
S: USA
N: Henrik Storner
E: storner@osiris.ping.dk
......
......@@ -34,7 +34,7 @@ http://www.datanet.hu/generations/linux/Changes.html (English).
bunshou no nihongo ban wa
http://jf.gee.kyoto-u.ac.jp/JF/v2.0/Changes-2.0.html ni arimasu.
Last updated: August 29, 1996.
Last updated: September 02, 1996.
Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
Current Releases
......@@ -350,8 +350,10 @@ Frame Relay
Frame relay support for Linux is now available as well. Currently,
only Sangoma cards are supported, but the interface is such that others
will be as drivers become available. To use this, grab
ftp://ftp.invlogic.com/linux/frad-0.15.tgz and
ftp://ftp.invlogic.com/linux/routing.tgz.
ftp://linux.invlogic.com/pub/fr/frad-0.15.tgz (soon to be
frad-0.20.tgz). Another package of interest is
ftp://linux.invlogic.com/pub/routing/routing.tgz (which allows Linux to
make routing decisions based on packet source).
Networking
==========
......
......@@ -70,3 +70,81 @@ I get worried that I've been doing this for too long ;-)
Linus
---------------------------------------------------------------------------
Notes on Oops tracing with klogd:
In order to help Linus and the other kernel developers there has been
substantial support incorporated into klogd for processing protection
faults. In order to have full support for address resolution at least
version 1.3-pl3 of the sysklogd package should be used.
When a protection fault occurs the klogd daemon automatically
translates important addresses in the kernel log messages to their
symbolic equivalents. This translated kernel message is then
forwarded through whatever reporting mechanism klogd is using. The
protection fault message can be simply cut out of the message files
and forwarded to the kernel developers.
Two types of address resolution are performed by klogd. The first is
static translation and the second is dynamic translation. Static
translation uses the System.map file in much the same manner that
ksymoops does. In order to do static translation the klogd daemon
must be able to find a system map file at daemon initialization time.
See the klogd man page for information on how klogd searches for map
files.
Dynamic address translation is important when kernel loadable modules
are being used. Since memory for kernel modules is allocated from the
kernel's dynamic memory pools there are no fixed locations for either
the start of the module or for functions and symbols in the module.
The kernel supports system calls which allow a program to determine
which modules are loaded and their location in memory. Using these
system calls the klogd daemon builds a symbol table which can be used
to debug a protection fault which occurs in a loadable kernel module.
At the very minimum klogd will provide the name of the module which
generated the protection fault. There may be additional symbolic
information available if the developer of the loadable module chose to
export symbol information from the module.
Since the kernel module environment can be dynamic there must be a
mechanism for notifying the klogd daemon when a change in module
environment occurs. There are command line options available which
allow klogd to signal the currently executing daemon that symbol
information should be refreshed. See the klogd manual page for more
information.
A patch is included with the sysklogd distribution which modifies the
modules-2.0.0 package to automatically signal klogd whenever a module
is loaded or unloaded. Applying this patch provides essentially
seamless support for debugging protection faults which occur with
kernel loadable modules.
The following is an example of a protection fault in a loadable module
processed by klogd:
---------------------------------------------------------------------------
Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc
Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, ^Pr3 = 0062d000
Aug 29 09:51:01 blizard kernel: *pde = 00000000
Aug 29 09:51:01 blizard kernel: Oops: 0002
Aug 29 09:51:01 blizard kernel: CPU: 0
Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868]
Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212
Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c
Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c
Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018
Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000)
Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001
Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00
Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036
Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128]
Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3
---------------------------------------------------------------------------
Dr. G.W. Wettstein Oncology Research Div. Computing Facility
Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com
820 4th St. N.
Fargo, ND 58122
Phone: 701-234-7556
VERSION = 2
PATCHLEVEL = 0
SUBLEVEL = 17
SUBLEVEL = 18
ARCH = i386
......
......@@ -58,7 +58,7 @@ piggy.o: $(SYSTEM)
$(ENCAPS) $(TARGET) piggy.o $$tmppiggy.gz $(INPUT_DATA) $(INPUT_LEN); \
else \
echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
ld -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
$(LD) -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
fi; \
rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
else
......
......@@ -87,7 +87,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (error_code & 1) {
#ifdef TEST_VERIFY_AREA
if (regs->cs == KERNEL_CS)
printk("WP fault at %08x\n", regs->eip);
printk("WP fault at %08lx\n", regs->eip);
#endif
do_wp_page(current, vma, address, error_code & 2);
return;
......
......@@ -198,7 +198,7 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
address += PAGE_SIZE;
}
}
flush_tlb();
local_flush_tlb();
return free_area_init(start_mem, end_mem);
}
......@@ -272,10 +272,10 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
/* test if the WP bit is honoured in supervisor mode */
if (wp_works_ok < 0) {
pg0[0] = pte_val(mk_pte(0, PAGE_READONLY));
flush_tlb();
local_flush_tlb();
__asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
pg0[0] = 0;
flush_tlb();
local_flush_tlb();
if (wp_works_ok < 0)
wp_works_ok = 0;
}
......
......@@ -132,7 +132,7 @@ void stdma_release(void)
int stdma_others_waiting(void)
{
return stdma_wait != NULL;
return waitqueue_active(&stdma_wait);
}
......
......@@ -752,6 +752,8 @@ int init_module(void)
void cleanup_module(void)
{
unregister_blkdev(MAJOR_NR, "xd");
free_irq(xd_irq, NULL);
free_dma(xd_dma);
}
#endif /* MODULE */
......@@ -380,8 +380,9 @@ void do_tty_hangup(struct tty_struct * tty, struct file_operations *fops)
continue;
if (filp->private_data != tty)
continue;
if (filp->f_inode
&& filp->f_inode->i_rdev == CONSOLE_DEV)
if (!filp->f_inode)
continue;
if (filp->f_inode->i_rdev == CONSOLE_DEV)
continue;
if (filp->f_op != &tty_fops)
continue;
......
......@@ -14,7 +14,7 @@
#ifndef LAYER2_H
#define LAYER2_H
#include <bytesex.h>
#include <asm/byteorder.h>
#define BANK1 0x0000U /* PC -> Board */
#define BANK2 0x01ffU /* Board -> PC */
......@@ -85,7 +85,7 @@
*/
struct msg_fmt {
#if __BYTE_ORDER == 1234 /* Little Endian */
#ifdef __LITTLE_ENDIAN /* Little Endian */
u_char scmd;
u_char cmd;
u_char proc;
......
......@@ -137,7 +137,7 @@ static int ac_probe1(int ioaddr, struct device *dev)
for (i = 0; i < 4; i++)
if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
printk("EISA ID mismatch, %8x vs %8x.\n",
inl(ioaddr + AC_EISA_ID), AC_EISA_ID);
inl(ioaddr + AC_ID_PORT), AC_EISA_ID);
return ENODEV;
}
......
......@@ -4325,6 +4325,7 @@ static int ncr_detach(ncb_p np, int irq)
lcb_p lp;
int target, lun;
int i;
u_char scntl3;
printf("%s: releasing host resources\n", ncr_name(np));
......@@ -4371,12 +4372,15 @@ static int ncr_detach(ncb_p np, int irq)
/*
** Reset NCR chip
** Preserve scntl3 for automatic clock detection.
*/
printf("%s: resetting chip\n", ncr_name(np));
scntl3 = INB (nc_scntl3);
OUTB (nc_istat, SRST);
DELAY (1000);
OUTB (nc_istat, 0 );
OUTB (nc_scntl3, scntl3);
/*
** Release Memory mapped IO region and IO mapped region
......@@ -7353,7 +7357,7 @@ static void ncr_getclock (ncb_p np, u_char scntl3)
*/
if ((scntl3 & 7) < 3) {
printf ("%s: assuming 40MHz clock", ncr_name(np));
printf ("%s: assuming 40MHz clock\n", ncr_name(np));
scntl3 = 3; /* assume 40MHz if no value supplied by BIOS */
}
......
......@@ -9,7 +9,7 @@ endif
endif
lowlevel.o: $(OBJS)
ld -r -o lowlevel.o $(OBJS)
$(LD) -r -o lowlevel.o $(OBJS)
clean:
rm -f core x y z *~ *.o
......
......@@ -258,7 +258,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex,
eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr),
elf_prot,
elf_type,
ELF_PAGESTART(eppnt->p_offset));
eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
if (error > -1024UL) {
/* Real error */
......@@ -585,7 +585,8 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
elf_prot,
(MAP_FIXED | MAP_PRIVATE |
MAP_DENYWRITE | MAP_EXECUTABLE),
ELF_PAGESTART(elf_ppnt->p_offset));
(elf_ppnt->p_offset -
ELF_PAGEOFFSET(elf_ppnt->p_vaddr)));
#ifdef LOW_ELF_STACK
if (ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack)
......@@ -802,10 +803,12 @@ do_load_elf_library(int fd){
/* Now use mmap to map the library into memory. */
error = do_mmap(file,
ELF_PAGESTART(elf_phdata->p_vaddr),
elf_phdata->p_filesz + ELF_PAGEOFFSET(elf_phdata->p_vaddr),
(elf_phdata->p_filesz +
ELF_PAGEOFFSET(elf_phdata->p_vaddr)),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
ELF_PAGESTART(elf_phdata->p_offset));
(elf_phdata->p_offset -
ELF_PAGEOFFSET(elf_phdata->p_vaddr)));
k = elf_phdata->p_vaddr + elf_phdata->p_filesz;
if (k > elf_bss) elf_bss = k;
......
......@@ -1046,10 +1046,6 @@ static struct buffer_head * get_unused_buffer_head(void)
return NULL;
bh = unused_list;
unused_list = bh->b_next_free;
bh->b_next_free = NULL;
bh->b_data = NULL;
bh->b_size = 0;
bh->b_state = 0;
return bh;
}
......@@ -1070,11 +1066,18 @@ static struct buffer_head * create_buffers(unsigned long page, unsigned long siz
bh = get_unused_buffer_head();
if (!bh)
goto no_grow;
bh->b_dev = B_FREE; /* Flag as unused */
bh->b_this_page = head;
head = bh;
bh->b_data = (char *) (page+offset);
bh->b_state = 0;
bh->b_next_free = NULL;
bh->b_count = 0;
bh->b_size = size;
bh->b_dev = B_FREE; /* Flag as unused */
bh->b_data = (char *) (page+offset);
bh->b_list = 0;
}
return head;
/*
......@@ -1128,13 +1131,11 @@ static inline void free_async_buffers (struct buffer_head * bh)
* This function expects the page to be locked and may return before I/O is complete.
* You then have to check page->locked, page->uptodate, and maybe wait on page->wait.
*/
int brw_page(int rw, unsigned long address, kdev_t dev, int b[], int size, int bmap)
int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size, int bmap)
{
struct buffer_head *bh, *prev, *next, *arr[MAX_BUF_PER_PAGE];
int block, nr;
struct page *page;
page = mem_map + MAP_NR(address);
if (!PageLocked(page))
panic("brw_page: page not locked for I/O");
clear_bit(PG_uptodate, &page->flags);
......@@ -1144,7 +1145,7 @@ int brw_page(int rw, unsigned long address, kdev_t dev, int b[], int size, int b
* They do _not_ show up in the buffer hash table!
* They are _not_ registered in page->buffers either!
*/
bh = create_buffers(address, size);
bh = create_buffers(page_address(page), size);
if (!bh) {
clear_bit(PG_locked, &page->flags);
wake_up(&page->wait);
......@@ -1336,7 +1337,7 @@ int generic_readpage(struct inode * inode, struct page * page)
} while (i > 0);
/* IO start */
brw_page(READ, page_address(page), inode->i_dev, nr, inode->i_sb->s_blocksize, 1);
brw_page(READ, page, inode->i_dev, nr, inode->i_sb->s_blocksize, 1);
return 0;
}
......@@ -1422,7 +1423,7 @@ int try_to_free_buffer(struct buffer_head * bh, struct buffer_head ** bhp,
return 0;
if (tmp->b_count || buffer_protected(tmp) ||
buffer_dirty(tmp) || buffer_locked(tmp) ||
buffer_waiting(bh))
buffer_waiting(tmp))
return 0;
if (priority && buffer_touched(tmp))
return 0;
......
......@@ -564,7 +564,7 @@ rpc_closesock(struct rpc_sock *rsock)
unsigned long t0 = jiffies;
rsock->shutdown = 1;
while (rsock->pending || rsock->backlog) {
while (rsock->pending || waitqueue_active(&rsock->backlog)) {
interruptible_sleep_on(&rsock->shutwait);
if (current->signal & ~current->blocked)
return -EINTR;
......
......@@ -227,7 +227,7 @@ void UMSDOS_read_inode(struct inode *inode)
if (S_ISDIR(inode->i_mode)
&& (inode->u.umsdos_i.u.dir_info.creating != 0
|| inode->u.umsdos_i.u.dir_info.looking != 0
|| inode->u.umsdos_i.u.dir_info.p != NULL)){
|| waitqueue_active(&inode->u.umsdos_i.u.dir_info.p))){
Printk (("read inode %d %d %p\n"
,inode->u.umsdos_i.u.dir_info.creating
,inode->u.umsdos_i.u.dir_info.looking
......
......@@ -90,7 +90,7 @@ extern void enable_irq(unsigned int);
"outb %al,$0x21\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\tmovb $0xE0+"#nr",%al\n\t" \
"1:\tmovb $0x60+"#nr",%al\n\t" \
"outb %al,$0x20\n\t"
#define ACK_SECOND(mask,nr) \
......@@ -102,11 +102,11 @@ extern void enable_irq(unsigned int);
"outb %al,$0xA1\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\tmovb $0xE0+"#nr",%al\n\t" \
"1:\tmovb $0x60+"#nr",%al\n\t" \
"outb %al,$0xA0\n\t" \
"jmp 1f\n" \
"1:\tjmp 1f\n" \
"1:\tmovb $0xE2,%al\n\t" \
"1:\tmovb $0x62,%al\n\t" \
"outb %al,$0x20\n\t"
#define UNBLK_FIRST(mask) \
......
......@@ -53,6 +53,7 @@ __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
#define flush_tlb() __flush_tlb()
#define flush_tlb_all() __flush_tlb()
#define local_flush_tlb() __flush_tlb()
static inline void flush_tlb_mm(struct mm_struct *mm)
{
......
......@@ -653,7 +653,7 @@ extern struct buffer_head * breada(kdev_t dev,int block, int size,
extern int generic_readpage(struct inode *, struct page *);
extern int generic_file_read(struct inode *, struct file *, char *, int);
extern int generic_file_mmap(struct inode *, struct file *, struct vm_area_struct *);
extern int brw_page(int, unsigned long, kdev_t, int [], int, int);
extern int brw_page(int, struct page *, kdev_t, int [], int, int);
extern void put_super(kdev_t dev);
unsigned long generate_cluster(kdev_t dev, int b[], int size);
......
......@@ -77,7 +77,7 @@
((M) == SCSI_DISK_MAJOR \
|| (M) == SCSI_CDROM_MAJOR)
static inline int scsi_blk_major(int m) {
static __inline__ int scsi_blk_major(int m) {
return SCSI_BLK_MAJOR(m);
}
......
......@@ -42,13 +42,10 @@ static inline unsigned long _page_hashfn(struct inode * inode, unsigned long off
#undef s
}
#define page_hash(inode,offset) page_hash_table[_page_hashfn(inode,offset)]
#define page_hash(inode,offset) (page_hash_table+_page_hashfn(inode,offset))
static inline struct page * find_page(struct inode * inode, unsigned long offset)
static inline struct page * __find_page(struct inode * inode, unsigned long offset, struct page *page)
{
struct page *page;
page = page_hash(inode, offset);
goto inside;
for (;;) {
page = page->next_hash;
......@@ -67,9 +64,14 @@ static inline struct page * find_page(struct inode * inode, unsigned long offset
return page;
}
static inline struct page *find_page(struct inode * inode, unsigned long offset)
{
return __find_page(inode, offset, *page_hash(inode, offset));
}
static inline void remove_page_from_hash_queue(struct page * page)
{
struct page **p = &page_hash(page->inode,page->offset);
struct page **p = page_hash(page->inode,page->offset);
page_cache_size--;
if (page->next_hash)
......@@ -81,10 +83,8 @@ static inline void remove_page_from_hash_queue(struct page * page)
page->next_hash = page->prev_hash = NULL;
}
static inline void add_page_to_hash_queue(struct inode * inode, struct page * page)
static inline void __add_page_to_hash_queue(struct page * page, struct page **p)
{
struct page **p = &page_hash(inode,page->offset);
page_cache_size++;
set_bit(PG_referenced, &page->flags);
page->age = PAGE_AGE_VALUE;
......@@ -94,6 +94,12 @@ static inline void add_page_to_hash_queue(struct inode * inode, struct page * pa
*p = page;
}
static inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long offset)
{
__add_page_to_hash_queue(page, page_hash(inode,offset));
}
static inline void remove_page_from_inode_queue(struct page * page)
{
struct inode * inode = page->inode;
......
......@@ -959,8 +959,17 @@ static int init(void * unused)
}
}
#endif
/*
* This keeps serial console MUCH cleaner, but does assume
* the console driver checks there really is a video device
* attached (Sparc effectively does).
*/
(void) open("/dev/tty1",O_RDWR,0);
if ((open("/dev/tty1",O_RDWR,0) < 0) &&
(open("/dev/ttyS0",O_RDWR,0) < 0))
printk("Unable to open a initial console.\n");
(void) dup(0);
(void) dup(0);
......
......@@ -1180,8 +1180,10 @@ static int setscheduler(pid_t pid, int policy,
p->policy = policy;
p->rt_priority = lp.sched_priority;
cli();
if (p->next_run)
move_last_runqueue(p);
sti();
schedule();
return 0;
......@@ -1237,8 +1239,9 @@ asmlinkage int sys_sched_getparam(pid_t pid, struct sched_param *param)
asmlinkage int sys_sched_yield(void)
{
cli();
move_last_runqueue(current);
sti();
return 0;
}
......
......@@ -255,13 +255,14 @@ void update_vm_cache(struct inode * inode, unsigned long pos, const char * buf,
}
static inline void add_to_page_cache(struct page * page,
struct inode * inode, unsigned long offset)
struct inode * inode, unsigned long offset,
struct page **hash)
{
page->count++;
page->flags &= ~((1 << PG_uptodate) | (1 << PG_error));
page->offset = offset;
add_page_to_inode_queue(inode, page);
add_page_to_hash_queue(inode, page);
__add_page_to_hash_queue(page, hash);
}
/*
......@@ -272,32 +273,31 @@ static inline void add_to_page_cache(struct page * page,
static unsigned long try_to_read_ahead(struct inode * inode, unsigned long offset, unsigned long page_cache)
{
struct page * page;
struct page ** hash;
offset &= PAGE_MASK;
if (!page_cache) {
switch (page_cache) {
case 0:
page_cache = __get_free_page(GFP_KERNEL);
if (!page_cache)
return 0;
}
if (offset >= inode->i_size)
return page_cache;
#if 1
page = find_page(inode, offset);
if (page) {
break;
default:
if (offset >= inode->i_size)
break;
hash = page_hash(inode, offset);
page = __find_page(inode, offset, *hash);
if (!page) {
/*
* Ok, add the new page to the hash-queues...
*/
page = mem_map + MAP_NR(page_cache);
add_to_page_cache(page, inode, offset, hash);
inode->i_op->readpage(inode, page);
page_cache = 0;
}
release_page(page);
return page_cache;
}
/*
* Ok, add the new page to the hash-queues...
*/
page = mem_map + MAP_NR(page_cache);
add_to_page_cache(page, inode, offset);
inode->i_op->readpage(inode, page);
free_page(page_cache);
return 0;
#else
return page_cache;
#endif
}
/*
......@@ -457,13 +457,12 @@ static void profile_readahead(int async, struct file *filp)
#endif
static inline unsigned long generic_file_readahead(int reada_ok, struct file * filp, struct inode * inode,
unsigned long pos, struct page * page,
unsigned long ppos, struct page * page,
unsigned long page_cache)
{
unsigned long max_ahead, ahead;
unsigned long raend, ppos;
unsigned long raend;
ppos = pos & PAGE_MASK;
raend = filp->f_raend & PAGE_MASK;
max_ahead = 0;
......@@ -607,7 +606,7 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
} else {
unsigned long needed;
needed = ((pos + count) & PAGE_MASK) - (pos & PAGE_MASK);
needed = ((pos + count) & PAGE_MASK) - ppos;
if (filp->f_ramax < needed)
filp->f_ramax = needed;
......@@ -619,7 +618,7 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
}
for (;;) {
struct page *page;
struct page *page, **hash;
if (pos >= inode->i_size)
break;
......@@ -627,7 +626,8 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
/*
* Try to find the data in the page cache..
*/
page = find_page(inode, pos & PAGE_MASK);
hash = page_hash(inode, pos & PAGE_MASK);
page = __find_page(inode, pos & PAGE_MASK, *hash);
if (!page)
goto no_cached_page;
......@@ -640,7 +640,7 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
* the page has been rewritten.
*/
if (PageUptodate(page) || PageLocked(page))
page_cache = generic_file_readahead(reada_ok, filp, inode, pos, page, page_cache);
page_cache = generic_file_readahead(reada_ok, filp, inode, pos & PAGE_MASK, page, page_cache);
else if (reada_ok && filp->f_ramax > MIN_READAHEAD)
filp->f_ramax = MIN_READAHEAD;
......@@ -696,7 +696,7 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
*/
page = mem_map + MAP_NR(page_cache);
page_cache = 0;
add_to_page_cache(page, inode, pos & PAGE_MASK);
add_to_page_cache(page, inode, pos & PAGE_MASK, hash);
/*
* Error handling is tricky. If we get a read error,
......@@ -764,7 +764,7 @@ int generic_file_read(struct inode * inode, struct file * filp, char * buf, int
static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
{
unsigned long offset;
struct page * page;
struct page * page, **hash;
struct inode * inode = area->vm_inode;
unsigned long old_page, new_page;
......@@ -776,7 +776,8 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long
/*
* Do we have something in the page cache already?
*/
page = find_page(inode, offset);
hash = page_hash(inode, offset);
page = __find_page(inode, offset, *hash);
if (!page)
goto no_cached_page;
......@@ -841,7 +842,7 @@ static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long
*/
page = mem_map + MAP_NR(new_page);
new_page = 0;
add_to_page_cache(page, inode, offset);
add_to_page_cache(page, inode, offset, hash);
if (inode->i_op->readpage(inode, page) != 0)
goto failure;
......
......@@ -144,7 +144,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
if ((len = PAGE_ALIGN(len)) == 0)
return addr;
if (addr > TASK_SIZE || len > TASK_SIZE || addr > TASK_SIZE-len)
if (len > TASK_SIZE || addr > TASK_SIZE-len)
return -EINVAL;
/* offset overflow? */
......@@ -199,8 +199,6 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
if (flags & MAP_FIXED) {
if (addr & ~PAGE_MASK)
return -EINVAL;
if (len > TASK_SIZE || addr > TASK_SIZE - len)
return -EINVAL;
} else {
addr = get_unmapped_area(addr, len);
if (!addr)
......
......@@ -168,9 +168,10 @@ void swap_after_unlock_page (unsigned long entry)
* asynchronous function now --- we must call wait_on_page afterwards
* if synchronous IO is required.
*/
void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer)
void ll_rw_page(int rw, kdev_t dev, unsigned long offset, char * buffer)
{
int block = page;
int block = offset;
struct page *page;
switch (rw) {
case READ:
......@@ -185,7 +186,8 @@ void ll_rw_page(int rw, kdev_t dev, unsigned long page, char * buffer)
default:
panic("ll_rw_page: bad block dev cmd, must be R/W");
}
if (set_bit(PG_locked, &mem_map[MAP_NR(buffer)].flags))
page = mem_map + MAP_NR(buffer);
if (set_bit(PG_locked, &page->flags))
panic ("ll_rw_page: page already locked");
brw_page(rw, (unsigned long) buffer, dev, &block, PAGE_SIZE, 0);
brw_page(rw, page, dev, &block, PAGE_SIZE, 0);
}
......@@ -618,7 +618,9 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, unsigned long info, s
* Build and send the packet.
*/
icmp_build_xmit(&icmp_param, saddr, iph->saddr, ((iph->tos & 0x38) | 6));
icmp_build_xmit(&icmp_param, saddr, iph->saddr,
icmp_pointers[type].error ?
(iph->tos & 0x1E) | 0xC0 : iph->tos);
}
......
......@@ -236,6 +236,10 @@ static int raw_sendto(struct sock *sk, const unsigned char *from,
memcpy(&sin, usin, sizeof(sin));
if (sin.sin_family && sin.sin_family != AF_INET)
return(-EINVAL);
/*
* Protocol type is host ordered byte.
*/
sin.sin_port=ntohs(sin.sin_port);
}
else
{
......
......@@ -958,6 +958,7 @@ static int do_tcp_sendmsg(struct sock *sk,
{
if (copied)
return copied;
send_sig(SIGPIPE,current,0);
return -EPIPE;
}
......
......@@ -863,6 +863,12 @@ static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
return -EINVAL;
}
if(sk->shutdown&SEND_SHUTDOWN)
{
send_sig(SIGPIPE,current,0);
return -EPIPE;
}
if(sunaddr!=NULL)
{
if(sock->type==SOCK_STREAM)
......@@ -973,10 +979,27 @@ static int unix_sendmsg(struct socket *sock, struct msghdr *msg, int len, int no
sock->state=SS_UNCONNECTED;
sti();
kfree_skb(skb, FREE_WRITE);
/*
* Check with 1003.1g - what should
* datagram error
*/
if (!sent)
sent = -ECONNRESET;
return sent;
}
/*
* Stream sockets SIGPIPE
*/
if(sock->type==SOCK_STREAM && other->dead)
{
kfree_skb(skb, FREE_WRITE);
sti();
if(!sent)
return -ECONNRESET;
else
return sent;
{
send_sig(SIGPIPE,current,0);
sent = -EPIPE;
}
return sent;
}
}
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment