]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.102 2.1.102
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:33 +0000 (15:15 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:15:33 +0000 (15:15 -0500)
Documentation/Configure.help
arch/i386/kernel/irq.c
fs/isofs/inode.c

index c80521f3ddb06ce60eba00b5899ad74ee3053c0a..a45f45dee7fb6d26e61b1aa20ec160ed2da4db4c 100644 (file)
@@ -6016,16 +6016,20 @@ CONFIG_SOLARIS_X86_PARTITION
 
 ADFS filesystem support (read only) (EXPERIMENTAL)
 CONFIG_ADFS_FS
-  Acorn Disc Filing System is the standard filesystem of the Risc OS
-  operating system which runs on Acorn's ARM based Risc PC computers.
-  If you say Y here, Linux will be able to read from ADFS partitions
-  on hard drives and from ADFS-formatted floppy disks. 
+  The Acorn Disc Filing System is the standard filesystem of the RiscOS
+  operating system which runs on Acorn's ARM based Risc PC systems and
+  the Acorn Archimedes range of machines. These should be the first
+  partition (ie, /dev/[hs]d?1) on each of your drives. If you say Y
+  here, Linux will be able to read from ADFS partitions on hard drives
+  and from ADFS-formatted floppy discs.
 
   This code is also available as a module called adfs.o ( = code which
   can be inserted in and removed from the running kernel whenever you
   want). If you want to compile it as a module, say M here and read
   Documentation/modules.txt.
 
+  If unsure, say N.
+
 /dev/pts filesystem (experimental)
 CONFIG_DEVPTS_FS
   If you say Y here, you'll get a virtual filesystem which can be
@@ -6506,13 +6510,6 @@ CONFIG_SOFTCURSOR
   or change their color depending on the virtual console you're on.
   See Documentation/VGA-softcursor.txt for more information.
 
-Acorn's ADFS filesystem support (read only) (EXPERIMENTAL)
-CONFIG_ADFS_FS
-  The Advanced Disk File System is the filesystem used on floppy and
-  hard disks by Acorn Systems.  Currently in development, as a read-
-  only driver for hard disks.  These should be the first partition
-  (eg. /dev/[sh]d?1) on each of your drives.  If unsure, say N.
-
 Standard/generic serial support
 CONFIG_SERIAL
   This selects whether you want to include the driver for the standard
index 0cdf2e8848d875bb804d4d3a6ef99f9044ea786a..811fc0b807a0611f9e9c62ac146121873389881b 100644 (file)
@@ -87,6 +87,7 @@ spinlock_t irq_controller_lock;
 unsigned int io_apic_irqs = 0;
 
 struct hw_interrupt_type {
+       const char * typename;
        void (*handle)(unsigned int irq, int cpu, struct pt_regs * regs);
        void (*enable)(unsigned int irq);
        void (*disable)(unsigned int irq);
@@ -98,6 +99,7 @@ static void enable_8259A_irq (unsigned int irq);
 static void disable_8259A_irq (unsigned int irq);
 
 static struct hw_interrupt_type i8259A_irq_type = {
+       "XT-PIC",
        do_8259A_IRQ,
        enable_8259A_irq,
        disable_8259A_irq
@@ -121,6 +123,7 @@ static void enable_edge_ioapic_irq (unsigned int irq);
 static void disable_edge_ioapic_irq (unsigned int irq);
 
 static struct hw_interrupt_type ioapic_edge_irq_type = {
+       "IO-APIC-edge",
        do_edge_ioapic_IRQ,
        enable_edge_ioapic_irq,
        disable_edge_ioapic_irq
@@ -132,6 +135,7 @@ static void enable_level_ioapic_irq (unsigned int irq);
 static void disable_level_ioapic_irq (unsigned int irq);
 
 static struct hw_interrupt_type ioapic_level_irq_type = {
+       "IO-APIC-level",
        do_level_ioapic_IRQ,
        enable_level_ioapic_irq,
        disable_level_ioapic_irq
@@ -350,16 +354,7 @@ int get_irq_list(char *buf)
                        p += sprintf(p, "%10u ",
                                kstat.irqs[cpu_logical_map(j)][i]);
 #endif
-               if (IO_APIC_IRQ(i)) {
-                       p += sprintf(p, " IO-APIC");
-#ifdef __SMP__
-                       if (irq_desc[i].handler == &ioapic_level_irq_type)
-                               p += sprintf(p, "-level ");
-                       else
-                               p += sprintf(p, "-edge  ");
-#endif
-               } else
-                       p += sprintf(p, "  XT-PIC       ");
+               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
                p += sprintf(p, "  %s", action->name);
 
                for (action=action->next; action; action = action->next) {
@@ -370,7 +365,6 @@ int get_irq_list(char *buf)
        p += sprintf(p, "NMI: %10u\n", atomic_read(&nmi_counter));
 #ifdef __SMP__
        p += sprintf(p, "IPI: %10lu\n", ipi_count);
-       print_IO_APIC();
 #endif         
        return p - buf;
 }
@@ -1050,6 +1044,7 @@ int setup_x86_irq(unsigned int irq, struct irqaction * new)
                        }
                }
 #endif
+               irq_desc[irq].status = 0;
                irq_desc[irq].handler->enable(irq);
        }
        spin_unlock_irqrestore(&irq_controller_lock,flags);
index 03900d80a7a2eeb6a7770b085c043a3a2b4fcb8e..a1a460c06901d5c852cf73c1a7c8d6dc041afa8f 100644 (file)
@@ -132,20 +132,12 @@ static int parse_options(char *options, struct iso9660_options * popt)
 
 #ifdef CONFIG_JOLIET
                if (!strcmp(this_char,"iocharset")) {
-                       char *p;
-                       int len;
-
-                       p = value;
-                       while (*value && *value != ',') value++;
-                       len = value - p;
-                       if (len) {
-                               popt->iocharset = kmalloc(len+1, GFP_KERNEL);
-                               memcpy(popt->iocharset, p, len);
-                               popt->iocharset[len] = 0;
-                       } else {
-                               popt->iocharset = NULL;
+                       popt->iocharset = value;
+                       while (*value && *value != ',')
+                               value++;
+                       if (value == popt->iocharset)
                                return 0;
-                       }
+                       *value = 0;
                } else
 #endif
                if (!strcmp(this_char,"map") && value) {
@@ -266,32 +258,28 @@ static unsigned int isofs_get_last_session(kdev_t dev)
 struct super_block *isofs_read_super(struct super_block *s, void *data,
                                     int silent)
 {
-       struct buffer_head            * bh = NULL;
+       struct buffer_head            * bh = NULL, *pri_bh = NULL;
        unsigned int                    blocksize;
        unsigned int                    blocksize_bits;
        kdev_t                          dev = s->s_dev;
-       struct hs_volume_descriptor   * hdp;
        struct hs_primary_descriptor  * h_pri = NULL;
+       struct iso_primary_descriptor * pri = NULL;
+       struct iso_supplementary_descriptor *sec = NULL;
+       struct iso_directory_record   * rootp;
        int                             high_sierra;
-       int                             iso_blknum;
+       int                             iso_blknum, block;
        int                             joliet_level = 0;
-       struct iso9660_options          opt;
        int                             orig_zonesize;
-       struct iso_primary_descriptor * pri = NULL;
-       struct iso_directory_record   * rootp;
-       struct iso_supplementary_descriptor *sec = NULL;
-       struct iso_volume_descriptor  * vdp;
        unsigned int                    vol_desc_start;
        struct inode                  * inode;
-
+       struct iso9660_options          opt;
 
        MOD_INC_USE_COUNT;
+       /* lock before any blocking operations */
+       lock_super(s);
 
-       if (!parse_options((char *) data,&opt)) {
-               s->s_dev = 0;
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
+       if (!parse_options((char *) data, &opt))
+               goto out_unlock;
 
 #if 0
        printk("map = %c\n", opt.map);
@@ -303,6 +291,7 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        printk("blocksize = %d\n", opt.blocksize);
        printk("gid = %d\n", opt.gid);
        printk("uid = %d\n", opt.uid);
+       printk("iocharset = %s\n", opt.iocharset);
 #endif
 
        /*
@@ -333,8 +322,6 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
 
        set_blocksize(dev, opt.blocksize);
 
-       lock_super(s);
-
        s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */
 
        vol_desc_start = isofs_get_last_session(dev);
@@ -342,32 +329,25 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        for (iso_blknum = vol_desc_start+16;
              iso_blknum < vol_desc_start+100; iso_blknum++)
        {
-           int b = iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits);
+           struct hs_volume_descriptor   * hdp;
+           struct iso_volume_descriptor  * vdp;
 
-           if (!(bh = bread(dev,b,opt.blocksize))) {
-               s->s_dev = 0;
-               printk("isofs_read_super: bread failed, dev "
-                      "%s iso_blknum %d block %d\n",
-                      kdevname(dev), iso_blknum, b);
-               unlock_super(s);
-               MOD_DEC_USE_COUNT;
-               return NULL;
-           }
+           block = iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits);
+           if (!(bh = bread(dev, block, opt.blocksize)))
+               goto out_no_read;               
 
            vdp = (struct iso_volume_descriptor *)bh->b_data;
            hdp = (struct hs_volume_descriptor *)bh->b_data;
            
            if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
                if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
-                   goto out;
-               if (isonum_711 (hdp->type) == ISO_VD_END)
-                   goto out;
+                   goto out_freebh;
                
                s->u.isofs_sb.s_high_sierra = 1;
                high_sierra = 1;
                opt.rock = 'n';
                h_pri = (struct hs_primary_descriptor *)vdp;
-               break;
+               goto root_found;
            }
 
            if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
@@ -376,9 +356,13 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
                if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) {
                    if (pri == NULL) {
                        pri = (struct iso_primary_descriptor *)vdp;
+                       /* Save the buffer in case we need it ... */
+                       pri_bh = bh;
+                       bh = NULL;
                    }
+               }
 #ifdef CONFIG_JOLIET
-               else if (isonum_711 (vdp->type) == ISO_VD_SUPPLEMENTARY) {
+               else if (isonum_711 (vdp->type) == ISO_VD_SUPPLEMENTARY) {
                    sec = (struct iso_supplementary_descriptor *)vdp;
                    if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) {
                        if (opt.joliet == 'y') {
@@ -392,27 +376,31 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
                            printk("ISO9660 Extensions: Microsoft Joliet Level %d\n",
                                   joliet_level);
                        }
-                       break;
+                       goto root_found;
                    } else {
                        /* Unknown supplementary volume descriptor */
                        sec = NULL;
                    }
-#endif
                }
+#endif
                /* Just skip any volume descriptors we don't recognize */
            }
 
            brelse(bh);
+           bh = NULL;
        }
-       if ((pri == NULL) && (sec == NULL) && (h_pri == NULL)) {
-           if (!silent)
-               printk("Unable to identify CD-ROM format.\n");
-           s->s_dev = 0;
-           unlock_super(s);
-           MOD_DEC_USE_COUNT;
-           return NULL;
-       }
+       /*
+        * If we fall through, either no volume descriptor was found,
+        * or else we passed a primary descriptor looking for others.
+        */
+       if (!pri)
+               goto out_unknown_format;
+       brelse(bh);
+       bh = pri_bh;
+       pri_bh = NULL;
 
+root_found:
+       brelse(pri_bh);
        s->u.isofs_sb.s_joliet_level = joliet_level;
 
        if (joliet_level && opt.rock == 'n') {
@@ -425,10 +413,8 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        if(high_sierra){
          rootp = (struct iso_directory_record *) h_pri->root_directory_record;
 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-         if (isonum_723 (h_pri->volume_set_size) != 1) {
-           printk("Multi-volume disks not supported.\n");
-           goto out;
-         }
+         if (isonum_723 (h_pri->volume_set_size) != 1)
+               goto out_no_support;
 #endif IGNORE_WRONG_MULTI_VOLUME_SPECS
          s->u.isofs_sb.s_nzones = isonum_733 (h_pri->volume_space_size);
          s->u.isofs_sb.s_log_zone_size = isonum_723 (h_pri->logical_block_size);
@@ -436,10 +422,8 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        } else {
          rootp = (struct iso_directory_record *) pri->root_directory_record;
 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-         if (isonum_723 (pri->volume_set_size) != 1) {
-           printk("Multi-volume disks not supported.\n");
-           goto out;
-         }
+         if (isonum_723 (pri->volume_set_size) != 1)
+               goto out_no_support;
 #endif IGNORE_WRONG_MULTI_VOLUME_SPECS
          s->u.isofs_sb.s_nzones = isonum_733 (pri->volume_space_size);
          s->u.isofs_sb.s_log_zone_size = isonum_723 (pri->logical_block_size);
@@ -454,20 +438,13 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
 
        /*
         * If the zone size is smaller than the hardware sector size,
-        * this is a fatal error.  This would occur if the
-        * disc drive had sectors that were 2048 bytes, but the filesystem
-        * had blocks that were 512 bytes (which should only very rarely
-        * happen.
+        * this is a fatal error.  This would occur if the disc drive
+        * had sectors that were 2048 bytes, but the filesystem had
+        * blocks that were 512 bytes (which should only very rarely
+        * happen.)
         */
-       if(    (blocksize != 0)
-           && (orig_zonesize < blocksize) )
-         {
-             printk("Logical zone size(%d) < hardware blocksize(%u)\n",
-                    orig_zonesize, blocksize);
-             goto out;
-
-         }
-
+       if(blocksize != 0 && orig_zonesize < blocksize)
+               goto out_bad_size;
 
        switch (s -> u.isofs_sb.s_log_zone_size)
          { case  512: s -> u.isofs_sb.s_log_zone_size =  9; break;
@@ -475,8 +452,7 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
            case 2048: s -> u.isofs_sb.s_log_zone_size = 11; break;
 
            default:
-             printk("Bad logical zone size %ld\n", s -> u.isofs_sb.s_log_zone_size);
-             goto out;
+               goto out_bad_zone_size;
          }
 
        s->s_magic = ISOFS_SUPER_MAGIC;
@@ -488,8 +464,6 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
 
        s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */;
 
-       brelse(bh);
-       
        /* RDE: data zone now byte offset! */
 
        s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) +
@@ -502,10 +476,9 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        printk(KERN_DEBUG "First datazone:%ld   Root inode number %d\n",
               s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size,
               s->u.isofs_sb.s_firstdatazone);
-       if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n");
+       if(high_sierra)
+               printk(KERN_DEBUG "Disc in High Sierra format.\n");
 #endif
-       unlock_super(s);
-       /* set up enough so that it can read an inode */
 
        /*
         * Force the blocksize to 512 for 512 byte sectors.  The file
@@ -544,27 +517,17 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        s->u.isofs_sb.s_nls_iocharset = NULL;
 
 #ifdef CONFIG_JOLIET
-       if (joliet_level == 0) {
-               if (opt.iocharset) {
-                       kfree(opt.iocharset);
-                       opt.iocharset = NULL;
-               }
-       } else if (opt.utf8 == 0) {
-               char * p;
-               p = opt.iocharset ? opt.iocharset : "iso8859-1";
+       if (joliet_level && opt.utf8 == 0) {
+               char * p = opt.iocharset ? opt.iocharset : "iso8859-1";
                s->u.isofs_sb.s_nls_iocharset = load_nls(p);
                if (! s->u.isofs_sb.s_nls_iocharset) {
                        /* Fail only if explicit charset specified */
-                       if (opt.iocharset) {
-                               kfree(opt.iocharset);
-                               goto out;
-                       } else {
-                               s->u.isofs_sb.s_nls_iocharset = load_nls_default();
-                       }
+                       if (opt.iocharset)
+                               goto out_freebh;
+                       s->u.isofs_sb.s_nls_iocharset = load_nls_default();
                }
        }
 #endif
-       s->s_dev = dev;
        s->s_op = &isofs_sops;
        s->u.isofs_sb.s_mapping = opt.map;
        s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 2 : 0);
@@ -605,31 +568,62 @@ struct super_block *isofs_read_super(struct super_block *s, void *data,
        }
 
        s->s_root = d_alloc_root(inode, NULL);
-       unlock_super(s);
-
-       if (!(s->s_root)) {
-               s->s_dev = 0;
-               printk("get root inode failed\n");
-#ifdef CONFIG_JOLIET
-               if (s->u.isofs_sb.s_nls_iocharset)
-                       unload_nls(s->u.isofs_sb.s_nls_iocharset);
-               if (opt.iocharset) kfree(opt.iocharset);
-#endif
-               MOD_DEC_USE_COUNT;
-               return NULL;
-       }
+       if (!(s->s_root))
+               goto out_no_root;
 
-       if(!check_disk_change(s->s_dev)) {
+       if(!check_disk_change(dev)) {
+               brelse(bh);
+               unlock_super(s);
                return s;
        }
+       /*
+        * Disk changed? Free the root dentry and clean up ...
+        */
+       dput(s->s_root);
+       goto out_freechar;
+
+       /*
+        * Display error message
+        */
+out_no_root:
+       printk(KERN_ERR "isofs_read_super: get root inode failed\n");
+       goto out_iput;
+out_bad_zone_size:
+       printk(KERN_WARNING "Bad logical zone size %ld\n",
+               s->u.isofs_sb.s_log_zone_size);
+       goto out_freebh;
+out_bad_size:
+       printk(KERN_WARNING "Logical zone size(%d) < hardware blocksize(%u)\n",
+               orig_zonesize, blocksize);
+       goto out_freebh;
+#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
+out_no_support:
+       printk(KERN_WARNING "Multi-volume disks not supported.\n");
+       goto out_freebh;
+#endif
+out_unknown_format:
+       if (!silent)
+               printk(KERN_WARNING "Unable to identify CD-ROM format.\n");
+       goto out_freebh;
+out_no_read:
+       printk(KERN_WARNING "isofs_read_super: "
+               "bread failed, dev=%s, iso_blknum=%d, block=%d\n",
+               kdevname(dev), iso_blknum, block);
+       goto out_unlock;
+
+       /*
+        * Cascaded error cleanup to ensure all resources are freed.
+        */
+out_iput:
+       iput(inode);
+out_freechar:
 #ifdef CONFIG_JOLIET
        if (s->u.isofs_sb.s_nls_iocharset)
                unload_nls(s->u.isofs_sb.s_nls_iocharset);
 #endif
-       if (opt.iocharset) kfree(opt.iocharset);
-
- out: /* Kick out for various error conditions */
+out_freebh:
        brelse(bh);
+out_unlock:
        s->s_dev = 0;
        unlock_super(s);
        MOD_DEC_USE_COUNT;