linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / s390 / block / dasd_ioctl.c
index f1892ba..fafeeae 100644 (file)
@@ -116,6 +116,18 @@ dasd_ioctl(struct inode *inp, struct file *filp,
        return -EINVAL;
 }
 
+long
+dasd_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       int rval;
+
+       lock_kernel();
+       rval = dasd_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+       unlock_kernel();
+
+       return (rval == -EINVAL) ? -ENOIOCTLCMD : rval;
+}
+
 static int
 dasd_ioctl_api_version(struct block_device *bdev, int no, long args)
 {
@@ -304,7 +316,8 @@ dasd_ioctl_format(struct block_device *bdev, int no, long args)
 
        if (device == NULL)
                return -ENODEV;
-       if (test_bit(DASD_FLAG_RO, &device->flags))
+
+       if (device->features & DASD_FEATURE_READONLY)
                return -EROFS;
        if (copy_from_user(&fdata, (void __user *) args,
                           sizeof (struct format_data_t)))
@@ -349,6 +362,9 @@ dasd_ioctl_read_profile(struct block_device *bdev, int no, long args)
        if (device == NULL)
                return -ENODEV;
 
+       if (dasd_profile_level == DASD_PROFILE_OFF)
+               return -EIO;
+
        if (copy_to_user((long __user *) args, (long *) &device->profile,
                         sizeof (struct dasd_profile_info_t)))
                return -EFAULT;
@@ -405,8 +421,15 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
        dasd_info->cu_model = cdev->id.cu_model;
        dasd_info->dev_type = cdev->id.dev_type;
        dasd_info->dev_model = cdev->id.dev_model;
-       dasd_info->open_count = atomic_read(&device->open_count);
        dasd_info->status = device->state;
+       /*
+        * The open_count is increased for every opener, that includes
+        * the blkdev_get in dasd_scan_partitions.
+        * This must be hidden from user-space.
+        */
+       dasd_info->open_count = atomic_read(&device->open_count);
+       if (!device->bdev)
+               dasd_info->open_count++;
        
        /*
         * check if device is really formatted
@@ -415,9 +438,9 @@ dasd_ioctl_information(struct block_device *bdev, int no, long args)
        if ((device->state < DASD_STATE_READY) ||
            (dasd_check_blocksize(device->bp_block)))
                dasd_info->format = DASD_FORMAT_NONE;
-       
-       dasd_info->features |= test_bit(DASD_FLAG_RO, &device->flags) ?
-               DASD_FEATURE_READONLY : DASD_FEATURE_DEFAULT;
+
+       dasd_info->features |=
+               ((device->features & DASD_FEATURE_READONLY) != 0);
 
        if (device->discipline)
                memcpy(dasd_info->type, device->discipline->name, 4);
@@ -460,7 +483,7 @@ static int
 dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
 {
        struct dasd_device *device;
-       int intval;
+       int intval, rc;
 
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
@@ -472,39 +495,11 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args)
        device =  bdev->bd_disk->private_data;
        if (device == NULL)
                return -ENODEV;
-       set_disk_ro(bdev->bd_disk, intval);
-       if (intval)
-               set_bit(DASD_FLAG_RO, &device->flags);
-       else
-               clear_bit(DASD_FLAG_RO, &device->flags);
-       return 0;
-}
 
-/*
- * Return disk geometry.
- */
-static int
-dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)
-{
-       struct hd_geometry geo = { 0, };
-       struct dasd_device *device;
-
-       device =  bdev->bd_disk->private_data;
-       if (device == NULL)
-               return -ENODEV;
-
-       if (device == NULL || device->discipline == NULL ||
-           device->discipline->fill_geometry == NULL)
-               return -EINVAL;
-
-       geo = (struct hd_geometry) {};
-       device->discipline->fill_geometry(device, &geo);
-       geo.start = get_start_sect(bdev) >> device->s2b_shift;
-       if (copy_to_user((struct hd_geometry __user *) args, &geo,
-                        sizeof (struct hd_geometry)))
-               return -EFAULT;
+       set_disk_ro(bdev->bd_disk, intval);
+       rc = dasd_set_feature(device->cdev, DASD_FEATURE_READONLY, intval);
 
-       return 0;
+       return rc;
 }
 
 /*
@@ -523,7 +518,6 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
        { BIODASDPRRST, dasd_ioctl_reset_profile },
        { BLKROSET, dasd_ioctl_set_ro },
        { DASDAPIVER, dasd_ioctl_api_version },
-       { HDIO_GETGEO, dasd_ioctl_getgeo },
        { -1, NULL }
 };