]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.1.81pre1 2.1.81pre1
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:32 +0000 (15:14 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:32 +0000 (15:14 -0500)
I just made a pre-2.1.81 available on ftp.kernel.org.
This fixes the known problems of 2.1.80, and also makes the interrupt
routing by default look like it always used to look - everything goes
through the traditional external 8259A-compatible logic.
The code to handle IO-APIC interrupt routing is still there, but as no
interrupts are actually marked as io-apic interrupts you don't see it in
action yet. The advantage of this is that people who want to work on this
have a base that contains all the logic, and that we only need to figure
out how to reliably make all the IRQ routing decisions.

                Linus

26 files changed:
CREDITS
Documentation/filesystems/smbfs.txt
Makefile
arch/i386/kernel/irq.c
arch/i386/kernel/irq.h
arch/i386/kernel/smp.c
drivers/char/hfmodem/gentbl.c
drivers/char/keyboard.c
drivers/scsi/BusLogic.c
fs/minix/inode.c
fs/proc/array.c
fs/smbfs/dir.c
fs/smbfs/file.c
fs/smbfs/inode.c
fs/smbfs/proc.c
fs/super.c
include/asm-i386/smp.h
include/linux/kernel_stat.h
include/linux/minix_fs_sb.h
include/linux/smb_fs.h
include/linux/smb_fs_i.h
include/linux/smp.h
init/main.c
kernel/fork.c
net/ipv4/arp.c
net/ipv4/tcp.c

diff --git a/CREDITS b/CREDITS
index e187ed0ce20730803410fbb8dcd4af7bc37dfbeb..3bd591c152ec4a2bd703e646c12cc427ced3a3f3 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -465,11 +465,12 @@ S: 26506 Norden
 S: Germany
 
 N: Jeremy Fitzhardinge
-E: jeremy@sw.oz.au
+E: jeremy@zip.com.au
 D: Improved mmap and munmap handling
 D: General mm minor tidyups
-S: 99 Albermarle Street
-S: Newtown 2042
+S: 67 Surrey St.
+S: Darlinghurst, Sydney
+S: NSW 2010
 S: Australia
 
 N: Ralf Flaxa
@@ -705,6 +706,7 @@ S: United Kingdom
 N: Ron Holt
 E: ron@caldera.com
 W: http://www.holt.org/
+P: 1024/1FD44539 DF 4B EB 9F 5B 68 38 9A  40 E3 FB 71 D1 C8 0B 56
 D: Kernel development
 D: Minor kernel modifications to support Wabi and Wine
 S: Caldera, Inc.
@@ -820,9 +822,11 @@ S: Germany
 
 N: Ian Kluft
 E: ikluft@thunder.sbay.org
-D: Smail binary packages for Slackware and Debian
-S: 2200 Monroe Street #1509
-S: Santa Clara, California 95050-3452
+W: http://www.kluft.com/~ikluft/
+D: NET-1 beta testing & minor patches, original Smail binary packages for
+D: Slackware and Debian, vote-taker for 2nd comp.os.linux reorganization
+S: PO Box 611311
+S: San Jose, CA 95161-1311
 S: USA
 
 N: Alain L. Knaff
@@ -977,6 +981,14 @@ S: 33 Ridgefield Cr
 S: Nepean, Ontario
 S: Canada K2H 6S3
 
+N: Jamie Lokier
+E: jamie@imbolc.ucc.ie
+D: Reboot-through-BIOS for broken 486 motherboards
+S: 26 Oatlands Road
+S: Oxford
+S: OX2 0ET
+S: United Kingdom
+
 N: Warner Losh
 E: imp@village.org
 D: Linux/MIPS Deskstation support, Provided OI/OB for Linux
@@ -1146,6 +1158,7 @@ S: USA
 
 N: Rick Miller
 E: rdmiller@execpc.com
+W: http://www.execpc.com/~rdmiller/
 D: Original Linux Device Registrar (Major/minor numbers)
 D: au-play, bwBASIC
 S: S78 W16203 Woods Road
@@ -1309,8 +1322,12 @@ E: Frederic.Potter@masi.ibp.fr
 D: Some PCI kernel support
 
 N: Stefan Probst
-E: snprobst@immd4.informatik.uni-erlangen.de
-D: The Linux Support Team Erlangen
+E: sp@caldera.de
+D: The Linux Support Team Erlangen, 1993-97
+S: Caldera (Deutschland) GmbH
+S: Lazarettstrasse 8
+S: 91054 Erlangen
+S: Germany
 
 N: Daniel Quinlan
 E: quinlan@pathname.com
@@ -1652,6 +1669,14 @@ S: Obere Heerbergstrasse 17
 S: 97078 Wuerzburg
 S: Germany
 
+N: Greg Ungerer
+E: gerg@stallion.com
+D: Author of Stallion multiport serial drivers
+S: Stallion Technologies
+S: 33 Woodstock Rd
+S: Toowong, QLD. 4066
+S: Australia
+
 N: Jeffrey A. Uphoff
 E: juphoff@nrao.edu
 E: jeff.uphoff@linux.org
index 04eb2e58617b09337405ec52feff2c8e7fb7527b..5fc08057638457353dc7f5643cb1a7e98a8fdf1c 100644 (file)
@@ -1,27 +1,20 @@
 Smbfs is a filesystem that implements the SMB protocol, which is the
 protocol used by Windows for Workgroups, Windows 95 and Windows NT.
-Smbfs was inspired by samba, the program written by Andrew Tridgell
+Smbfs was inspired by Samba, the program written by Andrew Tridgell
 that turns any unix host into a file server for DOS or Windows clients.
 See ftp://nimbus.anu.edu.au/pub/tridge/samba/ for this interesting
 program suite and much more information on SMB, NetBIOS over TCP/IP,
 and explanations for concepts like netbios name or share.
 
-To use smbfs, you need to install the Samba package (Samba-1.9.17p1 or
-later), and you need the special mount program from the smbfs package
-(smbfs-2.1.0 or later), found on
+To use smbfs, you must first install the Samba package (Samba-1.9.18p1 or
+later). This package includes the special smbmount utility needed to mount
+smbfs volumes. Refer to the smbmount(8) and smbmnt(8) manpages for the
+details regarding smbfs mounts.
 
-       ftp://ftp.gwdg.de/pub/linux/misc/smbfs/dontuse
-
-After downloading the smbfs package, apply the patch to the smbclient
-program and recompile.  Smbfs can then be mounted from the smbclient
-command line, as for example:
-
-       smb: \>mount /mnt/tmp -f 755
-
-For convenience, you may wish to package the command in a script like this:
-
-#!/bin/sh
-echo "mount /mnt/tmp -f 755" | smbclient //server/c$ -U administrator%
+The smbmount utility reads the Samba smb.conf config file for some of its
+options, and at least one of these is important for smbfs operation. You
+should enable the TCP_NODELAY socket option, or else directory listings
+will be dramatically slower (under Win NT at least).
 
 Mount-Time Options
 Windows 95 has several bugs that affect SMB operations, and smbfs includes
@@ -37,11 +30,12 @@ to the file mode argument of the mount command for the Win 95 servers.
 Option                  Value  Effect
 Identify Win 95 Server    1    Enables bug fixes
 Use Core Attributes       2    Speeds up directory scans, only mtime
+Use Dir Attributes        4    Alternate way to get file attributes
 
 To apply the options, sum the values and prepend it to the file mode. For
-example, to use both options with file mode 755, you would prepend 3 to 755:
+example, to use options 1 and 2 with file mode 755, you would specify 3755:
 
-       cnt>mount /mnt/tmp -f 3755
+       mount /mnt/tmp -f 3755
 
 Smbfs will print a message at mount time confirming the selected options.
 Note that _only_ Windows 95 servers require special treatment; using the
index 719235cff08ca7e7ae8cbd02a7ca47ec603db94e..8ab1b6a9b256fd0fbe151d2694f6963bf83b0496 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -343,14 +343,17 @@ endif
 
 clean: archclean
        rm -f kernel/ksyms.lst include/linux/compile.h
-       rm -f `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
-       rm -f `find . -type f -name 'core' -print`
-       rm -f `find . -name '.*.flags' -print`
+       rm -f core `find . -name '*.[oas]' ! -regex '.*lxdialog/.*' -print`
+       rm -f core `find . -type f -name 'core' -print`
+       rm -f core `find . -name '.*.flags' -print`
+       rm -f core `find . -size 0`
        rm -f vmlinux System.map
        rm -f .tmp*
        rm -f drivers/char/consolemap_deftbl.c drivers/char/conmakehash
        rm -f drivers/sound/bin2hex drivers/sound/hex2hex
-       rm -f `find modules/ -type f -print`
+       if [ -d modules ]; then \
+               rm -f core `find modules/ -type f -print`; \
+       fi
        rm -f submenu*
 
 mrproper: clean
index 23bb2be9d710f11c30e4ae280d91b57e3c7ccb8c..67f24e734a84c5a44c9e0bf1efe16eb793bcf0a6 100644 (file)
@@ -120,15 +120,16 @@ static int irq_owner [NR_IRQS] = { NO_PROC_ID, };
 #ifndef __SMP__
   static const unsigned int io_apic_irqs = 0;
 #else
-       /*
-        * the timer interrupt is not connected to the IO-APIC on all boards
-        * (mine is such ;), and since it is not performance critical anyway,
-        * we route it through the INTA pin and win lots of design simplicity.
-        * Ditto the obsolete EISA dma chaining irq. All other interrupts are
-        * routed through the IO-APIC, distributed amongst all CPUs, dependent
-        * on irq traffic and CPU load.
-        */
-  const unsigned int io_apic_irqs = ~((1<<0)|(1<<2)|(1<<13));
+  /*
+   * Default to all normal IRQ's _not_ using the IO APIC.
+   *
+   * To get IO-APIC interrupts you should either:
+   *  - turn some of them into IO-APIC interrupts at runtime
+   *    with some magic system call interface.
+   *  - explicitly use irq 16-19 depending on which PCI irq
+   *    line your PCI controller uses.
+   */
+  unsigned int io_apic_irqs = 0xFF0000;
 #endif
 
 static inline int ack_irq(int irq)
@@ -179,14 +180,16 @@ static inline int ack_irq(int irq)
 
 void set_8259A_irq_mask(int irq)
 {
-       if (irq >= 16) {
-               printk ("HUH #3 (%d)?\n", irq);
-               return;
-       }
-       if (irq & 8) {
-               outb(cached_A1,0xA1);
-       } else {
-               outb(cached_21,0x21);
+       /*
+        * (it might happen that we see IRQ>15 on a UP box, with SMP
+        * emulation)
+        */
+       if (irq < 16) {
+               if (irq & 8) {
+                       outb(cached_A1,0xA1);
+               } else {
+                       outb(cached_21,0x21);
+               }
        }
 }
 
@@ -356,12 +359,13 @@ int get_irq_list(char *buf)
                        continue;
                p += sprintf(p, "%3d: ",i);
 #ifndef __SMP__
-               p += sprintf(p, "%10u ", kstat.interrupts[0][i]);
+               p += sprintf(p, "%10u ", kstat_irqs(i));
 #else
                for (j=0; j<smp_num_cpus; j++)
                        p += sprintf(p, "%10u ",
-                               kstat.interrupts[cpu_logical_map[j]][i]);
+                               kstat.irqs[cpu_logical_map(j)][i]);
 #endif
+
                if (IO_APIC_IRQ(i))
                        p += sprintf(p, " IO-APIC ");
                else
@@ -596,15 +600,13 @@ again:
        while (test_bit(0,&global_irq_lock)) mb();
 #endif
 
-       kstat.interrupts[cpu][irq]++;
+       kstat.irqs[cpu][irq]++;
        status = 0;
        action = *(irq + irq_action);
 
        if (action) {
-#if 0
                if (!(action->flags & SA_INTERRUPT))
                        __sti();
-#endif
 
                do {
                        status |= action->flags;
@@ -897,7 +899,7 @@ unsigned long probe_irq_on (void)
        /*
         * save current irq counts
         */
-       memcpy(probe_irqs,kstat.interrupts,NR_CPUS*NR_IRQS*sizeof(int));
+       memcpy(probe_irqs,kstat.irqs,NR_CPUS*NR_IRQS*sizeof(int));
 
        /*
         * first, enable any unassigned irqs
@@ -922,7 +924,7 @@ unsigned long probe_irq_on (void)
         */
        for (i=0; i<NR_IRQS; i++)
                for (j=0; j<NR_CPUS; j++)
-                       if (kstat.interrupts[j][i] != probe_irqs[j][i])
+                       if (kstat.irqs[j][i] != probe_irqs[j][i])
                                irqs &= ~(i<<1);
 
        return irqs;
@@ -935,7 +937,7 @@ int probe_irq_off (unsigned long irqs)
        for (i=0; i<NR_IRQS; i++) {
                int sum = 0;
                for (j=0; j<NR_CPUS; j++) {
-                       sum += kstat.interrupts[j][i];
+                       sum += kstat.irqs[j][i];
                        sum -= probe_irqs[j][i];
                }
                if (sum && (irqs & (i<<1))) {
index c4a9c1b76fa5798dc4bb528f85f7627463d33eda..b7a4dc472868a6bf73c65a3f2d5ae770fea77145 100644 (file)
@@ -19,7 +19,12 @@ void ack_APIC_irq (void);
 void setup_IO_APIC (void);
 void init_IO_APIC_traps(void);
 
-extern const unsigned int io_apic_irqs;
+#ifdef __SMP__
+ extern unsigned int io_apic_irqs;
+#else
+ extern const unsigned int io_apic_irqs;
+#endif
+
 #define IO_APIC_IRQ(x) ((1<<x) & io_apic_irqs)
 
 #define MAX_IRQ_SOURCES 128
index c0e391ff65db14571bac63aa4f547dd0fa1192b4..35944e8487f66d6bba7c18893c1940a429bcd5c2 100644 (file)
@@ -115,7 +115,7 @@ unsigned long cpu_present_map = 0;                  /* Bitmask of existing CPU's                            */
 int smp_num_cpus = 1;                                  /* Total count of live CPU's                            */
 int smp_threads_ready=0;                               /* Set when the idlers are all forked                   */
 volatile int cpu_number_map[NR_CPUS];                  /* which CPU maps to which logical number               */
-volatile int cpu_logical_map[NR_CPUS];                 /* which logical number maps to which CPU               */
+volatile int __cpu_logical_map[NR_CPUS];                       /* which logical number maps to which CPU               */
 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */
 volatile unsigned long smp_invalidate_needed;          /* Used for the invalidate map that's also checked in the spinlock */
 volatile unsigned long kstack_ptr;                     /* Stack vector for booting CPU's                       */
@@ -526,7 +526,7 @@ __initfunc(int smp_scan_config(unsigned long base, unsigned long length))
                                 *      set some other information about it.
                                 */
                                nlong = boot_cpu_id<<24;        /* Dummy 'self' for bootup */
-                               cpu_logical_map[0] = boot_cpu_id;
+                               __cpu_logical_map[0] = boot_cpu_id;
                                global_irq_holder = boot_cpu_id;
                                current->processor = boot_cpu_id;
 
@@ -717,7 +717,7 @@ __initfunc(static void do_boot_cpu(int i))
                panic("No idle process for CPU %d", i);
 
        idle->processor = i;
-       cpu_logical_map[cpucount] = i;
+       __cpu_logical_map[cpucount] = i;
        cpu_number_map[i] = cpucount;
 
        /* start_eip had better be page-aligned! */
@@ -861,7 +861,7 @@ __initfunc(static void do_boot_cpu(int i))
                        /* number CPUs logically, starting from 1 (BSP is 0) */
 #if 0
                        cpu_number_map[i] = cpucount;
-                       cpu_logical_map[cpucount] = i;
+                       __cpu_logical_map[cpucount] = i;
 #endif
                        printk("OK.\n");
                        printk("CPU%d: ", i);
@@ -927,6 +927,7 @@ __initfunc(void smp_boot_cpus(void))
        if (!smp_found_config)
        {
                printk(KERN_NOTICE "SMP motherboard not detected. Using dummy APIC emulation.\n");
+               io_apic_irqs = 0;
                return;
        }
 
@@ -1087,6 +1088,12 @@ __initfunc(void smp_boot_cpus(void))
        if(smp_b_stepping)
                printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
        SMP_PRINTK(("Boot done.\n"));
+
+       /*
+        * Here we can be sure that there is an IO-APIC in the system, lets
+        * go and set it up:
+        */
+       setup_IO_APIC();
 }
 
 /*
index 558b9a4057855512cf216d5d14632058bf34b816..d60651b1b173eadb610376ef3655e35e8b46256b 100644 (file)
@@ -25,8 +25,8 @@
  */
 
 /*****************************************************************************/
-      
-#include <linux/hfmodem.h>
+
+/* This is compiled with HOSTCC - do not include any <linux/foo.h> headers. */
 #include <math.h>
 #include <stdio.h>
 
index 81b56e689fe3d3bb06635164c4d101171de03531..41527aa3f2685de9de5aeb7f5c77df77aba3212d 100644 (file)
@@ -603,7 +603,7 @@ static void do_fn(unsigned char value, char up_flag)
 static void do_pad(unsigned char value, char up_flag)
 {
        static const char *pad_chars = "0123456789+-*/\015,.?()";
-       static const char *app_map = "pqrstuvwxylSRQMnn?PQ";
+       static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
 
        if (up_flag)
                return;         /* no action, if this is a key release */
index 59ca8226baa598ba996f8ce2e84ca895470d4b7e..fbdb29d6be32a0c90645062db442f3ab95775671 100644 (file)
@@ -2338,15 +2338,11 @@ static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
     Issue the Test Command Complete Interrupt commands.
   */
  
-  InitialInterruptCount = 0;
-  for (i=0; i<NR_CPUS; i++)
-       InitialInterruptCount += kstat.interrupts[i][HostAdapter->IRQ_Channel];
+  InitialInterruptCount = kstat_irqs(HostAdapter->IRQ_Channel);
   for (i = 0; i < TestCount; i++)
     BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
                     NULL, 0, NULL, 0);
-  FinalInterruptCount = 0;
-  for (i=0; i<NR_CPUS; i++)
-       FinalInterruptCount += kstat.interrupts[i][HostAdapter->IRQ_Channel];
+  FinalInterruptCount = kstat_irqs(HostAdapter->IRQ_Channel);
   /*
     Verify that BusLogic_InterruptHandler was called at least TestCount
     times.  Shared IRQ Channels could cause more than TestCount interrupts to
index 898f56f199fe1fdd45cf1ebb7e3b5bafec97039b..05bf6706d8a0be79eb378f168cd968a6135b1e94 100644 (file)
@@ -12,9 +12,9 @@
 #include <linux/module.h>
 
 #include <linux/sched.h>
-#include <linux/minix_fs.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/malloc.h>
 #include <linux/string.h>
 #include <linux/stat.h>
 #include <linux/locks.h>
@@ -24,6 +24,8 @@
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 
+#include <linux/minix_fs.h>
+
 static void minix_delete_inode(struct inode *inode)
 {
        inode->i_size = 0;
@@ -62,12 +64,13 @@ void minix_put_super(struct super_block *sb)
                sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
                mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
        }
-       sb->s_dev = 0;
        for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
                brelse(sb->u.minix_sb.s_imap[i]);
        for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
                brelse(sb->u.minix_sb.s_zmap[i]);
        brelse (sb->u.minix_sb.s_sbh);
+       kfree(sb->u.minix_sb.s_imap);
+       sb->s_dev = 0;
        unlock_super(sb);
        MOD_DEC_USE_COUNT;
        return;
@@ -161,30 +164,29 @@ static const char * minix_checkroot(struct super_block *s, struct inode *dir)
        return errmsg;
 }
 
-struct super_block *minix_read_super(struct super_block *s,void *data,
+struct super_block *minix_read_super(struct super_block *s, void *data,
                                     int silent)
 {
        struct buffer_head *bh;
+       struct buffer_head **map;
        struct minix_super_block *ms;
        int i, block;
        kdev_t dev = s->s_dev;
        const char * errmsg;
        struct inode *root_inode;
        
+       /* N.B. These should be compile-time tests */
        if (32 != sizeof (struct minix_inode))
                panic("bad V1 i-node size");
        if (64 != sizeof(struct minix2_inode))
                panic("bad V2 i-node size");
+
        MOD_INC_USE_COUNT;
        lock_super(s);
        set_blocksize(dev, BLOCK_SIZE);
-       if (!(bh = bread(dev,1,BLOCK_SIZE))) {
-               s->s_dev = 0;
-               unlock_super(s);
-               printk("MINIX-fs: unable to read superblock\n");
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
+       if (!(bh = bread(dev,1,BLOCK_SIZE)))
+               goto out_bad_sb;
+
        ms = (struct minix_super_block *) bh->b_data;
        s->u.minix_sb.s_ms = ms;
        s->u.minix_sb.s_sbh = bh;
@@ -192,6 +194,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
        s->s_blocksize = 1024;
        s->s_blocksize_bits = 10;
        s->u.minix_sb.s_ninodes = ms->s_ninodes;
+       s->u.minix_sb.s_nzones = ms->s_nzones;
        s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
        s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
        s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
@@ -200,103 +203,74 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
        s->s_magic = ms->s_magic;
        if (s->s_magic == MINIX_SUPER_MAGIC) {
                s->u.minix_sb.s_version = MINIX_V1;
-               s->u.minix_sb.s_nzones = ms->s_nzones;
                s->u.minix_sb.s_dirsize = 16;
                s->u.minix_sb.s_namelen = 14;
        } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
                s->u.minix_sb.s_version = MINIX_V1;
-               s->u.minix_sb.s_nzones = ms->s_nzones;
                s->u.minix_sb.s_dirsize = 32;
                s->u.minix_sb.s_namelen = 30;
        } else if (s->s_magic == MINIX2_SUPER_MAGIC) {
                s->u.minix_sb.s_version = MINIX_V2;
-               s->u.minix_sb.s_nzones = ms->s_zones;
                s->u.minix_sb.s_dirsize = 16;
                s->u.minix_sb.s_namelen = 14;
        } else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
                s->u.minix_sb.s_version = MINIX_V2;
-               s->u.minix_sb.s_nzones = ms->s_zones;
                s->u.minix_sb.s_dirsize = 32;
                s->u.minix_sb.s_namelen = 30;
-       } else {
-               s->s_dev = 0;
-               unlock_super(s);
-               brelse(bh);
-               if (!silent)
-                       printk("VFS: Can't find a minix or minix V2 filesystem on dev "
-                              "%s.\n", kdevname(dev));
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
-       for (i=0;i < MINIX_I_MAP_SLOTS;i++)
-               s->u.minix_sb.s_imap[i] = NULL;
-       for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
-               s->u.minix_sb.s_zmap[i] = NULL;
-       if (s->u.minix_sb.s_zmap_blocks > MINIX_Z_MAP_SLOTS) {
-               s->s_dev = 0;
-               unlock_super (s);
-               brelse (bh);
-               if (!silent)
-                       printk ("MINIX-fs: filesystem too big\n");
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
+       } else
+               goto out_no_fs;
+
+       if (s->u.minix_sb.s_zmap_blocks > MINIX_Z_MAP_SLOTS)
+               goto out_too_big;
+       /*
+        * Allocate the buffer map to keep the superblock small.
+        */
+       i = (MINIX_I_MAP_SLOTS + MINIX_Z_MAP_SLOTS) * sizeof(bh);
+       map = kmalloc(i, GFP_KERNEL);
+       if (!map)
+               goto out_no_map;
+       memset(map, 0, i);
+       s->u.minix_sb.s_imap = &map[0];
+       s->u.minix_sb.s_zmap = &map[MINIX_I_MAP_SLOTS];
+
        block=2;
-       for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
-               if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
-                       block++;
-               else
-                       break;
-       for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
-               if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
-                       block++;
-               else
-                       break;
-       if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
-               for(i=0;i<MINIX_I_MAP_SLOTS;i++)
-                       brelse(s->u.minix_sb.s_imap[i]);
-               for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
-                       brelse(s->u.minix_sb.s_zmap[i]);
-               s->s_dev = 0;
-               unlock_super(s);
-               brelse(bh);
-               printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
-               MOD_DEC_USE_COUNT;
-               return NULL;
+       for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++) {
+               if (!(s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)))
+                       goto out_no_bitmap;
+               block++;
+       }
+       for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++) {
+               if (!(s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)))
+                       goto out_no_bitmap;
+               block++;
        }
+       if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks)
+               goto out_no_bitmap;
+
        minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
        minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
-       unlock_super(s);
        /* set up enough so that it can read an inode */
-       s->s_dev = dev;
        s->s_op = &minix_sops;
-       root_inode = iget(s,MINIX_ROOT_INO);
-       s->s_root = d_alloc_root(root_inode, NULL);
-       if (!s->s_root) {
-               s->s_dev = 0;
-               brelse(bh);
-               if (!silent)
-                       printk("MINIX-fs: get root inode failed\n");
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
-
+       root_inode = iget(s, MINIX_ROOT_INO);
+       if (!root_inode)
+               goto out_no_root;
+       /*
+        * Check the fs before we get the root dentry ...
+        */
        errmsg = minix_checkroot(s, root_inode);
-       if (errmsg) {
-               if (!silent)
-                       printk("MINIX-fs: %s\n", errmsg);
-               d_delete(s->s_root); /* XXX Is this enough? */
-               s->s_dev = 0;
-               brelse (bh);
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
+       if (errmsg)
+               goto out_bad_root;
+
+       s->s_root = d_alloc_root(root_inode, NULL);
+       if (!s->s_root)
+               goto out_iput;
 
        if (!(s->s_flags & MS_RDONLY)) {
                ms->s_state &= ~MINIX_VALID_FS;
                mark_buffer_dirty(bh, 1);
                s->s_dirt = 1;
        }
+       unlock_super(s);
        if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
                printk ("MINIX-fs: mounting unchecked file system, "
                        "running fsck is recommended.\n");
@@ -304,6 +278,54 @@ struct super_block *minix_read_super(struct super_block *s,void *data,
                printk ("MINIX-fs: mounting file system with errors, "
                        "running fsck is recommended.\n");
        return s;
+
+out_bad_root:
+       if (!silent)
+               printk("MINIX-fs: %s\n", errmsg);
+out_iput:
+       iput(root_inode);
+       goto out_freemap;
+
+out_no_root:
+       if (!silent)
+               printk("MINIX-fs: get root inode failed\n");
+       goto out_freemap;
+
+out_no_bitmap:
+       printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
+    out_freemap:
+       for(i=0;i<MINIX_I_MAP_SLOTS;i++)
+               brelse(s->u.minix_sb.s_imap[i]);
+       for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
+               brelse(s->u.minix_sb.s_zmap[i]);
+       kfree(s->u.minix_sb.s_imap);
+       goto out_release;
+
+out_no_map:
+       if (!silent)
+               printk ("MINIX-fs: can't allocate map\n");
+       goto out_release;
+
+out_too_big:
+       if (!silent)
+               printk ("MINIX-fs: filesystem too big\n");
+       goto out_release;
+
+out_no_fs:
+       if (!silent)
+               printk("VFS: Can't find a minix or minix V2 filesystem on dev "
+                      "%s.\n", kdevname(dev));
+    out_release:
+       brelse(bh);
+       goto out_unlock;
+
+out_bad_sb:
+       printk("MINIX-fs: unable to read superblock\n");
+    out_unlock:
+       s->s_dev = 0;
+       unlock_super(s);
+       MOD_DEC_USE_COUNT;
+       return NULL;
 }
 
 int minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
index 8f242b1f7f925f0299add17b06ce9018735b6ece..e4f1003fdcf12cc7cf9960f8dbe4c1ffbd733a55 100644 (file)
@@ -221,20 +221,14 @@ static int get_loadavg(char * buffer)
 
 static int get_kstat(char * buffer)
 {
-       int i, j, len;
+       int i, len;
        unsigned sum = 0;
        extern unsigned long total_forks;
        unsigned long ticks;
 
        ticks = jiffies * smp_num_cpus;
-#ifndef __SMP__
        for (i = 0 ; i < NR_IRQS ; i++)
-               sum += kstat.interrupts[0][i];
-#else
-       for (j = 0 ; j < smp_num_cpus ; j++)
-               for (i = 0 ; i < NR_IRQS ; i++)
-                       sum += kstat.interrupts[cpu_logical_map[j]][i];
-#endif
+               sum += kstat_irqs(i);
 
 #ifdef __SMP__
        len = sprintf(buffer,
@@ -246,12 +240,12 @@ static int get_kstat(char * buffer)
        for (i = 0 ; i < smp_num_cpus; i++)
                len += sprintf(buffer + len, "cpu%d %u %u %u %lu\n",
                        i,
-                       kstat.per_cpu_user[cpu_logical_map[i]],
-                       kstat.per_cpu_nice[cpu_logical_map[i]],
-                       kstat.per_cpu_system[cpu_logical_map[i]],
-                       jiffies - (  kstat.per_cpu_user[cpu_logical_map[i]] \
-                                  + kstat.per_cpu_nice[cpu_logical_map[i]] \
-                                  + kstat.per_cpu_system[cpu_logical_map[i]]));
+                       kstat.per_cpu_user[cpu_logical_map(i)],
+                       kstat.per_cpu_nice[cpu_logical_map(i)],
+                       kstat.per_cpu_system[cpu_logical_map(i)],
+                       jiffies - (  kstat.per_cpu_user[cpu_logical_map(i)] \
+                                  + kstat.per_cpu_nice[cpu_logical_map(i)] \
+                                  + kstat.per_cpu_system[cpu_logical_map(i)]));
        len += sprintf(buffer + len,
                "disk %u %u %u %u\n"
                "disk_rio %u %u %u %u\n"
@@ -292,17 +286,8 @@ static int get_kstat(char * buffer)
                kstat.pswpin,
                kstat.pswpout,
                sum);
-       for (i = 0 ; i < NR_IRQS ; i++) {
-#ifndef __SMP__
-               len += sprintf(buffer + len, " %u", kstat.interrupts[0][i]);
-#else
-               int sum=0;
-
-               for (j = 0 ; j < smp_num_cpus ; j++)
-                       sum += kstat.interrupts[cpu_logical_map[j]][i];
-               len += sprintf(buffer + len, " %u", sum);
-#endif
-       }
+       for (i = 0 ; i < NR_IRQS ; i++)
+               len += sprintf(buffer + len, " %u", kstat_irqs(i));
        len += sprintf(buffer + len,
                "\nctxt %u\n"
                "btime %lu\n"
@@ -1147,8 +1132,8 @@ static int get_pidcpu(int pid, char * buffer)
        for (i = 0 ; i < smp_num_cpus; i++)
                len += sprintf(buffer + len, "cpu%d %lu %lu\n",
                        i,
-                       tsk->per_cpu_utime[cpu_logical_map[i]],
-                       tsk->per_cpu_stime[cpu_logical_map[i]]);
+                       tsk->per_cpu_utime[cpu_logical_map(i)],
+                       tsk->per_cpu_stime[cpu_logical_map(i)]);
 
        return len;
 }
index 6546b5e7d5ae53a43a00b279b6ffe0c4d0417f59..ed547eee62be45cd316054285e17f9cb0fb91cf6 100644 (file)
@@ -351,8 +351,6 @@ dentry->d_parent->d_name.name, dentry->d_name.name, error);
                inode = smb_iget(dir->i_sb, &finfo);
                if (inode)
                {
-                       /* cache the dentry pointer */
-                       inode->u.smbfs_i.dentry = dentry;
        add_entry:
                        dentry->d_op = &smbfs_dentry_operations;
                        d_add(dentry, inode);
@@ -372,8 +370,8 @@ smb_instantiate(struct dentry *dentry, __u16 fileid, int have_id)
 {
        struct smb_sb_info *server = server_from_dentry(dentry);
        struct inode *inode;
-       struct smb_fattr fattr;
        int error;
+       struct smb_fattr fattr;
 
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_instantiate: file %s/%s, fileid=%u\n",
@@ -395,8 +393,6 @@ dentry->d_parent->d_name.name, dentry->d_name.name, fileid);
                inode->u.smbfs_i.access = SMB_O_RDWR;
                inode->u.smbfs_i.open = server->generation;
        }
-       /* cache the dentry pointer */
-       inode->u.smbfs_i.dentry = dentry;
        d_instantiate(dentry, inode);
 out:
        return error;
index 4c21236ec525c176ff088a997e41c36d0204ee08..96e3614902fc771e8151310c9483dc045fabe54e 100644 (file)
@@ -54,10 +54,9 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
 static int
 smb_readpage_sync(struct dentry *dentry, struct page *page)
 {
-       struct inode *inode = dentry->d_inode;
        char *buffer = (char *) page_address(page);
        unsigned long offset = page->offset;
-       int rsize = smb_get_rsize(SMB_SERVER(inode));
+       int rsize = smb_get_rsize(server_from_dentry(dentry));
        int count = PAGE_SIZE;
        int result;
 
@@ -81,14 +80,14 @@ dentry->d_parent->d_name.name, dentry->d_name.name, result);
                if (count < rsize)
                        rsize = count;
 
-               result = smb_proc_read(inode, offset, rsize, buffer);
+               result = smb_proc_read(dentry, offset, rsize, buffer);
                if (result < 0)
                        goto io_error;
 
                count -= result;
                offset += result;
                buffer += result;
-               inode->i_atime = CURRENT_TIME;
+               dentry->d_inode->i_atime = CURRENT_TIME;
                if (result < rsize)
                        break;
        } while (count);
@@ -129,7 +128,7 @@ smb_writepage_sync(struct dentry *dentry, struct page *page,
 {
        struct inode *inode = dentry->d_inode;
        u8 *buffer = (u8 *) page_address(page) + offset;
-       int wsize = smb_get_wsize(SMB_SERVER(inode));
+       int wsize = smb_get_wsize(server_from_dentry(dentry));
        int result, written = 0;
 
        offset += page->offset;
@@ -142,7 +141,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, wsize);
                if (count < wsize)
                        wsize = count;
 
-               result = smb_proc_write(inode, offset, wsize, buffer);
+               result = smb_proc_write(dentry, offset, wsize, buffer);
                if (result < 0)
                        goto io_error;
                /* N.B. what if result < wsize?? */
index b8b208df0e83209c256a895af858c714228cc91d..9648c119acbc38fa960085b1a62c5a7dca5cd475 100644 (file)
@@ -180,6 +180,59 @@ printk("smb_invalidate_inodes\n");
        invalidate_inodes(SB_of(server));
 }
 
+/*
+ * This is called to update the inode attributes after
+ * we've made changes to a file or directory.
+ */
+static int
+smb_refresh_inode(struct dentry *dentry)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+       struct smb_fattr fattr;
+
+       error = smb_proc_getattr(dentry, &fattr);
+       if (!error)
+       {
+               smb_renew_times(dentry);
+               /*
+                * Check whether the type part of the mode changed,
+                * and don't update the attributes if it did.
+                */
+               if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
+                       smb_set_inode_attr(inode, &fattr);
+               else
+               {
+                       /*
+                        * Big trouble! The inode has become a new object,
+                        * so any operations attempted on it are invalid.
+                        *
+                        * To limit damage, mark the inode as bad so that
+                        * subsequent lookup validations will fail.
+                        */
+#ifdef SMBFS_PARANOIA
+printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
+dentry->d_parent->d_name.name, dentry->d_name.name,
+inode->i_mode, fattr.f_mode);
+#endif
+                       fattr.f_mode = inode->i_mode; /* save mode */
+                       make_bad_inode(inode);
+                       inode->i_mode = fattr.f_mode; /* restore mode */
+                       /*
+                        * No need to worry about unhashing the dentry: the
+                        * lookup validation will see that the inode is bad.
+                        * But we do want to invalidate the caches ...
+                        */
+                       if (!S_ISDIR(inode->i_mode))
+                               invalidate_inode_pages(inode);
+                       else
+                               smb_invalid_dir_cache(inode);
+                       error = -EIO;
+               }
+       }
+       return error;
+}
+
 /*
  * This is called when we want to check whether the inode
  * has changed on the server.  If it has changed, we must
@@ -220,7 +273,7 @@ jiffies, inode->u.smbfs_i.oldmtime);
         * (Note: a size change should have a different mtime.)
         */
        last_time = inode->i_mtime;
-       error = smb_refresh_inode(inode);
+       error = smb_refresh_inode(dentry);
        if (error || inode->i_mtime != last_time)
        {
 #ifdef SMBFS_DEBUG_VERBOSE
@@ -238,99 +291,15 @@ out:
 }
 
 /*
- * This is called to update the inode attributes after
- * we've made changes to a file or directory.
- */
-int
-smb_refresh_inode(struct inode *inode)
-{
-       struct dentry * dentry = inode->u.smbfs_i.dentry;
-       struct smb_fattr fattr;
-       int error;
-
-       pr_debug("smb_refresh_inode\n");
-       if (!dentry)
-       {
-               printk("smb_refresh_inode: no dentry, can't refresh\n");
-               error = -EIO;
-               goto out;
-       }
-
-       error = smb_proc_getattr(dentry, &fattr);
-       if (!error)
-       {
-               smb_renew_times(dentry);
-               /*
-                * Check whether the type part of the mode changed,
-                * and don't update the attributes if it did.
-                */
-               if ((inode->i_mode & S_IFMT) == (fattr.f_mode & S_IFMT))
-                       smb_set_inode_attr(inode, &fattr);
-               else
-               {
-                       /*
-                        * Big trouble! The inode has become a new object,
-                        * so any operations attempted on it are invalid.
-                        *
-                        * To limit damage, mark the inode as bad so that
-                        * subsequent lookup validations will fail.
-                        */
-#ifdef SMBFS_PARANOIA
-printk("smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-inode->i_mode, fattr.f_mode);
-#endif
-                       fattr.f_mode = inode->i_mode; /* save mode */
-                       make_bad_inode(inode);
-                       inode->i_mode = fattr.f_mode; /* restore mode */
-                       /*
-                        * No need to worry about unhashing the dentry: the
-                        * lookup validation will see that the inode is bad.
-                        * But we do want to invalidate the caches ...
-                        */
-                       if (!S_ISDIR(inode->i_mode))
-                               invalidate_inode_pages(inode);
-                       else
-                               smb_invalid_dir_cache(inode);
-                       error = -EIO;
-               }
-       }
-out:
-       return error;
-
-}
-
-/*
- * This routine is called for every iput().
+ * This routine is called for every iput(). We clear i_nlink
+ * on the last use to force a call to delete_inode.
  */
 static void
 smb_put_inode(struct inode *ino)
 {
        pr_debug("smb_put_inode: count = %d\n", ino->i_count);
-
-       if (ino->i_count > 1) {
-               struct dentry * dentry;
-               /*
-                * Check whether the dentry still holds this inode. 
-                * This looks scary, but should work ... if this is
-                * the last use, d_inode == NULL or d_count == 0. 
-                */
-               dentry = (struct dentry *) ino->u.smbfs_i.dentry;
-               if (dentry && (dentry->d_inode != ino || dentry->d_count == 0))
-               {
-                       ino->u.smbfs_i.dentry = NULL;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_put_inode: cleared dentry for %s/%s (%ld), count=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ino->i_ino, ino->i_count);
-#endif
-               }
-       } else {
-               /*
-                * Last use ... clear i_nlink to force
-                * smb_delete_inode to be called.
-               */
+       if (ino->i_count == 1)
                ino->i_nlink = 0;
-       }
 }
 
 /*
@@ -379,7 +348,6 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
 {
        struct smb_mount_data *mnt;
        struct inode *root_inode;
-       struct dentry *dentry;
        struct smb_fattr root;
 
        MOD_INC_USE_COUNT;
@@ -435,6 +403,8 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
                printk("SMBFS: Win 95 bug fixes enabled\n");
        if (mnt->version & SMB_FIX_OLDATTR)
                printk("SMBFS: Using core getattr (Win 95 speedup)\n");
+       else if (mnt->version & SMB_FIX_DIRATTR)
+               printk("SMBFS: Using dir ff getattr\n");
 
        /*
         * Keep the super block locked while we get the root inode.
@@ -444,11 +414,9 @@ smb_read_super(struct super_block *sb, void *raw_data, int silent)
        if (!root_inode)
                goto out_no_root;
 
-       dentry = d_alloc_root(root_inode, NULL);
-       if (!dentry)
+       sb->s_root = d_alloc_root(root_inode, NULL);
+       if (!sb->s_root)
                goto out_no_root;
-       root_inode->u.smbfs_i.dentry = dentry;
-       sb->s_root = dentry;
 
        unlock_super(sb);
        return sb;
@@ -465,7 +433,7 @@ out_no_mem:
        unlock_super(sb);
        goto out_fail;
 out_wrong_data:
-       printk("smb_read_super: need mount version %d\n", SMB_MOUNT_VERSION);
+       printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION);
        goto out_fail;
 out_no_data:
        printk("smb_read_super: missing data argument\n");
@@ -609,7 +577,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name, fattr.f_mode,attr->ia_mode);
 
 out:
        if (refresh)
-               smb_refresh_inode(inode);
+               smb_refresh_inode(dentry);
        return error;
 }
 
index b5e612a01879417a7f45299220f4c60423e7b5c9..69312d9162dc328ad5fea5636456fceea32546dc 100644 (file)
@@ -531,7 +531,8 @@ server->conn_pid);
        if (server->state == CONN_VALID)
        {
 #ifdef SMBFS_PARANOIA
-printk("smb_retry: new connection pid=%d\n", server->conn_pid);
+printk("smb_retry: new pid=%d, generation=%d\n",
+server->conn_pid, server->generation);
 #endif
                result = 1;
        }
@@ -643,25 +644,17 @@ printk("smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid);
        }
        server->conn_pid = current->pid;
 
-#ifdef SMBFS_PARANOIA
-if (server->sock_file)
-printk("smb_newconn: old socket not closed!\n");
-#endif
-
        filp->f_count += 1;
        server->sock_file = filp;
        smb_catch_keepalive(server);
        server->opt = *opt;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_newconn: protocol=%d, max_xmit=%d\n",
-server->opt.protocol, server->opt.max_xmit);
-#endif
        server->generation += 1;
        server->state = CONN_VALID;
-#ifdef SMBFS_PARANOIA
-printk("smb_newconn: state valid, pid=%d\n", server->conn_pid);
-#endif
        error = 0;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_newconn: protocol=%d, max_xmit=%d, pid=%d\n",
+server->opt.protocol, server->opt.max_xmit, server->conn_pid);
+#endif
 
 out:
        wake_up_interruptible(&server->wait);
@@ -987,9 +980,9 @@ smb_close_fileid(struct dentry *dentry, __u16 fileid)
    file-id would not be valid after a reconnection. */
 
 int
-smb_proc_read(struct inode *ino, off_t offset, int count, char *data)
+smb_proc_read(struct dentry *dentry, off_t offset, int count, char *data)
 {
-       struct smb_sb_info *server = SMB_SERVER(ino);
+       struct smb_sb_info *server = server_from_dentry(dentry);
        __u16 returned_count, data_len;
        char *buf;
        int result;
@@ -997,7 +990,7 @@ smb_proc_read(struct inode *ino, off_t offset, int count, char *data)
        smb_lock_server(server);
        smb_setup_header(server, SMBread, 5, 0);
        buf = server->packet;
-       WSET(buf, smb_vwv0, ino->u.smbfs_i.fileid);
+       WSET(buf, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid);
        WSET(buf, smb_vwv1, count);
        DSET(buf, smb_vwv2, offset);
        WSET(buf, smb_vwv4, 0);
@@ -1022,29 +1015,27 @@ smb_proc_read(struct inode *ino, off_t offset, int count, char *data)
 out:
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_proc_read: file %s/%s, count=%d, result=%d\n",
-((struct dentry *) ino->u.smbfs_i.dentry)->d_parent->d_name.name, 
-((struct dentry *) ino->u.smbfs_i.dentry)->d_name.name, count, result);
+dentry->d_parent->d_name.name, dentry->d_name.name, count, result);
 #endif
        smb_unlock_server(server);
        return result;
 }
 
 int
-smb_proc_write(struct inode *ino, off_t offset, int count, const char *data)
+smb_proc_write(struct dentry *dentry, off_t offset, int count, const char *data)
 {
-       struct smb_sb_info *server = SMB_SERVER(ino);
+       struct smb_sb_info *server = server_from_dentry(dentry);
        int result;
        __u8 *p;
 
-       smb_lock_server(server);
 #if SMBFS_DEBUG_VERBOSE
 printk("smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
-((struct dentry *)ino->u.smbfs_i.dentry)->d_parent->d_name.name, 
-((struct dentry *)ino->u.smbfs_i.dentry)->d_name.name, 
+dentry->d_parent->d_name.name, dentry->d_name.name, 
 count, offset, server->packet_size);
 #endif
+       smb_lock_server(server);
        p = smb_setup_header(server, SMBwrite, 5, count + 3);
-       WSET(server->packet, smb_vwv0, ino->u.smbfs_i.fileid);
+       WSET(server->packet, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid);
        WSET(server->packet, smb_vwv1, count);
        DSET(server->packet, smb_vwv2, offset);
        WSET(server->packet, smb_vwv4, 0);
@@ -1544,9 +1535,10 @@ smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
         * Check whether to change the info level.  There appears to be
         * a bug in Win NT 4.0's handling of info level 1, whereby it
         * truncates the directory scan for certain patterns of files.
-        * Hence we use level 259 for NT. (And Win 95 as well ...)
+        * Hence we use level 259 for NT.
         */
-       if (server->opt.protocol >= SMB_PROTOCOL_NT1)
+       if (server->opt.protocol >= SMB_PROTOCOL_NT1 &&
+           !(server->mnt->version & SMB_FIX_WIN95))
                info_level = 259;
 
        smb_lock_server(server);
@@ -1639,8 +1631,8 @@ printk("smb_proc_readdir_long: error=%d, breaking\n", result);
                if (server->rcls != 0)
                { 
 #ifdef SMBFS_PARANOIA
-printk("smb_proc_readdir_long: rcls=%d, err=%d, breaking\n",
-server->rcls, server->err);
+printk("smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n",
+mask, entries, server->rcls, server->err);
 #endif
                        entries = -smb_errno(server);
                        break;
@@ -1749,6 +1741,94 @@ smb_proc_readdir(struct dentry *dir, int fpos, void *cachep)
                return smb_proc_readdir_short(server, dir, fpos, cachep);
 }
 
+/*
+ * This version uses the trans2 TRANSACT2_FINDFIRST message 
+ * to get the attribute data.
+ * Note: called with the server locked.
+ *
+ * Bugs Noted:
+ */
+static int
+smb_proc_getattr_ff(struct smb_sb_info *server, struct dentry *dentry,
+                       struct smb_fattr *fattr)
+{
+       char *param = server->temp_buf, *mask = param + 12;
+       __u16 date, time;
+       unsigned char *resp_data = NULL;
+       unsigned char *resp_param = NULL;
+       int resp_data_len = 0;
+       int resp_param_len = 0;
+       int mask_len, result;
+
+retry:
+       mask_len = smb_encode_path(server, mask, dentry, NULL) - mask;
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_proc_getattr_ff: name=%s, len=%d\n", mask, mask_len);
+#endif
+       WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
+       WSET(param, 2, 1);      /* max count */
+       WSET(param, 4, 1);      /* close after this call */
+       WSET(param, 6, 1);      /* info_level */
+       DSET(param, 8, 0);
+
+       result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
+                                   0, NULL, 12 + mask_len + 1, param,
+                                   &resp_data_len, &resp_data,
+                                   &resp_param_len, &resp_param);
+       if (result < 0)
+       {
+               if (smb_retry(server))
+                       goto retry;
+               goto out;
+       }
+       if (server->rcls != 0)
+       { 
+               result = -smb_errno(server);
+#ifdef SMBFS_PARANOIA
+if (result != -ENOENT)
+printk("smb_proc_getattr_ff: error for %s, rcls=%d, err=%d\n",
+mask, server->rcls, server->err);
+#endif
+               goto out;
+       }
+       /* Make sure we got enough data ... */
+       result = -EINVAL;
+       if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
+       {
+#ifdef SMBFS_PARANOIA
+printk("smb_proc_getattr_ff: bad result for %s, len=%d, count=%d\n",
+mask, resp_data_len, WVAL(resp_param, 2));
+#endif
+               goto out;
+       }
+
+       /*
+        * Decode the response into the fattr ...
+        */
+       date = WVAL(resp_data, 0);
+       time = WVAL(resp_data, 2);
+       fattr->f_ctime = date_dos2unix(date, time);
+
+       date = WVAL(resp_data, 4);
+       time = WVAL(resp_data, 6);
+       fattr->f_atime = date_dos2unix(date, time);
+
+       date = WVAL(resp_data, 8);
+       time = WVAL(resp_data, 10);
+       fattr->f_mtime = date_dos2unix(date, time);
+#ifdef SMBFS_DEBUG_VERBOSE
+printk("smb_proc_getattr_ff: name=%s, date=%x, time=%x, mtime=%ld\n",
+mask, date, time, fattr->f_mtime);
+#endif
+       fattr->f_size = DVAL(resp_data, 12);
+       /* ULONG allocation size */
+       fattr->attr = WVAL(resp_data, 20);
+       result = 0;
+
+out:
+       return result;
+}
+
 /*
  * Note: called with the server locked.
  */
@@ -1883,11 +1963,17 @@ smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr)
         * Win 95 is painfully slow at returning trans2 getattr info,
         * so we provide the SMB_FIX_OLDATTR option switch.
         */
-       if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2 &&
-           !(server->mnt->version & SMB_FIX_OLDATTR))
-               result = smb_proc_getattr_trans2(server, dir, fattr);
-       else
+       if (server->opt.protocol >= SMB_PROTOCOL_LANMAN2) {
+               if (server->mnt->version & SMB_FIX_OLDATTR)
+                       goto core_attr;
+               if (server->mnt->version & SMB_FIX_DIRATTR)
+                       result = smb_proc_getattr_ff(server, dir, fattr);
+               else
+                       result = smb_proc_getattr_trans2(server, dir, fattr);
+       } else {
+       core_attr:
                result = smb_proc_getattr_core(server, dir, fattr);
+       }
 
        smb_finish_dirent(server, fattr);
 
index 0029255a538f8a3643129629fadaca391602f288..cefd90c9bd23c17a40b735019b19e83e4130ed41 100644 (file)
@@ -95,28 +95,37 @@ struct vfsmount *lookup_vfsmnt(kdev_t dev)
        /* NOTREACHED */
 }
 
-struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_name)
+static struct vfsmount *add_vfsmnt(struct super_block *sb,
+                       const char *dev_name, const char *dir_name)
 {
        struct vfsmount *lptr;
-       char *tmp;
+       char *tmp, *name;
 
        lptr = (struct vfsmount *)kmalloc(sizeof(struct vfsmount), GFP_KERNEL);
-        if (!lptr)
-               return NULL;
+       if (!lptr)
+               goto out;
        memset(lptr, 0, sizeof(struct vfsmount));
 
-       lptr->mnt_dev = dev;
+       lptr->mnt_sb = sb;
+       lptr->mnt_dev = sb->s_dev;
+       lptr->mnt_flags = sb->s_flags;
        sema_init(&lptr->mnt_sem, 1);
+
+       /* N.B. Is it really OK to have a vfsmount without names? */
        if (dev_name && !IS_ERR(tmp = getname(dev_name))) {
-               if ((lptr->mnt_devname =
-                   (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
-                       strcpy(lptr->mnt_devname, tmp);
+               name = (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL);
+               if (name) {
+                       strcpy(name, tmp);
+                       lptr->mnt_devname = name;
+               }
                putname(tmp);
        }
        if (dir_name && !IS_ERR(tmp = getname(dir_name))) {
-               if ((lptr->mnt_dirname =
-                   (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
-                       strcpy(lptr->mnt_dirname, tmp);
+               name = (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL);
+               if (name) {
+                       strcpy(name, tmp);
+                       lptr->mnt_dirname = name;
+               }
                putname(tmp);
        }
 
@@ -126,10 +135,11 @@ struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_na
                vfsmnttail->mnt_next = lptr;
                vfsmnttail = lptr;
        }
-       return (lptr);
+out:
+       return lptr;
 }
 
-void remove_vfsmnt(kdev_t dev)
+static void remove_vfsmnt(kdev_t dev)
 {
        struct vfsmount *lptr, *tofree;
 
@@ -496,6 +506,23 @@ out:
        return err;
 }
 
+/*
+ * Find a super_block with no device assigned.
+ */
+static struct super_block *get_empty_super(void)
+{
+       struct super_block *s = 0+super_blocks;
+
+       for (; s < NR_SUPER+super_blocks; s++) {
+               if (s->s_dev)
+                       continue;
+               if (!s->s_lock)
+                       return s;
+               printk("VFS: empty superblock %p locked!\n", s);
+       }
+       return NULL;
+}
+
 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
                                       void *data, int silent)
 {
@@ -503,44 +530,39 @@ static struct super_block * read_super(kdev_t dev,const char *name,int flags,
        struct file_system_type *type;
 
        if (!dev)
-               goto out_fail;
+               goto out_null;
        check_disk_change(dev);
        s = get_super(dev);
        if (s)
-               return s;
+               goto out;
+
        type = get_fs_type(name);
        if (!type) {
                printk("VFS: on device %s: get_fs_type(%s) failed\n",
                       kdevname(dev), name);
-               goto out_fail;
-       }
-       for (s = 0+super_blocks ;; s++) {
-               if (s >= NR_SUPER+super_blocks)
-                       goto out_fail;
-               if (s->s_dev)
-                       continue;
-               if (s->s_lock) {
-                       printk("VFS: empty superblock %p locked!\n", s);
-                       continue;
-               }
-               break;
+               goto out;
        }
+       s = get_empty_super();
+       if (!s)
+               goto out;
        s->s_dev = dev;
        s->s_flags = flags;
        s->s_dirt = 0;
        /* N.B. Should lock superblock now ... */
-       if (!type->read_super(s,data, silent))
-               goto fail;
+       if (!type->read_super(s, data, silent))
+               goto out_fail;
        s->s_dev = dev; /* N.B. why do this again?? */
        s->s_rd_only = 0;
        s->s_type = type;
+out:
        return s;
 
        /* N.B. s_dev should be cleared in type->read_super */
-fail:
-       s->s_dev = 0;
 out_fail:
-       return NULL;
+       s->s_dev = 0;
+out_null:
+       s = NULL;
+       goto out;
 }
 
 /*
@@ -603,17 +625,16 @@ static void d_mount(struct dentry *covered, struct dentry *dentry)
        dentry->d_covers = covered;
 }
 
-static int do_umount(kdev_t dev,int unmount_root)
+static int do_umount(kdev_t dev, int unmount_root)
 {
        struct super_block * sb;
        int retval;
        
+       retval = -ENOENT;
        sb = get_super(dev);
-       if (!sb)
-               return -ENOENT;
+       if (!sb || !sb->s_root)
+               goto out;
 
-       if (!sb->s_root)
-               return -ENOENT;
        /*
         * Before checking whether the filesystem is still busy,
         * make sure the kernel doesn't hold any quotafiles open
@@ -659,7 +680,6 @@ static int do_umount(kdev_t dev,int unmount_root)
                        sb->s_op->put_super(sb);
        }
        remove_vfsmnt(dev);
-       retval = 0;
 out:
        return retval;
 }
@@ -781,7 +801,7 @@ int fs_may_mount(kdev_t dev)
 
 int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
 {
-       struct dentry * dir_d = NULL;
+       struct dentry * dir_d;
        struct super_block * sb;
        struct vfsmount *vfsmnt;
        int error;
@@ -806,15 +826,13 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
                goto dput_and_out;
 
        /*
-        * Check whether to read the super block
+        * Note: If the superblock already exists,
+        * read_super just does a get_super().
         */
-       sb = get_super(dev);
-       if (!sb || !sb->s_root) {
-               error = -EINVAL;
-               sb = read_super(dev,type,flags,data,0);
-               if (!sb)
-                       goto dput_and_out;
-       }
+       error = -EINVAL;
+       sb = read_super(dev, type, flags, data, 0);
+       if (!sb)
+               goto dput_and_out;
 
        /*
         * We may have slept while reading the super block, 
@@ -825,20 +843,19 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
                goto dput_and_out;
 
        error = -ENOMEM;
-       vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
-       if (vfsmnt) {
-               vfsmnt->mnt_sb = sb;
-               vfsmnt->mnt_flags = flags;
-               d_mount(dir_d, sb->s_root);
-               error = 0;
-               goto out;               /* we don't dput(dir) - see umount */
-       }
+       vfsmnt = add_vfsmnt(sb, dev_name, dir_name);
+       if (!vfsmnt)
+               goto dput_and_out;
+       d_mount(dir_d, sb->s_root);
+       error = 0;      /* we don't dput(dir_d) - see umount */
 
-dput_and_out:
-       dput(dir_d);
 out:
        up(&mount_sem);
        return error;   
+
+dput_and_out:
+       dput(dir_d);
+       goto out;
 }
 
 
@@ -1063,14 +1080,11 @@ __initfunc(static void do_mount_root(void))
        if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
                ROOT_DEV = 0;
                if ((fs_type = get_fs_type("nfs"))) {
-                       if ((vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/"))) {
-
-                               sb = &super_blocks[0];
-                               while (sb->s_dev) sb++;
-                               vfsmnt->mnt_sb = sb;
-
-                               sb->s_dev = get_unnamed_dev();
-                               sb->s_flags = root_mountflags & ~MS_RDONLY;
+                       sb = get_empty_super(); /* "can't fail" */
+                       sb->s_dev = get_unnamed_dev();
+                       sb->s_flags = root_mountflags & ~MS_RDONLY;
+                       vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
+                       if (vfsmnt) {
                                if (nfs_root_mount(sb) >= 0) {
                                        sb->s_rd_only = 0;
                                        sb->s_dirt = 0;
@@ -1081,9 +1095,10 @@ __initfunc(static void do_mount_root(void))
                                        printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
                                        return;
                                }
-                               sb->s_dev = 0;
-                               put_unnamed_dev(sb->s_dev);
+                               remove_vfsmnt(sb->s_dev);
                        }
+                       put_unnamed_dev(sb->s_dev);
+                       sb->s_dev = 0;
                }
                if (!ROOT_DEV) {
                        printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
@@ -1136,12 +1151,10 @@ __initfunc(static void do_mount_root(void))
                        printk ("VFS: Mounted root (%s filesystem)%s.\n",
                                fs_type->name,
                                (sb->s_flags & MS_RDONLY) ? " readonly" : "");
-                       vfsmnt = add_vfsmnt(ROOT_DEV, "/dev/root", "/");
-                       if (!vfsmnt)
-                               panic("VFS: add_vfsmnt failed for root fs");
-                       vfsmnt->mnt_sb = sb;
-                       vfsmnt->mnt_flags = root_mountflags;
-                       return;
+                       vfsmnt = add_vfsmnt(sb, "/dev/root", "/");
+                       if (vfsmnt)
+                               return;
+                       panic("VFS: add_vfsmnt failed for root fs");
                }
        }
        panic("VFS: Unable to mount root fs on %s",
@@ -1225,10 +1238,8 @@ __initfunc(static int do_change_root(kdev_t new_root_dev,const char *put_old))
                return error;
        }
        remove_vfsmnt(old_root_dev);
-       vfsmnt = add_vfsmnt(old_root_dev,"/dev/root.old",put_old);
+       vfsmnt = add_vfsmnt(old_root->d_sb, "/dev/root.old", put_old);
        if (vfsmnt) {
-               vfsmnt->mnt_sb = old_root->d_inode->i_sb;
-               vfsmnt->mnt_flags = vfsmnt->mnt_sb->s_flags;
                d_mount(dir_d,old_root);
                return 0;
        }
index 8bad18d9047fb1079bcccfe5ae7647ea160f61c3..6fb2e2541d228cba6d610b3a8e89439fa2c11978 100644 (file)
@@ -159,7 +159,6 @@ extern unsigned char *apic_reg;
 extern unsigned char boot_cpu_id;
 extern unsigned long cpu_present_map;
 extern volatile int cpu_number_map[NR_CPUS];
-extern volatile int cpu_logical_map[NR_CPUS];
 extern volatile unsigned long smp_invalidate_needed;
 extern void smp_flush_tlb(void);
 extern volatile unsigned long kernel_flag, kernel_counter;
@@ -171,6 +170,11 @@ extern unsigned long ipi_count;
 extern void smp_invalidate_rcv(void);          /* Process an NMI */
 extern void smp_local_timer_interrupt(struct pt_regs * regs);
 extern void setup_APIC_clock (void);
+extern volatile int __cpu_logical_map[NR_CPUS];
+extern inline int cpu_logical_map(int cpu)
+{
+       return __cpu_logical_map[cpu];
+}
 
 
 /*
@@ -235,5 +239,12 @@ extern __inline int hard_smp_processor_id(void)
 #define SMP_FROM_INT           1
 #define SMP_FROM_SYSCALL       2
 
+#else
+#ifndef ASSEMBLY
+extern inline int cpu_logical_map(int cpu)
+{
+       return cpu;
+}
+#endif
 #endif
 #endif
index 09c70e1a55c0e94d790e671ebc3fec195f37058e..6bf0d79cb4f8e510e25e013c460e8a26101f5c94 100644 (file)
@@ -2,6 +2,7 @@
 #define _LINUX_KERNEL_STAT_H
 
 #include <asm/irq.h>
+#include <asm/smp.h>
 #include <linux/smp.h>
 #include <linux/tasks.h>
 
@@ -25,7 +26,7 @@ struct kernel_stat {
        unsigned int dk_drive_wblk[DK_NDRIVE];
        unsigned int pgpgin, pgpgout;
        unsigned int pswpin, pswpout;
-       unsigned int interrupts[NR_CPUS][NR_IRQS];
+       unsigned int irqs[NR_CPUS][NR_IRQS];
        unsigned int ipackets, opackets;
        unsigned int ierrors, oerrors;
        unsigned int collisions;
@@ -34,4 +35,17 @@ struct kernel_stat {
 
 extern struct kernel_stat kstat;
 
+/*
+ * Number of interrupts per specific IRQ source, since bootup
+ */
+extern inline int kstat_irqs (int irq)
+{
+       int i, sum=0;
+
+       for (i = 0 ; i < smp_num_cpus ; i++)
+               sum += kstat.irqs[cpu_logical_map(i)][irq];
+
+       return sum;
+}
+
 #endif /* _LINUX_KERNEL_STAT_H */
index e77b4efc6e9a5d3caa16f951506a854b38e18442..c533e63ac29872597c50c9d6d1babad9bb8aa7f5 100644 (file)
@@ -12,10 +12,10 @@ struct minix_sb_info {
                        unsigned long s_firstdatazone;
                        unsigned long s_log_zone_size;
                        unsigned long s_max_size;
-                       struct buffer_head * s_imap[8];
-                       struct buffer_head * s_zmap[64];
                        unsigned long s_dirsize;
                        unsigned long s_namelen;
+                       struct buffer_head ** s_imap;
+                       struct buffer_head ** s_zmap;
                        struct buffer_head * s_sbh;
                        struct minix_super_block * s_ms;
                        unsigned short s_mount_state;
index eaca428076fcf8283f429faced16ddd3affb1da8..96bc89fd276b10572f3352a2cf1ee72b9837e930 100644 (file)
@@ -76,6 +76,7 @@ smb_vfree(void *obj)
  */
 #define SMB_FIX_WIN95  0x0001  /* Win 95 server */
 #define SMB_FIX_OLDATTR        0x0002  /* Use core getattr (Win 95 speedup) */
+#define SMB_FIX_DIRATTR        0x0004  /* Use find_first for getattr */
 
 /* linux/fs/smbfs/mmap.c */
 int smb_mmap(struct file *, struct vm_area_struct *);
@@ -95,7 +96,6 @@ struct super_block *smb_read_super(struct super_block *, void *, int);
 void smb_get_inode_attr(struct inode *, struct smb_fattr *);
 void smb_invalidate_inodes(struct smb_sb_info *);
 int  smb_revalidate_inode(struct dentry *);
-int  smb_refresh_inode(struct inode *);
 int  smb_notify_change(struct dentry *, struct iattr *);
 unsigned long smb_invent_inos(unsigned long);
 struct inode *smb_iget(struct super_block *, struct smb_fattr *);
@@ -112,8 +112,8 @@ int smb_close(struct inode *);
 void smb_close_dentry(struct dentry *);
 int smb_close_fileid(struct dentry *, __u16);
 int smb_open(struct dentry *, int);
-int smb_proc_read(struct inode *, off_t, int, char *);
-int smb_proc_write(struct inode *, off_t, int, const char *);
+int smb_proc_read(struct dentry *, off_t, int, char *);
+int smb_proc_write(struct dentry *, off_t, int, const char *);
 int smb_proc_create(struct dentry *, __u16, time_t, __u16 *);
 int smb_proc_mv(struct dentry *, struct dentry *);
 int smb_proc_mkdir(struct dentry *);
index 71e57ea6a5c08762648c45c5e70d34e999a425cd..4aea02c3cc7aaef794a7672274ac07b9c90106db 100644 (file)
@@ -21,15 +21,14 @@ struct smb_inode_info {
         * file handles are local to a connection. A file is open if
         * (open == generation).
         */
-        unsigned int open;
+        unsigned int open;     /* open generation */
        __u16 fileid;           /* What id to handle a file with? */
        __u16 attr;             /* Attribute fields, DOS value */
 
-       __u16 access;           /* Access bits. */
+       __u16 access;           /* Access mode */
        __u16 cache_valid;      /* dircache valid? */
        unsigned long oldmtime; /* last time refreshed */
        unsigned long closed;   /* timestamp when closed */
-       void * dentry;          /* The dentry we were opened with */
 };
 
 #endif
index 5923a141a63e479d95487fa450cf43f697e8e338..1a8d71f588b1bf7f9caa2c16b6eee55af2213e7e 100644 (file)
@@ -61,5 +61,6 @@ extern volatile int smp_msg_id;
 #define smp_message_pass(t,m,d,w)      
 #define smp_threads_ready              1
 #define kernel_lock()
+
 #endif
 #endif
index ca50ca57f4f7d0aad5f2c1f980171699dafb1215..f776efa02e6148d88a504224ba31116a2fbb03c5 100644 (file)
@@ -927,8 +927,6 @@ int cpu_idle(void *unused)
 
 #else
 
-extern void setup_IO_APIC(void);
-
 /*
  *     Multiprocessor idle thread is in arch/...
  */
@@ -1051,7 +1049,6 @@ __initfunc(asmlinkage void start_kernel(void))
        printk("POSIX conformance testing by UNIFIX\n");
 #ifdef __SMP__
        smp_init();
-       setup_IO_APIC();
 #endif
 #ifdef CONFIG_SYSCTL
        sysctl_init();
index 09849f7eb4f83f758c0cb70a1a416f61dd13f686..07b03ebe4f21ef776a7723565ca94f3d4c3b1e66 100644 (file)
@@ -437,7 +437,6 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t
  */
 int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
 {
-        int i;
        int nr;
        int error = -ENOMEM;
        struct task_struct *p;
@@ -483,11 +482,14 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
        p->times.tms_utime = p->times.tms_stime = 0;
        p->times.tms_cutime = p->times.tms_cstime = 0;
 #ifdef __SMP__
-       p->has_cpu = 0;
-       p->processor = NO_PROC_ID;
-       /* ?? should we just memset this ?? */
-       for(i = 0; i < smp_num_cpus; i++)
-               p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0;
+       {
+               int i;
+               p->has_cpu = 0;
+               p->processor = NO_PROC_ID;
+               /* ?? should we just memset this ?? */
+               for(i = 0; i < smp_num_cpus; i++)
+                       p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0;
+       }
 #endif
        p->lock_depth = 0;
        p->start_time = jiffies;
index d9c45c413ec693c7433f7fe1ace456203852ae88..8d4d09ee19fc599a6a73cf5731bbf074ff4ddbc8 100644 (file)
@@ -392,7 +392,9 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
 
 /* END OF OBSOLETE FUNCTIONS */
 
-
+/*
+ * Note: requires bh_atomic locking.
+ */
 int arp_bind_neighbour(struct dst_entry *dst)
 {
        struct device *dev = dst->dev;
@@ -734,11 +736,9 @@ int arp_req_set(struct arpreq *r, struct device * dev)
        start_bh_atomic();
        neigh = __neigh_lookup(&arp_tbl, &ip, dev, 1);
        if (neigh) {
-               unsigned state = 0;
-               if (r->arp_flags&ATF_PERM)
+               unsigned state = NUD_STALE;
+               if (r->arp_flags & ATF_PERM)
                        state = NUD_PERMANENT;
-               else
-                       state = NUD_STALE;
                err = neigh_update(neigh, (r->arp_flags&ATF_COM) ?
                                   r->arp_ha.sa_data : NULL, state, 1, 0);
                neigh_release(neigh);
@@ -764,16 +764,21 @@ static unsigned arp_state_to_flags(struct neighbour *neigh)
 static int arp_req_get(struct arpreq *r, struct device *dev)
 {
        u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
-       struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
+       struct neighbour *neigh;
+       int err = -ENXIO;
+
+       start_bh_atomic();
+       neigh = __neigh_lookup(&arp_tbl, &ip, dev, 0);
        if (neigh) {
                memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len);
                r->arp_ha.sa_family = dev->type;
                strncpy(r->arp_dev, dev->name, sizeof(r->arp_dev));
                r->arp_flags = arp_state_to_flags(neigh);
                neigh_release(neigh);
-               return 0;
+               err = 0;
        }
-       return -ENXIO;
+       end_bh_atomic();
+       return err;
 }
 
 int arp_req_delete(struct arpreq *r, struct device * dev)
@@ -802,7 +807,7 @@ int arp_req_delete(struct arpreq *r, struct device * dev)
 
        err = -ENXIO;
        start_bh_atomic();
-       neigh = neigh_lookup(&arp_tbl, &ip, dev);
+       neigh = __neigh_lookup(&arp_tbl, &ip, dev, 0);
        if (neigh) {
                err = neigh_update(neigh, NULL, NUD_FAILED, 1, 0);
                neigh_release(neigh);
@@ -856,6 +861,11 @@ int arp_ioctl(unsigned int cmd, void *arg)
                err = -EINVAL;
                if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)
                        goto out;
+       } else if (cmd != SIOCSARP) {
+               /* dev has not been set ... */
+               printk(KERN_ERR "arp_ioctl: invalid, null device\n");
+               err = -EINVAL;
+               goto out;
        }
 
        switch(cmd) {
@@ -863,6 +873,7 @@ int arp_ioctl(unsigned int cmd, void *arg)
                err = arp_req_delete(&r, dev);
                break;
        case SIOCSARP:
+               /* This checks for dev == NULL */
                err = arp_req_set(&r, dev);
                break;
        case SIOCGARP:
index 6b68c628a322a8676120a7702421e792177c5904..091d31dc8ce80e1111a6be178457caad15572274 100644 (file)
@@ -614,7 +614,7 @@ unsigned int tcp_poll(struct socket *sock, poll_table *wait)
                        mask |= POLLIN | POLLRDNORM;
 
 #if 1 /* This needs benchmarking and real world tests */
-               space = sk->dst_cache->pmtu + 128;
+               space = (sk->dst_cache ? sk->dst_cache->pmtu : sk->mss) + 128;
                if (space < 2048) /* XXX */
                        space = 2048;
 #else /* 2.0 way */
@@ -663,7 +663,7 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
                        return put_user(amount, (int *)arg);
                }
                default:
-                       return(-EINVAL);
+                       return(-ENOIOCTLCMD);
        };
 }