diff -u --recursive --new-file v2.0.18/linux/CREDITS linux/CREDITS --- v2.0.18/linux/CREDITS Sun Sep 8 19:50:20 1996 +++ linux/CREDITS Tue Sep 10 09:08:32 1996 @@ -388,10 +388,10 @@ D: Debugging: SCSI code; Cyclades serial driver; APM driver D: Debugging: XFree86 Mach 32 server, accelerated server code -N: Juergen Fischer -E: fischer@server.et-inf.fho-emden.de +N: Jürgen Fischer +E: fischer@et-inf.fho-emden.de (=?iso-8859-1?q?J=FCrgen?= Fischer) D: Author of Adaptec AHA-152x scsi driver -S: Schulstrasse 18 +S: Schulstraße 18 S: 26506 Norden S: Germany @@ -532,9 +532,7 @@ N: Kai Harrekilde-Petersen E: khp@dolphinics.no -W: http://www.dolphinics.no/~khp -P: 1024/D2CDF895 F6 33 E0 4E 01 17 85 8C 4F 7F 1F F8 14 E7 86 1D -D: ftape-HOWTO, i82078 fdc detection code, ftape maintainer. +D: Original author of the ftape-HOWTO, i82078 fdc detection code. S: Peder Holters vei 13 S: 1168 Oslo S: Norway diff -u --recursive --new-file v2.0.18/linux/Documentation/Changes linux/Documentation/Changes --- v2.0.18/linux/Documentation/Changes Sun Sep 8 19:50:20 1996 +++ linux/Documentation/Changes Wed Sep 11 11:45:10 1996 @@ -34,7 +34,7 @@ bunshou no nihongo ban wa http://jf.gee.kyoto-u.ac.jp/JF/v2.0/Changes-2.0.html ni arimasu. -Last updated: September 02, 1996. +Last updated: September 10, 1996. Current Author: Chris Ricker (gt1355b@prism.gatech.edu). Current Releases @@ -74,6 +74,14 @@ /etc/sysconfig/network-scripts/ifup-lo, changing the line `route add -net $(IPADDR)' to `route add -net 127.0.0.0' and you should be fine. + People have also reported problems due to the naming of the dummy +network interface driver. If the dummy driver is compiled into the +kernel, its name is "dummy." If the dummy driver is compiled as a +module, its name is "dummy0." Furthermore, more than one dummy driver +can be loaded if compiled as a module. Each subsequent loading of the +driver adds a new dummy interface whose name is incremented by one +("dummy1," "dummy2," etc.). + Booting Changes =============== @@ -194,6 +202,15 @@ device drivers compiled into the kernel, so don't get grandiose ideas about going completely modular and then forget to compile ext2fs support and ide/SCSI drive support into your kernel ;-). + +Kernel messages +=============== + + Kernel messages without a specific log level use the kernel's +default log level. In 1.2 kernels, the default log level was 6 +(information), while in 2.0.x kernels it is 4 (warning). Adjust your +configuration of syslogd appropriately (or edit printk.c in the kernel +source ;-). PPP driver ========== diff -u --recursive --new-file v2.0.18/linux/Documentation/networking/arcnet.txt linux/Documentation/networking/arcnet.txt --- v2.0.18/linux/Documentation/networking/arcnet.txt Mon May 27 14:22:44 1996 +++ linux/Documentation/networking/arcnet.txt Tue Sep 10 09:08:32 1996 @@ -117,12 +117,9 @@ Loadable Module Support ----------------------- -Configure and rebuild Linux. When asked, answer 'n' to "arcnet support" if +Configure and rebuild Linux. When asked, answer 'm' to "arcnet support" if you want to use the loadable module. -Actually, with Linux 1.3.24 and higher, you should answer 'm' to build the -module. - make config make dep make clean @@ -130,15 +127,16 @@ make modules If you're using a loadable module, you need to use insmod to load it, and -you need to specify various characteristics of your card on the command -line. For example: +you can specify various characteristics of your card on the command +line. (In recent versions of the driver, autoprobing is much more reliable +and works as a module, so most of this is now unnecessary.) + +For example: cd /usr/src/linux/modules - insmod arcnet.o io=0x300 irqnum=2 shmem=0xd0000 -You can also add a num=1, num=2 etc for additional arcnet cards that will -use arc1, arc2 etc for their device names (instead of the default, arc0). + insmod arcnet.o io=0x300 irq=2 shmem=0xd0000 -** NEWS FLASH! Starting with 2.30 ALPHA, the ARCnet driver can autoprobe - even as a module. So "insmod arcnet.o" by itself should work. +You can name the device using something like "device=arc1" (for a second +card) or "device=eth0" (for weird compatibility reasons) if you like. Using the Driver @@ -154,6 +152,19 @@ By the way, be sure to change all references from "eth0" to "arc0" in the HOWTOs. Remember that ARCnet isn't a "true" ethernet, and the device name is DIFFERENT. + + +Multiple Cards in One Computer +------------------------------ + +Linux has pretty good support for this now, but since I've been busy, the +ARCnet driver has somewhat suffered in this respect. For now, the easiest +way to use multiple ARCnet cards is to build it as a loadable module and +then do something like this: + insmod -o arc0 arcnet + insmod -o arc1 arcnet device=arc1 +(Note that in the first line, the default is device=arc0, but it doesn't +hurt if you want to add it for consistency.) How do I get it to work with...? diff -u --recursive --new-file v2.0.18/linux/Documentation/oops-tracing.txt linux/Documentation/oops-tracing.txt --- v2.0.18/linux/Documentation/oops-tracing.txt Sun Sep 8 19:50:20 1996 +++ linux/Documentation/oops-tracing.txt Fri Sep 6 19:19:04 1996 @@ -126,7 +126,7 @@ 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: current->tss.cr3 = 0062d000, %cr3 = 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 diff -u --recursive --new-file v2.0.18/linux/MAINTAINERS linux/MAINTAINERS --- v2.0.18/linux/MAINTAINERS Sat Aug 17 21:19:25 1996 +++ linux/MAINTAINERS Tue Sep 10 09:08:32 1996 @@ -178,9 +178,8 @@ S: Maintained FTAPE/QIC-117: -P: Kai Harrekilde-Petersen -M: khp@dolphinics.no -W: http://www.dolphinics.no/~khp/ftape.html +P: Claus-Justus Heine +M: claus@momo.math.rwth-aachen.de L: linux-tape@vger.rutgers.edu S: Maintained diff -u --recursive --new-file v2.0.18/linux/Makefile linux/Makefile --- v2.0.18/linux/Makefile Sun Sep 8 19:50:20 1996 +++ linux/Makefile Sun Sep 8 20:14:51 1996 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 0 -SUBLEVEL = 18 +SUBLEVEL = 19 ARCH = i386 diff -u --recursive --new-file v2.0.18/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c --- v2.0.18/linux/arch/alpha/kernel/ptrace.c Fri May 3 15:55:57 1996 +++ linux/arch/alpha/kernel/ptrace.c Mon Sep 9 21:04:56 1996 @@ -266,7 +266,7 @@ struct vm_area_struct * vma; addr &= PAGE_MASK; - vma = find_vma(tsk,addr); + vma = find_vma(tsk->mm,addr); if (!vma) return NULL; if (vma->vm_start <= addr) diff -u --recursive --new-file v2.0.18/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c --- v2.0.18/linux/arch/alpha/mm/fault.c Thu Aug 1 15:53:34 1996 +++ linux/arch/alpha/mm/fault.c Mon Sep 9 21:04:56 1996 @@ -58,8 +58,11 @@ struct pt_regs regs) { struct vm_area_struct * vma; + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; - vma = find_vma(current, address); + down(&mm->mmap_sem); + vma = find_vma(mm, address); if (!vma) goto bad_area; if (vma->vm_start <= address) @@ -85,6 +88,7 @@ goto bad_area; } handle_mm_fault(vma, address, cause > 0); + up(&mm->mmap_sem); return; /* @@ -92,11 +96,12 @@ * Fix it, but check if it's kernel or user first.. */ bad_area: + up(&mm->mmap_sem); if (user_mode(®s)) { printk("%s: memory violation at pc=%08lx rp=%08lx (bad address = %08lx)\n", - current->comm, regs.pc, regs.r26, address); + tsk->comm, regs.pc, regs.r26, address); die_if_kernel("oops", ®s, cause); - force_sig(SIGSEGV, current); + force_sig(SIGSEGV, tsk); return; } /* diff -u --recursive --new-file v2.0.18/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v2.0.18/linux/arch/i386/kernel/Makefile Wed Feb 7 08:55:34 1996 +++ linux/arch/i386/kernel/Makefile Mon Sep 9 13:55:58 1996 @@ -11,7 +11,6 @@ # $(CPP) -D__ASSEMBLY__ -traditional $< -o $*.s ifdef SMP - .S.o: $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o else diff -u --recursive --new-file v2.0.18/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.0.18/linux/arch/i386/kernel/irq.c Thu Jun 6 13:44:42 1996 +++ linux/arch/i386/kernel/irq.c Mon Sep 9 09:32:19 1996 @@ -232,7 +232,7 @@ action = irq_action[i]; if (!action) continue; - len += sprintf(buf+len, "%2d: %8d %c %s", + len += sprintf(buf+len, "%2d: %10u %c %s", i, kstat.interrupts[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); diff -u --recursive --new-file v2.0.18/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.0.18/linux/arch/i386/kernel/process.c Sat Aug 17 21:19:26 1996 +++ linux/arch/i386/kernel/process.c Mon Sep 9 13:06:14 1996 @@ -33,7 +33,6 @@ #include #include - asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); #ifdef CONFIG_APM diff -u --recursive --new-file v2.0.18/linux/arch/i386/kernel/ptrace.c linux/arch/i386/kernel/ptrace.c --- v2.0.18/linux/arch/i386/kernel/ptrace.c Thu May 2 16:11:56 1996 +++ linux/arch/i386/kernel/ptrace.c Mon Sep 9 21:04:56 1996 @@ -187,7 +187,7 @@ struct vm_area_struct * vma; addr &= PAGE_MASK; - vma = find_vma(tsk,addr); + vma = find_vma(tsk->mm,addr); if (!vma) return NULL; if (vma->vm_start <= addr) diff -u --recursive --new-file v2.0.18/linux/arch/i386/lib/Makefile linux/arch/i386/lib/Makefile --- v2.0.18/linux/arch/i386/lib/Makefile Tue Aug 15 15:07:02 1995 +++ linux/arch/i386/lib/Makefile Mon Sep 9 16:09:16 1996 @@ -2,7 +2,15 @@ # Makefile for i386-specific library files.. # +ifdef SMP +.S.o: + $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o +else +.S.o: + $(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o +endif + L_TARGET = lib.a -L_OBJS = checksum.o +L_OBJS = checksum.o semaphore.o include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.0.18/linux/arch/i386/lib/semaphore.S linux/arch/i386/lib/semaphore.S --- v2.0.18/linux/arch/i386/lib/semaphore.S Thu Jan 1 02:00:00 1970 +++ linux/arch/i386/lib/semaphore.S Wed Sep 11 14:15:08 1996 @@ -0,0 +1,31 @@ +/* + * linux/arch/i386/lib/semaphore.S + * + * Copyright (C) 1996 Linus Torvalds + */ + +#include + +/* + * "down_failed" is called with the eventual return address + * in %eax, and the address of the semaphore in %ecx. We need + * to increment the number of waiters on the semaphore, + * call "__down()", and then eventually return to try again. + */ +.globl down_failed +ALIGN +down_failed: + pushl %eax + pushl %ecx + call SYMBOL_NAME(__down) + popl %ecx + ret + +.globl up_wakeup +ALIGN +up_wakeup: + pushl %eax + pushl %ecx + call SYMBOL_NAME(__up) + popl %ecx + ret diff -u --recursive --new-file v2.0.18/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c --- v2.0.18/linux/arch/i386/mm/fault.c Sun Sep 8 19:50:20 1996 +++ linux/arch/i386/mm/fault.c Mon Sep 9 21:04:56 1996 @@ -33,13 +33,21 @@ */ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) { + void (*handler)(struct task_struct *, + struct vm_area_struct *, + unsigned long, + int); + struct task_struct *tsk = current; + struct mm_struct *mm = tsk->mm; struct vm_area_struct * vma; unsigned long address; unsigned long page; + int write; /* get the address */ __asm__("movl %%cr2,%0":"=r" (address)); - vma = find_vma(current, address); + down(&mm->mmap_sem); + vma = find_vma(mm, address); if (!vma) goto bad_area; if (vma->vm_start <= address) @@ -63,36 +71,37 @@ * we can handle it.. */ good_area: - /* - * was it a write? - */ - if (error_code & 2) { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - } else { - /* read with protection fault? */ - if (error_code & 1) - goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + write = 0; + handler = do_no_page; + switch (error_code & 3) { + default: /* 3: write, present */ + handler = do_wp_page; +#ifdef TEST_VERIFY_AREA + if (regs->cs == KERNEL_CS) + printk("WP fault at %08lx\n", regs->eip); +#endif + /* fall through */ + case 2: /* write, not present */ + if (!(vma->vm_flags & VM_WRITE)) + goto bad_area; + write++; + break; + case 1: /* read, present */ goto bad_area; + case 0: /* read, not present */ + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto bad_area; } + handler(tsk, vma, address, write); + up(&mm->mmap_sem); /* * Did it hit the DOS screen memory VA from vm86 mode? */ if (regs->eflags & VM_MASK) { unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT; if (bit < 32) - current->tss.screen_bitmap |= 1 << bit; - } - if (error_code & 1) { -#ifdef TEST_VERIFY_AREA - if (regs->cs == KERNEL_CS) - printk("WP fault at %08lx\n", regs->eip); -#endif - do_wp_page(current, vma, address, error_code & 2); - return; + tsk->tss.screen_bitmap |= 1 << bit; } - do_no_page(current, vma, address, error_code & 2); return; /* @@ -100,11 +109,12 @@ * Fix it, but check if it's kernel or user first.. */ bad_area: + up(&mm->mmap_sem); if (error_code & 4) { - current->tss.cr2 = address; - current->tss.error_code = error_code; - current->tss.trap_no = 14; - force_sig(SIGSEGV, current); + tsk->tss.cr2 = address; + tsk->tss.error_code = error_code; + tsk->tss.trap_no = 14; + force_sig(SIGSEGV, tsk); return; } /* @@ -128,7 +138,7 @@ printk(" at virtual address %08lx\n",address); __asm__("movl %%cr3,%0" : "=r" (page)); printk(KERN_ALERT "current->tss.cr3 = %08lx, %%cr3 = %08lx\n", - current->tss.cr3, page); + tsk->tss.cr3, page); page = ((unsigned long *) page)[address >> 22]; printk(KERN_ALERT "*pde = %08lx\n", page); if (page & 1) { diff -u --recursive --new-file v2.0.18/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c --- v2.0.18/linux/drivers/block/ide-tape.c Wed Aug 21 09:18:07 1996 +++ linux/drivers/block/ide-tape.c Tue Sep 10 19:50:32 1996 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-tape.c Version 1.6 - ALPHA Aug 16, 1996 + * linux/drivers/block/ide-tape.c Version 1.7 - ALPHA Sep 10, 1996 * * Copyright (C) 1995, 1996 Gadi Oxman * @@ -32,7 +32,7 @@ * ht0 major=37,minor=0 first IDE tape, rewind on close. * nht0 major=37,minor=128 first IDE tape, no rewind on close. * - * Run /usr/src/linux/drivers/block/MAKEDEV.ide to create the above entries. + * Run /usr/src/linux/scripts/MAKEDEV.ide to create the above entries. * We currently support only one ide tape drive. * * The general magnetic tape commands compatible interface, as defined by @@ -186,6 +186,7 @@ * Fixed nasty null dereferencing bug. * Ver 1.6 Aug 16 96 Fixed FPU usage in the driver. * Fixed end of media bug. + * Ver 1.7 Sep 10 96 Minor changes for the CONNER CTT8000-A model. * * We are currently in an *alpha* stage. The driver is not complete and not * much tested. I would strongly suggest to: @@ -1079,6 +1080,7 @@ printk ("LBA: %s",id->capability & 0x02 ? "Yes\n":"No\n"); printk ("IORDY can be disabled: %s",id->capability & 0x04 ? "Yes\n":"No\n"); printk ("IORDY supported: %s",id->capability & 0x08 ? "Yes\n":"Unknown\n"); + printk ("ATAPI overlap supported: %s",id->capability & 0x20 ? "Yes\n":"No\n"); printk ("PIO Cycle Timing Category: %d\n",id->tPIO); printk ("DMA Cycle Timing Category: %d\n",id->tDMA); printk ("Single Word DMA supported modes: "); @@ -1487,7 +1489,9 @@ if (!pc->abort) { printk ("ide-tape: %s: I/O error, ",drive->name); printk ("pc = %x, key = %x, asc = %x, ascq = %x\n",pc->c[0],tape->sense_key,tape->asc,tape->ascq); +#if IDETAPE_DEBUG_LOG printk ("ide-tape: Maximum retries reached - Giving up\n"); +#endif /* IDETAPE_DEBUG_LOG */ pc->error=1; /* Giving up */ } tape->failed_pc=NULL; @@ -1678,15 +1682,15 @@ if (!pc->writing) { /* Reading - Check that we have enough space */ temp=(unsigned long) pc->actually_transferred + bcount.all; if ( temp > pc->request_transfer) { - printk ("ide-tape: The tape wants to send us more data than requested - "); if (temp > pc->buffer_size) { - printk ("Discarding data\n"); + printk ("ide-tape: The tape wants to send us more data than requested - discarding data\n"); idetape_discard_data (drive,bcount.all); ide_set_handler (drive,&idetape_pc_intr,WAIT_CMD); return; } - else - printk ("Allowing transfer\n"); +#if IDETAPE_DEBUG_LOG + printk ("ide-tape: The tape wants to send us more data than requested - allowing transfer\n"); +#endif /* IDETAPE_DEBUG_LOG */ } } #if IDETAPE_DEBUG_BUGS @@ -2925,7 +2929,7 @@ printk ("ide-tape: The block device interface should not be used for data transfers.\n"); printk ("ide-tape: Use the character device interfaces\n"); printk ("ide-tape: /dev/ht0 and /dev/nht0 instead.\n"); - printk ("ide-tape: (Run linux/drivers/block/MAKEDEV.ide to create them)\n"); + printk ("ide-tape: (Run linux/scripts/MAKEDEV.ide to create them)\n"); printk ("ide-tape: Aborting request.\n"); ide_end_request (0,HWGROUP (drive)); /* Let the common code handle it */ diff -u --recursive --new-file v2.0.18/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h --- v2.0.18/linux/drivers/block/ide-tape.h Wed Aug 21 09:18:07 1996 +++ linux/drivers/block/ide-tape.h Tue Sep 10 19:50:32 1996 @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide-tape.h Version 1.5 - ALPHA Apr 12, 1996 + * linux/drivers/block/ide-tape.h Version 1.7 - ALPHA Sep 10, 1996 * * Copyright (C) 1995, 1996 Gadi Oxman */ @@ -238,7 +238,7 @@ */ #define IDETAPE_DSC_READ_WRITE_FALLBACK_FREQUENCY 5*HZ/100 /* 50 msec */ -#define IDETAPE_DSC_READ_WRITE_LOWEST_FREQUENCY 30*HZ/100 /* 300 msec */ +#define IDETAPE_DSC_READ_WRITE_LOWEST_FREQUENCY 40*HZ/100 /* 400 msec */ #define IDETAPE_DSC_FAST_MEDIA_ACCESS_FREQUENCY 1*HZ /* 1 second */ #define IDETAPE_FAST_SLOW_THRESHOLD 5*60*HZ /* 5 minutes */ #define IDETAPE_DSC_SLOW_MEDIA_ACCESS_FREQUENCY 60*HZ /* 1 minute */ diff -u --recursive --new-file v2.0.18/linux/drivers/block/triton.c linux/drivers/block/triton.c --- v2.0.18/linux/drivers/block/triton.c Sat Aug 17 21:19:26 1996 +++ linux/drivers/block/triton.c Tue Sep 10 19:50:32 1996 @@ -127,7 +127,8 @@ * known to work fine with this interface under Linux. */ const char *good_dma_drives[] = {"Micropolis 2112A", - "CONNER CTMA 4000"}; + "CONNER CTMA 4000", + "CONNER CTT8000-A"}; /* * Our Physical Region Descriptor (PRD) table should be large enough diff -u --recursive --new-file v2.0.18/linux/drivers/char/psaux.c linux/drivers/char/psaux.c --- v2.0.18/linux/drivers/char/psaux.c Thu Aug 29 19:15:14 1996 +++ linux/drivers/char/psaux.c Mon Sep 9 15:14:53 1996 @@ -567,6 +567,7 @@ void cleanup_module(void) { misc_deregister(&psaux_mouse); + kfree(queue); } #endif diff -u --recursive --new-file v2.0.18/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.0.18/linux/drivers/char/tty_io.c Sun Sep 8 19:50:20 1996 +++ linux/drivers/char/tty_io.c Sat Sep 7 18:09:14 1996 @@ -777,8 +777,9 @@ ret = write(tty, file, buf, size); if (ret <= 0) break; - count -= ret; written += ret; + buf += ret; + count -= ret; if (!count) break; ret = -ERESTARTSYS; diff -u --recursive --new-file v2.0.18/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.0.18/linux/drivers/net/de4x5.c Wed Aug 21 09:18:08 1996 +++ linux/drivers/net/de4x5.c Tue Sep 10 09:08:32 1996 @@ -210,11 +210,13 @@ 0.44 13-Aug-96 Fix RX overflow bug in 2114[023] chips. Fix EISA probe bugs reported by and + 0.441 9-Sep-96 Change dc21041_autoconf() to probe quiet BNC media + with a loopback packet. ========================================================================= */ -static const char *version = "de4x5.c:v0.44 96/8/13 davies@wanton.lkg.dec.com\n"; +static const char *version = "de4x5.c:v0.441 96/9/9 davies@wanton.lkg.dec.com\n"; #include @@ -2227,12 +2229,8 @@ if (sts < 0) { next_tick = sts & ~TIMER_CB; } else { - if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) { - lp->media = NC; - } else { - lp->local_state++; /* Ensure media connected */ - next_tick = dc21041_autoconf(dev); - } + lp->local_state++; /* Ensure media connected */ + next_tick = dc21041_autoconf(dev); } break; diff -u --recursive --new-file v2.0.18/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.0.18/linux/drivers/pci/pci.c Wed Aug 21 09:18:08 1996 +++ linux/drivers/pci/pci.c Wed Sep 11 11:45:10 1996 @@ -69,6 +69,7 @@ DEVICE( DEC, DEC_TULIP_FAST, "DC21140"), DEVICE( DEC, DEC_FDDI, "DEFPA"), DEVICE( DEC, DEC_TULIP_PLUS, "DC21041"), + DEVICE( DEC, DEC_21052_AB, "DC21052-AB"), DEVICE( CIRRUS, CIRRUS_5430, "GD 5430"), DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"), DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434"), @@ -230,8 +231,10 @@ DEVICE( INTEL, INTEL_82371_1, "82371 Triton PIIX"), DEVICE( INTEL, INTEL_82441, "82441FX Natoma"), DEVICE( INTEL, INTEL_82439, "82439HX Triton II"), - DEVICE( INTEL, INTEL_82371SB_0,"82371SB Natoma/Triton II PIIX"), - DEVICE( INTEL, INTEL_82371SB_1,"82371SB Natoma/Triton II PIIX"), + DEVICE( INTEL, INTEL_82371SB_0,"82371SB Natoma/Triton II PIIX3"), + DEVICE( INTEL, INTEL_82371SB_1,"82371SB Natoma/Triton II PIIX3"), + DEVICE( INTEL, INTEL_82371SB_2,"82371SB Natoma/Triton II PIIX3"), + DEVICE( INTEL, INTEL_82437VX, "82437VX Triton II"), DEVICE( INTEL, INTEL_P6, "Orion P6"), DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"), DEVICE( ADAPTEC, ADAPTEC_7855, "AIC-7855"), @@ -433,6 +436,7 @@ case PCI_CLASS_SERIAL_FIREWIRE: return "FireWire (IEEE 1394)"; case PCI_CLASS_SERIAL_ACCESS: return "ACCESS Bus"; case PCI_CLASS_SERIAL_SSA: return "SSA"; + case PCI_CLASS_SERIAL_USB: return "USB Controller"; case PCI_CLASS_SERIAL_FIBER: return "Fiber Channel"; default: return "Unknown class"; diff -u --recursive --new-file v2.0.18/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v2.0.18/linux/drivers/scsi/aha152x.c Wed Aug 21 09:18:08 1996 +++ linux/drivers/scsi/aha152x.c Sun Sep 8 19:45:09 1996 @@ -1,6 +1,6 @@ /* aha152x.c -- Adaptec AHA-152x driver - * Author: Juergen E. Fischer, fischer@et-inf.fho-emden.de - * Copyright 1993, 1994, 1995, 1996 Juergen E. Fischer + * Author: Jürgen E. Fischer, fischer@et-inf.fho-emden.de + * Copyright 1993, 1994, 1995, 1996 Jürgen E. Fischer * * * This driver is based on @@ -20,9 +20,12 @@ * General Public License for more details. * * - * $Id: aha152x.c,v 1.17 1996/08/17 16:05:14 fischer Exp fischer $ + * $Id: aha152x.c,v 1.18 1996/09/07 20:10:40 fischer Exp $ * * $Log: aha152x.c,v $ + * Revision 1.18 1996/09/07 20:10:40 fischer + * - fixed can_queue handling (multiple outstanding commands working again) + * * Revision 1.17 1996/08/17 16:05:14 fischer * - biosparam improved * - interrupt verification @@ -975,7 +978,7 @@ shpnt->this_id=setup[i].scsiid; if(setup[i].reconnect) - shpnt->hostt->can_queue=AHA152X_MAXQUEUE; + shpnt->can_queue=AHA152X_MAXQUEUE; /* RESET OUT */ SETBITS(SCSISEQ, SCSIRSTO); diff -u --recursive --new-file v2.0.18/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h --- v2.0.18/linux/drivers/scsi/aha152x.h Wed Aug 21 09:18:09 1996 +++ linux/drivers/scsi/aha152x.h Sun Sep 8 19:45:51 1996 @@ -2,7 +2,7 @@ #define _AHA152X_H /* - * $Id: aha152x.h,v 1.17 1996/08/17 16:07:38 fischer Exp fischer $ + * $Id: aha152x.h,v 1.18 1996/09/07 20:10:26 fischer Exp $ */ #if defined(__KERNEL__) @@ -23,7 +23,7 @@ (unless we support more than 1 cmd_per_lun this should do) */ #define AHA152X_MAXQUEUE 7 -#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.17 $" +#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.18 $" extern struct proc_dir_entry proc_scsi_aha152x; diff -u --recursive --new-file v2.0.18/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c --- v2.0.18/linux/drivers/scsi/sr.c Sat Aug 17 21:19:28 1996 +++ linux/drivers/scsi/sr.c Sat Sep 7 18:13:04 1996 @@ -167,7 +167,8 @@ if (driver_byte(result) != 0 && /* An error occurred */ SCpnt->sense_buffer[0] == 0xF0 && /* Sense data is valid */ (SCpnt->sense_buffer[2] == MEDIUM_ERROR || - SCpnt->sense_buffer[2] == VOLUME_OVERFLOW)) + SCpnt->sense_buffer[2] == VOLUME_OVERFLOW || + SCpnt->sense_buffer[2] == ILLEGAL_REQUEST)) { long error_sector = (SCpnt->sense_buffer[3] << 24) | (SCpnt->sense_buffer[4] << 16) | diff -u --recursive --new-file v2.0.18/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c --- v2.0.18/linux/drivers/sound/sb_common.c Mon Aug 5 10:13:53 1996 +++ linux/drivers/sound/sb_common.c Tue Sep 10 10:08:12 1996 @@ -674,9 +674,6 @@ devc->dev = num_audiodevs; devc->caps = hw_config->driver_use_1; - irq2devc[hw_config->irq] = devc; - devc->irq_ok = 0; - if (snd_set_irq_handler (hw_config->irq, sbintr, "sound blaster", devc->osp) < 0) { @@ -685,6 +682,9 @@ return; } + irq2devc[hw_config->irq] = devc; + devc->irq_ok = 0; + if (devc->major == 4) if (!sb16_set_irq_hw (devc, devc->irq)) /* Unsupported IRQ */ { @@ -705,7 +705,9 @@ } #ifndef NO_SB_IRQ_TEST - for (n = 0; n < 3 && devc->irq_ok == 0; n++) + if (devc->major != 4 || devc->minor > 11) /* Not Sb16 v4.5 or v4.11 */ + { + for (n = 0; n < 3 && devc->irq_ok == 0; n++) if (sb_dsp_command (devc, 0xf2)) /* Cause interrupt immediately */ { int i; @@ -723,6 +725,7 @@ { DDB (printk ("IRQ test OK (IRQ%d)\n", devc->irq)); } + } #endif request_region (hw_config->io_base, 16, "sound blaster"); diff -u --recursive --new-file v2.0.18/linux/fs/exec.c linux/fs/exec.c --- v2.0.18/linux/fs/exec.c Fri Jul 5 15:06:38 1996 +++ linux/fs/exec.c Mon Sep 9 21:04:57 1996 @@ -299,7 +299,7 @@ mpnt->vm_offset = 0; mpnt->vm_inode = NULL; mpnt->vm_pte = 0; - insert_vm_struct(current, mpnt); + insert_vm_struct(current->mm, mpnt); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; } diff -u --recursive --new-file v2.0.18/linux/fs/namei.c linux/fs/namei.c --- v2.0.18/linux/fs/namei.c Sun Jul 7 20:27:04 1996 +++ linux/fs/namei.c Mon Sep 9 21:04:57 1996 @@ -32,7 +32,7 @@ if (get_fs() == KERNEL_DS) return 0; - vma = find_vma(current, address); + vma = find_vma(current->mm, address); if (!vma || vma->vm_start > address || !(vma->vm_flags & VM_READ)) return -EFAULT; address = vma->vm_end - address; diff -u --recursive --new-file v2.0.18/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- v2.0.18/linux/fs/ncpfs/dir.c Thu Jul 18 15:52:00 1996 +++ linux/fs/ncpfs/dir.c Sun Sep 8 17:58:06 1996 @@ -252,7 +252,7 @@ if (c_entry == NULL) { i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE; - c_entry = (struct ncp_dirent *) ncp_kmalloc(i, GFP_KERNEL); + c_entry = (struct ncp_dirent *) vmalloc(i); if (c_entry == NULL) { printk("ncp_readdir: no MEMORY for cache\n"); @@ -560,9 +560,8 @@ return; } - ncp_kfree_s(c_entry, - sizeof(struct ncp_dirent) * NCP_READDIR_CACHE_SIZE); - c_entry = NULL; + vfree(c_entry); + c_entry = NULL; DPRINTK("ncp_free_dir_cache: exit\n"); } diff -u --recursive --new-file v2.0.18/linux/fs/proc/mem.c linux/fs/proc/mem.c --- v2.0.18/linux/fs/proc/mem.c Thu May 2 16:00:28 1996 +++ linux/fs/proc/mem.c Mon Sep 9 21:04:57 1996 @@ -23,12 +23,12 @@ */ #define mem_write NULL -static int check_range(struct task_struct * tsk, unsigned long addr, int count) +static int check_range(struct mm_struct * mm, unsigned long addr, int count) { struct vm_area_struct *vma; int retval; - vma = find_vma(tsk, addr); + vma = find_vma(mm, addr); if (!vma) return -EACCES; if (vma->vm_start > addr) @@ -93,7 +93,7 @@ if (!tsk) return -ESRCH; addr = file->f_pos; - count = check_range(tsk, addr, count); + count = check_range(tsk->mm, addr, count); if (count < 0) return count; tmp = buf; diff -u --recursive --new-file v2.0.18/linux/fs/smbfs/Makefile linux/fs/smbfs/Makefile --- v2.0.18/linux/fs/smbfs/Makefile Tue Nov 7 19:54:28 1995 +++ linux/fs/smbfs/Makefile Sun Sep 8 17:58:06 1996 @@ -11,4 +11,8 @@ O_OBJS := proc.o sock.o inode.o file.o dir.o ioctl.o mmap.o M_OBJS := $(O_TARGET) +# If you want debugging output, please uncomment the following line + +# EXTRA_CFLAGS += -DDEBUG_SMB=1 -DDEBUG_SMB_MALLOC=1 + include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.0.18/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c --- v2.0.18/linux/fs/smbfs/dir.c Wed Jul 3 12:09:32 1996 +++ linux/fs/smbfs/dir.c Sun Sep 8 17:58:06 1996 @@ -33,9 +33,6 @@ get_pname_static(struct inode *dir, const char *name, int len, char *path, int *res_len); -static struct inode * -smb_iget(struct inode *dir, char *path, struct smb_dirent *finfo); - static void put_pname(char *path); @@ -129,17 +126,6 @@ * smb_readdir provides a listing in the form of filling the dirent structure. * Note that dirent resides in the user space. This is to support reading of a * directory "stream". - * Arguments: - * inode --- Pointer to to the directory. - * filp --- The directory stream. (filp->f_pos indicates - * position in the stream.) - * dirent --- Will hold count directory entries. (Is in user space.) - * count --- Number of entries to be read. Should indicate the total - * buffer space available for filling with dirents. - * Return values: - * < 0 --- An error occurred (linux/errno.h). - * = 0 --- - * > 0 --- Success, amount of bytes written to dirent. * Notes: * Since we want to reduce directory lookups we revert into a * dircache. It is taken rather directly out of the nfs_readdir. @@ -462,45 +448,21 @@ assume that path is allocated for us. */ static struct inode * -smb_iget(struct inode *dir, char *path, struct smb_dirent *finfo) +smb_iget(struct inode *dir, char *path, struct smb_dirent *finfo, + struct smb_inode_info *new_inode_info) { - struct smb_dirent newent = { 0 }; struct inode *inode; - int error, len; - struct smb_inode_info *new_inode_info; + int len; struct smb_inode_info *root; - if (!dir) { - printk("smb_iget: dir is NULL\n"); + if ( (dir == NULL) || (path == NULL) || (finfo == NULL) + || (new_inode_info == NULL)) + { + printk("smb_iget: parameter is NULL\n"); return NULL; } - if (!path) { - printk("smb_iget: path is NULL\n"); - return NULL; - } - len = strlen(path); - - if (!finfo) { - error = smb_proc_getattr(&(SMB_SBP(dir->i_sb)->s_server), - path, len, &newent); - if (error) { - printk("smb_iget: getattr error = %d\n", -error); - return NULL; - } - finfo = &newent; - DPRINTK("smb_iget: Read finfo:\n"); - DPRINTK("smb_iget: finfo->attr = 0x%X\n", finfo->attr); - } - - new_inode_info = smb_kmalloc(sizeof(struct smb_inode_info), - GFP_KERNEL); - - if (new_inode_info == NULL) { - printk("smb_iget: could not alloc mem for %s\n", path); - return NULL; - } new_inode_info->state = SMB_INODE_LOOKED_UP; new_inode_info->nused = 0; @@ -525,6 +487,10 @@ root->next = new_inode_info; if (!(inode = iget(dir->i_sb, (int)new_inode_info))) { + new_inode_info->next->prev = new_inode_info->prev; + new_inode_info->prev->next = new_inode_info->next; + SMB_INOP(dir)->nused -= 1; + printk("smb_iget: iget failed!"); return NULL; } @@ -665,6 +631,8 @@ int error; int found_in_cache; + struct smb_inode_info *new_inode_info = NULL; + *result = NULL; if (!dir || !S_ISDIR(dir->i_mode)) { @@ -689,24 +657,29 @@ result_info = smb_find_inode(SMB_SERVER(dir), name); - if (result_info != 0) { - +in_tree: + if (result_info != NULL) { if (result_info->state == SMB_INODE_CACHED) result_info->state = SMB_INODE_LOOKED_UP; - put_pname(name); - /* Here we convert the inode_info address into an inode number */ *result = iget(dir->i_sb, (int)result_info); + + if (new_inode_info != NULL) + { + smb_kfree_s(new_inode_info, + sizeof(struct smb_inode_info)); + } + + put_pname(name); iput(dir); - if (*result == NULL) { - return -EACCES; - } else { - return 0; - } + if (*result == NULL) { + return -EACCES; + } + return 0; } /* Ok, now we have made our name. We have to build a new @@ -748,7 +721,19 @@ } } - if (!(*result = smb_iget(dir, name, &finfo))) { + new_inode_info = smb_kmalloc(sizeof(struct smb_inode_info), + GFP_KERNEL); + + /* Here somebody else might have inserted the inode */ + result_info = smb_find_inode(SMB_SERVER(dir), name); + if (result_info != NULL) + { + goto in_tree; + } + + if ((*result = smb_iget(dir, name, &finfo, new_inode_info)) == NULL) + { + smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info)); put_pname(name); iput(dir); return -EACCES; @@ -766,6 +751,7 @@ int error; char *path = NULL; struct smb_dirent entry; + struct smb_inode_info *new_inode_info; *result = NULL; @@ -781,6 +767,15 @@ return error; } + new_inode_info = smb_kmalloc(sizeof(struct smb_inode_info), + GFP_KERNEL); + if (new_inode_info == NULL) + { + put_pname(path); + iput(dir); + return -ENOMEM; + } + entry.attr = 0; entry.ctime = CURRENT_TIME; entry.atime = CURRENT_TIME; @@ -789,6 +784,7 @@ error = smb_proc_create(SMB_SERVER(dir), path, len, &entry); if (error < 0) { + smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info)); put_pname(path); iput(dir); return error; @@ -796,7 +792,9 @@ smb_invalid_dir_cache(dir->i_ino); - if (!(*result = smb_iget(dir, path, &entry)) < 0) { + if ((*result = smb_iget(dir, path, &entry, new_inode_info)) == NULL) + { + smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info)); put_pname(path); iput(dir); return error; diff -u --recursive --new-file v2.0.18/linux/fs/smbfs/file.c linux/fs/smbfs/file.c --- v2.0.18/linux/fs/smbfs/file.c Wed Jun 5 13:22:47 1996 +++ linux/fs/smbfs/file.c Sun Sep 8 17:58:06 1996 @@ -32,7 +32,6 @@ smb_make_open(struct inode *i, int right) { struct smb_dirent *dirent; - int open_result; if (i == NULL) { printk("smb_make_open: got NULL inode\n"); @@ -45,13 +44,13 @@ if ((dirent->opened) == 0) { /* tries max. rights */ - open_result = smb_proc_open(SMB_SERVER(i), - dirent->path, dirent->len, - dirent); - if (open_result) + int open_result = smb_proc_open(SMB_SERVER(i), + dirent->path, dirent->len, + dirent); + if (open_result) + { return open_result; - - dirent->opened = 1; + } } if ( ((right == O_RDONLY) && ( (dirent->access == O_RDONLY) @@ -142,7 +141,8 @@ } static int -smb_file_write(struct inode *inode, struct file *file, const char *buf, int count) +smb_file_write(struct inode *inode, struct file *file, const char *buf, + int count) { int result, bufsize, to_write, already_written; off_t pos; diff -u --recursive --new-file v2.0.18/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c --- v2.0.18/linux/fs/smbfs/inode.c Wed Jun 5 13:22:48 1996 +++ linux/fs/smbfs/inode.c Sun Sep 8 17:58:06 1996 @@ -121,28 +121,37 @@ static void smb_put_inode(struct inode *inode) { - struct smb_dirent *finfo = SMB_FINFO(inode); + struct smb_dirent *finfo = SMB_FINFO(inode); + struct smb_server *server = SMB_SERVER(inode); + struct smb_inode_info *info = SMB_INOP(inode); + + int opened = finfo->opened; + int mtime = finfo->mtime; + int file_id = finfo->fileid; + int isdir = S_ISDIR(inode->i_mode); + unsigned long ino = inode->i_ino; - if (finfo->opened != 0) { + /* Remove the inode before closing the file, because the close + will sleep. This hopefully removes a race condition. */ - /* smb_proc_close wants mtime in finfo */ - finfo->mtime = inode->i_mtime; - - if (smb_proc_close(SMB_SERVER(inode), finfo)) { - /* We can't do anything but complain. */ - printk("smb_put_inode: could not close\n"); - } - } - - smb_free_inode_info(SMB_INOP(inode)); + clear_inode(inode); + smb_free_inode_info(info); - if (S_ISDIR(inode->i_mode)) { + if (isdir) + { DDPRINTK("smb_put_inode: put directory %ld\n", inode->i_ino); - smb_invalid_dir_cache(inode->i_ino); + smb_invalid_dir_cache(ino); } - clear_inode(inode); + if (opened != 0) + { + if (smb_proc_close(server, file_id, mtime)) + { + /* We can't do anything but complain. */ + DPRINTK("smb_put_inode: could not close\n"); + } + } } static void @@ -151,6 +160,7 @@ struct smb_server *server = &(SMB_SBP(sb)->s_server); smb_proc_disconnect(server); + smb_dont_catch_keepalive(server); close_fp(server->sock_file); lock_super(sb); @@ -299,6 +309,7 @@ fail: filp->f_count -= 1; + smb_dont_catch_keepalive(server); smb_kfree_s(SMB_SBP(sb), sizeof(struct smb_sb_info)); return NULL; } diff -u --recursive --new-file v2.0.18/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c --- v2.0.18/linux/fs/smbfs/proc.c Thu Jul 11 13:52:06 1996 +++ linux/fs/smbfs/proc.c Sun Sep 8 17:58:06 1996 @@ -545,6 +545,13 @@ smb_lock_server(server); + if (entry->opened != 0) + { + /* Somebody else opened the file while we slept */ + smb_unlock_server(server); + return 0; + } + retry: p = smb_setup_header(server, SMBopen, 2, 2 + len); WSET(buf, smb_vwv0, 0x42); /* read/write */ @@ -585,9 +592,11 @@ entry->size = DVAL(buf, smb_vwv4); entry->access = WVAL(buf, smb_vwv6); + entry->opened = 1; + entry->access &= 3; + smb_unlock_server(server); - entry->access &= 3; DPRINTK("smb_proc_open: entry->access = %d\n", entry->access); return 0; } @@ -595,13 +604,14 @@ /* smb_proc_close: in finfo->mtime we can send a modification time to the server */ int -smb_proc_close(struct smb_server *server, struct smb_dirent *finfo) +smb_proc_close(struct smb_server *server, + __u16 fileid, __u32 mtime) { char *buf = server->packet; smb_setup_header_exclusive(server, SMBclose, 3, 0); - WSET(buf, smb_vwv0, finfo->fileid); - DSET(buf, smb_vwv1, utc2local(finfo->mtime)); + WSET(buf, smb_vwv0, fileid); + DSET(buf, smb_vwv1, utc2local(mtime)); return smb_request_ok_unlock(server, SMBclose, 0, 0); } @@ -756,24 +766,25 @@ } -/* smb_proc_do_create: We expect entry->attry & entry->ctime to be set. */ +/* smb_proc_create: We expect entry->attr & entry->ctime to be set. */ -static int -smb_proc_do_create(struct smb_server *server, const char *path, int len, - struct smb_dirent *entry, word command) +int +smb_proc_create(struct smb_server *server, const char *path, int len, + struct smb_dirent *entry) { int error; char *p; char *buf = server->packet; + __u16 fileid; smb_lock_server(server); retry: - p = smb_setup_header(server, command, 3, len + 2); + p = smb_setup_header(server, SMBcreate, 3, len + 2); WSET(buf, smb_vwv0, entry->attr); DSET(buf, smb_vwv1, utc2local(entry->ctime)); smb_encode_ascii(p, path, len); - if ((error = smb_request_ok(server, command, 1, 0)) < 0) { + if ((error = smb_request_ok(server, SMBcreate, 1, 0)) < 0) { if (smb_retry(server)) { goto retry; } @@ -781,28 +792,14 @@ return error; } - entry->opened = 1; - entry->fileid = WVAL(buf, smb_vwv0); + entry->opened = 0; + fileid = WVAL(buf, smb_vwv0); smb_unlock_server(server); - smb_proc_close(server, entry); + smb_proc_close(server, fileid, 0); return 0; } - -int -smb_proc_create(struct smb_server *server, const char *path, int len, - struct smb_dirent *entry) -{ - return smb_proc_do_create(server, path, len, entry, SMBcreate); -} - -int -smb_proc_mknew(struct smb_server *server, const char *path, int len, - struct smb_dirent *entry) -{ - return smb_proc_do_create(server, path, len, entry, SMBmknew); -} int smb_proc_mv(struct smb_server *server, @@ -1154,6 +1151,7 @@ char *p; char *lastname; + int lastname_len; int i; int first, total_count; struct smb_dirent *current_entry; @@ -1286,16 +1284,16 @@ p = resp_param; if (first != 0) { - ff_dir_handle = WVAL(p,0); + ff_dir_handle = WVAL(p,0); ff_searchcount = WVAL(p,2); - ff_eos = WVAL(p,4); - ff_lastname = WVAL(p,8); + ff_eos = WVAL(p,4); + ff_lastname = WVAL(p,8); } else { ff_searchcount = WVAL(p,0); - ff_eos = WVAL(p,2); - ff_lastname = WVAL(p,6); + ff_eos = WVAL(p,2); + ff_lastname = WVAL(p,6); } if (ff_searchcount == 0) @@ -1306,16 +1304,19 @@ /* we might need the lastname for continuations */ lastname = ""; + lastname_len = 0; if (ff_lastname > 0) { switch(info_level) { case 260: - lastname = p + ff_lastname + 94; + lastname = p + ff_lastname; + lastname_len = resp_data_len - ff_lastname; ff_resume_key = 0; break; case 1: lastname = p + ff_lastname + 1; + lastname_len = strlen(lastname); ff_resume_key = 0; break; } @@ -1330,12 +1331,14 @@ mask = smb_kmalloc(dirlen, GFP_KERNEL); if (mask == NULL) { - printk("smb_proc_readdir_long: Memory allocation failed\n"); + printk("smb_proc_readdir_long: " + "Memory allocation failed\n"); result = -ENOMEM; break; } - strcpy(mask, lastname); } + strncpy(mask, lastname, lastname_len); + mask[lastname_len] = '\0'; /* Now we are ready to parse smb directory entries. */ @@ -1475,6 +1478,8 @@ int result = 0; struct smb_dirent temp_entry; + memset(&temp_entry, 0, sizeof(temp_entry)); + if ((result=smb_proc_open(server,path,len, &temp_entry)) < 0) { /* We cannot open directories, so we try to use the @@ -1489,8 +1494,8 @@ entry->ctime = temp_entry.ctime; entry->size = temp_entry.size; } - - smb_proc_close(server, &temp_entry); + + smb_proc_close(server, temp_entry.fileid, temp_entry.mtime); return result; } else { @@ -1824,7 +1829,6 @@ smb_decode_word(server->packet+32, &(server->server_uid)); } else - { server->maxxmt = 0; server->maxmux = 0; @@ -1838,6 +1842,7 @@ smb_setup_header(server, SMBtcon, 0, 6 + strlen(server->m.service) + strlen(server->m.password) + strlen(dev)); + p = SMB_BUF(server->packet); p = smb_encode_ascii(p, server->m.service, strlen(server->m.service)); p = smb_encode_ascii(p,server->m.password, strlen(server->m.password)); @@ -1891,11 +1896,14 @@ { int result; smb_lock_server(server); + result = smb_proc_reconnect(server); + if ((result < 0) && (server->packet != NULL)) { smb_kfree_s(server->packet, server->max_xmit); server->packet = NULL; } + smb_unlock_server(server); return result; } diff -u --recursive --new-file v2.0.18/linux/fs/smbfs/sock.c linux/fs/smbfs/sock.c --- v2.0.18/linux/fs/smbfs/sock.c Wed Jun 5 13:22:48 1996 +++ linux/fs/smbfs/sock.c Sun Sep 8 17:58:06 1996 @@ -24,8 +24,9 @@ #define _S(nr) (1<<((nr)-1)) -static int _recvfrom(struct socket *sock, unsigned char *ubuf, int size, int noblock, unsigned flags, - struct sockaddr_in *sa, int *addr_len) +static int +_recvfrom(struct socket *sock, unsigned char *ubuf, int size, + int noblock, unsigned flags, struct sockaddr_in *sa, int *addr_len) { struct iovec iov; struct msghdr msg; @@ -44,7 +45,10 @@ return sock->ops->recvmsg(sock, &msg, size, noblock, flags, addr_len); } -static int _send(struct socket *sock, const void *buff, int len, int nonblock, unsigned flags) { +static int +_send(struct socket *sock, const void *buff, int len, + int nonblock, unsigned flags) +{ struct iovec iov; struct msghdr msg; diff -u --recursive --new-file v2.0.18/linux/fs/super.c linux/fs/super.c --- v2.0.18/linux/fs/super.c Sat Aug 10 10:03:15 1996 +++ linux/fs/super.c Mon Sep 9 21:04:57 1996 @@ -794,7 +794,7 @@ if (!data) return 0; - vma = find_vma(current, (unsigned long) data); + vma = find_vma(current->mm, (unsigned long) data); if (!vma || (unsigned long) data < vma->vm_start) return -EFAULT; if (!(vma->vm_flags & VM_READ)) diff -u --recursive --new-file v2.0.18/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h --- v2.0.18/linux/include/asm-alpha/semaphore.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-alpha/semaphore.h Wed Sep 11 14:18:02 1996 @@ -0,0 +1,43 @@ +#ifndef _ALPHA_SEMAPHORE_H +#define _ALPHA_SEMAPHORE_H + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + */ + +struct semaphore { + int count; + int waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +extern void __down(struct semaphore * sem); +extern void wake_up(struct wait_queue ** p); + +/* + * These are not yet interrupt-safe: should use ldl_l/stl_c here.. + * + * See include/asm-i386/semaphore.h on how to do this correctly + * without any jumps or wakeups taken for the no-contention cases. + */ +extern inline void down(struct semaphore * sem) +{ + sem->count--; + /* "down_failed" */ + if (sem->count < 0) + __down(sem); +} + +extern inline void up(struct semaphore * sem) +{ + sem->count++; + /* "up_wakeup" */ + __up(sem); +} + +#endif diff -u --recursive --new-file v2.0.18/linux/include/asm-i386/irq.h linux/include/asm-i386/irq.h --- v2.0.18/linux/include/asm-i386/irq.h Sun Sep 8 19:50:21 1996 +++ linux/include/asm-i386/irq.h Tue Sep 10 10:17:55 1996 @@ -90,7 +90,7 @@ "outb %al,$0x21\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\tmovb $0x60+"#nr",%al\n\t" \ + "1:\tmovb $0x20,%al\n\t" \ "outb %al,$0x20\n\t" #define ACK_SECOND(mask,nr) \ @@ -102,12 +102,11 @@ "outb %al,$0xA1\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\tmovb $0x60+"#nr",%al\n\t" \ + "1:\tmovb $0x20,%al\n\t" \ "outb %al,$0xA0\n\t" \ "jmp 1f\n" \ "1:\tjmp 1f\n" \ - "1:\tmovb $0x62,%al\n\t" \ - "outb %al,$0x20\n\t" + "1:\toutb %al,$0x20\n\t" #define UNBLK_FIRST(mask) \ "inb $0x21,%al\n\t" \ diff -u --recursive --new-file v2.0.18/linux/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h --- v2.0.18/linux/include/asm-i386/semaphore.h Thu Jan 1 02:00:00 1970 +++ linux/include/asm-i386/semaphore.h Wed Sep 11 13:17:14 1996 @@ -0,0 +1,65 @@ +#ifndef _I386_SEMAPHORE_H +#define _I386_SEMAPHORE_H + +/* + * SMP- and interrupt-safe semaphores.. + * + * (C) Copyright 1996 Linus Torvalds + */ + +struct semaphore { + int count; + int waiting; + struct wait_queue * wait; +}; + +#define MUTEX ((struct semaphore) { 1, 0, NULL }) +#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) + +extern void __down(struct semaphore * sem); +extern void wake_up(struct wait_queue ** p); + +/* + * This is ugly, but we want the default case to fall through. + * "down_failed" is a special asm handler that calls the C + * routine that actually waits. See arch/i386/lib/semaphore.S + */ +extern inline void down(struct semaphore * sem) +{ + __asm__ __volatile__( + "# atomic down operation\n" + "1:\n\t" + "leal 1b,%%eax\n\t" +#ifdef __SMP__ + "lock ; " +#endif + "decl %0\n\t" + "js down_failed" + :/* no outputs */ + :"m" (sem->count), "c" (sem) + :"ax","dx","memory"); +} + +/* + * Note! This is subtle. We jump to wake people up only if + * the semaphore was negative (== somebody was waiting on it). + * The default case (no contention) will result in NO + * jumps for both down() and up(). + */ +extern inline void up(struct semaphore * sem) +{ + __asm__ __volatile__( + "# atomic up operation\n\t" + "leal 1f,%%eax\n\t" +#ifdef __SMP__ + "lock ; " +#endif + "incl %0\n\t" + "jle up_wakeup\n" + "1:" + :/* no outputs */ + :"m" (sem->count), "c" (sem) + :"ax", "dx", "memory"); +} + +#endif diff -u --recursive --new-file v2.0.18/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.0.18/linux/include/linux/fs.h Sun Sep 8 19:50:21 1996 +++ linux/include/linux/fs.h Wed Sep 11 14:36:23 1996 @@ -16,6 +16,8 @@ #include #include +#include + /* * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix * that later. Anyway, now the file code is no longer dependent diff -u --recursive --new-file v2.0.18/linux/include/linux/mm.h linux/include/linux/mm.h --- v2.0.18/linux/include/linux/mm.h Sat Aug 10 10:03:15 1996 +++ linux/include/linux/mm.h Wed Sep 11 14:36:23 1996 @@ -285,8 +285,8 @@ /* mmap.c */ extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long off); -extern void merge_segments(struct task_struct *, unsigned long, unsigned long); -extern void insert_vm_struct(struct task_struct *, struct vm_area_struct *); +extern void merge_segments(struct mm_struct *, unsigned long, unsigned long); +extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *); extern void remove_shared_vm_struct(struct vm_area_struct *); extern void build_mmap_avl(struct mm_struct *); extern void exit_mmap(struct mm_struct *); @@ -334,12 +334,12 @@ #define avl_empty (struct vm_area_struct *) NULL /* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ -static inline struct vm_area_struct * find_vma (struct task_struct * task, unsigned long addr) +static inline struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr) { struct vm_area_struct * result = NULL; - if (task->mm) { - struct vm_area_struct * tree = task->mm->mmap_avl; + if (mm) { + struct vm_area_struct * tree = mm->mmap_avl; for (;;) { if (tree == avl_empty) break; @@ -357,13 +357,13 @@ /* Look up the first VMA which intersects the interval start_addr..end_addr-1, NULL if none. Assume start_addr < end_addr. */ -static inline struct vm_area_struct * find_vma_intersection (struct task_struct * task, unsigned long start_addr, unsigned long end_addr) +static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) { struct vm_area_struct * vma; - vma = find_vma(task,start_addr); - if (!vma || end_addr <= vma->vm_start) - return NULL; + vma = find_vma(mm,start_addr); + if (vma && end_addr <= vma->vm_start) + vma = NULL; return vma; } diff -u --recursive --new-file v2.0.18/linux/include/linux/pagemap.h linux/include/linux/pagemap.h --- v2.0.18/linux/include/linux/pagemap.h Sun Sep 8 19:50:21 1996 +++ linux/include/linux/pagemap.h Wed Sep 11 14:36:23 1996 @@ -71,16 +71,21 @@ static inline void remove_page_from_hash_queue(struct page * page) { - struct page **p = page_hash(page->inode,page->offset); + struct page **p; + struct page *next_hash, *prev_hash; - page_cache_size--; - if (page->next_hash) - page->next_hash->prev_hash = page->prev_hash; - if (page->prev_hash) - page->prev_hash->next_hash = page->next_hash; + next_hash = page->next_hash; + prev_hash = page->prev_hash; + page->next_hash = NULL; + page->prev_hash = NULL; + if (next_hash) + next_hash->prev_hash = prev_hash; + if (prev_hash) + prev_hash->next_hash = next_hash; + p = page_hash(page->inode,page->offset); if (*p == page) - *p = page->next_hash; - page->next_hash = page->prev_hash = NULL; + *p = next_hash; + page_cache_size--; } static inline void __add_page_to_hash_queue(struct page * page, struct page **p) diff -u --recursive --new-file v2.0.18/linux/include/linux/pci.h linux/include/linux/pci.h --- v2.0.18/linux/include/linux/pci.h Wed Aug 21 09:18:10 1996 +++ linux/include/linux/pci.h Wed Sep 11 11:45:10 1996 @@ -264,6 +264,7 @@ #define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 #define PCI_DEVICE_ID_DEC_FDDI 0x000F #define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 +#define PCI_DEVICE_ID_DEC_21052_AB 0x0021 #define PCI_VENDOR_ID_CIRRUS 0x1013 #define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 @@ -555,6 +556,8 @@ #define PCI_DEVICE_ID_INTEL_82439 0x1250 #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 +#define PCI_DEVICE_ID_INTEL_82437VX 0x7030 #define PCI_DEVICE_ID_INTEL_P6 0x84c4 #define PCI_VENDOR_ID_ADAPTEC 0x9004 diff -u --recursive --new-file v2.0.18/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.0.18/linux/include/linux/sched.h Mon Sep 2 15:18:26 1996 +++ linux/include/linux/sched.h Wed Sep 11 14:36:23 1996 @@ -17,7 +17,9 @@ #include #include #include + #include +#include #include #include @@ -146,6 +148,7 @@ unsigned long def_flags; struct vm_area_struct * mmap; struct vm_area_struct * mmap_avl; + struct semaphore mmap_sem; }; #define INIT_MM { \ @@ -157,7 +160,7 @@ 0, 0, 0, 0, \ 0, 0, 0, \ 0, \ - &init_mmap, &init_mmap } + &init_mmap, &init_mmap, MUTEX } struct signal_struct { int count; @@ -458,24 +461,6 @@ add_wait_queue(wait_address,&entry->wait); p->nr++; } - -extern void __down(struct semaphore * sem); - -/* - * These are not yet interrupt-safe - */ -extern inline void down(struct semaphore * sem) -{ - if (sem->count <= 0) - __down(sem); - sem->count--; -} - -extern inline void up(struct semaphore * sem) -{ - sem->count++; - wake_up(&sem->wait); -} #define REMOVE_LINKS(p) do { unsigned long flags; \ save_flags(flags) ; cli(); \ diff -u --recursive --new-file v2.0.18/linux/include/linux/smb_fs.h linux/include/linux/smb_fs.h --- v2.0.18/linux/include/linux/smb_fs.h Thu Jul 25 20:31:45 1996 +++ linux/include/linux/smb_fs.h Wed Sep 11 14:41:26 1996 @@ -124,7 +124,8 @@ byte *smb_encode_smb_length(byte *p, dword len); int smb_proc_open(struct smb_server *server, const char *pathname, int len, struct smb_dirent *entry); -int smb_proc_close(struct smb_server *server, struct smb_dirent *finfo); +int smb_proc_close(struct smb_server *server, + __u16 fileid, __u32 mtime); int smb_proc_read(struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data, int fs); int smb_proc_read_raw(struct smb_server *server, struct smb_dirent *finfo, @@ -135,8 +136,6 @@ off_t offset, long count, const char *data); int smb_proc_create(struct smb_server *server, const char *path, int len, struct smb_dirent *entry); -int smb_proc_mknew(struct smb_server *server, const char *path, int len, - struct smb_dirent *entry); int smb_proc_mv(struct smb_server *server, const char *opath, const int olen, const char *npath, const int nlen); int smb_proc_mkdir(struct smb_server *server, const char *path, const int len); diff -u --recursive --new-file v2.0.18/linux/include/linux/wait.h linux/include/linux/wait.h --- v2.0.18/linux/include/linux/wait.h Sun Sep 1 09:15:33 1996 +++ linux/include/linux/wait.h Mon Sep 9 16:09:16 1996 @@ -26,14 +26,6 @@ return head && head != WAIT_QUEUE_HEAD(q); } -struct semaphore { - int count; - struct wait_queue * wait; -}; - -#define MUTEX ((struct semaphore) { 1, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, NULL }) - struct select_table_entry { struct wait_queue wait; struct wait_queue ** wait_address; diff -u --recursive --new-file v2.0.18/linux/init/main.c linux/init/main.c --- v2.0.18/linux/init/main.c Sun Sep 8 19:50:21 1996 +++ linux/init/main.c Wed Sep 11 11:44:54 1996 @@ -799,6 +799,7 @@ prof_len = (unsigned long) &_etext - (unsigned long) &_stext; prof_len >>= prof_shift; memory_start += prof_len * sizeof(unsigned int); + memset(prof_buffer, 0, prof_len * sizeof(unsigned int)); } memory_start = console_init(memory_start,memory_end); #ifdef CONFIG_PCI @@ -968,7 +969,7 @@ if ((open("/dev/tty1",O_RDWR,0) < 0) && (open("/dev/ttyS0",O_RDWR,0) < 0)) - printk("Unable to open a initial console.\n"); + printk("Unable to open an initial console.\n"); (void) dup(0); (void) dup(0); diff -u --recursive --new-file v2.0.18/linux/ipc/shm.c linux/ipc/shm.c --- v2.0.18/linux/ipc/shm.c Sun Sep 1 09:15:34 1996 +++ linux/ipc/shm.c Mon Sep 9 21:04:57 1996 @@ -425,8 +425,8 @@ /* add new mapping */ current->mm->total_vm += (shmd->vm_end - shmd->vm_start) >> PAGE_SHIFT; - insert_vm_struct(current, shmd); - merge_segments(current, shmd->vm_start, shmd->vm_end); + insert_vm_struct(current->mm, shmd); + merge_segments(current->mm, shmd->vm_start, shmd->vm_end); /* map page range */ error = 0; @@ -505,7 +505,7 @@ return -EINVAL; } if (!(shmflg & SHM_REMAP)) - if ((shmd = find_vma_intersection(current, addr, addr + shp->shm_segsz))) { + if ((shmd = find_vma_intersection(current->mm, addr, addr + shp->shm_segsz))) { /* printk("shmat() -> EINVAL because the interval [0x%lx,0x%lx) intersects an already mapped interval [0x%lx,0x%lx).\n", addr, addr + shp->shm_segsz, shmd->vm_start, shmd->vm_end); */ return -EINVAL; diff -u --recursive --new-file v2.0.18/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.0.18/linux/kernel/ksyms.c Thu Jul 18 14:28:48 1996 +++ linux/kernel/ksyms.c Mon Sep 9 21:04:57 1996 @@ -121,8 +121,6 @@ X(verify_area), X(do_mmap), X(do_munmap), - X(insert_vm_struct), - X(merge_segments), X(exit_mm), /* internal kernel memory management */ diff -u --recursive --new-file v2.0.18/linux/kernel/sched.c linux/kernel/sched.c --- v2.0.18/linux/kernel/sched.c Sun Sep 8 19:50:21 1996 +++ linux/kernel/sched.c Wed Sep 11 15:15:44 1996 @@ -482,17 +482,88 @@ printk(" *q = %p\n",*q); } +/* + * Semaphores are implemented using a two-way counter: + * The "count" variable is decremented for each process + * that tries to sleep, while the "waiting" variable is + * incremented _while_ the process is sleeping on that + * semaphore. + * + * Notably, the inline "up()" and "down()" functions can + * efficiently test if they need to do any extra work (up + * needs to do something only if count was negative before + * the increment operation. + */ +static inline void normalize_semaphore(struct semaphore *sem) +{ + atomic_add(xchg(&sem->waiting,0), &sem->count); +} + +/* + * When __up() is called, the count was negative before + * incrementing it, and we need to wake up somebody. In + * most cases "waiting" will be positive, and the normalization + * will allow things to continue. However, if somebody has + * /just/ done a down(), it may be that count was negative + * without waiting being positive (or in the generic case + * "count is more negative than waiting is positive"), and + * the waiter needs to check this itself (see __down). + * + * Note that these functions are only called when there is + * contention on the lock, and as such all this is the + * "non-critical" part of the whole semaphore business. The + * critical part is the inline stuff in + * where we want to avoid any extra jumps and calls. + */ +inline void __up(struct semaphore *sem) +{ + normalize_semaphore(sem); + wake_up(&sem->wait); +} + void __down(struct semaphore * sem) { - struct wait_queue wait = { current, NULL }; + struct task_struct *tsk = current; + struct wait_queue wait = { tsk, NULL }; + + /* + * The order here is important. We add ourselves to the + * wait queues and mark ourselves sleeping _first_. That + * way, if a "up()" comes in here, we'll either get + * woken up (up happens after the wait queues are set up) + * OR we'll have "waiting > 0". + */ + tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue(&sem->wait, &wait); - current->state = TASK_UNINTERRUPTIBLE; - while (sem->count <= 0) { - schedule(); - current->state = TASK_UNINTERRUPTIBLE; + atomic_inc(&sem->waiting); + + /* + * Ok, we're set up. The only race here is really that + * an "up()" might have incremented count before we got + * here, so we check "count+waiting". If that is larger + * than zero, we shouldn't sleep, but re-try the lock. + */ + if (sem->count+sem->waiting <= 0) { + /* + * If "count+waiting" <= 0, we have to wait + * for a up(), which will normalize the count. + * Remember, at this point we have decremented + * count, and incremented up, so if count is + * zero or positive we need to return to re-try + * the lock. It _may_ be that both count and + * waiting is zero and that it is still locked, + * but we still want to re-try the lock in that + * case to make count go negative again so that + * the optimized "up()" wake_up sequence works. + */ + do { + schedule(); + tsk->state = TASK_UNINTERRUPTIBLE; + } while (sem->count < 0); } - current->state = TASK_RUNNING; + tsk->state = TASK_RUNNING; remove_wait_queue(&sem->wait, &wait); + normalize_semaphore(sem); } static inline void __sleep_on(struct wait_queue **p, int state) diff -u --recursive --new-file v2.0.18/linux/mm/filemap.c linux/mm/filemap.c --- v2.0.18/linux/mm/filemap.c Sun Sep 8 19:50:22 1996 +++ linux/mm/filemap.c Mon Sep 9 21:04:57 1996 @@ -1230,7 +1230,7 @@ * If the interval [start,end) covers some unmapped address ranges, * just ignore them, but return -EFAULT at the end. */ - vma = find_vma(current, start); + vma = find_vma(current->mm, start); unmapped_error = 0; for (;;) { /* Still start < end. */ diff -u --recursive --new-file v2.0.18/linux/mm/memory.c linux/mm/memory.c --- v2.0.18/linux/mm/memory.c Sat Aug 17 21:19:29 1996 +++ linux/mm/memory.c Mon Sep 9 21:04:57 1996 @@ -686,7 +686,7 @@ if (!size || get_fs() == KERNEL_DS) return 0; - vma = find_vma(current, start); + vma = find_vma(current->mm, start); if (!vma) goto bad_area; if (vma->vm_start > start) diff -u --recursive --new-file v2.0.18/linux/mm/mlock.c linux/mm/mlock.c --- v2.0.18/linux/mm/mlock.c Sun Feb 25 11:17:59 1996 +++ linux/mm/mlock.c Mon Sep 9 21:04:57 1996 @@ -40,7 +40,7 @@ n->vm_inode->i_count++; if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - insert_vm_struct(current, n); + insert_vm_struct(current->mm, n); return 0; } @@ -61,7 +61,7 @@ n->vm_inode->i_count++; if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - insert_vm_struct(current, n); + insert_vm_struct(current->mm, n); return 0; } @@ -93,8 +93,8 @@ vma->vm_ops->open(left); vma->vm_ops->open(right); } - insert_vm_struct(current, left); - insert_vm_struct(current, right); + insert_vm_struct(current->mm, left); + insert_vm_struct(current->mm, right); return 0; } @@ -148,7 +148,7 @@ return -EINVAL; if (end == start) return 0; - vma = find_vma(current, start); + vma = find_vma(current->mm, start); if (!vma || vma->vm_start > start) return -ENOMEM; @@ -178,7 +178,7 @@ break; } } - merge_segments(current, start, end); + merge_segments(current->mm, start, end); return error; } @@ -240,7 +240,7 @@ if (error) break; } - merge_segments(current, 0, TASK_SIZE); + merge_segments(current->mm, 0, TASK_SIZE); return error; } diff -u --recursive --new-file v2.0.18/linux/mm/mmap.c linux/mm/mmap.c --- v2.0.18/linux/mm/mmap.c Sun Sep 8 19:50:22 1996 +++ linux/mm/mmap.c Mon Sep 9 21:04:57 1996 @@ -66,19 +66,20 @@ { unsigned long rlim; unsigned long newbrk, oldbrk; + struct mm_struct *mm = current->mm; - if (brk < current->mm->end_code) - return current->mm->brk; + if (brk < mm->end_code) + return mm->brk; newbrk = PAGE_ALIGN(brk); - oldbrk = PAGE_ALIGN(current->mm->brk); + oldbrk = PAGE_ALIGN(mm->brk); if (oldbrk == newbrk) - return current->mm->brk = brk; + return mm->brk = brk; /* * Always allow shrinking brk */ - if (brk <= current->mm->brk) { - current->mm->brk = brk; + if (brk <= mm->brk) { + mm->brk = brk; do_munmap(newbrk, oldbrk-newbrk); return brk; } @@ -88,25 +89,25 @@ rlim = current->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; - if (brk - current->mm->end_code > rlim) - return current->mm->brk; + if (brk - mm->end_code > rlim) + return mm->brk; /* * Check against existing mmap mappings. */ - if (find_vma_intersection(current, oldbrk, newbrk+PAGE_SIZE)) - return current->mm->brk; + if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE)) + return mm->brk; /* * Check if we have enough memory.. */ if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) - return current->mm->brk; + return mm->brk; /* * Ok, looks good - let it rip. */ - current->mm->brk = brk; + mm->brk = brk; do_mmap(NULL, oldbrk, newbrk-oldbrk, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0); @@ -139,6 +140,7 @@ unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long off) { + struct mm_struct * mm = current->mm; struct vm_area_struct * vma; if ((len = PAGE_ALIGN(len)) == 0) @@ -152,8 +154,8 @@ return -EINVAL; /* mlock MCL_FUTURE? */ - if (current->mm->def_flags & VM_LOCKED) { - unsigned long locked = current->mm->locked_vm << PAGE_SHIFT; + if (mm->def_flags & VM_LOCKED) { + unsigned long locked = mm->locked_vm << PAGE_SHIFT; locked += len; if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) return -EAGAIN; @@ -218,10 +220,10 @@ if (!vma) return -ENOMEM; - vma->vm_mm = current->mm; + vma->vm_mm = mm; vma->vm_start = addr; vma->vm_end = addr + len; - vma->vm_flags = vm_flags(prot,flags) | current->mm->def_flags; + vma->vm_flags = vm_flags(prot,flags) | mm->def_flags; if (file) { if (file->f_mode & 1) @@ -269,14 +271,14 @@ } flags = vma->vm_flags; - insert_vm_struct(current, vma); - merge_segments(current, vma->vm_start, vma->vm_end); + insert_vm_struct(mm, vma); + merge_segments(mm, vma->vm_start, vma->vm_end); /* merge_segments might have merged our vma, so we can't use it any more */ - current->mm->total_vm += len >> PAGE_SHIFT; + mm->total_vm += len >> PAGE_SHIFT; if (flags & VM_LOCKED) { unsigned long start = addr; - current->mm->locked_vm += len >> PAGE_SHIFT; + mm->locked_vm += len >> PAGE_SHIFT; do { char c = get_user((char *) start); len -= PAGE_SIZE; @@ -302,7 +304,7 @@ addr = TASK_SIZE / 3; addr = PAGE_ALIGN(addr); - for (vmm = find_vma(current, addr); ; vmm = vmm->vm_next) { + for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { /* At this point: (!vmm || addr < vmm->vm_end). */ if (TASK_SIZE - len < addr) return 0; @@ -752,7 +754,7 @@ if (mpnt->vm_ops && mpnt->vm_ops->open) mpnt->vm_ops->open(mpnt); area->vm_end = addr; /* Truncate area */ - insert_vm_struct(current, mpnt); + insert_vm_struct(current->mm, mpnt); } /* construct whatever mapping is needed */ @@ -766,7 +768,7 @@ area->vm_end = area->vm_start; area->vm_ops->close(area); } - insert_vm_struct(current, mpnt); + insert_vm_struct(current->mm, mpnt); } asmlinkage int sys_munmap(unsigned long addr, size_t len) @@ -796,7 +798,7 @@ * every area affected in some way (by any overlap) is put * on the list. If nothing is put on, nothing is affected. */ - mpnt = find_vma(current, addr); + mpnt = find_vma(current->mm, addr); if (!mpnt) return 0; avl_neighbours(mpnt, current->mm->mmap_avl, &prev, &next); @@ -887,7 +889,7 @@ * Insert vm structure into process list sorted by address * and into the inode's i_mmap ring. */ -void insert_vm_struct(struct task_struct *t, struct vm_area_struct *vmp) +void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp) { struct vm_area_struct *share; struct inode * inode; @@ -895,7 +897,7 @@ #if 0 /* equivalent, but slow */ struct vm_area_struct **p, *mpnt; - p = &t->mm->mmap; + p = &mm->mmap; while ((mpnt = *p) != NULL) { if (mpnt->vm_start > vmp->vm_start) break; @@ -908,13 +910,13 @@ #else struct vm_area_struct * prev, * next; - avl_insert_neighbours(vmp, &t->mm->mmap_avl, &prev, &next); - if ((prev ? prev->vm_next : t->mm->mmap) != next) + avl_insert_neighbours(vmp, &mm->mmap_avl, &prev, &next); + if ((prev ? prev->vm_next : mm->mmap) != next) printk("insert_vm_struct: tree inconsistent with list\n"); if (prev) prev->vm_next = vmp; else - t->mm->mmap = vmp; + mm->mmap = vmp; vmp->vm_next = next; #endif @@ -963,14 +965,16 @@ * We don't need to traverse the entire list, only those segments * which intersect or are adjacent to a given interval. */ -void merge_segments (struct task_struct * task, unsigned long start_addr, unsigned long end_addr) +void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) { struct vm_area_struct *prev, *mpnt, *next; - mpnt = find_vma(task, start_addr); + down(&mm->mmap_sem); + mpnt = find_vma(mm, start_addr); if (!mpnt) - return; - avl_neighbours(mpnt, task->mm->mmap_avl, &prev, &next); + goto no_vma; + + avl_neighbours(mpnt, mm->mmap_avl, &prev, &next); /* we have prev->vm_next == mpnt && mpnt->vm_next = next */ if (!prev) { @@ -1014,7 +1018,7 @@ * big segment can possibly merge with the next one. * The old unused mpnt is freed. */ - avl_remove(mpnt, &task->mm->mmap_avl); + avl_remove(mpnt, &mm->mmap_avl); prev->vm_end = mpnt->vm_end; prev->vm_next = mpnt->vm_next; if (mpnt->vm_ops && mpnt->vm_ops->close) { @@ -1028,4 +1032,6 @@ kfree_s(mpnt, sizeof(*mpnt)); mpnt = prev; } +no_vma: + up(&mm->mmap_sem); } diff -u --recursive --new-file v2.0.18/linux/mm/mprotect.c linux/mm/mprotect.c --- v2.0.18/linux/mm/mprotect.c Wed Apr 3 10:59:33 1996 +++ linux/mm/mprotect.c Mon Sep 9 21:04:57 1996 @@ -112,7 +112,7 @@ n->vm_inode->i_count++; if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - insert_vm_struct(current, n); + insert_vm_struct(current->mm, n); return 0; } @@ -135,7 +135,7 @@ n->vm_inode->i_count++; if (n->vm_ops && n->vm_ops->open) n->vm_ops->open(n); - insert_vm_struct(current, n); + insert_vm_struct(current->mm, n); return 0; } @@ -169,8 +169,8 @@ vma->vm_ops->open(left); vma->vm_ops->open(right); } - insert_vm_struct(current, left); - insert_vm_struct(current, right); + insert_vm_struct(current->mm, left); + insert_vm_struct(current->mm, right); return 0; } @@ -216,7 +216,7 @@ return -EINVAL; if (end == start) return 0; - vma = find_vma(current, start); + vma = find_vma(current->mm, start); if (!vma || vma->vm_start > start) return -EFAULT; @@ -248,6 +248,6 @@ break; } } - merge_segments(current, start, end); + merge_segments(current->mm, start, end); return error; } diff -u --recursive --new-file v2.0.18/linux/mm/mremap.c linux/mm/mremap.c --- v2.0.18/linux/mm/mremap.c Wed Jun 26 09:44:52 1996 +++ linux/mm/mremap.c Mon Sep 9 21:04:57 1996 @@ -143,8 +143,8 @@ new_vma->vm_inode->i_count++; if (new_vma->vm_ops && new_vma->vm_ops->open) new_vma->vm_ops->open(new_vma); - insert_vm_struct(current, new_vma); - merge_segments(current, new_vma->vm_start, new_vma->vm_end); + insert_vm_struct(current->mm, new_vma); + merge_segments(current->mm, new_vma->vm_start, new_vma->vm_end); do_munmap(addr, old_len); return new_addr; } @@ -180,7 +180,7 @@ /* * Ok, we need to grow.. */ - vma = find_vma(current, addr); + vma = find_vma(current->mm, addr); if (!vma || vma->vm_start > addr) return -EFAULT; /* We can't remap across vm area boundaries */ diff -u --recursive --new-file v2.0.18/linux/mm/vmscan.c linux/mm/vmscan.c --- v2.0.18/linux/mm/vmscan.c Sat Aug 17 21:19:29 1996 +++ linux/mm/vmscan.c Mon Sep 9 21:04:57 1996 @@ -109,7 +109,7 @@ if (page_map->count != 1) return 0; if (!(entry = get_swap_page())) - return -1; /* Aieee!!! Out of swap space! */ + return 0; /* Aieee!!! Out of swap space! */ vma->vm_mm->rss--; flush_cache_page(vma, address); set_pte(page_table, __pte(entry)); @@ -253,7 +253,7 @@ /* * Find the proper vm-area */ - vma = find_vma(p, address); + vma = find_vma(p->mm, address); if (!vma) return 0; if (address < vma->vm_start) @@ -312,8 +312,6 @@ if (!--p->swap_cnt) swap_task++; switch (swap_out_process(p, dma, wait)) { - case -1: - return 0; case 0: if (p->swap_cnt) swap_task++;