2.4.9-pre3 s390 patch for partition code

2.4.9-pre3 s390 patch for partition code

Post by Martin Schwidefsk » Tue, 19 Mar 2002 23:10:14



Hi Pete,

Quote:>This is a patch that I extracted from a tarball received last week.
>It is said to be failed by Marcelo for 2.4.18, but something is
>need to fix this.

Definitly.

Quote:>To that end, I considered pulling ioctls and replacing them with
>reads, but it is too much work. So, I talked to Al Viro
>and secured his help to have ioctl_by_bdev working at check_part()
>time with a proper fix. Before it is available, I suggest we
>push the fs/block_dev.c change into 2.4.19-preX as a stop-gap.

Even worse, you can't replace the ioctls by reads. You need two
pieces of information 1) the number of the label block which is
different for the three formats CMS1, VOL1, and LNX1 and 2) the
geometry of the device to do the calculations for the VOL1 format.
Both informations are only known to the dasd driver. The only
clean way to get them is to "ask" the dasd driver using an ioctl.
The try to be smarter then the dasd driver and do you own reads
to find out what is needed is imho asking for trouble.

Quote:>The fs/partitions/ibm.c change from the tarball was useful, but
>I *STRONGLY* disagree with putting so much *on the stack.
>It may explain why we have so much trouble with stacks on s390:
>they are simply overused. I changed the code to allocate structures
>properly. This should go in regartless of Al's work on ioctl.

I just checked. Its 744 bytes for ibm_partition(). Probably a bit
much ... so you version makes sense.

blue skies,
   Martin

Linux/390 Design & Development, IBM Deutschland Entwicklung GmbH
Sch?naicherstr. 220, D-71032 B?blingen, Telefon: 49 - (0)7031 - 16-2247

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://www.veryComputer.com/
Please read the FAQ at  http://www.veryComputer.com/

 
 
 

2.4.9-pre3 s390 patch for partition code

Post by Pete Zaitce » Sun, 24 Mar 2002 07:30:11


> From: "Martin Schwidefsky" <schwidef...@de.ibm.com>
> Date: Fri, 22 Mar 2002 09:08:59 +0100
> I have sent Marcelo the partition code with my second to last update.
> I certainly can resend it but I think Marcelo is waiting to for explicit
> ok from Al Viro before he will accept this patch. Marcelo, is this
> correct?

OK, there was a little change here. Al came good on his promise
to fix the ioctl_by_bdev properly. I tested his fix both on
s390 and i386, and it seems to work. Do you guys think it may
be worth adding for upcoming 2.4.19?

The code of the change is a move of a call to get_blkops outside
of the semaphore, so check_partition can do blkdev_get->do_open.

-- Pete

diff -ur -X dontdiff linux-2.4.19-pre4/fs/block_dev.c linux-2.4.19-pre4-390/fs/block_dev.c
--- linux-2.4.19-pre4/fs/block_dev.c    Mon Feb 25 11:38:08 2002
+++ linux-2.4.19-pre4-390/fs/block_dev.c        Fri Mar 22 11:47:34 2002
@@ -541,34 +541,44 @@

 static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
 {
-       int ret = -ENXIO;
+       int ret;
        kdev_t dev = to_kdev_t(bdev->bd_dev);
+       struct block_device_operations *bdops;
+
+       lock_kernel();
+       bdops = bdev->bd_op;
+       if (!bdops)
+               bdops = get_blkfops(MAJOR(dev));
+       if (bdops && bdops->owner)
+               __MOD_INC_USE_COUNT(bdops->owner);
+       unlock_kernel();
+
+       if (!bdops) {
+               bdput(bdev);
+               return -ENXIO;
+       }

        down(&bdev->bd_sem);
        lock_kernel();
-       if (!bdev->bd_op)
-               bdev->bd_op = get_blkfops(MAJOR(dev));
-       if (bdev->bd_op) {
-               ret = 0;
-               if (bdev->bd_op->owner)
-                       __MOD_INC_USE_COUNT(bdev->bd_op->owner);
-               if (bdev->bd_op->open)
-                       ret = bdev->bd_op->open(inode, file);
-               if (!ret) {
-                       bdev->bd_openers++;
-                       bdev->bd_inode->i_size = blkdev_size(dev);
-                       bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
-               } else {
-                       if (bdev->bd_op->owner)
-                               __MOD_DEC_USE_COUNT(bdev->bd_op->owner);
-                       if (!bdev->bd_openers)
-                               bdev->bd_op = NULL;
-               }
+       ret = 0;
+       bdev->bd_op = bdops;
+       if (bdops->open)
+               ret = bdops->open(inode, file);
+       if (!ret) {
+               bdev->bd_openers++;
+               bdev->bd_inode->i_size = blkdev_size(dev);
+               bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
+       } else {
+               if (!bdev->bd_openers)
+                       bdev->bd_op = NULL;
        }
        unlock_kernel();
        up(&bdev->bd_sem);
-       if (ret)
+       if (ret) {
+               if (bdops->owner)
+                       __MOD_DEC_USE_COUNT(bdops->owner);
                bdput(bdev);
+       }
        return ret;
 }

diff -ur -X dontdiff linux-2.4.19-pre4/fs/partitions/Makefile linux-2.4.19-pre4-390/fs/partitions/Makefile
--- linux-2.4.19-pre4/fs/partitions/Makefile    Thu Jul 26 16:30:04 2001
+++ linux-2.4.19-pre4-390/fs/partitions/Makefile        Thu Mar 21 18:23:15 2002
@@ -9,7 +9,7 @@

 O_TARGET := partitions.o

-export-objs := check.o ibm.o
+export-objs := check.o

 obj-y := check.o

diff -ur -X dontdiff linux-2.4.19-pre4/fs/partitions/check.c linux-2.4.19-pre4-390/fs/partitions/check.c
--- linux-2.4.19-pre4/fs/partitions/check.c     Mon Feb 25 11:38:09 2002
+++ linux-2.4.19-pre4-390/fs/partitions/check.c Fri Mar 22 11:41:28 2002
@@ -222,6 +222,7 @@
        unsigned long first_sector;
        struct block_device *bdev;
        char buf[64];
+       int res;
        int i;

        if (first_time)
@@ -246,10 +247,12 @@
        else
                printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
        bdev = bdget(kdev_t_to_nr(dev));
-       bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9;
-       bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev));
+       res = blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW);
+       if (res) {
+               printk(" unable to open\n");
+               goto setup_devfs;
+       }
        for (i = 0; check_part[i]; i++) {
-               int res;
                res = check_part[i](hd, bdev, first_sector, first_part_minor);
                if (res) {
                        if (res < 0 &&  warn_no_part)
@@ -257,12 +260,11 @@
                        goto setup_devfs;
                }
        }
-
        printk(" unknown partition table\n");
 setup_devfs:
        invalidate_bdev(bdev, 1);
        truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
-       bdput(bdev);
+       blkdev_put(bdev, BDEV_RAW);
        i = first_part_minor - 1;
        devfs_register_partitions (hd, i, hd->sizes ? 0 : 1);
 }
diff -ur -X dontdiff linux-2.4.19-pre4/fs/partitions/ibm.c linux-2.4.19-pre4-390/fs/partitions/ibm.c
--- linux-2.4.19-pre4/fs/partitions/ibm.c       Mon Oct  1 20:03:26 2001
+++ linux-2.4.19-pre4-390/fs/partitions/ibm.c   Thu Mar 21 18:23:15 2002
@@ -8,6 +8,7 @@
  * History of changes (starts July 2000)
  * 07/10/00 Fixed detection of CMS formatted disks    
  * 02/13/00 VTOC partition support added
+ * 12/27/01 fixed PL030593 (CMS reserved minidisk not detected on 64 bit)
  */

 #include <linux/config.h>
@@ -29,47 +30,6 @@
 #include "check.h"
 #include <asm/vtoc.h>

-typedef enum {
-  ibm_partition_lnx1 = 0,
-  ibm_partition_vol1 = 1,
-  ibm_partition_cms1 = 2,
-  ibm_partition_none = 3
-} ibm_partition_t;
-
-static char* part_names[] = {   [ibm_partition_lnx1] = "LNX1",
-                            [ibm_partition_vol1] = "VOL1",
-                            [ibm_partition_cms1] = "CMS1",
-                            [ibm_partition_none] = "(nonl)"
-};
-
-static ibm_partition_t
-get_partition_type ( char * type )
-{
-       int i;
-       for ( i = 0; i < 3; i ++) {
-               if ( ! strncmp (type,part_names[i],4) )
-                       break;
-       }
-        return i;
-}
-
-/*
- * add the two default partitions
- * - whole dasd
- * - whole dasd without "offset"
- */
-static inline void
-two_partitions(struct gendisk *hd,
-              int minor,
-              int blocksize,
-              int offset,
-              int size) {
-
-        add_gd_partition( hd, minor, 0, size);
-       add_gd_partition( hd, minor+1, offset*blocksize, size-offset*blocksize);
-}
-
-
 /*
  * compute the block number from a
  * cyl-cyl-head-head structure
@@ -94,117 +54,150 @@

 int
 ibm_partition(struct gendisk *hd, struct block_device *bdev,
-               unsigned long first_sector, int first_part_minor)
+             unsigned long first_sector, int first_part_minor)
 {
-       Sector sect, sect2;
-       unsigned char *data;
-       ibm_partition_t partition_type;
+       int blocksize, offset, size;
+       dasd_information_t *info;
+       struct hd_geometry *geo;
        char type[5] = {0,};
        char name[7] = {0,};
-       struct hd_geometry *geo;
-       int blocksize;
-       int offset=0, size=0, psize=0, counter=0;
-       unsigned int blk;
-       format1_label_t f1;
-       volume_label_t vlabel;
-       dasd_information_t *info;
-       kdev_t dev = to_kdev_t(bdev->bd_dev);
+       volume_label_t *vlabel;
+       unsigned char *data;
+       Sector sect;

        if ( first_sector != 0 )
                BUG();

-       info = (struct dasd_information_t *)kmalloc(sizeof(dasd_information_t),
-                                                   GFP_KERNEL);
-       if ( info == NULL )
-               return 0;
-       if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)(info)))
-               return 0;
-       geo = (struct hd_geometry *)kmalloc(sizeof(struct hd_geometry),
-                                           GFP_KERNEL);
-       if ( geo == NULL )
-               return 0;
-       if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo);
-               return 0;
-       blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
-       if ( blocksize <= 0 ) {
-               return 0;
-       }
-       blocksize >>= 9;
-      
-       data = read_dev_sector(bdev, inode->label_block*blocksize, &sect);
-       if (!data)
-               return 0;
-
+       if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
+               goto out_noinfo;
+       if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
+               goto out_nogeo;
+       if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
+               goto out_novlab;
+
+       if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long) info) != 0 ||
+           ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long) geo) != 0)
+               goto out_noioctl;
+
+       if ((blocksize = get_hardsect_size(to_kdev_t(bdev->bd_dev))) <= 0)
+               goto out_badsect;
+
+       /*
+        * Get volume label, extract name and type.
+        */
+       data = read_dev_sector(bdev, info->label_block*(blocksize/512), &sect);
+       if (data == NULL)
+               goto out_readerr;
        strncpy (type, data, 4);
-       if ((!info->FBA_layout) && (!strcmp(info->type,"ECKD"))) {
-               strncpy ( name, data + 8, 6);
-       } else {
-               strncpy ( name, data + 4, 6);
-       }
-       memcpy (&vlabel, data, sizeof(volume_label_t));
+       if ((!info->FBA_layout) && (!strcmp(info->type, "ECKD")))
+               strncpy(name, data + 8, 6);
+       else
+               strncpy(name, data + 4, 6);
+       memcpy (vlabel, data, sizeof(volume_label_t));
+       put_dev_sector(sect);
+
+       EBCASC(type, 4);
+       EBCASC(name, 6);

-       EBCASC(type,4);
-       EBCASC(name,6);
-      
-       partition_type = get_partition_type(type);
-       printk ( "%4s/%8s:",part_names[partition_type],name);
-       switch ( partition_type ) {
-       case ibm_partition_cms1:
-               if (* ((long *)data + 13) != 0) {
+       /*
+        * Three different types: CMS1, VOL1 and LNX1/unlabeled
+        */
+       if (strncmp(type, "CMS1", 4) == 0) {
+               /*
+                * VM style CMS1 labeled disk
+                */
+               int *label = (int *) data;
+
+               if (label[13] != 0) {
+                       printk("CMS1/%8s(MDSK):", name);
                        /* disk is reserved minidisk */
-                       long *label=(long*)data;
-                       blocksize = label[3]>>9;
+                       blocksize = label[3];
                        offset = label[13];
-                       size = (label[7]-1)*blocksize;
-                       printk ("(MDSK)");
+                       size = (label[7] - 1)*(blocksize >> 9);
                } else {
+                       printk("CMS1/%8s:", name);
                        offset = (info->label_block + 1);
-                       size = hd -> sizes[MINOR(dev)]<<1;
-               }
-               two_partitions( hd, MINOR(dev), blocksize, offset, size);
-               break;
-       case ibm_partition_lnx1:
-       case ibm_partition_none:
-               offset = (info->label_block + 1);
-               size = hd -> sizes[MINOR(dev)]<<1;
-               two_partitions( hd, MINOR(dev), blocksize, offset, size);
-               break;
-       case ibm_partition_vol1:
-               size = hd -> sizes[MINOR(dev)]<<1;
-               add_gd_partition(hd, MINOR(dev), 0, size);
-              
-               /* get block number and read then first format1 label */
-               blk = cchhb2blk(&vlabel.vtoc, geo) + 1;
-               data = read_dev_sector(bdev, blk * blocksize, &sect2);
-               if (data) {
-                       memcpy (&f1, data, sizeof(format1_label_t));
-                       put_dev_sector(sect2);
+                       size = hd->sizes[first_part_minor - 1] << 1;
                }
+               // add_gd_partition(hd, first_part_minor - 1, 0, size);
+               add_gd_partition(hd, first_part_minor,
+                                offset*(blocksize >> 9),
+                                size-offset*(blocksize >> 9));
+       } else if (strncmp(type, "VOL1", 4) == 0) {
+               /*
+                * New style VOL1 labeled disk
+                */
+               unsigned int blk;
+               int counter;
+
+               printk("VOL1/%8s:", name);
+               // add_gd_partition(hd, first_part_minor
...

read more »