]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] cciss partitioning stuff, per-disk gendisks
authorAlexander Viro <viro@math.psu.edu>
Tue, 13 Aug 2002 01:32:18 +0000 (18:32 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 13 Aug 2002 01:32:18 +0000 (18:32 -0700)
drivers/block/cciss.c
drivers/block/cciss.h
drivers/block/cpqarray.c
fs/partitions/check.c

index df07b097193d150c925f63e57c1271313384858d..db3d25ebfd35c1ebd42bf0a98879df3326b9fdd9 100644 (file)
@@ -105,10 +105,9 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                unsigned int cmd, unsigned long arg);
 
 static int revalidate_allvol(kdev_t dev);
-static int revalidate_logvol(kdev_t dev, int maxusage);
 static int cciss_revalidate(kdev_t dev);
 static int deregister_disk(int ctlr, int logvol);
-static int register_new_disk(kdev_t dev, int cltr);
+static int register_new_disk(int cltr);
 
 static void cciss_getgeometry(int cntl_num);
 
@@ -333,27 +332,6 @@ static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
         }
 }
 
-/*  
- * fills in the disk information. 
- */
-static void cciss_geninit( int ctlr)
-{
-       drive_info_struct *drv;
-       int i;
-       
-       /* Loop through each real device */ 
-       hba[ctlr]->gendisk.nr_real = 0; 
-       for(i=0; i< NWD; i++)
-       {
-               drv = &(hba[ctlr]->drv[i]);
-               if( !(drv->nr_blocks))
-                       continue;
-               hba[ctlr]->hd[i << NWD_SHIFT].nr_sects = drv->nr_blocks;
-               //hba[ctlr]->gendisk.nr_real++;
-               (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->block_size;
-       }
-       hba[ctlr]->gendisk.nr_real = hba[ctlr]->highest_lun+1;
-}
 /*
  * Open.  Make sure the device is really there.
  */
@@ -599,7 +577,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 
        case CCISS_REGNEWD:
        {
-               return(register_new_disk(inode->i_rdev, ctlr));
+               return(register_new_disk(ctlr));
        }       
        case CCISS_PASSTHRU:
        {
@@ -726,49 +704,11 @@ static int cciss_revalidate(kdev_t dev)
 {
         int ctlr = major(dev) - MAJOR_NR;
        int target = minor(dev) >> NWD_SHIFT;
-        struct gendisk *gdev = &(hba[ctlr]->gendisk);
-       gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blocks;
+        struct gendisk *disk = &hba[ctlr]->gendisk[target];
+       disk->part[0].nr_sects = hba[ctlr]->drv[target].nr_blocks;
        return 0;
 }
 
-/* Borrowed and adapted from sd.c */
-/*
- * FIXME: we are missing the exclusion with ->open() here - it can happen
- * just as we are rereading partition tables.
- */
-static int revalidate_logvol(kdev_t dev, int maxusage)
-{
-        int ctlr, target;
-        struct gendisk *gdev;
-        unsigned long flags;
-        int res;
-
-        target = minor(dev) >> NWD_SHIFT;
-        ctlr = major(dev) - MAJOR_NR;
-        gdev = &(hba[ctlr]->gendisk);
-
-        spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
-        if (hba[ctlr]->drv[target].usage_count > maxusage) {
-                spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-                printk(KERN_WARNING "cciss: Device busy for "
-                        "revalidation (usage=%d)\n",
-                        hba[ctlr]->drv[target].usage_count);
-                return -EBUSY;
-        }
-        hba[ctlr]->drv[target].usage_count++;
-        spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
-
-       res = wipe_partitions(dev);
-       if (res)
-               goto leave;
-
-       /* setup partitions per disk */
-       grok_partitions(dev, hba[ctlr]->drv[target].nr_blocks);
-leave:
-        hba[ctlr]->drv[target].usage_count--;
-        return res;
-}
-
 /*
  * revalidate_allvol is for online array config utilities.  After a
  * utility reconfigures the drives in the array, it can use this function
@@ -799,6 +739,15 @@ static int revalidate_allvol(kdev_t dev)
         hba[ctlr]->usage_count++;
        spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
 
+       for(i=0; i< NWD; i++) {
+               struct gendisk *disk = &hba[ctlr]->gendisk[i];
+               if (disk->major_name) {
+                       wipe_partitions(mk_kdev(disk->major, disk->first_minor));
+                       del_gendisk(disk);
+                       disk->major_name = NULL;
+               }
+       }
+
         /*
          * Set the partition and block size structures for all volumes
          * on this controller to zero.  We will reread all of this data
@@ -806,8 +755,6 @@ static int revalidate_allvol(kdev_t dev)
        memset(hba[ctlr]->hd,         0, sizeof(struct hd_struct) * 256);
         memset(hba[ctlr]->drv,        0, sizeof(drive_info_struct)
                                                * CISS_MAX_LUN);
-        hba[ctlr]->gendisk.nr_real = 0;
-
         /*
          * Tell the array controller not to give us any interrupts while
          * we check the new geometry.  Then turn interrupts back on when
@@ -817,13 +764,20 @@ static int revalidate_allvol(kdev_t dev)
         cciss_getgeometry(ctlr);
         hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_ON);
 
-        cciss_geninit(ctlr);
-        for(i=0; i<NWD; i++) {
-               kdev_t kdev = mk_kdev(major(dev), i << NWD_SHIFT);
-                if (hba[ctlr]->gendisk.part[ i<<NWD_SHIFT ].nr_sects)
-                        revalidate_logvol(kdev, 2);
+       /* Loop through each real device */ 
+       for (i = 0; i < NWD; i++) {
+               struct gendisk *disk = &hba[ctlr]->gendisk[i];
+               drive_info_struct *drv = &(hba[ctlr]->drv[i]);
+               if (!drv->nr_blocks)
+                       continue;
+               (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->block_size;
+               disk->major_name = hba[ctlr]->names + 12 * i;
+               add_gendisk(disk);
+               register_disk(disk,
+                             mk_kdev(disk->major, disk->first_minor),
+                             1<<disk->minor_shift, disk->fops,
+                             drv->nr_blocks);
        }
-
         hba[ctlr]->usage_count--;
         return 0;
 }
@@ -831,18 +785,15 @@ static int revalidate_allvol(kdev_t dev)
 static int deregister_disk(int ctlr, int logvol)
 {
        unsigned long flags;
-       struct gendisk *gdev = &(hba[ctlr]->gendisk);
+       struct gendisk *disk = &hba[ctlr]->gendisk[logvol];
        ctlr_info_t  *h = hba[ctlr];
-       int start, max_p;
-
 
        if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
 
        spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
        /* make sure logical volume is NOT is use */
-       if( h->drv[logvol].usage_count > 1)
-       {
+       if( h->drv[logvol].usage_count > 1) {
                spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
                 return -EBUSY;
        }
@@ -850,25 +801,24 @@ static int deregister_disk(int ctlr, int logvol)
        spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
 
        /* invalidate the devices and deregister the disk */ 
-       max_p = 1 << gdev->minor_shift;
-       start = logvol << gdev->minor_shift;
-       wipe_partitions(mk_kdev(MAJOR_NR+ctlr, start));
+       if (disk->major_name) {
+               wipe_partitions(mk_kdev(disk->major, disk->first_minor));
+               del_gendisk(disk);
+               disk->major_name = NULL;
+       }
        /* check to see if it was the last disk */
-       if (logvol == h->highest_lun)
-       {
+       if (logvol == h->highest_lun) {
                /* if so, find the new hightest lun */
                int i, newhighest =-1;
-               for(i=0; i<h->highest_lun; i++)
-               {
+               for(i=0; i<h->highest_lun; i++) {
                        /* if the disk has size > 0, it is available */
-                       if (h->gendisk.part[i << gdev->minor_shift].nr_sects)
+                       if (h->drv[i].nr_blocks)
                                newhighest = i;
                }
                h->highest_lun = newhighest;
                                
        }
        --h->num_luns;
-       gdev->nr_real = h->highest_lun+1; 
        /* zero out the disk size info */ 
        h->drv[logvol].nr_blocks = 0;
        h->drv[logvol].block_size = 0;
@@ -1065,11 +1015,11 @@ case CMD_HARDWARE_ERR:
         return(return_status);
 
 }
-static int register_new_disk(kdev_t dev, int ctlr)
+static int register_new_disk(int ctlr)
 {
-        struct gendisk *gdev = &(hba[ctlr]->gendisk);
+        struct gendisk *disk;
         ctlr_info_t  *h = hba[ctlr];
-        int start, max_p, i;
+        int i;
        int num_luns;
        int logvol;
        int new_lun_found = 0;
@@ -1084,7 +1034,6 @@ static int register_new_disk(kdev_t dev, int ctlr)
        __u32 lunid = 0;
        unsigned int block_size;
        unsigned int total_size;
-       kdev_t kdev;
 
         if (!capable(CAP_SYS_RAWIO))
                 return -EPERM;
@@ -1292,15 +1241,16 @@ static int register_new_disk(kdev_t dev, int ctlr)
                        hba[ctlr]->drv[logvol].sectors,
                        hba[ctlr]->drv[logvol].cylinders);
        hba[ctlr]->drv[logvol].usage_count = 0;
-       max_p = 1 << gdev->minor_shift;
-        start = logvol<< gdev->minor_shift;
-       kdev = mk_kdev(MAJOR_NR + ctlr, logvol<< gdev->minor_shift);
-
-       wipe_partitions(kdev);
        ++hba[ctlr]->num_luns;
-       gdev->nr_real = hba[ctlr]->highest_lun + 1;
        /* setup partitions per disk */
-       grok_partitions(kdev, hba[ctlr]->drv[logvol].nr_blocks);
+        disk = &hba[ctlr]->gendisk[logvol];
+       disk->major_name = hba[ctlr]->names + 12 * logvol;
+       add_gendisk(disk);
+       register_disk(disk,
+                     mk_kdev(disk->major, disk->first_minor),
+                     1<<disk->minor_shift,
+                     disk->fops,
+                     hba[ctlr]->drv[logvol].nr_blocks);
        
        kfree(ld_buff);
        kfree(size_buff);
@@ -2488,22 +2438,28 @@ static int __init cciss_init_one(struct pci_dev *pdev,
 
        blk_queue_max_sectors(q, 512);
 
-       /* Fill in the gendisk data */  
-       hba[i]->gendisk.major = MAJOR_NR + i;
-       hba[i]->gendisk.major_name = "cciss";
-       hba[i]->gendisk.minor_shift = NWD_SHIFT;
-       hba[i]->gendisk.part = hba[i]->hd;
-       hba[i]->gendisk.nr_real = hba[i]->highest_lun+1;  
 
-       /* Get on the disk list */ 
-       add_gendisk(&(hba[i]->gendisk));
+       for(j=0; j<NWD; j++) {
+               drive_info_struct *drv = &(hba[i]->drv[j]);
+               struct gendisk *disk = hba[i]->gendisk + j;
 
-       cciss_geninit(i);
-       for(j=0; j<NWD; j++)
-               register_disk(&(hba[i]->gendisk),
-                       mk_kdev(MAJOR_NR+i, j <<4), 
-                       MAX_PART, &cciss_fops, 
-                       hba[i]->drv[j].nr_blocks);
+               sprintf(hba[i]->names + 12 * j, "cciss/c%dd%d", i, j);
+               disk->major = MAJOR_NR + i;
+               disk->first_minor = j << NWD_SHIFT;
+               disk->major_name = NULL;
+               disk->minor_shift = NWD_SHIFT;
+               disk->part = hba[i]->hd + (j << NWD_SHIFT);
+               disk->nr_real = 1;
+               if( !(drv->nr_blocks))
+                       continue;
+               (BLK_DEFAULT_QUEUE(MAJOR_NR + i))->hardsect_size = drv->block_size;
+               disk->major_name = hba[i]->names + 12 * j;
+               add_gendisk(disk);
+               register_disk(disk,
+                             mk_kdev(disk->major, disk->first_minor),
+                             1<<disk->minor_shift, disk->fops,
+                             drv->nr_blocks);
+       }
 
        cciss_register_scsi(i, 1);  /* hook ourself into SCSI subsystem */
 
@@ -2513,7 +2469,7 @@ static int __init cciss_init_one(struct pci_dev *pdev,
 static void __devexit cciss_remove_one (struct pci_dev *pdev)
 {
        ctlr_info_t *tmp_ptr;
-       int i;
+       int i, j;
        char flush_buf[4];
        int return_code; 
 
@@ -2548,7 +2504,13 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
        remove_proc_entry(hba[i]->devname, proc_cciss); 
        
        /* remove it from the disk list */
-       del_gendisk(&(hba[i]->gendisk));
+       for (j = 0; j < NWD; j++) {
+               struct gendisk *disk = &hba[i]->gendisk[j];
+               if (disk->major_name) {
+                       del_gendisk(disk);
+                       disk->major_name = NULL;
+               }
+       }
 
        pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
                            hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
index 3179b51e56bfe60055651b8ca9967fc91197cccd..7192717a23fe08452670c39ca08b6a3bbfc0df8c 100644 (file)
@@ -81,7 +81,8 @@ struct ctlr_info
        int                     nr_frees; 
 
        // Disk structures we need to pass back
-       struct gendisk   gendisk;
+       struct gendisk   gendisk[NWD];
+       char names[12 * NWD];
           // indexed by minor numbers
        struct hd_struct hd[256];
        int              sizes[256];
index b5e79170bb2920b05bc59215e9332b287bfa9732..b9dfeb902e3ca6f3295dc2b2f629f38758a19b9d 100644 (file)
@@ -1483,6 +1483,7 @@ static int revalidate_allvol(kdev_t dev)
                if (!drv->nr_blks)
                        continue;
                (BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size;
+               disk->major_name = ida_names + (ctlr*NWD+i)*10;
                add_gendisk(disk);
                register_disk(disk,
                              mk_kdev(disk->major,disk->first_minor),
index cc5b412bac28d728908e644cd18322d008d2c220..4cab6f920e2b43a1ef577c00acb3ba95d5d4c23c 100644 (file)
@@ -137,11 +137,6 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
                        sprintf(s, "%s%d", "md", unit);
                        maj = s;
                        break;
-               case COMPAQ_CISS_MAJOR ... COMPAQ_CISS_MAJOR+7:
-                       sprintf(s, "cciss/c%dd%d",
-                               hd->major - COMPAQ_CISS_MAJOR, unit);
-                       maj = s;
-                       break;
                case ATARAID_MAJOR:
                        sprintf(s, "ataraid/d%d", unit);
                        maj = s;