diff --git a/configure.d/1_vfs_ioctl.conf b/configure.d/1_vfs_ioctl.conf new file mode 100644 index 0000000..8813cc5 --- /dev/null +++ b/configure.d/1_vfs_ioctl.conf @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright(c) 2012-2020 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause-Clear +# + +. $(dirname $3)/conf_framework + +check() { + cur_name=$(basename $2) + config_file_path=$1 + if compile_module $cur_name "vfs_ioctl(NULL, 0, 0);" "linux/fs.h" + then + echo $cur_name "1" >> $config_file_path + else + echo $cur_name "2" >> $config_file_path + fi +} + +apply() { + case "$1" in + "1") + add_function " + static inline int cas_vfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { + return vfs_ioctl(file, cmd, arg); + }" ;; + "2") + add_function " + static inline int cas_vfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { + int error = -ENOTTY; + + if (!file->f_op->unlocked_ioctl) + goto out; + + error = file->f_op->unlocked_ioctl(file, cmd, arg); + if (error == -ENOIOCTLCMD) + error = -ENOTTY; + out: + return error; + }" ;; + *) + exit 1 + esac +} + +conf_run $@ diff --git a/modules/cas_disk/exp_obj.c b/modules/cas_disk/exp_obj.c index 2916d78..0af9ad0 100644 --- a/modules/cas_disk/exp_obj.c +++ b/modules/cas_disk/exp_obj.c @@ -217,22 +217,54 @@ static int _casdsk_get_next_part_no(struct block_device *bd) return part_no; } -static int _casdsk_del_partitions(struct block_device *bd) +static int _casdsk_del_partitions(struct casdsk_disk *dsk) { - int result = 0; - int part_no; + struct block_device *bd = casdsk_disk_get_blkdev(dsk); + struct file *bd_file; + unsigned long __user usr_bpart; + unsigned long __user usr_barg; struct blkpg_partition bpart; struct blkpg_ioctl_arg barg; + int result = 0; + int part_no; - memset(&bpart, 0, sizeof(struct blkpg_partition)); - memset(&barg, 0, sizeof(struct blkpg_ioctl_arg)); - barg.data = (void __force __user *) &bpart; + bd_file = filp_open(dsk->path, 0, 0); + if (IS_ERR(bd_file)) + return PTR_ERR(bd_file); + + usr_bpart = cas_vm_mmap(NULL, 0, sizeof(bpart)); + if (IS_ERR((void *)usr_bpart)) { + result = PTR_ERR((void *)usr_bpart); + goto out_map_bpart; + } + + usr_barg = cas_vm_mmap(NULL, 0, sizeof(barg)); + if (IS_ERR((void *)usr_barg)) { + result = PTR_ERR((void *)usr_barg); + goto out_map_barg; + } + + + memset(&bpart, 0, sizeof(bpart)); + memset(&barg, 0, sizeof(barg)); + barg.data = (void __user *)usr_bpart; barg.op = BLKPG_DEL_PARTITION; + result = copy_to_user((void __user *)usr_barg, &barg, sizeof(barg)); + if (result) { + result = -EINVAL; + goto out_copy; + } while ((part_no = _casdsk_get_next_part_no(bd))) { bpart.pno = part_no; - result = ioctl_by_bdev(bd, BLKPG, (unsigned long) &barg); + result = copy_to_user((void __user *)usr_bpart, &bpart, + sizeof(bpart)); + if (result) { + result = -EINVAL; + break; + } + result = cas_vfs_ioctl(bd_file, BLKPG, usr_barg); if (result == 0) { printk(CASDSK_KERN_INFO "Partition %d on %s hidden\n", part_no, bd->bd_disk->disk_name); @@ -243,6 +275,12 @@ static int _casdsk_del_partitions(struct block_device *bd) } } +out_copy: + cas_vm_munmap(usr_barg, sizeof(barg)); +out_map_barg: + cas_vm_munmap(usr_bpart, sizeof(bpart)); +out_map_bpart: + filp_close(bd_file, NULL); return result; } @@ -262,7 +300,7 @@ static int _casdsk_exp_obj_hide_parts(struct casdsk_disk *dsk) return 0; if (disk_max_parts(dsk->bd->bd_disk) > 1) { - if (_casdsk_del_partitions(bd)) { + if (_casdsk_del_partitions(dsk)) { printk(CASDSK_KERN_ERR "Error deleting a partition on thedevice %s\n", gdsk->disk_name);