Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Stefan Haberland and committed by
Jens Axboe
26d7e28e 9353848c

+62 -6
+1
MAINTAINERS
··· 14628 14628 W: http://www.ibm.com/developerworks/linux/linux390/ 14629 14629 F: block/partitions/ibm.c 14630 14630 F: drivers/s390/block/dasd* 14631 + F: include/linux/dasd_mod.h 14631 14632 14632 14633 S390 IOMMU (PCI) 14633 14634 M: Gerald Schaefer <gerald.schaefer@de.ibm.com>
+18 -6
block/partitions/ibm.c
··· 13 13 #include <asm/ebcdic.h> 14 14 #include <linux/uaccess.h> 15 15 #include <asm/vtoc.h> 16 + #include <linux/module.h> 17 + #include <linux/dasd_mod.h> 16 18 17 19 #include "check.h" 18 - 19 20 20 21 union label_t { 21 22 struct vtoc_volume_label_cdl vol; ··· 289 288 */ 290 289 int ibm_partition(struct parsed_partitions *state) 291 290 { 291 + int (*fn)(struct gendisk *disk, dasd_information2_t *info); 292 292 struct block_device *bdev = state->bdev; 293 + struct gendisk *disk = bdev->bd_disk; 293 294 int blocksize, res; 294 295 loff_t i_size, offset, size; 295 296 dasd_information2_t *info; ··· 302 299 union label_t *label; 303 300 304 301 res = 0; 302 + if (!disk->fops->getgeo) 303 + goto out_exit; 304 + fn = symbol_get(dasd_biodasdinfo); 305 + if (!fn) 306 + goto out_exit; 305 307 blocksize = bdev_logical_block_size(bdev); 306 308 if (blocksize <= 0) 307 - goto out_exit; 309 + goto out_symbol; 308 310 i_size = i_size_read(bdev->bd_inode); 309 311 if (i_size == 0) 310 - goto out_exit; 312 + goto out_symbol; 311 313 info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); 312 314 if (info == NULL) 313 - goto out_exit; 315 + goto out_symbol; 314 316 geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); 315 317 if (geo == NULL) 316 318 goto out_nogeo; 317 319 label = kmalloc(sizeof(union label_t), GFP_KERNEL); 318 320 if (label == NULL) 319 321 goto out_nolab; 320 - if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) 322 + /* set start if not filled by getgeo function e.g. virtblk */ 323 + geo->start = get_start_sect(bdev); 324 + if (disk->fops->getgeo(bdev, geo)) 321 325 goto out_freeall; 322 - if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0) { 326 + if (fn(disk, info)) { 323 327 kfree(info); 324 328 info = NULL; 325 329 } ··· 369 359 kfree(geo); 370 360 out_nogeo: 371 361 kfree(info); 362 + out_symbol: 363 + symbol_put(dasd_biodasdinfo); 372 364 out_exit: 373 365 return res; 374 366 }
+34
drivers/s390/block/dasd_ioctl.c
··· 22 22 #include <asm/schid.h> 23 23 #include <asm/cmb.h> 24 24 #include <linux/uaccess.h> 25 + #include <linux/dasd_mod.h> 25 26 26 27 /* This is ugly... */ 27 28 #define PRINTK_HEADER "dasd_ioctl:" ··· 665 664 dasd_put_device(base); 666 665 return rc; 667 666 } 667 + 668 + 669 + /** 670 + * dasd_biodasdinfo() - fill out the dasd information structure 671 + * @disk [in]: pointer to gendisk structure that references a DASD 672 + * @info [out]: pointer to the dasd_information2_t structure 673 + * 674 + * Provide access to DASD specific information. 675 + * The gendisk structure is checked if it belongs to the DASD driver by 676 + * comparing the gendisk->fops pointer. 677 + * If it does not belong to the DASD driver -EINVAL is returned. 678 + * Otherwise the provided dasd_information2_t structure is filled out. 679 + * 680 + * Returns: 681 + * %0 on success and a negative error value on failure. 682 + */ 683 + int dasd_biodasdinfo(struct gendisk *disk, struct dasd_information2_t *info) 684 + { 685 + struct dasd_device *base; 686 + int error; 687 + 688 + if (disk->fops != &dasd_device_operations) 689 + return -EINVAL; 690 + 691 + base = dasd_device_from_gendisk(disk); 692 + if (!base) 693 + return -ENODEV; 694 + error = __dasd_ioctl_information(base->block, info); 695 + dasd_put_device(base); 696 + return error; 697 + } 698 + /* export that symbol_get in partition detection is possible */ 699 + EXPORT_SYMBOL_GPL(dasd_biodasdinfo);
+9
include/linux/dasd_mod.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef DASD_MOD_H 3 + #define DASD_MOD_H 4 + 5 + #include <asm/dasd.h> 6 + 7 + extern int dasd_biodasdinfo(struct gendisk *disk, dasd_information2_t *info); 8 + 9 + #endif