patch-2.4.8 linux/fs/partitions/ibm.c

Next file: linux/fs/partitions/ldm.c
Previous file: linux/fs/partitions/check.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.7/linux/fs/partitions/ibm.c linux/fs/partitions/ibm.c
@@ -10,14 +10,14 @@
  * 02/13/00 VTOC partition support added
  */
 
-#include <linux/module.h>
+#include <linux/config.h>
 #include <linux/fs.h>
 #include <linux/genhd.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/blk.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/hdreg.h>
 #include <linux/ioctl.h>
 #include <linux/version.h>
@@ -29,14 +29,6 @@
 #include "check.h"
 #include <asm/vtoc.h>
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
-/* We hook in when DASD is a module... */
-int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL;
-int (*genhd_dasd_fillgeo)(int,struct hd_geometry *) = NULL;
-EXPORT_SYMBOL(genhd_dasd_fillgeo);
-EXPORT_SYMBOL(genhd_dasd_name);
-#endif /* LINUX_IS_24 */
-
 typedef enum {
   ibm_partition_lnx1 = 0,
   ibm_partition_vol1 = 1,
@@ -50,6 +42,73 @@
 			     [ibm_partition_none] = "(nonl)"
 };
 
+static int
+get_drive_geometry(int kdev,struct hd_geometry *geo) 
+{
+	int rc = 0;
+	mm_segment_t old_fs;
+	struct file *filp;
+	struct inode *inode;
+        /* find out offset of volume label (partn table) */
+        filp = (struct file *)kmalloc (sizeof(struct file),GFP_KERNEL);
+        if ( filp == NULL ) {
+                printk (KERN_WARNING __FILE__ " ibm_partition: kmalloc failed fo
+r filp\n");
+                return -ENOMEM;
+        }
+        memset(filp,0,sizeof(struct file));
+        filp ->f_mode = 1; /* read only */
+        inode = get_empty_inode();
+	if ( inode == NULL )
+		return -ENOMEM;
+        inode -> i_rdev = kdev;
+	inode -> i_bdev = bdget(kdev_t_to_nr(kdev));
+	rc = blkdev_open(inode,filp);
+        if ( rc == 0 ) {
+		old_fs=get_fs();
+		set_fs(KERNEL_DS);
+		rc = inode-> i_bdev -> bd_op->ioctl (inode, filp, HDIO_GETGEO, 
+						     (unsigned long)(geo))
+			;
+		set_fs(old_fs);
+	}
+	blkdev_put(inode->i_bdev,BDEV_FILE);
+	return rc;
+}
+
+static int
+get_drive_info(int kdev,dasd_information_t *info) 
+{
+	int rc = 0;
+	mm_segment_t old_fs;
+	struct file *filp;
+	struct inode *inode;
+        /* find out offset of volume label (partn table) */
+        filp = (struct file *)kmalloc (sizeof(struct file),GFP_KERNEL);
+        if ( filp == NULL ) {
+                printk (KERN_WARNING __FILE__ " ibm_partition: kmalloc failed fo
+r filp\n");
+                return -ENOMEM;
+        }
+        memset(filp,0,sizeof(struct file));
+        filp ->f_mode = 1; /* read only */
+        inode = get_empty_inode();
+	if ( inode == NULL )
+		return -ENOMEM;
+        inode -> i_rdev = kdev;
+	inode -> i_bdev = bdget(kdev_t_to_nr(kdev));
+        rc = blkdev_open(inode,filp);
+        if ( rc == 0 ) {
+		old_fs=get_fs();
+		set_fs(KERNEL_DS);
+		rc = inode-> i_bdev -> bd_op->ioctl (inode, filp, BIODASDINFO, 
+						     (unsigned long)(info));
+		set_fs(old_fs);
+	}
+	blkdev_put(inode->i_bdev,BDEV_FILE);
+	return rc;
+}
+
 static ibm_partition_t
 get_partition_type ( char * type )
 {
@@ -110,38 +169,52 @@
 	ibm_partition_t partition_type;
 	char type[5] = {0,};
 	char name[7] = {0,};
-	struct hd_geometry geo;
+	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;
 
 	if ( first_sector != 0 ) {
 		BUG();
 	}
-	if ( !genhd_dasd_fillgeo ) {
+	info = (struct dasd_information_t *)kmalloc(sizeof(dasd_information_t),
+						    GFP_KERNEL);
+	if ( info == NULL )
+		return 0;
+	if (get_drive_info (dev,info)) 
+		return 0;
+	geo = (struct hd_geometry *)kmalloc(sizeof(struct hd_geometry),
+					    GFP_KERNEL);
+	if ( geo == NULL )
+		return 0;
+	if (get_drive_geometry (dev,geo)) 
 		return 0;
-	}
-	genhd_dasd_fillgeo(dev,&geo);
 	blocksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
 	if ( blocksize <= 0 ) {
 		return 0;
 	}
-
+	
 	set_blocksize(dev, blocksize);  /* OUCH !! */
-	if ( ( bh = bread( dev, geo.start, blocksize) ) != NULL ) {
+	if ( ( bh = bread( dev, info->label_block, blocksize) ) != NULL ) {
 		strncpy ( type,bh -> b_data + 0, 4);
-		strncpy ( name,bh -> b_data + 4, 6);
+		if ((!info->FBA_layout) && (!strcmp(info->type,"ECKD"))) {
+		        
+		        strncpy ( name,bh -> b_data + 8, 6);
+		} else {
+		        strncpy ( name,bh -> b_data + 4, 6);		  
+		}
 		memcpy (&vlabel, bh->b_data, sizeof(volume_label_t));
         } else {
 		return 0;
 	}
 	EBCASC(type,4);
 	EBCASC(name,6);
-
+	
 	partition_type = get_partition_type(type);
-	printk ( "%6s/%6s:",part_names[partition_type],name);
+	printk ( "%4s/%8s:",part_names[partition_type],name);
 	switch ( partition_type ) {
 	case ibm_partition_cms1:
 		if (* (((long *)bh->b_data) + 13) != 0) {
@@ -152,38 +225,37 @@
 			size = (label[7]-1)*(blocksize>>9); 
 			printk ("(MDSK)");
 		} else {
-			offset = (geo.start + 1);
+			offset = (info->label_block + 1);
 			size = hd -> sizes[MINOR(dev)]<<1;
 		}
-		two_partitions( hd, MINOR(dev), blocksize, 
-				offset, size);
+		two_partitions( hd, MINOR(dev), blocksize, offset, size);
 		break;
 	case ibm_partition_lnx1: 
 	case ibm_partition_none:
-		offset = (geo.start + 1);
+		offset = (info->label_block + 1);
 		size = hd -> sizes[MINOR(dev)]<<1;
-		two_partitions( hd, MINOR(dev), blocksize, 
-				offset, size);
+		two_partitions( hd, MINOR(dev), blocksize, offset, size);
 		break;
-	case ibm_partition_vol1:
+	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;
+		blk = cchhb2blk(&vlabel.vtoc, geo) + 1;
 		if ((buf = bread( dev, blk, blocksize)) != NULL) {
 		        memcpy (&f1, buf->b_data, sizeof(format1_label_t));
 			bforget(buf);
 		}
-
+		
 		while (f1.DS1FMTID == _ascebc['1']) {
-		        offset = cchh2blk(&f1.DS1EXT1.llimit, &geo);
-			psize  = cchh2blk(&f1.DS1EXT1.ulimit, &geo) - 
-				offset + 1;
+		        offset = cchh2blk(&f1.DS1EXT1.llimit, geo);
+			psize  = cchh2blk(&f1.DS1EXT1.ulimit, geo) - 
+				offset + geo->sectors;
 			
 			counter++;
 			add_gd_partition(hd, MINOR(dev) + counter, 
-					  offset * (blocksize >> 9),
-					  psize * (blocksize >> 9));
+					 offset * (blocksize >> 9),
+					 psize * (blocksize >> 9));
 			
 			blk++;
 			if ((buf = bread( dev, blk, blocksize)) != NULL) {
@@ -197,9 +269,8 @@
 		add_gd_partition( hd, MINOR(dev), 0, 0);
 		add_gd_partition( hd, MINOR(dev) + 1, 0, 0);
 	}
-
+	
 	printk ( "\n" );
 	bforget(bh);
 	return 1;
 }
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)