Commit 26d7e28e authored by Stefan Haberland's avatar Stefan Haberland Committed by Jens Axboe

s390/dasd: remove ioctl_by_bdev calls

The IBM partition parser requires device type specific information only
available to the DASD driver to correctly register partitions. The
current approach of using ioctl_by_bdev with a fake user space pointer
is discouraged.

Fix this by replacing IOCTL calls with direct in-kernel function calls.
Suggested-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarStefan Haberland <sth@linux.ibm.com>
Reviewed-by: default avatarJan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 9353848c
...@@ -14628,6 +14628,7 @@ S: Supported ...@@ -14628,6 +14628,7 @@ S: Supported
W: http://www.ibm.com/developerworks/linux/linux390/ W: http://www.ibm.com/developerworks/linux/linux390/
F: block/partitions/ibm.c F: block/partitions/ibm.c
F: drivers/s390/block/dasd* F: drivers/s390/block/dasd*
F: include/linux/dasd_mod.h
S390 IOMMU (PCI) S390 IOMMU (PCI)
M: Gerald Schaefer <gerald.schaefer@de.ibm.com> M: Gerald Schaefer <gerald.schaefer@de.ibm.com>
......
...@@ -13,10 +13,11 @@ ...@@ -13,10 +13,11 @@
#include <asm/ebcdic.h> #include <asm/ebcdic.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/vtoc.h> #include <asm/vtoc.h>
#include <linux/module.h>
#include <linux/dasd_mod.h>
#include "check.h" #include "check.h"
union label_t { union label_t {
struct vtoc_volume_label_cdl vol; struct vtoc_volume_label_cdl vol;
struct vtoc_volume_label_ldl lnx; struct vtoc_volume_label_ldl lnx;
...@@ -288,7 +289,9 @@ static int find_cms1_partitions(struct parsed_partitions *state, ...@@ -288,7 +289,9 @@ static int find_cms1_partitions(struct parsed_partitions *state,
*/ */
int ibm_partition(struct parsed_partitions *state) int ibm_partition(struct parsed_partitions *state)
{ {
int (*fn)(struct gendisk *disk, dasd_information2_t *info);
struct block_device *bdev = state->bdev; struct block_device *bdev = state->bdev;
struct gendisk *disk = bdev->bd_disk;
int blocksize, res; int blocksize, res;
loff_t i_size, offset, size; loff_t i_size, offset, size;
dasd_information2_t *info; dasd_information2_t *info;
...@@ -299,24 +302,31 @@ int ibm_partition(struct parsed_partitions *state) ...@@ -299,24 +302,31 @@ int ibm_partition(struct parsed_partitions *state)
union label_t *label; union label_t *label;
res = 0; res = 0;
if (!disk->fops->getgeo)
goto out_exit;
fn = symbol_get(dasd_biodasdinfo);
if (!fn)
goto out_exit;
blocksize = bdev_logical_block_size(bdev); blocksize = bdev_logical_block_size(bdev);
if (blocksize <= 0) if (blocksize <= 0)
goto out_exit; goto out_symbol;
i_size = i_size_read(bdev->bd_inode); i_size = i_size_read(bdev->bd_inode);
if (i_size == 0) if (i_size == 0)
goto out_exit; goto out_symbol;
info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL);
if (info == NULL) if (info == NULL)
goto out_exit; goto out_symbol;
geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL);
if (geo == NULL) if (geo == NULL)
goto out_nogeo; goto out_nogeo;
label = kmalloc(sizeof(union label_t), GFP_KERNEL); label = kmalloc(sizeof(union label_t), GFP_KERNEL);
if (label == NULL) if (label == NULL)
goto out_nolab; goto out_nolab;
if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) /* set start if not filled by getgeo function e.g. virtblk */
geo->start = get_start_sect(bdev);
if (disk->fops->getgeo(bdev, geo))
goto out_freeall; goto out_freeall;
if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0) { if (fn(disk, info)) {
kfree(info); kfree(info);
info = NULL; info = NULL;
} }
...@@ -359,6 +369,8 @@ int ibm_partition(struct parsed_partitions *state) ...@@ -359,6 +369,8 @@ int ibm_partition(struct parsed_partitions *state)
kfree(geo); kfree(geo);
out_nogeo: out_nogeo:
kfree(info); kfree(info);
out_symbol:
symbol_put(dasd_biodasdinfo);
out_exit: out_exit:
return res; return res;
} }
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <asm/schid.h> #include <asm/schid.h>
#include <asm/cmb.h> #include <asm/cmb.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/dasd_mod.h>
/* This is ugly... */ /* This is ugly... */
#define PRINTK_HEADER "dasd_ioctl:" #define PRINTK_HEADER "dasd_ioctl:"
...@@ -664,3 +665,36 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -664,3 +665,36 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode,
dasd_put_device(base); dasd_put_device(base);
return rc; return rc;
} }
/**
* dasd_biodasdinfo() - fill out the dasd information structure
* @disk [in]: pointer to gendisk structure that references a DASD
* @info [out]: pointer to the dasd_information2_t structure
*
* Provide access to DASD specific information.
* The gendisk structure is checked if it belongs to the DASD driver by
* comparing the gendisk->fops pointer.
* If it does not belong to the DASD driver -EINVAL is returned.
* Otherwise the provided dasd_information2_t structure is filled out.
*
* Returns:
* %0 on success and a negative error value on failure.
*/
int dasd_biodasdinfo(struct gendisk *disk, struct dasd_information2_t *info)
{
struct dasd_device *base;
int error;
if (disk->fops != &dasd_device_operations)
return -EINVAL;
base = dasd_device_from_gendisk(disk);
if (!base)
return -ENODEV;
error = __dasd_ioctl_information(base->block, info);
dasd_put_device(base);
return error;
}
/* export that symbol_get in partition detection is possible */
EXPORT_SYMBOL_GPL(dasd_biodasdinfo);
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DASD_MOD_H
#define DASD_MOD_H
#include <asm/dasd.h>
extern int dasd_biodasdinfo(struct gendisk *disk, dasd_information2_t *info);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment