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: Christoph Hellwig <hch@lst.de> Signed-off-by: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
9353848c65
commit
26d7e28e38
|
@ -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 @@
|
||||||
#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,
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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 @@ out_nolab:
|
||||||
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 @@
|
||||||
#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,
|
||||||
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);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* 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
|
Loading…
Reference in New Issue