From: Linus Torvalds Date: Fri, 23 Nov 2007 20:16:21 +0000 (-0500) Subject: Linux 2.1.116 X-Git-Tag: 2.1.116 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=ac995a26c87ac75983960cbe4085a77b6bbe3e4d;p=history.git Linux 2.1.116 I just released Linux-2.1.116. I've tested it fairly extensively on my SMP box, both with little memory and much, and I cannot make it lock up any more. Special thanks to Dean Gaudet who helped me set up a apache configuration that finally made me able to repeat the lockup, and made me able to debug the thing. Most of the 2.1.116 patches are "just" alpha and m68k updates, and can be ignored by most people. The bugfixes are, roughly: - fixed serious low-memory situation problem, where a critical resource allocation problem could result in nasy behaviour. Notably, doing TCP under low memory could result in TCP trying to allocate memory in a tight loop and locking out kswapd completely so that the situation would never be rectified. In short, the machine hung. This problem has been there forever, the only reason it doesn't show up under 2.0.x seems to be because under 2.0.x the TCP allocation was always for a single page, for which this situation never arises. Under 2.1.x the slab code forced multi-page allocations. If you've seen lockups with 2.1.x, this may be the cause. This was what held up 2.1.116 for so long. - various minor driver updates. Networking, radio, bttv. - NFS over TCP still doesn't work, but at least it fails due to new reasons. Alan, try your squid thing under 2.1.116. I suspect it will hold up now, Linus --- diff --git a/Documentation/devices.tex b/Documentation/devices.tex index 4aac47c90c79..84c0e487507c 100644 --- a/Documentation/devices.tex +++ b/Documentation/devices.tex @@ -1,5 +1,5 @@ \documentstyle{article} -% $Id: devices.tex,v 1.12 1998/08/06 04:52:01 hpa Exp $ +% $Id: devices.tex,v 1.14 1998/08/10 22:39:24 hpa Exp $ % --------------------------------------------------------------------------- % Adopt somewhat reasonable margins, so it doesn't take a million % pages to print... :-) If you're actually putting this in print, you @@ -48,7 +48,7 @@ foo \kill}% % \title{{\bf Linux Allocated Devices}} \author{Maintained by H. Peter Anvin $<$hpa@zytor.com$>$} -\date{Last revised: August 5, 1998} +\date{Last revised: August 10, 1998} \maketitle % \noindent @@ -246,7 +246,7 @@ Your cooperation is appreciated. \major{78}{}{char }{PAM Software's multimodem boards} \major{79}{}{char }{PAM Software's multimodem boards -- alternate devices} \major{80}{}{char }{Photometrics AT200 CCD camera} -\major{81}{}{char }{Brooktree Bt848 frame grabbers} +\major{81}{}{char }{video4linux} \major{82}{}{char }{WiNRADiO communications receiver card} \major{83}{}{char }{Teletext/videotext interfaces} \major{84}{}{char }{Ikon 1011[57] Versatec Greensheet Interface} @@ -275,7 +275,8 @@ Your cooperation is appreciated. \major{107}{}{char }{3Dfx Voodoo Graphics device} \major{108}{}{char }{Device independent PPP interface} \major{109}{}{char }{Reserved for logical volume manager} -\major{110}{--119}{}{Unallocated} +\major{110}{}{char }{miroMEDIA Surround board} +\major{111}{--119}{}{Unallocated} \major{120}{--127}{}{Local/experimental use} \major{128}{--135}{char }{Unix98 PTY masters} \major{136}{--143}{char }{Unix98 PTY slaves} @@ -438,19 +439,18 @@ schemes, the meaning of the numbers vary. \minor{64}{/dev/ttyS0}{First serial port} \minordots \minor{127}{/dev/ttyS63}{64th serial port} - \minor{128}{/dev/ptyp0}{First old pseudo-tty master} + \minor{128}{/dev/ptyp0}{OBSOLETE} \minordots - \minor{191}{/dev/ptysf}{64th old pseudo-tty master} - \minor{192}{/dev/ttyp0}{First old pseudo-tty slave} + \minor{191}{/dev/ptysf}{OBSOLETE} + \minor{192}{/dev/ttyp0}{OBSOLETE} \minordots - \minor{255}{/dev/ttysf}{64th old pseudo-tty slave} + \minor{255}{/dev/ttysf}{OBSOLETE} \end{devicelist} \noindent -For compatibility with previous versions of Linux, the first 64 PTYs -are replicated under this device number. This use is deprecated with -the release of Linux 2.0 and may be removed in a future version of -Linux. To ensure proper operation, do not mix old and new PTY devices. +Older versions of the Linux kernel used this major number for BSD PTY +devices. As of Linux 2.1.115, this is no longer supported. Use major +numbers 2 and 3. \begin{devicelist} \major{ 5}{}{char }{Alternate TTY devices} @@ -583,9 +583,6 @@ physical disks. \minor{133}{/dev/exttrp}{External device trap} \minor{134}{/dev/apm\_bios}{Advanced Power Management BIOS} \minor{135}{/dev/rtc}{Real Time Clock} - \minor{136}{/dev/qcam0}{QuickCam on {\file lp0}} - \minor{137}{/dev/qcam1}{QuickCam on {\file lp1}} - \minor{138}{/dev/qcam2}{QuickCam on {\file lp2}} \minor{139}{/dev/openprom}{SPARC OpenBoot PROM} \minor{140}{/dev/relay8}{Berkshire Products Octal relay card} \minor{141}{/dev/relay16}{Berkshire Products ISO-16 relay card} @@ -599,8 +596,8 @@ physical disks. \minor{149}{/dev/input/mouse}{Linux/SGI Irix emulation mouse} \minor{150}{/dev/input/keyboard}{Linux/SGI Irix emulation keyboard} \minor{151}{/dev/led}{Front panel LEDs} - \minor{152}{/dev/radio}{Radio card (type?)} \minor{153}{/dev/mergemem}{Memory merge device} + \minor{154}{/dev/pmu}{Macintosh PowerBook power manager} \end{devicelist} \begin{devicelist} @@ -1677,16 +1674,19 @@ Currently for Dolphin Interconnect Solutions' PCI-SCI bridge. \end{devicelist} \begin{devicelist} -\major{81}{}{char }{Brooktree Bt848 frame grabbers} - \minor{0}{/dev/bttv0}{First Bt848 card} - \minor{0}{/dev/bttv1}{Second Bt848 card} - \minordots - \minor{16}{/dev/bttvc0}{Control for first Bt848 card} - \minor{17}{/dev/bttvc1}{Control for second Bt848 card} - \minordots - \minor{32}{/dev/bttv-vbi0}{VBI data of first Bt848 card} - \minor{33}{/dev/bttv-vbi1}{VBI data of second Bt848 card} - \minordots +\major{81}{}{char }{video4linux} + \minor{0}{/dev/video0}{Video capture/overlay device} + \minordots + \minor{63}{/dev/video63}{Video capture/overlay device} + \minor{64}{/dev/radio0}{Radio device} + \minordots + \minor{127}{/dev/radio63}{Radio device} + \minor{192}{/dev/vtx0}{Teletext device} + \minordots + \minor{223}{/dev/vtx31}{Teletext device} + \minor{224}{/dev/vbi0}{Vertical blank interupt} + \minordots + \minor{255}{/dev/vbi31}{Vertical blank interupt} \end{devicelist} \begin{devicelist} @@ -1910,7 +1910,14 @@ $<$arla-announce-request@stacken.kth.se$>$. \end{devicelist} \begin{devicelist} -\major{110}{--119}{}{Unallocated} +\major{110}{}{char }{miroMEDIA Surround board} + \minor{0}{/dev/srnd0}{First miroMEDIA Surround board} + \minor{1}{/dev/srnd1}{First miroMEDIA Surround board} + \minordots +\end{devicelist} + +\begin{devicelist} +\major{111}{--119}{}{Unallocated} \end{devicelist} \begin{devicelist} @@ -1989,6 +1996,8 @@ It is recommended that these links exist on all systems: \link{/dev/core}{/proc/kcore}{symbolic}{Backward compatibility} \link{/dev/ramdisk}{ram0}{symbolic}{Backward compatibility} \link{/dev/ftape}{qft0}{symbolic}{Backward compatibility} +\link{/dev/bttv0}{video0}{symbolic}{Backward compatibility} +\link{/dev/radio}{radio0}{symbolic}{Backward compatibility} \link{/dev/scd?}{sr?}{hard}{Alternate name for CD-ROMs} \end{nodelist} diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 148d589bc190..d91a44323943 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -1,7 +1,7 @@ LINUX ALLOCATED DEVICES Maintained by H. Peter Anvin - Last revised: August 5, 1998 + Last revised: August 10, 1998 This list is the Linux Device List, the official registry of allocated device numbers and /dev directory nodes for the Linux operating @@ -184,19 +184,16 @@ Your cooperation is appreciated. 64 = /dev/ttyS0 First serial port ... 127 = /dev/ttyS63 64th serial port - 128 = /dev/ptyp0 First old pseudo-tty master + 128 = /dev/ptyp0 OBSOLETE ... - 191 = /dev/ptysf 64th old pseudo-tty master - 192 = /dev/ttyp0 First old pseudo-tty slave + 191 = /dev/ptysf OBSOLETE + 192 = /dev/ttyp0 OBSOLETE ... - 255 = /dev/ttysf 64th old pseudo-tty slave + 255 = /dev/ttysf OBSOLETE - For compatibility with previous versions of Linux, the - first 64 PTYs are replicated under this device number. - This use is deprecated with the release of Linux 2.0 - and may be removed in a future version of Linux. To - ensure proper operation, do not mix old and new PTY - devices. + Older versions of the Linux kernel used this major + number for BSD PTY devices. As of Linux 2.1.115, this + is no longer supported. Use major numbers 2 and 3. 5 char Alternate TTY devices 0 = /dev/tty Current TTY device @@ -310,9 +307,6 @@ Your cooperation is appreciated. 133 = /dev/exttrp External device trap 134 = /dev/apm_bios Advanced Power Management BIOS 135 = /dev/rtc Real Time Clock - 136 = /dev/qcam0 QuickCam on lp0 - 137 = /dev/qcam1 QuickCam on lp1 - 138 = /dev/qcam2 QuickCam on lp2 139 = /dev/openprom SPARC OpenBoot PROM 140 = /dev/relay8 Berkshire Products Octal relay card 141 = /dev/relay16 Berkshire Products ISO-16 relay card @@ -326,8 +320,8 @@ Your cooperation is appreciated. 149 = /dev/input/mouse Linux/SGI Irix emulation mouse 150 = /dev/input/keyboard Linux/SGI Irix emulation keyboard 151 = /dev/led Front panel LEDs - 152 = /dev/radio Radio card (type?) 153 = /dev/mergemem Memory merge device + 154 = /dev/pmu Macintosh PowerBook power manager 11 char Raw keyboard device 0 = /dev/kbd Raw keyboard device @@ -1163,16 +1157,19 @@ Your cooperation is appreciated. 80 char Photometrics AT200 CCD camera 0 = /dev/at200 Photometrics AT200 CCD camera - 81 char Brooktree Bt848 frame grabbers - 0 = /dev/bttv0 First Bt848 card - 1 = /dev/bttv1 Second Bt848 card + 81 char video4linux + 0 = /dev/video0 Video capture/overlay device + ... + 63 = /dev/video63 Video capture/overlay device + 64 = /dev/radio0 Radio device ... - 16 = /dev/bttvc0 Control for first Bt848 card - 17 = /dev/bttvc1 Control for second Bt848 card + 127 = /dev/radio63 Radio device + 192 = /dev/vtx0 Teletext device ... - 32 = /dev/bttv-vbi0 VBI data of first Bt848 card - 33 = /dev/bttv-vbi1 VBI data of second Bt848 card + 223 = /dev/vtx31 Teletext device + 224 = /dev/vbi0 Vertical blank interrupt ... + 255 = /dev/vbi31 Vertical blank interrupt 82 char WiNRADiO communications receiver card 0 = /dev/winradio0 First WiNRADiO card @@ -1330,7 +1327,12 @@ Your cooperation is appreciated. 109 char Reserved for logical volume manager -108-119 UNALLOCATED +110 char miroMEDIA Surround board + 0 = /dev/srnd0 First miroMEDIA Surround board + 1 = /dev/srnd1 Second miroMEDIA Surround board + ... + +111-119 UNALLOCATED 120-127 LOCAL/EXPERIMENTAL USE @@ -1388,6 +1390,8 @@ It is recommended that these links exist on all systems: /dev/core /proc/kcore symbolic Backward compatibility /dev/ramdisk ram0 symbolic Backward compatibility /dev/ftape qft0 symbolic Backward compatibility +/dev/bttv0 video0 symbolic Backward compatibility +/dev/radio radio0 symbolic Backward compatibility /dev/scd? sr? hard Alternate SCSI CD-ROM name Locally defined links diff --git a/Makefile b/Makefile index 62981e9d300e..2291847750a2 100644 --- a/Makefile +++ b/Makefile @@ -228,8 +228,10 @@ config: symlinks scripts/split-include scripts/split-include include/linux/autoconf.h include/config; \ fi -linuxsubdirs: dummy - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done +linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS)) + +$(patsubst %, _dir_%, $(SUBDIRS)) : dummy + $(MAKE) -C $(patsubst _dir_%, %, $@) $(TOPDIR)/include/linux/version.h: include/linux/version.h $(TOPDIR)/include/linux/compile.h: include/linux/compile.h @@ -271,26 +273,8 @@ init/version.o: init/version.c include/linux/compile.h init/main.o: init/main.c $(CC) $(CFLAGS) $(PROFILING) -c -o $*.o $< -fs: dummy - $(MAKE) linuxsubdirs SUBDIRS=fs - -lib: dummy - $(MAKE) linuxsubdirs SUBDIRS=lib - -mm: dummy - $(MAKE) linuxsubdirs SUBDIRS=mm - -ipc: dummy - $(MAKE) linuxsubdirs SUBDIRS=ipc - -kernel: dummy - $(MAKE) linuxsubdirs SUBDIRS=kernel - -drivers: dummy - $(MAKE) linuxsubdirs SUBDIRS=drivers - -net: dummy - $(MAKE) linuxsubdirs SUBDIRS=net +fs lib mm ipc kernel drivers net: dummy + $(MAKE) $(subst $@, _dir_$@, $@) MODFLAGS = -DMODULE ifdef CONFIG_MODULES @@ -298,11 +282,10 @@ ifdef CONFIG_MODVERSIONS MODFLAGS += -DMODVERSIONS -include $(HPATH)/linux/modversions.h endif -modules: include/linux/version.h - @set -e; \ - for i in $(SUBDIRS); \ - do $(MAKE) -C $$i CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules; \ - done +modules: $(patsubst %, _mod_%, $(SUBDIRS)) + +$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h + $(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules modules_install: @( \ @@ -396,7 +379,9 @@ sums: dep-files: scripts/mkdep archdep include/linux/version.h scripts/mkdep init/*.c > .depend scripts/mkdep `find $(FINDHPATH) -follow -name \*.h ! -name modversions.h -print` > .hdepend - set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep; done +# set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i fastdep ;done +# let this be made through the fastdep rule in Rules.make + $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)" MODVERFILE := diff --git a/Rules.make b/Rules.make index c64024d8fe1d..8b4759e43f49 100644 --- a/Rules.make +++ b/Rules.make @@ -105,15 +105,23 @@ endif fastdep: dummy $(TOPDIR)/scripts/mkdep $(wildcard *.[chS] local.h.master) > .depend ifdef ALL_SUB_DIRS - set -e; for i in $(ALL_SUB_DIRS); do $(MAKE) -C $$i fastdep; done + $(MAKE) $(patsubst %,_sfdep_%,$(ALL_SUB_DIRS)) _FASTDEP_ALL_SUB_DIRS="$(ALL_SUB_DIRS)" endif +ifdef _FASTDEP_ALL_SUB_DIRS +$(patsubst %,_sfdep_%,$(_FASTDEP_ALL_SUB_DIRS)): + $(MAKE) -C $(patsubst _sfdep_%,%,$@) fastdep +endif + + # # A rule to make subdirectories # -sub_dirs: dummy +sub_dirs: dummy $(patsubst %,_subdir_%,$(SUB_DIRS)) + ifdef SUB_DIRS - set -e; for i in $(SUB_DIRS); do $(MAKE) -C $$i; done +$(patsubst %,_subdir_%,$(SUB_DIRS)) : dummy + $(MAKE) -C $(patsubst _subdir_%,%,$@) endif # @@ -123,13 +131,20 @@ ALL_MOBJS = $(MX_OBJS) $(M_OBJS) ifneq "$(strip $(ALL_MOBJS))" "" PDWN=$(shell $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh) endif -modules: $(ALL_MOBJS) $(MIX_OBJS) $(MI_OBJS) dummy + ifdef MOD_SUB_DIRS - set -e; for i in $(MOD_SUB_DIRS); do $(MAKE) -C $$i modules; done +$(patsubst %,_modsubdir_%,$(MOD_SUB_DIRS)) : dummy + $(MAKE) -C $(patsubst _modsubdir_%,%,$@) modules endif + ifdef MOD_IN_SUB_DIRS - set -e; for i in $(MOD_IN_SUB_DIRS); do $(MAKE) -C $$i modules; done +$(patsubst %,_modinsubdir_%,$(MOD_IN_SUB_DIRS)) : dummy + $(MAKE) -C $(patsubst _modinsubdir_%,%,$@) modules endif + +modules: $(ALL_MOBJS) $(MIX_OBJS) $(MI_OBJS) dummy \ + $(patsubst %,_modsubdir_%,$(MOD_SUB_DIRS)) \ + $(patsubst %,_modinsubdir_%,$(MOD_IN_SUB_DIRS)) ifneq "$(strip $(MOD_LIST_NAME))" "" rm -f $$TOPDIR/modules/$(MOD_LIST_NAME) ifdef MOD_SUB_DIRS diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 469ad752fdc8..aac4866c13cc 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -153,7 +153,6 @@ ENTRY(lcall7) .globl ret_from_smpfork ret_from_smpfork: GET_CURRENT(%ebx) -call __putlock btrl $0, SYMBOL_NAME(scheduler_lock) jmp ret_from_sys_call #endif /* __SMP__ */ diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 53996c0c803b..6490984b16fc 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -6,6 +6,6 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a -L_OBJS = checksum.o semaphore.o delay.o usercopy.o getuser.o putuser.o lock.o lock_check.o +L_OBJS = checksum.o semaphore.o delay.o usercopy.o getuser.o putuser.o include $(TOPDIR)/Rules.make diff --git a/arch/i386/lib/lock.S b/arch/i386/lib/lock.S deleted file mode 100644 index c500c05f89c1..000000000000 --- a/arch/i386/lib/lock.S +++ /dev/null @@ -1,33 +0,0 @@ -.globl __getlock -__getlock: - pushl %eax - - movl $-8192,%eax - andl %esp,%eax - movl 36(%eax),%eax - incl spinlocks(,%eax,4) - - popl %eax - ret - -.globl __putlock -__putlock: - pushl %eax - - movl $-8192,%eax - andl %esp,%eax - movl 36(%eax),%eax - decl spinlocks(,%eax,4) - js __bad_put - - popl %eax - ret - -__bad_put: - pushl %edx - pushl %ecx - call __putlock_negative - popl %ecx - popl %edx - popl %eax - ret diff --git a/arch/i386/lib/lock_check.c b/arch/i386/lib/lock_check.c deleted file mode 100644 index e95ca6145691..000000000000 --- a/arch/i386/lib/lock_check.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include - -unsigned int spinlocks[32]; - -static void show_stack(unsigned int *stack) -{ - int i; - - for (i = 0; i < 40; i++) { - extern int get_options, __start_fixup; - unsigned int p = stack[i]; - if (p >= (unsigned int) &get_options && p < (unsigned int)&__start_fixup) - printk("[<%08x>] ", p); - } -} - -void __putlock_negative( - unsigned int ecx, - unsigned int edx, - unsigned int eax, - unsigned int from_where) -{ - static int count = 0; - - spinlocks[current->processor] = 0; - - if (count < 5) { - count++; - printk("negative putlock from %x\n", from_where); - show_stack(&ecx); - } -} - -void __check_locks(unsigned int type) -{ - static int warned = 0; - - if (warned < 5) { - unsigned int from_where = (&type)[-1]; - unsigned int this_cpu = current->processor; - int bad_irq = 0; - - if (type) { - unsigned long flags; - __save_flags(flags); - if (!(flags & 0x200) || (global_irq_holder == this_cpu)) - bad_irq = 1; - } - - if (spinlocks[this_cpu] || - local_irq_count[this_cpu] || - local_bh_count[this_cpu] || - bad_irq) { - warned++; - printk("scheduling with spinlocks=%d at %x\n", spinlocks[this_cpu], from_where); - show_stack(&type); - } - } -} - - diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c index 8901882db7a4..6b313d99c3a9 100644 --- a/arch/i386/lib/usercopy.c +++ b/arch/i386/lib/usercopy.c @@ -10,8 +10,6 @@ inline unsigned long __generic_copy_to_user(void *to, const void *from, unsigned long n) { - if ((unsigned long) to < TASK_SIZE) - __check_locks(1); if (access_ok(VERIFY_WRITE, to, n)) __copy_user(to,from,n); return n; @@ -20,8 +18,6 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n) inline unsigned long __generic_copy_from_user(void *to, const void *from, unsigned long n) { - if ((unsigned long) from < TASK_SIZE) - __check_locks(1); if (access_ok(VERIFY_READ, from, n)) __copy_user(to,from,n); return n; @@ -60,7 +56,6 @@ long __strncpy_from_user(char *dst, const char *src, long count) { long res; - __check_locks(1); __do_strncpy_from_user(dst, src, count, res); return res; } @@ -69,7 +64,6 @@ long strncpy_from_user(char *dst, const char *src, long count) { long res = -EFAULT; - __check_locks(1); if (access_ok(VERIFY_READ, src, 1)) __do_strncpy_from_user(dst, src, count, res); return res; @@ -102,7 +96,6 @@ strncpy_from_user(char *dst, const char *src, long count) unsigned long clear_user(void *to, unsigned long n) { - __check_locks(1); if (access_ok(VERIFY_WRITE, to, n)) __do_clear_user(to, n); return n; @@ -111,7 +104,6 @@ clear_user(void *to, unsigned long n) unsigned long __clear_user(void *to, unsigned long n) { - __check_locks(1); __do_clear_user(to, n); return n; } @@ -126,7 +118,6 @@ long strlen_user(const char *s) { unsigned long res; - __check_locks(1); __asm__ __volatile__( "0: repne; scasb\n" " notl %0\n" diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index 8116648a3c5e..e739090f12aa 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -414,7 +414,8 @@ check_table: * This is necessary for drives for situations where * the translated geometry is unavailable from the BIOS. */ - for (i = 0; i < 4 ; i++) { + int xlate_done = 0; + for (i = 0; i < 4 && !xlate_done; i++) { struct partition *q = &p[i]; if (NR_SECTS(q) && (q->sector & 63) == 1 @@ -423,10 +424,16 @@ check_table: if (heads == 32 || heads == 64 || heads == 128 || heads == 255) { (void) ide_xlate_1024(dev, heads, " [PTBL]"); - break; + xlate_done = 1; } } } + if (!xlate_done) { + /* + * Default translation is equivalent of "BIOS LBA": + */ + ide_xlate_1024(dev, -2, " [LBA]"); + } } } #endif /* CONFIG_BLK_DEV_IDE */ diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 1c4b63dd2698..01a4e18e4b53 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide.c Version 6.17 March 29, 1998 + * linux/drivers/block/ide.c Version 6.18 August 16, 1998 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -89,6 +89,7 @@ * Version 6.15 added SMP awareness to IDE drivers * Version 6.16 fixed various bugs; even more SMP friendly * Version 6.17 fix for newest EZ-Drive problem + * Version 6.18 default unpartitioned-disk translation now "BIOS LBA" * * Some additional driver compile-time options are in ide.h * @@ -2562,7 +2563,7 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg) printk("%s ", msg); - if (xparm == -1 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63)) + if (xparm < 0 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63)) return 0; /* small disk: no translation needed */ if (drive->id) { @@ -2590,15 +2591,14 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg) #if FAKE_FDISK_FOR_EZDRIVE if (xparm == -1) { drive->remap_0_to_1 = 1; - msg = "0->1"; + printk("[remap 0->1] "); } else #endif /* FAKE_FDISK_FOR_EZDRIVE */ if (xparm == 1) { drive->sect0 = 63; drive->bios_cyl = (tracks - 1) / drive->bios_head; - msg = "+63"; + printk("[remap +63] "); } - printk("[remap %s] ", msg); } drive->part[0].nr_sects = current_capacity(drive); printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect); diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 111c6685e337..ddec2b425572 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -16,6 +16,7 @@ * once to be processed * 97-4-11 Making protocol independent of endianity etc. * 97-9-13 Cosmetic changes + * 98-5-13 Attempt to make 64-bit-clean on 64-bit machines * * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall * why not: would need verify_area and friends, would share yet another @@ -24,18 +25,24 @@ #define PARANOIA #include -#define MAJOR_NR NBD_MAJOR -#include #include +#include #include #include #include #include +#include #include #include +#include + +#define MAJOR_NR NBD_MAJOR +#include + +#define LO_MAGIC 0x68797548 static int nbd_blksizes[MAX_NBD] = {1024, 1024,}; static int nbd_sizes[MAX_NBD] = {0x7fffffff, 0x7fffffff,}; @@ -68,8 +75,7 @@ static int nbd_open(struct inode *inode, struct file *file) /* * Send or receive packet. */ -static -int nbd_xmit(int send, struct socket *sock, char *buf, int size) +static int nbd_xmit(int send, struct socket *sock, char *buf, int size) { mm_segment_t oldfs; int result; @@ -132,7 +138,7 @@ void nbd_send_req(struct socket *sock, struct request *req) DEBUG("NBD: sending control, "); request.magic = htonl(NBD_REQUEST_MAGIC); request.type = htonl(req->cmd); - request.from = htonl(req->sector * 512); + request.from = cpu_to_be64( (u64) req->sector * (u64) 512); request.len = htonl(req->current_nr_sectors << 9); memcpy(request.handle, &req, sizeof(req)); @@ -153,8 +159,8 @@ void nbd_send_req(struct socket *sock, struct request *req) } #define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; } -struct request * /* NULL returned = something went wrong, inform userspace */ - nbd_read_stat(struct nbd_device *lo) +struct request *nbd_read_stat(struct nbd_device *lo) + /* NULL returned = something went wrong, inform userspace */ { int result; struct nbd_reply reply; @@ -425,8 +431,8 @@ int nbd_init(void) { int i; - if (sizeof(struct nbd_request) != 24) { - printk(KERN_CRIT "Sizeof nbd_request needs to be 24 in order to work!\n" ); + if (sizeof(struct nbd_request) != 28) { + printk(KERN_CRIT "Sizeof nbd_request needs to be 28 in order to work!\n" ); return -EIO; } diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 4aaa67579cb4..a7ea984973d9 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c @@ -86,7 +86,15 @@ static void pty_close(struct tty_struct * tty, struct file * filp) if (tty->driver.subtype == PTY_TYPE_MASTER) { tty_hangup(tty->link); set_bit(TTY_OTHER_CLOSED, &tty->flags); - devpts_pty_kill(MINOR(tty->device) - tty->driver.minor_start); +#ifdef CONFIG_UNIX98_PTYS + { + unsigned int major = MAJOR(tty->device) - UNIX98_PTY_MASTER_MAJOR; + if ( major < UNIX98_NR_MAJORS ) { + devpts_pty_kill( MINOR(tty->device) + - tty->driver.minor_start + tty->driver.name_base ); + } + } +#endif } } @@ -215,16 +223,20 @@ static int pty_chars_in_buffer(struct tty_struct *tty) return ((count < N_TTY_BUF_SIZE/2) ? 0 : count); } -/* - * Return the minor device number of a given pty. This lets us - * open a master pty with the multi-headed ptmx device, then - * find out which one we got after it is open, with an ioctl. +/* + * Return the device number of a Unix98 PTY (only!). This lets us open a + * master pty with the multi-headed ptmx device, then find out which + * one we got after it is open, with an ioctl. */ -static int pty_get_device_minor(struct tty_struct *tty, unsigned int *value) +#ifdef CONFIG_UNIX98_PTYS +static int pty_get_device_number(struct tty_struct *tty, unsigned int *value) { - unsigned int result = MINOR(tty->device); + unsigned int result = MINOR(tty->device) + - tty->driver.minor_start + tty->driver.name_base; return put_user(result, value); } +#endif + /* Set the lock flag on a pty */ static int pty_set_lock(struct tty_struct *tty, int * arg) { @@ -238,22 +250,37 @@ static int pty_set_lock(struct tty_struct *tty, int * arg) return 0; } -static int pty_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) +static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { if (!tty) { printk("pty_ioctl called with NULL tty!\n"); return -EIO; } switch(cmd) { - case TIOCGPTN: /* Get PT Number */ - return pty_get_device_minor(tty, (unsigned int *)arg); case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int *) arg); } return -ENOIOCTLCMD; } +#ifdef CONFIG_UNIX98_PTYS +static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + if (!tty) { + printk("pty_unix98_ioctl called with NULL tty!\n"); + return -EIO; + } + switch(cmd) { + case TIOCGPTN: /* Get PT Number */ + return pty_get_device_number(tty, (unsigned int *)arg); + } + + return pty_bsd_ioctl(tty,file,cmd,arg); +} +#endif + static void pty_flush_buffer(struct tty_struct *tty) { struct tty_struct *to = tty->link; @@ -370,7 +397,7 @@ __initfunc(int pty_init(void)) * assign it here, instead of up with the rest of the * pty_driver initialization. */ - pty_driver.ioctl = pty_ioctl; + pty_driver.ioctl = pty_bsd_ioctl; /* Unix98 devices */ #ifdef CONFIG_UNIX98_PTYS @@ -381,6 +408,7 @@ __initfunc(int pty_init(void)) ptm_driver[i].proc_entry = 0; ptm_driver[i].major = UNIX98_PTY_MASTER_MAJOR+i; ptm_driver[i].minor_start = 0; + ptm_driver[i].name_base = i*NR_PTYS; ptm_driver[i].num = NR_PTYS; ptm_driver[i].other = &pts_driver[i]; ptm_driver[i].table = ptm_table[i]; @@ -393,6 +421,7 @@ __initfunc(int pty_init(void)) pts_driver[i].proc_entry = 0; pts_driver[i].major = UNIX98_PTY_SLAVE_MAJOR+i; pts_driver[i].minor_start = 0; + pts_driver[i].name_base = i*NR_PTYS; pts_driver[i].num = ptm_driver[i].num; pts_driver[i].other = &ptm_driver[i]; pts_driver[i].table = pts_table[i]; @@ -400,7 +429,7 @@ __initfunc(int pty_init(void)) pts_driver[i].termios_locked = pts_termios_locked[i]; pts_driver[i].driver_state = ptm_state[i]; - ptm_driver[i].ioctl = pty_ioctl; + ptm_driver[i].ioctl = pty_unix98_ioctl; if (tty_register_driver(&ptm_driver[i])) panic("Couldn't register Unix98 ptm driver major %d", diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 05edd59c15a6..5120d07be161 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1238,7 +1238,7 @@ retry_open: #ifdef CONFIG_UNIX98_PTYS if (device == PTMX_DEV) { /* find a free pty. */ - int major, minor, line; + int major, minor; struct tty_driver *driver; /* find a device that is not in use. */ @@ -1255,9 +1255,8 @@ retry_open: return -EIO; /* no free ptys */ ptmx_found: set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ - line = minor - driver->minor_start; - devpts_pty_new(line + major*NR_PTYS, MKDEV(driver->other->major, - line+driver->other->minor_start)); + minor -= driver->minor_start; + devpts_pty_new(driver->other->name_base + minor, MKDEV(driver->other->major, minor + driver->other->minor_start)); noctty = 1; goto init_dev_done; } diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 28f18d7ddae9..ade0ac77ae34 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -26,13 +26,14 @@ */ -#define BusLogic_DriverVersion "2.1.13" -#define BusLogic_DriverDate "17 April 1998" +#define BusLogic_DriverVersion "2.1.15" +#define BusLogic_DriverDate "17 August 1998" #include #include #include +#include #include #include #include @@ -1178,7 +1179,8 @@ static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T BusLogic_ProbeInfoCount - FlashPointCount; memcpy(SavedProbeInfo, BusLogic_ProbeInfoList, - sizeof(BusLogic_ProbeInfoList)); + BusLogic_ProbeInfoCount + * sizeof(BusLogic_ProbeInfo_T)); memcpy(&BusLogic_ProbeInfoList[0], &SavedProbeInfo[FlashPointCount], MultiMasterCount * sizeof(BusLogic_ProbeInfo_T)); @@ -3136,25 +3138,25 @@ static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter) HostAdapter->TargetStatistics[CCB->TargetID] .CommandsCompleted++; if (BusLogic_GlobalOptions.TraceErrors) - { - int i; - BusLogic_Notice("CCB #%ld Target %d: Result %X Host " - "Adapter Status %02X " - "Target Status %02X\n", - HostAdapter, CCB->SerialNumber, - CCB->TargetID, Command->result, - CCB->HostAdapterStatus, - CCB->TargetDeviceStatus); - BusLogic_Notice("CDB ", HostAdapter); - for (i = 0; i < CCB->CDB_Length; i++) - BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]); - BusLogic_Notice("\n", HostAdapter); - BusLogic_Notice("Sense ", HostAdapter); - for (i = 0; i < CCB->SenseDataLength; i++) - BusLogic_Notice(" %02X", HostAdapter, - Command->sense_buffer[i]); - BusLogic_Notice("\n", HostAdapter); - } + { + int i; + BusLogic_Notice("CCB #%ld Target %d: Result %X Host " + "Adapter Status %02X " + "Target Status %02X\n", + HostAdapter, CCB->SerialNumber, + CCB->TargetID, Command->result, + CCB->HostAdapterStatus, + CCB->TargetDeviceStatus); + BusLogic_Notice("CDB ", HostAdapter); + for (i = 0; i < CCB->CDB_Length; i++) + BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]); + BusLogic_Notice("\n", HostAdapter); + BusLogic_Notice("Sense ", HostAdapter); + for (i = 0; i < CCB->SenseDataLength; i++) + BusLogic_Notice(" %02X", HostAdapter, + Command->sense_buffer[i]); + BusLogic_Notice("\n", HostAdapter); + } } break; } @@ -4206,7 +4208,6 @@ int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer, BusLogic_TargetStatistics_T *TargetStatistics; int TargetID, Length; char *Buffer; - if (WriteFlag) return 0; for (HostAdapter = BusLogic_FirstRegisteredHostAdapter; HostAdapter != NULL; HostAdapter = HostAdapter->Next) @@ -4218,6 +4219,14 @@ int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer, return 0; } TargetStatistics = HostAdapter->TargetStatistics; + if (WriteFlag) + { + HostAdapter->ExternalHostAdapterResets = 0; + HostAdapter->HostAdapterInternalErrors = 0; + memset(TargetStatistics, 0, + BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T)); + return 0; + } Buffer = HostAdapter->MessageBuffer; Length = HostAdapter->MessageBufferLength; Length += sprintf(&Buffer[Length], "\n\ diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index 654550aedae3..9f01e3209378 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h @@ -1772,4 +1772,43 @@ static void BusLogic_Message(BusLogic_MessageLevel_T, char *, static void BusLogic_ParseDriverOptions(char *); +/* + Declare the Initialization Functions. +*/ + +static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *) __init; +static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *) __init; +static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *) __init; +static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *) __init; +static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *) __init; +static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T) __init; +static void +BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T *) __init; +static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *, int) __init; +static int +BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T *) __init; +static int +BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T *) __init; +static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T *) __init; +static boolean BusLogic_Failure(BusLogic_HostAdapter_T *, char *) __init; +static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *) __init; +static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *) __init; +static boolean +BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T *) __init; +static boolean +BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T *) __init; +static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *) __init; +static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *) __init; +static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *) __init; +static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T *) __init; +static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T *, + SCSI_Host_T *) __init; +static void BusLogic_SelectQueueDepths(SCSI_Host_T *, SCSI_Device_T *) __init; +int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *) __init; +int BusLogic_ReleaseHostAdapter(SCSI_Host_T *) __init; +static boolean BusLogic_ParseKeyword(char **, char *) __init; +static void BusLogic_ParseDriverOptions(char *) __init; +void BusLogic_Setup(char *, int *) __init; + + #endif /* BusLogic_DriverVersion */ diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index d94631a416e9..7c0232fa91d6 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -3165,11 +3165,11 @@ STATIC s32bits probe_adapter(PADAPTER_INFO pAdapterInfo) if(RD_HARPOON(ioport + hp_page_ctrl) & BIOS_SHADOW) { - pAdapterInfo->ai_FlashRomSize = 64 * 1024; /* 64k Rom */ + pAdapterInfo->ai_FlashRomSize = 64 * 1024; /* 64k ROM */ } else { - pAdapterInfo->ai_FlashRomSize = 32 * 1024; /* 32k Rom */ + pAdapterInfo->ai_FlashRomSize = 32 * 1024; /* 32k ROM */ } pAdapterInfo->ai_stateinfo |= (FAST20_ENA | TAG_QUEUE_ENA); @@ -4944,7 +4944,7 @@ int SccbMgr_isr(ULONG pCurrCard) * * Function: Sccb_bad_isr * - * Description: Some type of interrupt has occured which is slightly + * Description: Some type of interrupt has occurred which is slightly * out of the ordinary. We will now decode it fully, in * this routine. This is broken up in an attempt to save * processing time. @@ -7038,7 +7038,7 @@ void siwidr(ULONG port, UCHAR width) * * Function: sssyncv * - * Description: Write the desired value to the Sync Regisiter for the + * Description: Write the desired value to the Sync Register for the * ID specified. * *---------------------------------------------------------------------*/ diff --git a/drivers/scsi/README.BusLogic b/drivers/scsi/README.BusLogic index 05ac7412cd14..3ddc8b1f10a9 100644 --- a/drivers/scsi/README.BusLogic +++ b/drivers/scsi/README.BusLogic @@ -1,16 +1,17 @@ BusLogic MultiMaster and FlashPoint SCSI Driver for Linux - Version 2.0.12 for Linux 2.0 + Version 2.0.15 for Linux 2.0 + Version 2.1.15 for Linux 2.1 PRODUCTION RELEASE - 29 March 1998 + 17 August 1998 Leonard N. Zubkoff Dandelion Digital lnz@dandelion.com - Copyright 1995 by Leonard N. Zubkoff + Copyright 1995-1998 by Leonard N. Zubkoff INTRODUCTION @@ -80,7 +81,7 @@ including: ... Linux ...". Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont, California 94555, USA and can be reached at 510/796-6100 or on the World Wide Web at -http://www.mylex.com. Mylex Technical Support can be reached by electronic +http://www.mylex.com. Mylex HBA Technical Support can be reached by electronic mail at techsup@mylex.com, by Voice at 510/608-2400, or by FAX at 510/745-7715. Contact information for offices in Europe and Japan is available on the Web site. @@ -584,16 +585,16 @@ NOTE: Module Utilities 2.1.71 or later is required for correct parsing DRIVER INSTALLATION -This distribution was prepared for Linux kernel version 2.0.33, but should be +This distribution was prepared for Linux kernel version 2.0.35, but should be compatible with 2.0.4 or any later 2.0 series kernel. To install the new BusLogic SCSI driver, you may use the following commands, replacing "/usr/src" with wherever you keep your Linux kernel source tree: cd /usr/src - tar -xvzf BusLogic-2.0.12.tar.gz + tar -xvzf BusLogic-2.0.15.tar.gz mv README.* LICENSE.* BusLogic.[ch] FlashPoint.c linux/drivers/scsi - patch -p < BusLogic.patch + patch -p0 < BusLogic.patch (only for 2.0.33 and below) cd linux make config make depend diff --git a/drivers/scsi/README.Mylex b/drivers/scsi/README.Mylex index a786fabc6991..cdf69293f7d5 100644 --- a/drivers/scsi/README.Mylex +++ b/drivers/scsi/README.Mylex @@ -1,6 +1,5 @@ Please see the file README.BusLogic for information about Linux support for Mylex (formerly BusLogic) MultiMaster and FlashPoint SCSI Host Adapters. -The Mylex DAC960 PCI RAID Controllers are not supported at the present time, -but work on a Linux driver for the DAC960 is in progress. Please consult +The Mylex DAC960 PCI RAID Controllers are now supported. Please consult http://www.dandelion.com/Linux/ for further information on the DAC960 driver. diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h index f827bdae6a68..56af7f9df4ea 100644 --- a/fs/autofs/autofs_i.h +++ b/fs/autofs/autofs_i.h @@ -129,7 +129,7 @@ void autofs_hash_nuke(struct autofs_dirhash *); /* Expiration-handling functions */ void autofs_update_usage(struct autofs_dirhash *,struct autofs_dir_ent *); -struct autofs_dir_ent *autofs_expire(struct autofs_dirhash *,unsigned long); +struct autofs_dir_ent *autofs_expire(struct super_block *,struct autofs_sb_info *); /* Operations structures */ diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c index 7169bd075d00..bd9f33aabab4 100644 --- a/fs/autofs/dirhash.c +++ b/fs/autofs/dirhash.c @@ -37,15 +37,72 @@ void autofs_update_usage(struct autofs_dirhash *dh, autofs_init_usage(dh,ent); /* Relink at queue tail */ } -struct autofs_dir_ent *autofs_expire(struct autofs_dirhash *dh, - unsigned long timeout) +struct autofs_dir_ent *autofs_expire(struct super_block *sb, + struct autofs_sb_info *sbi) { + struct autofs_dirhash *dh = &sbi->dirhash; struct autofs_dir_ent *ent; + struct dentry *dentry; + unsigned long timeout = sbi->exp_timeout; ent = dh->expiry_head.exp_next; - if ( ent == &(dh->expiry_head) ) return NULL; - return (jiffies - ent->last_usage >= timeout) ? ent : NULL; + if ( ent == &(dh->expiry_head) ) + return NULL; /* No entries */ + + while ( jiffies - ent->last_usage >= timeout ) { + /* Move to end of list in case expiry isn't desirable */ + autofs_update_usage(dh, ent); + + /* Check to see that entry is expirable */ + if ( ent->ino < AUTOFS_FIRST_DIR_INO ) + return ent; /* Symlinks are always expirable */ + + /* Get the dentry for the autofs subdirectory */ + dentry = lookup_dentry(ent->name, dget(sb->s_root), 0); + + if ( IS_ERR(dentry) ) { + printk("autofs: no such dentry on expiry queue: %s\n", + ent->name); + autofs_delete_usage(ent); + continue; + } + + if ( !dentry->d_inode ) { + dput(dentry); + printk("autofs: negative dentry on expiry queue: %s\n", + ent->name); + autofs_delete_usage(ent); + continue; + } + + /* Make sure entry is mounted and unused; note that dentry will + point to the mounted-on-top root. */ + if ( !S_ISDIR(dentry->d_inode->i_mode) + || dentry->d_covers == dentry ) { + dput(dentry); + DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); + continue; + } + + /* + * Now, this is known to be a mount point; therefore the dentry + * will be held by the superblock. is_root_busy() will break if + * we hold a use count here, so we have to dput() it before calling + * is_root_busy(). However, since it is a mount point (already + * verified), dput() will be a nonblocking operation and the use + * count will not go to zero; therefore the call to is_root_busy() + * here is legal. + */ + dput(dentry); + + if ( !is_root_busy(dentry) ) { + DPRINTK(("autofs: signaling expire on %s\n", ent->name)); + return ent; /* Expirable! */ + } + DPRINTK(("autofs: didn't expire due to is_root_busy: %s\n", ent->name)); + } + return NULL; /* No expirable entries */ } void autofs_initialize_hash(struct autofs_dirhash *dh) { diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 2eec54de4ac7..0947e40e0498 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -289,7 +289,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c return -ENOSPC; } - ent->name = kmalloc(dentry->d_name.len, GFP_KERNEL); + ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL); if ( !ent->name ) { kfree(sl->data); kfree(ent); @@ -302,7 +302,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c ent->ino = AUTOFS_FIRST_SYMLINK + n; ent->hash = dentry->d_name.hash; - memcpy(ent->name, dentry->d_name.name,ent->len = dentry->d_name.len); + memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len)); autofs_hash_insert(dh,ent); d_instantiate(dentry, iget(dir->i_sb,ent->ino)); @@ -392,14 +392,14 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) if ( !ent ) return -ENOSPC; - ent->name = kmalloc(dentry->d_name.len, GFP_KERNEL); + ent->name = kmalloc(dentry->d_name.len+1, GFP_KERNEL); if ( !ent->name ) { kfree(ent); return -ENOSPC; } ent->hash = dentry->d_name.hash; - memcpy(ent->name, dentry->d_name.name, ent->len = dentry->d_name.len); + memcpy(ent->name, dentry->d_name.name, 1+(ent->len = dentry->d_name.len)); ent->ino = sbi->next_dir_ino++; autofs_hash_insert(dh,ent); dir->i_nlink++; @@ -434,20 +434,20 @@ static inline int autofs_get_protover(int *p) } /* Perform an expiry operation */ -static inline int autofs_expire_run(struct autofs_sb_info *sbi, +static inline int autofs_expire_run(struct super_block *sb, + struct autofs_sb_info *sbi, struct autofs_packet_expire *pkt_p) { struct autofs_dir_ent *ent; struct autofs_packet_expire pkt; - struct autofs_dirhash *dh = &(sbi->dirhash); - + memset(&pkt,0,sizeof pkt); pkt.hdr.proto_version = AUTOFS_PROTO_VERSION; pkt.hdr.type = autofs_ptype_expire; if ( !sbi->exp_timeout || - !(ent = autofs_expire(dh,sbi->exp_timeout)) ) + !(ent = autofs_expire(sb,sbi)) ) return -EAGAIN; pkt.len = ent->len; @@ -456,8 +456,6 @@ static inline int autofs_expire_run(struct autofs_sb_info *sbi, if ( copy_to_user(pkt_p, &pkt, sizeof(struct autofs_packet_expire)) ) return -EFAULT; - - autofs_update_usage(dh,ent); return 0; } @@ -494,7 +492,8 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, case AUTOFS_IOC_SETTIMEOUT: return autofs_get_set_timeout(sbi,(unsigned long *)arg); case AUTOFS_IOC_EXPIRE: - return autofs_expire_run(sbi,(struct autofs_packet_expire *)arg); + return autofs_expire_run(inode->i_sb,sbi, + (struct autofs_packet_expire *)arg); default: return -ENOSYS; } diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 1c8811848751..608b72d93614 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1054,7 +1054,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs) struct vm_area_struct *vma; struct elfhdr elf; off_t offset = 0, dataoff; - long limit = current->rlim[RLIMIT_CORE].rlim_cur; + unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur; int numnote = 4; struct memelfnote notes[4]; struct elf_prstatus prstatus; /* NT_PRSTATUS */ @@ -1077,7 +1077,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs) for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { if (maydump(vma)) { - int sz = vma->vm_end-vma->vm_start; + unsigned long sz = vma->vm_end-vma->vm_start; if (size+sz >= limit) break; diff --git a/fs/dcache.c b/fs/dcache.c index 979f7b903aee..4c7ea2e3b265 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -402,7 +402,7 @@ resume: this_parent = this_parent->d_parent; goto resume; } - return (count == 1); /* one remaining use count? */ + return (count > 1); /* remaining users? */ } /* diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index a87397a72f06..7c7b005d3829 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -32,7 +32,7 @@ int ntfs_fixup_record(ntfs_volume *vol, char *record, char *magic, int size) { int start, count, offset; - short fixup; + unsigned short fixup; if(!IS_MAGIC(record,magic)) return 0; diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h index c78e20618c00..a68b23fc638e 100644 --- a/include/asm-i386/semaphore.h +++ b/include/asm-i386/semaphore.h @@ -3,12 +3,6 @@ #include -#ifdef __SMP__ -extern void __check_locks(unsigned int); -#else -#define __check_locks(x) do { } while (0) -#endif - /* * SMP- and interrupt-safe semaphores.. * @@ -90,7 +84,6 @@ static inline int waking_non_zero(struct semaphore *sem) */ extern inline void down(struct semaphore * sem) { - __check_locks(0); __asm__ __volatile__( "# atomic down operation\n\t" #ifdef __SMP__ @@ -112,7 +105,6 @@ extern inline int down_interruptible(struct semaphore * sem) { int result; - __check_locks(0); __asm__ __volatile__( "# atomic interruptible down operation\n\t" #ifdef __SMP__ diff --git a/include/asm-i386/smplock.h b/include/asm-i386/smplock.h index 004e69951482..3bb933e4277a 100644 --- a/include/asm-i386/smplock.h +++ b/include/asm-i386/smplock.h @@ -8,20 +8,13 @@ extern spinlock_t kernel_flag; -#ifdef __SMP__ -extern void __check_locks(unsigned int); -#else -#define __check_locks(x) do { } while (0) -#endif - /* * Release global kernel lock and global interrupt lock */ #define release_kernel_lock(task, cpu) \ do { \ if (task->lock_depth >= 0) \ - __asm__ __volatile__(spin_unlock_string \ - :"=m" (__dummy_lock(&kernel_flag))); \ + spin_unlock(&kernel_flag); \ release_irqlock(cpu); \ __sti(); \ } while (0) @@ -32,8 +25,7 @@ do { \ #define reacquire_kernel_lock(task) \ do { \ if (task->lock_depth >= 0) \ - __asm__ __volatile__(spin_lock_string \ - :"=m" (__dummy_lock(&kernel_flag))); \ + spin_lock(&kernel_flag); \ } while (0) @@ -46,7 +38,6 @@ do { \ */ extern __inline__ void lock_kernel(void) { - __check_locks(1); __asm__ __volatile__( "incl %1\n\t" "jne 9f" diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 99d4e4a4c86c..e6fdf42f1d64 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -152,12 +152,10 @@ typedef struct { unsigned long a[100]; } __dummy_lock_t; #define spin_lock(lock) \ __asm__ __volatile__( \ spin_lock_string \ -"\n\tcall __getlock" \ :"=m" (__dummy_lock(lock))) #define spin_unlock(lock) \ __asm__ __volatile__( \ -"call __putlock\n\t" \ spin_unlock_string \ :"=m" (__dummy_lock(lock))) @@ -202,7 +200,6 @@ typedef struct { asm volatile("\n1:\t" \ "lock ; incl %0\n\t" \ "js 2f\n" \ -"call __getlock\n" \ ".section .text.lock,\"ax\"\n" \ "2:\tlock ; decl %0\n" \ "3:\tcmpl $0,%0\n\t" \ @@ -212,9 +209,7 @@ typedef struct { :"=m" (__dummy_lock(&(rw)->lock))) #define read_unlock(rw) \ - asm volatile( \ -"call __putlock\n" \ - "lock ; decl %0" \ + asm volatile("lock ; decl %0" \ :"=m" (__dummy_lock(&(rw)->lock))) #define write_lock(rw) \ @@ -223,7 +218,6 @@ typedef struct { "jc 4f\n" \ "2:\ttestl $0x7fffffff,%0\n\t" \ "jne 3f\n" \ -"call __getlock\n" \ ".section .text.lock,\"ax\"\n" \ "3:\tlock ; btrl $31,%0\n" \ "4:\tcmp $0,%0\n\t" \ @@ -233,10 +227,7 @@ typedef struct { :"=m" (__dummy_lock(&(rw)->lock))) #define write_unlock(rw) \ - asm volatile( \ -"call __putlock\n" \ - "lock ; btrl $31,%0": \ - "=m" (__dummy_lock(&(rw)->lock))) + asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock))) #define read_lock_irq(lock) do { __cli(); read_lock(lock); } while (0) #define read_unlock_irq(lock) do { read_unlock(lock); __sti(); } while (0) diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h index ae8bcbcf275c..9da2fff06f49 100644 --- a/include/asm-i386/uaccess.h +++ b/include/asm-i386/uaccess.h @@ -7,12 +7,6 @@ #include #include -#ifdef __SMP__ -extern void __check_locks(unsigned int); -#else -#define __check_locks(x) do { } while (0) -#endif - #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -118,7 +112,6 @@ extern void __get_user_4(void); /* Careful: we have to cast the result to the type of the pointer for sign reasons */ #define get_user(x,ptr) \ ({ int __ret_gu,__val_gu; \ - __check_locks(1); \ switch(sizeof (*(ptr))) { \ case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ @@ -143,7 +136,6 @@ extern void __put_user_bad(void); #define put_user(x,ptr) \ ({ int __ret_pu; \ - __check_locks(1); \ switch(sizeof (*(ptr))) { \ case 1: __put_user_x(1,__ret_pu,(__typeof__(*(ptr)))(x),ptr); break; \ case 2: __put_user_x(2,__ret_pu,(__typeof__(*(ptr)))(x),ptr); break; \ @@ -161,7 +153,6 @@ extern void __put_user_bad(void); #define __put_user_nocheck(x,ptr,size) \ ({ \ long __pu_err; \ - __check_locks(1); \ __put_user_size((x),(ptr),(size),__pu_err); \ __pu_err; \ }) @@ -204,7 +195,6 @@ struct __large_struct { unsigned long buf[100]; }; #define __get_user_nocheck(x,ptr,size) \ ({ \ long __gu_err, __gu_val; \ - __check_locks(1); \ __get_user_size(__gu_val,(ptr),(size),__gu_err); \ (x) = (__typeof__(*(ptr)))__gu_val; \ __gu_err; \ @@ -284,7 +274,6 @@ do { \ static inline unsigned long __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) { - __check_locks(1); __copy_user(to,from,n); return n; } @@ -292,7 +281,6 @@ __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n) static inline unsigned long __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n) { - __check_locks(1); __copy_user(to,from,n); return n; } @@ -387,7 +375,6 @@ unsigned long __generic_copy_from_user(void *, const void *, unsigned long); static inline unsigned long __constant_copy_to_user(void *to, const void *from, unsigned long n) { - __check_locks(1); if (access_ok(VERIFY_WRITE, to, n)) __constant_copy_user(to,from,n); return n; @@ -396,7 +383,6 @@ __constant_copy_to_user(void *to, const void *from, unsigned long n) static inline unsigned long __constant_copy_from_user(void *to, const void *from, unsigned long n) { - __check_locks(1); if (access_ok(VERIFY_READ, from, n)) __constant_copy_user(to,from,n); return n; @@ -405,7 +391,6 @@ __constant_copy_from_user(void *to, const void *from, unsigned long n) static inline unsigned long __constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n) { - __check_locks(1); __constant_copy_user(to,from,n); return n; } @@ -413,7 +398,6 @@ __constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n) static inline unsigned long __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n) { - __check_locks(1); __constant_copy_user(to,from,n); return n; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 169302fa1d41..d5b6081991b7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -258,6 +258,7 @@ extern inline unsigned long get_free_page(int gfp_mask) * Decide if we should try to do some swapout.. */ extern int free_memory_available(void); +extern struct wait_queue * kswapd_wait; #define free_page(addr) free_pages((addr),0) extern void FASTCALL(free_pages(unsigned long addr, unsigned long order)); @@ -312,8 +313,7 @@ extern void put_cached_page(unsigned long); * GFP bitmasks.. */ #define __GFP_WAIT 0x01 -#define __GFP_IO 0x02 -#define __GFP_LOW 0x00 +#define __GFP_LOW 0x02 #define __GFP_MED 0x04 #define __GFP_HIGH 0x08 @@ -321,9 +321,9 @@ extern void put_cached_page(unsigned long); #define GFP_BUFFER (__GFP_LOW | __GFP_WAIT) #define GFP_ATOMIC (__GFP_HIGH) -#define GFP_USER (__GFP_LOW | __GFP_WAIT | __GFP_IO) -#define GFP_KERNEL (__GFP_MED | __GFP_WAIT | __GFP_IO) -#define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO) +#define GFP_USER (__GFP_LOW | __GFP_WAIT) +#define GFP_KERNEL (__GFP_MED | __GFP_WAIT) +#define GFP_NFS (__GFP_HIGH | __GFP_WAIT) /* Flag - indicates that the buffer will be suitable for DMA. Ignored on some platforms, used as appropriate on others */ diff --git a/include/linux/nbd.h b/include/linux/nbd.h index d2d613c503a1..c2f2a4e089ae 100644 --- a/include/linux/nbd.h +++ b/include/linux/nbd.h @@ -1,16 +1,13 @@ #ifndef LINUX_NBD_H #define LINUX_NBD_H -#include -#include - -#define NBD_SET_SOCK _IO( 0xab, 0 ) -#define NBD_SET_BLKSIZE _IO( 0xab, 1 ) -#define NBD_SET_SIZE _IO( 0xab, 2 ) -#define NBD_DO_IT _IO( 0xab, 3 ) -#define NBD_CLEAR_SOCK _IO( 0xab, 4 ) -#define NBD_CLEAR_QUE _IO( 0xab, 5 ) -#define NBD_PRINT_DEBUG _IO( 0xab, 6 ) +#define NBD_SET_SOCK _IO( 0xab, 0 ) +#define NBD_SET_BLKSIZE _IO( 0xab, 1 ) +#define NBD_SET_SIZE _IO( 0xab, 2 ) +#define NBD_DO_IT _IO( 0xab, 3 ) +#define NBD_CLEAR_SOCK _IO( 0xab, 4 ) +#define NBD_CLEAR_QUE _IO( 0xab, 5 ) +#define NBD_PRINT_DEBUG _IO( 0xab, 6 ) #ifdef MAJOR_NR @@ -54,21 +51,23 @@ struct nbd_device { /* This now IS in some kind of include file... */ -#define NBD_REQUEST_MAGIC 0x12560953 -#define NBD_REPLY_MAGIC 0x96744668 -#define LO_MAGIC 0x68797548 +/* These are send over network in request/reply magic field */ + +#define NBD_REQUEST_MAGIC 0x25609513 +#define NBD_REPLY_MAGIC 0x67446698 +/* Do *not* use magics: 0x12560953 0x96744668. */ struct nbd_request { - __u32 magic; - __u32 from; - __u32 len; + u32 magic; + u32 type; /* == READ || == WRITE */ char handle[8]; - __u32 type; /* == READ || == WRITE */ + u64 from; + u32 len; }; struct nbd_reply { - __u32 magic; + u32 magic; + u32 error; /* 0 = ok, else error */ char handle[8]; /* handle you got from request */ - __u32 error; /* 0 = ok, else error */ }; #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index b81b3660a19e..b835fc2adea8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -320,6 +320,7 @@ struct task_struct { #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ #define PF_DUMPCORE 0x00000200 /* dumped core */ #define PF_SIGNALED 0x00000400 /* killed by a signal */ +#define PF_MEMALLOC 0x00000800 /* Allocating memory */ #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ #define PF_DTRACE 0x00200000 /* delayed trace (used on m68k) */ diff --git a/kernel/capability.c b/kernel/capability.c index cd576cf4a547..60d4ed6b52d5 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -68,7 +68,7 @@ asmlinkage int sys_capget(cap_user_header_t header, cap_user_data_t dataptr) if (target != current) read_unlock(&tasklist_lock); - spin_unlock(&task_capacibility_lock); + spin_unlock(&task_capability_lock); if (!error) { if (copy_to_user(dataptr, &data, sizeof data)) diff --git a/kernel/fork.c b/kernel/fork.c index 5b9e24163f33..5a577abe382e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -51,9 +51,9 @@ spinlock_t taskslot_lock = SPIN_LOCK_UNLOCKED; #define UIDHASH_SZ (PIDHASH_SZ >> 2) static struct user_struct { + atomic_t count; struct user_struct *next, **pprev; unsigned int uid; - int task_count; } *uidhash[UIDHASH_SZ]; spinlock_t uidhash_lock = SPIN_LOCK_UNLOCKED; @@ -98,12 +98,10 @@ void free_uid(struct task_struct *p) if (up) { p->user = NULL; - lock_kernel(); - if (!--up->task_count) { + if (atomic_dec_and_test(&up->count)) { uid_hash_remove(up); kmem_cache_free(uid_cachep, up); } - unlock_kernel(); } } @@ -119,11 +117,11 @@ int alloc_uid(struct task_struct *p) return -EAGAIN; p->user = up; up->uid = p->uid; - up->task_count = 0; + atomic_set(&up->count, 0); uid_hash_insert(up, hashent); } - up->task_count++; + atomic_inc(&up->count); return 0; } @@ -487,7 +485,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) lock_kernel(); if (p->user) { - if (p->user->task_count >= p->rlim[RLIMIT_NPROC].rlim_cur) + if (atomic_read(&p->user->count) >= p->rlim[RLIMIT_NPROC].rlim_cur) goto bad_fork_free; } @@ -567,7 +565,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs) nr_tasks++; if (p->user) - p->user->task_count++; + atomic_inc(&p->user->count); retval = -ENOMEM; /* copy all the process information */ @@ -633,7 +631,7 @@ bad_fork_cleanup: } if (p->user) - p->user->task_count++; + atomic_dec(&p->user->count); nr_tasks--; add_free_taskslot(p->tarray_ptr); bad_fork_free: diff --git a/kernel/kmod.c b/kernel/kmod.c index 1df9f4356c8f..ec0d85d32a98 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -22,7 +23,6 @@ modprobe_path is set via /proc/sys. */ char modprobe_path[256] = "/sbin/modprobe"; -static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; /* exec_modprobe is spawned from a kernel-mode user process, @@ -41,14 +41,15 @@ use_init_file_context(void) /* don't use the user's root, use init's root instead */ exit_fs(current); /* current->fs->count--; */ current->fs = task_init->fs; - current->fs->count++; + atomic_inc(¤t->fs->count); unlock_kernel(); } static int exec_modprobe(void * module_name) { - char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL}; + static char * envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; + char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL }; int i; use_init_file_context(); @@ -97,6 +98,7 @@ int request_module(const char * module_name) { int pid; int waitpid_result; + sigset_t tmpsig; /* Don't allow request_module() before the root fs is mounted! */ if ( ! current->fs->root ) { @@ -107,10 +109,25 @@ int request_module(const char * module_name) pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS); if (pid < 0) { - printk(KERN_ERR "kmod: fork failed, errno %d\n", -pid); + printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid); return pid; } + + /* Block everything but SIGKILL/SIGSTOP */ + spin_lock_irq(¤t->sigmask_lock); + tmpsig = current->blocked; + siginitset(¤t->blocked, ~(sigmask(SIGKILL)|sigmask(SIGSTOP))); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + waitpid_result = waitpid(pid, NULL, __WCLONE); + + /* Allow signals again.. */ + spin_lock_irq(¤t->sigmask_lock); + current->blocked = tmpsig; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + if (waitpid_result != pid) { printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n", pid, waitpid_result); diff --git a/kernel/sched.c b/kernel/sched.c index 6861cc171745..1b76fee500c8 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -470,8 +470,6 @@ asmlinkage void schedule(void) goto scheduling_in_interrupt; release_kernel_lock(prev, this_cpu); - __check_locks(1); - /* Do "administrative" work here while we don't hold any locks */ if (bh_active & bh_mask) do_bottom_half(); diff --git a/mm/filemap.c b/mm/filemap.c index f8b9b14e3be5..1cdfb61d94e4 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -172,10 +172,12 @@ static inline int shrink_one_page(struct page *page, int gfp_mask) break; } age_page(page); +#if 0 if (page->age) break; if (page_cache_size * 100 < (page_cache.min_percent * num_physpages)) break; +#endif if (PageSwapCache(page)) { delete_from_swap_cache(page); return 1; @@ -189,7 +191,7 @@ static inline int shrink_one_page(struct page *page, int gfp_mask) break; /* is it a buffer cache page? */ - if ((gfp_mask & __GFP_IO) && bh && try_to_free_buffer(bh, &bh, 6)) + if (bh && try_to_free_buffer(bh, &bh, 6)) return 1; break; @@ -211,8 +213,8 @@ int shrink_mmap(int priority, int gfp_mask) struct page * page; int count_max, count_min; - count_max = (limit<<2) >> (priority>>1); - count_min = (limit<<2) >> (priority); + count_max = (limit<<1) >> (priority>>1); + count_min = (limit<<1) >> (priority); page = mem_map + clock; do { @@ -327,6 +329,7 @@ static unsigned long try_to_read_ahead(struct file * file, */ page = mem_map + MAP_NR(page_cache); add_to_page_cache(page, inode, offset, hash); + set_bit(PG_referenced, &page->flags); inode->i_op->readpage(file, page); page_cache = 0; } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index bd237cd8fbeb..70766c353caa 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -239,7 +239,6 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order) goto nopage; if (gfp_mask & __GFP_WAIT) { - __check_locks(1); if (in_interrupt()) { static int count = 0; if (++count < 5) { @@ -264,6 +263,16 @@ unsigned long __get_free_pages(int gfp_mask, unsigned long order) spin_lock_irqsave(&page_alloc_lock, flags); RMQUEUE(order, (gfp_mask & GFP_DMA)); spin_unlock_irqrestore(&page_alloc_lock, flags); + + /* + * If we failed to find anything, we'll return NULL, but we'll + * wake up kswapd _now_ ad even wait for it synchronously if + * we can.. This way we'll at least make some forward progress + * over time. + */ + wake_up(&kswapd_wait); + if (gfp_mask & __GFP_WAIT) + schedule(); nopage: return 0; } diff --git a/mm/vmscan.c b/mm/vmscan.c index fdabc83656d8..b586bce72f93 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -42,7 +42,7 @@ int swapout_interval = HZ / 4; /* * The wait queue for waking up the pageout daemon: */ -static struct wait_queue * kswapd_wait = NULL; +struct wait_queue * kswapd_wait = NULL; static void init_swap_timer(void); @@ -469,7 +469,7 @@ static int do_try_to_free_page(int gfp_mask) return 1; state = 1; case 1: - if ((gfp_mask & __GFP_IO) && shm_swap(i, gfp_mask)) + if (shm_swap(i, gfp_mask)) return 1; state = 2; case 2: @@ -525,7 +525,7 @@ int kswapd(void *unused) /* Give kswapd a realtime priority. */ current->policy = SCHED_FIFO; - current->priority = 32; /* Fixme --- we need to standardise our + current->rt_priority = 32; /* Fixme --- we need to standardise our namings for POSIX.4 realtime scheduling priorities. */ @@ -558,22 +558,18 @@ int kswapd(void *unused) */ tries = pager_daemon.tries_base; tries >>= 4*free_memory_available(); - - while (tries--) { - int gfp_mask; - if (free_memory_available() > 1) - break; - gfp_mask = __GFP_IO; - do_try_to_free_page(gfp_mask); + do { + do_try_to_free_page(0); /* * Syncing large chunks is faster than swapping * synchronously (less head movement). -- Rik. */ if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster) run_task_queue(&tq_disk); - - } + if (free_memory_available() > 1) + break; + } while (--tries > 0); } /* As if we could ever get here - maybe we want to make this killable */ remove_wait_queue(&kswapd_wait, &wait); @@ -582,23 +578,30 @@ int kswapd(void *unused) } /* - * This is REALLY ugly. - * * We need to make the locks finer granularity, but right * now we need this so that we can do page allocations * without holding the kernel lock etc. + * + * The "PF_MEMALLOC" flag protects us against recursion: + * if we need more memory as part of a swap-out effort we + * will just silently return "success" to tell the page + * allocator to accept the allocation. */ int try_to_free_pages(unsigned int gfp_mask, int count) { - int retval; + int retval = 1; lock_kernel(); - do { - retval = do_try_to_free_page(gfp_mask); - if (!retval) - break; - count--; - } while (count > 0); + if (current->flags & PF_MEMALLOC) { + current->flags |= PF_MEMALLOC; + do { + retval = do_try_to_free_page(gfp_mask); + if (!retval) + break; + count--; + } while (count > 0); + current->flags &= PF_MEMALLOC; + } unlock_kernel(); return retval; } diff --git a/net/core/sock.c b/net/core/sock.c index 54d1c0a54628..07d12546241f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -543,8 +543,8 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int atomic_add(skb->truesize, &sk->wmem_alloc); skb->destructor = sock_wfree; skb->sk = sk; + return skb; } - return skb; } return NULL; } @@ -557,8 +557,8 @@ struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int atomic_add(skb->truesize, &sk->rmem_alloc); skb->destructor = sock_rfree; skb->sk = sk; + return skb; } - return skb; } return NULL; } diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 838498c21b4d..9641aaae31a8 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -370,6 +370,16 @@ static struct sk_buff *ip_glue(struct ipq *qp) skb->pkt_type = qp->fragments->skb->pkt_type; skb->protocol = qp->fragments->skb->protocol; + /* + * Clearly bogus, because security markings of the individual + * fragments should have been checked for consistency before + * gluing, and intermediate coalescing of fragments may have + * taken place in ip_defrag() before ip_glue() ever got called. + * If we're not going to do the consistency checking, we might + * as well take the value associated with the first fragment. + * --rct + */ + skb->security = qp->fragments->skb->security; /* Done with all fragments. Fixup the new IP header. */ iph = skb->nh.iph; diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index 8116db9d52dc..fabe85161349 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c @@ -25,6 +25,7 @@ * Oct 15, 1997 Farhan Thawar changed wan_encapsulate to add a pad byte of 0 * Apr 20, 1998 Alan Cox Fixed 2.1 symbols * May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate +* Aug 15, 1998 Arnaldo C. Melo Fixed device_setup return value *****************************************************************************/ #include /* offsetof(), etc. */ @@ -466,7 +467,7 @@ static int device_setup (wan_device_t* wandev, wandev_conf_t* u_conf) if(!copy_from_user(data, conf->data, conf->data_size)) { conf->data=data; - wandev->setup(wandev,conf); + err = wandev->setup(wandev,conf); } else err = -ENOBUFS;