mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	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/ | ||||
| F:	block/partitions/ibm.c | ||||
| F:	drivers/s390/block/dasd* | ||||
| F:	include/linux/dasd_mod.h | ||||
| 
 | ||||
| S390 IOMMU (PCI) | ||||
| M:	Gerald Schaefer <gerald.schaefer@de.ibm.com> | ||||
|  | ||||
| @ -13,10 +13,11 @@ | ||||
| #include <asm/ebcdic.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <asm/vtoc.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/dasd_mod.h> | ||||
| 
 | ||||
| #include "check.h" | ||||
| 
 | ||||
| 
 | ||||
| union label_t { | ||||
| 	struct vtoc_volume_label_cdl vol; | ||||
| 	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 (*fn)(struct gendisk *disk, dasd_information2_t *info); | ||||
| 	struct block_device *bdev = state->bdev; | ||||
| 	struct gendisk *disk = bdev->bd_disk; | ||||
| 	int blocksize, res; | ||||
| 	loff_t i_size, offset, size; | ||||
| 	dasd_information2_t *info; | ||||
| @ -299,24 +302,31 @@ int ibm_partition(struct parsed_partitions *state) | ||||
| 	union label_t *label; | ||||
| 
 | ||||
| 	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); | ||||
| 	if (blocksize <= 0) | ||||
| 		goto out_exit; | ||||
| 		goto out_symbol; | ||||
| 	i_size = i_size_read(bdev->bd_inode); | ||||
| 	if (i_size == 0) | ||||
| 		goto out_exit; | ||||
| 		goto out_symbol; | ||||
| 	info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); | ||||
| 	if (info == NULL) | ||||
| 		goto out_exit; | ||||
| 		goto out_symbol; | ||||
| 	geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); | ||||
| 	if (geo == NULL) | ||||
| 		goto out_nogeo; | ||||
| 	label = kmalloc(sizeof(union label_t), GFP_KERNEL); | ||||
| 	if (label == NULL) | ||||
| 		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; | ||||
| 	if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0) { | ||||
| 	if (fn(disk, info)) { | ||||
| 		kfree(info); | ||||
| 		info = NULL; | ||||
| 	} | ||||
| @ -359,6 +369,8 @@ out_nolab: | ||||
| 	kfree(geo); | ||||
| out_nogeo: | ||||
| 	kfree(info); | ||||
| out_symbol: | ||||
| 	symbol_put(dasd_biodasdinfo); | ||||
| out_exit: | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
| @ -22,6 +22,7 @@ | ||||
| #include <asm/schid.h> | ||||
| #include <asm/cmb.h> | ||||
| #include <linux/uaccess.h> | ||||
| #include <linux/dasd_mod.h> | ||||
| 
 | ||||
| /* This is ugly... */ | ||||
| #define PRINTK_HEADER "dasd_ioctl:" | ||||
| @ -664,3 +665,36 @@ int dasd_ioctl(struct block_device *bdev, fmode_t mode, | ||||
| 	dasd_put_device(base); | ||||
| 	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); | ||||
|  | ||||
							
								
								
									
										9
									
								
								include/linux/dasd_mod.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								include/linux/dasd_mod.h
									
									
									
									
									
										Normal file
									
								
							| @ -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
	
	Block a user
	 Stefan Haberland
						Stefan Haberland