One more approach to fs/partitions/ibm.c

Pete Zaitcev (zaitcev@redhat.com)
Tue, 23 Apr 2002 20:57:49 -0400


Al,

the failure of our experiment with check_partitions that did
do_open keeps nagging me like a bad tooth. Here's another
way to word around that problem. Observe that we do have
one backdoor already, so I am not making it any worse than
it was. What do you think?

-- Pete

diff -ur -X dontdiff linux-2.4.19-pre7/drivers/s390/block/dasd.c linux-2.4.19-pre7-390/drivers/s390/block/dasd.c
--- linux-2.4.19-pre7/drivers/s390/block/dasd.c Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre7-390/drivers/s390/block/dasd.c Tue Apr 23 17:13:57 2002
@@ -4187,6 +4187,7 @@
goto failed;
}
genhd_dasd_name = dasd_device_name;
+ genhd_dasd_ioctl = dasd_ioctl;

if (dasd_autodetect) { /* update device range to all devices */
for (irq = get_irq_first (); irq != -ENODEV;
@@ -4309,7 +4310,9 @@
printk (KERN_INFO PRINTK_HEADER
"De-Registered ECKD discipline successfully\n");
#endif /* CONFIG_DASD_ECKD_BUILTIN */
-
+
+ genhd_dasd_name = NULL;
+ genhd_dasd_ioctl = NULL;
dasd_proc_cleanup ();

list_for_each_safe (l, n, &dasd_major_info[0].list) {
diff -ur -X dontdiff linux-2.4.19-pre7/drivers/s390/block/dasd_int.h linux-2.4.19-pre7-390/drivers/s390/block/dasd_int.h
--- linux-2.4.19-pre7/drivers/s390/block/dasd_int.h Tue Apr 23 17:08:36 2002
+++ linux-2.4.19-pre7-390/drivers/s390/block/dasd_int.h Tue Apr 23 17:21:31 2002
@@ -367,6 +367,8 @@

extern debug_info_t *dasd_debug_area;
extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *);
+extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp,
+ unsigned int no, unsigned long data);

#endif /* __KERNEL__ */

diff -ur -X dontdiff linux-2.4.19-pre7/fs/partitions/Makefile linux-2.4.19-pre7-390/fs/partitions/Makefile
--- linux-2.4.19-pre7/fs/partitions/Makefile Tue Apr 23 17:08:48 2002
+++ linux-2.4.19-pre7-390/fs/partitions/Makefile Tue Apr 23 17:14:26 2002
@@ -9,7 +9,7 @@

O_TARGET := partitions.o

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

obj-y := check.o

diff -ur -X dontdiff linux-2.4.19-pre7/fs/partitions/check.c linux-2.4.19-pre7-390/fs/partitions/check.c
--- linux-2.4.19-pre7/fs/partitions/check.c Mon Feb 25 11:38:09 2002
+++ linux-2.4.19-pre7-390/fs/partitions/check.c Tue Apr 23 17:13:57 2002
@@ -77,13 +77,17 @@

/*
* This is ucking fugly but its probably the best thing for 2.4.x
- * Take it as a clear reminder than we should put the device name
+ * Take it as a clear reminder that: 1) we should put the device name
* generation in the object kdev_t points to in 2.5.
+ * and 2) ioctls better work on half-opened devices.
*/

#ifdef CONFIG_ARCH_S390
int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL;
+int (*genhd_dasd_ioctl)(struct inode *inp, struct file *filp,
+ unsigned int no, unsigned long data);
EXPORT_SYMBOL(genhd_dasd_name);
+EXPORT_SYMBOL(genhd_dasd_ioctl);
#endif

/*
diff -ur -X dontdiff linux-2.4.19-pre7/fs/partitions/ibm.c linux-2.4.19-pre7-390/fs/partitions/ibm.c
--- linux-2.4.19-pre7/fs/partitions/ibm.c Mon Oct 1 20:03:26 2001
+++ linux-2.4.19-pre7-390/fs/partitions/ibm.c Tue Apr 23 17:40:52 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
@@ -92,119 +52,187 @@
ptr->b;
}

+/*
+ * We used to use ioctl_by_bdev in early 2.4, but it broke
+ * between 2.4.9 and 2.4.18 somewhere.
+ */
+extern int (*genhd_dasd_ioctl)(struct inode *inp, struct file *filp,
+ unsigned int no, unsigned long data);
+
+static int
+ibm_ioctl_unopened(struct block_device *bdev, unsigned cmd, unsigned long arg)
+{
+ int res;
+ mm_segment_t old_fs = get_fs();
+
+ if (genhd_dasd_ioctl == NULL)
+ return -ENODEV;
+#if 0
+ lock_kernel();
+ if (bd_ops->owner)
+ __MOD_INC_USE_COUNT(bdev->bd_op->owner);
+ unlock_kernel();
+#endif
+ set_fs(KERNEL_DS);
+ res = (*genhd_dasd_ioctl)(bdev->bd_inode, NULL, cmd, arg);
+ set_fs(old_fs);
+#if 0
+ lock_kernel();
+ if (bd_ops->owner)
+ __MOD_DEV_USE_COUNT(bd_ops->owner);
+ unlock_kernel();
+#endif
+ return res;
+}
+
+/*
+ */
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, (unsig