compat_ioctl.c revision b3087cc4f31a66c8c7b63419e913ed9d34145f10
1f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/blkdev.h> 2f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/blkpg.h> 3f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/blktrace_api.h> 4f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/cdrom.h> 5f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/compat.h> 6f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/elevator.h> 7f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/fd.h> 8f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/hdreg.h> 9f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/syscalls.h> 10f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/smp_lock.h> 11f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/types.h> 12f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#include <linux/uaccess.h> 13f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 14f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannstatic int compat_put_ushort(unsigned long arg, unsigned short val) 15f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 16f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return put_user(val, (unsigned short __user *)compat_ptr(arg)); 17f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 18f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 19f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannstatic int compat_put_int(unsigned long arg, int val) 20f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 21f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return put_user(val, (compat_int_t __user *)compat_ptr(arg)); 22f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 23f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 24f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannstatic int compat_put_long(unsigned long arg, long val) 25f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 26f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return put_user(val, (compat_long_t __user *)compat_ptr(arg)); 27f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 28f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 29f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannstatic int compat_put_ulong(unsigned long arg, compat_ulong_t val) 30f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 31f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return put_user(val, (compat_ulong_t __user *)compat_ptr(arg)); 32f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 33f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 34f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannstatic int compat_put_u64(unsigned long arg, u64 val) 35f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 36f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return put_user(val, (compat_u64 __user *)compat_ptr(arg)); 37f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 38f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 399617db085c119879cd371e3212806a15596e121aArnd Bergmannstruct compat_hd_geometry { 409617db085c119879cd371e3212806a15596e121aArnd Bergmann unsigned char heads; 419617db085c119879cd371e3212806a15596e121aArnd Bergmann unsigned char sectors; 429617db085c119879cd371e3212806a15596e121aArnd Bergmann unsigned short cylinders; 439617db085c119879cd371e3212806a15596e121aArnd Bergmann u32 start; 449617db085c119879cd371e3212806a15596e121aArnd Bergmann}; 459617db085c119879cd371e3212806a15596e121aArnd Bergmann 469617db085c119879cd371e3212806a15596e121aArnd Bergmannstatic int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev, 479617db085c119879cd371e3212806a15596e121aArnd Bergmann struct compat_hd_geometry __user *ugeo) 489617db085c119879cd371e3212806a15596e121aArnd Bergmann{ 499617db085c119879cd371e3212806a15596e121aArnd Bergmann struct hd_geometry geo; 509617db085c119879cd371e3212806a15596e121aArnd Bergmann int ret; 519617db085c119879cd371e3212806a15596e121aArnd Bergmann 529617db085c119879cd371e3212806a15596e121aArnd Bergmann if (!ugeo) 539617db085c119879cd371e3212806a15596e121aArnd Bergmann return -EINVAL; 549617db085c119879cd371e3212806a15596e121aArnd Bergmann if (!disk->fops->getgeo) 559617db085c119879cd371e3212806a15596e121aArnd Bergmann return -ENOTTY; 569617db085c119879cd371e3212806a15596e121aArnd Bergmann 579617db085c119879cd371e3212806a15596e121aArnd Bergmann /* 589617db085c119879cd371e3212806a15596e121aArnd Bergmann * We need to set the startsect first, the driver may 599617db085c119879cd371e3212806a15596e121aArnd Bergmann * want to override it. 609617db085c119879cd371e3212806a15596e121aArnd Bergmann */ 619617db085c119879cd371e3212806a15596e121aArnd Bergmann geo.start = get_start_sect(bdev); 629617db085c119879cd371e3212806a15596e121aArnd Bergmann ret = disk->fops->getgeo(bdev, &geo); 639617db085c119879cd371e3212806a15596e121aArnd Bergmann if (ret) 649617db085c119879cd371e3212806a15596e121aArnd Bergmann return ret; 659617db085c119879cd371e3212806a15596e121aArnd Bergmann 669617db085c119879cd371e3212806a15596e121aArnd Bergmann ret = copy_to_user(ugeo, &geo, 4); 679617db085c119879cd371e3212806a15596e121aArnd Bergmann ret |= __put_user(geo.start, &ugeo->start); 689617db085c119879cd371e3212806a15596e121aArnd Bergmann if (ret) 699617db085c119879cd371e3212806a15596e121aArnd Bergmann ret = -EFAULT; 709617db085c119879cd371e3212806a15596e121aArnd Bergmann 719617db085c119879cd371e3212806a15596e121aArnd Bergmann return ret; 729617db085c119879cd371e3212806a15596e121aArnd Bergmann} 739617db085c119879cd371e3212806a15596e121aArnd Bergmann 749617db085c119879cd371e3212806a15596e121aArnd Bergmannstatic int compat_hdio_ioctl(struct inode *inode, struct file *file, 759617db085c119879cd371e3212806a15596e121aArnd Bergmann struct gendisk *disk, unsigned int cmd, unsigned long arg) 769617db085c119879cd371e3212806a15596e121aArnd Bergmann{ 779617db085c119879cd371e3212806a15596e121aArnd Bergmann mm_segment_t old_fs = get_fs(); 789617db085c119879cd371e3212806a15596e121aArnd Bergmann unsigned long kval; 799617db085c119879cd371e3212806a15596e121aArnd Bergmann unsigned int __user *uvp; 809617db085c119879cd371e3212806a15596e121aArnd Bergmann int error; 819617db085c119879cd371e3212806a15596e121aArnd Bergmann 829617db085c119879cd371e3212806a15596e121aArnd Bergmann set_fs(KERNEL_DS); 839617db085c119879cd371e3212806a15596e121aArnd Bergmann error = blkdev_driver_ioctl(inode, file, disk, 849617db085c119879cd371e3212806a15596e121aArnd Bergmann cmd, (unsigned long)(&kval)); 859617db085c119879cd371e3212806a15596e121aArnd Bergmann set_fs(old_fs); 869617db085c119879cd371e3212806a15596e121aArnd Bergmann 879617db085c119879cd371e3212806a15596e121aArnd Bergmann if (error == 0) { 889617db085c119879cd371e3212806a15596e121aArnd Bergmann uvp = compat_ptr(arg); 899617db085c119879cd371e3212806a15596e121aArnd Bergmann if (put_user(kval, uvp)) 909617db085c119879cd371e3212806a15596e121aArnd Bergmann error = -EFAULT; 919617db085c119879cd371e3212806a15596e121aArnd Bergmann } 929617db085c119879cd371e3212806a15596e121aArnd Bergmann return error; 939617db085c119879cd371e3212806a15596e121aArnd Bergmann} 949617db085c119879cd371e3212806a15596e121aArnd Bergmann 95b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmannstruct compat_cdrom_read_audio { 96b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann union cdrom_addr addr; 97b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann u8 addr_format; 98b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_int_t nframes; 99b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_caddr_t buf; 100b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann}; 101b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 102b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmannstruct compat_cdrom_generic_command { 103b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann unsigned char cmd[CDROM_PACKET_SIZE]; 104b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_caddr_t buffer; 105b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_uint_t buflen; 106b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_int_t stat; 107b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_caddr_t sense; 108b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann unsigned char data_direction; 109b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_int_t quiet; 110b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_int_t timeout; 111b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann compat_caddr_t reserved[1]; 112b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann}; 113b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 114b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmannstatic int compat_cdrom_read_audio(struct inode *inode, struct file *file, 115b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann struct gendisk *disk, unsigned int cmd, unsigned long arg) 116b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann{ 117b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann struct cdrom_read_audio __user *cdread_audio; 118b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann struct compat_cdrom_read_audio __user *cdread_audio32; 119b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann __u32 data; 120b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann void __user *datap; 121b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 122b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio)); 123b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann cdread_audio32 = compat_ptr(arg); 124b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 125b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann if (copy_in_user(&cdread_audio->addr, 126b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann &cdread_audio32->addr, 127b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann (sizeof(*cdread_audio32) - 128b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann sizeof(compat_caddr_t)))) 129b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return -EFAULT; 130b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 131b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann if (get_user(data, &cdread_audio32->buf)) 132b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return -EFAULT; 133b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann datap = compat_ptr(data); 134b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann if (put_user(datap, &cdread_audio->buf)) 135b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return -EFAULT; 136b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 137b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return blkdev_driver_ioctl(inode, file, disk, cmd, 138b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann (unsigned long)cdread_audio); 139b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann} 140b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 141b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmannstatic int compat_cdrom_generic_command(struct inode *inode, struct file *file, 142b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann struct gendisk *disk, unsigned int cmd, unsigned long arg) 143b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann{ 144b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann struct cdrom_generic_command __user *cgc; 145b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann struct compat_cdrom_generic_command __user *cgc32; 146b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann u32 data; 147b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann unsigned char dir; 148b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann int itmp; 149b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 150b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann cgc = compat_alloc_user_space(sizeof(*cgc)); 151b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann cgc32 = compat_ptr(arg); 152b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 153b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) || 154b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann get_user(data, &cgc32->buffer) || 155b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann put_user(compat_ptr(data), &cgc->buffer) || 156b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann copy_in_user(&cgc->buflen, &cgc32->buflen, 157b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann (sizeof(unsigned int) + sizeof(int))) || 158b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann get_user(data, &cgc32->sense) || 159b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann put_user(compat_ptr(data), &cgc->sense) || 160b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann get_user(dir, &cgc32->data_direction) || 161b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann put_user(dir, &cgc->data_direction) || 162b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann get_user(itmp, &cgc32->quiet) || 163b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann put_user(itmp, &cgc->quiet) || 164b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann get_user(itmp, &cgc32->timeout) || 165b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann put_user(itmp, &cgc->timeout) || 166b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann get_user(data, &cgc32->reserved[0]) || 167b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann put_user(compat_ptr(data), &cgc->reserved[0])) 168b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return -EFAULT; 169b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 170b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return blkdev_driver_ioctl(inode, file, disk, cmd, (unsigned long)cgc); 171b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann} 172b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 17318cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmannstruct compat_blkpg_ioctl_arg { 17418cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann compat_int_t op; 17518cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann compat_int_t flags; 17618cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann compat_int_t datalen; 17718cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann compat_caddr_t data; 17818cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann}; 17918cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann 18018cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmannstatic int compat_blkpg_ioctl(struct inode *inode, struct file *file, 18118cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32) 18218cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann{ 18318cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a)); 18418cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann compat_caddr_t udata; 18518cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann compat_int_t n; 18618cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann int err; 18718cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann 18818cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err = get_user(n, &ua32->op); 18918cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= put_user(n, &a->op); 19018cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= get_user(n, &ua32->flags); 19118cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= put_user(n, &a->flags); 19218cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= get_user(n, &ua32->datalen); 19318cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= put_user(n, &a->datalen); 19418cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= get_user(udata, &ua32->data); 19518cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann err |= put_user(compat_ptr(udata), &a->data); 19618cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann if (err) 19718cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann return err; 19818cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann 19918cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann return blkdev_ioctl(inode, file, cmd, (unsigned long)a); 20018cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann} 20118cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann 202f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#define BLKBSZGET_32 _IOR(0x12, 112, int) 203f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#define BLKBSZSET_32 _IOW(0x12, 113, int) 204f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann#define BLKGETSIZE64_32 _IOR(0x12, 114, int) 205f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 206171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmannstruct compat_blk_user_trace_setup { 207171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann char name[32]; 208171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann u16 act_mask; 209171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann u32 buf_size; 210171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann u32 buf_nr; 211171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann compat_u64 start_lba; 212171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann compat_u64 end_lba; 213171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann u32 pid; 214171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann}; 215171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann#define BLKTRACESETUP32 _IOWR(0x12, 115, struct compat_blk_user_trace_setup) 216171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 217171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmannstatic int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) 218171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann{ 219171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann struct blk_user_trace_setup buts; 220171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann struct compat_blk_user_trace_setup cbuts; 221171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann struct request_queue *q; 222171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann int ret; 223171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 224171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann q = bdev_get_queue(bdev); 225171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann if (!q) 226171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return -ENXIO; 227171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 228171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann if (copy_from_user(&cbuts, arg, sizeof(cbuts))) 229171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return -EFAULT; 230171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 231171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann buts = (struct blk_user_trace_setup) { 232171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann .act_mask = cbuts.act_mask, 233171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann .buf_size = cbuts.buf_size, 234171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann .buf_nr = cbuts.buf_nr, 235171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann .start_lba = cbuts.start_lba, 236171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann .end_lba = cbuts.end_lba, 237171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann .pid = cbuts.pid, 238171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann }; 239171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann memcpy(&buts.name, &cbuts.name, 32); 240171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 241171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann mutex_lock(&bdev->bd_mutex); 242171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann ret = do_blk_trace_setup(q, bdev, &buts); 243171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann mutex_unlock(&bdev->bd_mutex); 244171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann if (ret) 245171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return ret; 246171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 247171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann if (copy_to_user(arg, &buts.name, 32)) 248171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return -EFAULT; 249171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 250171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return 0; 251171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann} 252171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 2537199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmannstatic int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, 2547199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann struct gendisk *disk, unsigned cmd, unsigned long arg) 2557199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann{ 2567199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann int ret; 2577199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann 2587199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann switch (arg) { 2599617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_UNMASKINTR: 2609617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_MULTCOUNT: 2619617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_KEEPSETTINGS: 2629617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_32BIT: 2639617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_NOWERR: 2649617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_DMA: 2659617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_NICE: 2669617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_WCACHE: 2679617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_ACOUSTIC: 2689617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_ADDRESS: 2699617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GET_BUSSTATE: 2709617db085c119879cd371e3212806a15596e121aArnd Bergmann return compat_hdio_ioctl(inode, file, disk, cmd, arg); 271b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann case CDROMREADAUDIO: 272b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return compat_cdrom_read_audio(inode, file, disk, cmd, arg); 273b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann case CDROM_SEND_PACKET: 274b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann return compat_cdrom_generic_command(inode, file, disk, cmd, arg); 275b3087cc4f31a66c8c7b63419e913ed9d34145f10Arnd Bergmann 2767199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* 2777199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * No handler required for the ones below, we just need to 2787199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * convert arg to a 64 bit pointer. 2797199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann */ 2807199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case BLKSECTSET: 2817199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* 2827199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * 0x03 -- HD/IDE ioctl's used by hdparm and friends. 2837199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * Some need translations, these do not. 2847199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann */ 2857199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_GET_IDENTITY: 2867199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_DRIVE_TASK: 2877199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_DRIVE_CMD: 2887199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SCAN_HWIF: 2897199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */ 2907199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case 0x330: 2917199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* 0x02 -- Floppy ioctls */ 2927199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDMSGON: 2937199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDMSGOFF: 2947199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDSETEMSGTRESH: 2957199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDFLUSH: 2967199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDWERRORCLR: 2977199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDSETMAXERRS: 2987199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDGETMAXERRS: 2997199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDGETDRVTYP: 3007199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDEJECT: 3017199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDCLRPRM: 3027199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDFMTBEG: 3037199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDFMTEND: 3047199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDRESET: 3057199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDTWADDLE: 3067199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDFMTTRK: 3077199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case FDRAWCMD: 3087199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* CDROM stuff */ 3097199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMPAUSE: 3107199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMRESUME: 3117199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMPLAYMSF: 3127199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMPLAYTRKIND: 3137199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADTOCHDR: 3147199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADTOCENTRY: 3157199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMSTOP: 3167199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMSTART: 3177199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMEJECT: 3187199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMVOLCTRL: 3197199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMSUBCHNL: 3207199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMMULTISESSION: 3217199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_GET_MCN: 3227199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMRESET: 3237199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMVOLREAD: 3247199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMSEEK: 3257199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMPLAYBLK: 3267199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMCLOSETRAY: 3277199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_DISC_STATUS: 3287199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_CHANGER_NSLOTS: 3297199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_GET_CAPABILITY: 3307199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* Ignore cdrom.h about these next 5 ioctls, they absolutely do 3317199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * not take a struct cdrom_read, instead they take a struct cdrom_msf 3327199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * which is compatible. 3337199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann */ 3347199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADMODE2: 3357199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADMODE1: 3367199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADRAW: 3377199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADCOOKED: 3387199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMREADALL: 3397199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* DVD ioctls */ 3407199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case DVD_READ_STRUCT: 3417199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case DVD_WRITE_STRUCT: 3427199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case DVD_AUTH: 3437199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann arg = (unsigned long)compat_ptr(arg); 3447199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* These intepret arg as an unsigned long, not as a pointer, 3457199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann * so we must not do compat_ptr() conversion. */ 3467199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_MULTCOUNT: 3477199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_UNMASKINTR: 3487199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_KEEPSETTINGS: 3497199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_32BIT: 3507199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_NOWERR: 3517199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_DMA: 3527199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_PIO_MODE: 3537199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_NICE: 3547199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_WCACHE: 3557199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_ACOUSTIC: 3567199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_BUSSTATE: 3577199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case HDIO_SET_ADDRESS: 3587199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROMEJECT_SW: 3597199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_SET_OPTIONS: 3607199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_CLEAR_OPTIONS: 3617199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_SELECT_SPEED: 3627199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_SELECT_DISC: 3637199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_MEDIA_CHANGED: 3647199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_DRIVE_STATUS: 3657199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_LOCKDOOR: 3667199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann case CDROM_DEBUG: 3677199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann break; 3687199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann default: 3697199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann /* unknown ioctl number */ 3707199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann return -ENOIOCTLCMD; 3717199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann } 3727199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann 3737199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann if (disk->fops->unlocked_ioctl) 3747199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann return disk->fops->unlocked_ioctl(file, cmd, arg); 3757199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann 3767199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann if (disk->fops->ioctl) { 3777199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann lock_kernel(); 3787199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann ret = disk->fops->ioctl(inode, file, cmd, arg); 3797199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann unlock_kernel(); 3807199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann return ret; 3817199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann } 3827199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann 3837199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann return -ENOTTY; 3847199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann} 3857199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann 386f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannstatic int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, 387f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann struct block_device *bdev, 388f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann unsigned cmd, unsigned long arg) 389f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 390f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann struct backing_dev_info *bdi; 391f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 392f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann switch (cmd) { 393f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKRAGET: 394f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKFRAGET: 395f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann if (!arg) 396f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return -EINVAL; 397f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann bdi = blk_get_backing_dev_info(bdev); 398f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann if (bdi == NULL) 399f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return -ENOTTY; 400f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_long(arg, 401f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); 402f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKROGET: /* compatible */ 403f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_int(arg, bdev_read_only(bdev) != 0); 404f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */ 405f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_int(arg, block_size(bdev)); 406f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKSSZGET: /* get block device hardware sector size */ 407f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_int(arg, bdev_hardsect_size(bdev)); 408f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKSECTGET: 409f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_ushort(arg, 410f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann bdev_get_queue(bdev)->max_sectors); 411f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKRASET: /* compatible, but no compat_ptr (!) */ 412f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKFRASET: 413f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann if (!capable(CAP_SYS_ADMIN)) 414f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return -EACCES; 415f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann bdi = blk_get_backing_dev_info(bdev); 416f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann if (bdi == NULL) 417f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return -ENOTTY; 418f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; 419f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return 0; 420f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKGETSIZE: 421f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann if ((bdev->bd_inode->i_size >> 9) > ~0UL) 422f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return -EFBIG; 423f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9); 424f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 425f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKGETSIZE64_32: 426f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return compat_put_u64(arg, bdev->bd_inode->i_size); 427171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann 428171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann case BLKTRACESETUP32: 429171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return compat_blk_trace_setup(bdev, compat_ptr(arg)); 430171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann case BLKTRACESTART: /* compatible */ 431171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann case BLKTRACESTOP: /* compatible */ 432171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann case BLKTRACETEARDOWN: /* compatible */ 433171044d449611c6e5040b37210ff6aba47f33ee4Arnd Bergmann return blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); 434f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann } 435f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return -ENOIOCTLCMD; 436f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 437f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 438f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann/* Most of the generic ioctls are handled in the normal fallback path. 439f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann This assumes the blkdev's low level compat_ioctl always returns 440f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann ENOIOCTLCMD for unknown ioctls. */ 441f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmannlong compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) 442f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann{ 443f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann int ret = -ENOIOCTLCMD; 444f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann struct inode *inode = file->f_mapping->host; 445f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann struct block_device *bdev = inode->i_bdev; 446f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann struct gendisk *disk = bdev->bd_disk; 447f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 448f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann switch (cmd) { 4499617db085c119879cd371e3212806a15596e121aArnd Bergmann case HDIO_GETGEO: 4509617db085c119879cd371e3212806a15596e121aArnd Bergmann return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); 451f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKFLSBUF: 452f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKROSET: 453f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann /* 454f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann * the ones below are implemented in blkdev_locked_ioctl, 455f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann * but we call blkdev_ioctl, which gets the lock for us 456f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann */ 457f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKRRPART: 458f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return blkdev_ioctl(inode, file, cmd, 459f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann (unsigned long)compat_ptr(arg)); 460f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann case BLKBSZSET_32: 461f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann return blkdev_ioctl(inode, file, BLKBSZSET, 462f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann (unsigned long)compat_ptr(arg)); 46318cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann case BLKPG: 46418cf7f8723d913ce02bea43e468bebdd07bc880cArnd Bergmann return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(arg)); 465f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann } 466f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 467f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann lock_kernel(); 468f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann ret = compat_blkdev_locked_ioctl(inode, file, bdev, cmd, arg); 469f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann /* FIXME: why do we assume -> compat_ioctl needs the BKL? */ 470f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl) 471f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann ret = disk->fops->compat_ioctl(file, cmd, arg); 472f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann unlock_kernel(); 473f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann 4747199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann if (ret != -ENOIOCTLCMD) 4757199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann return ret; 4767199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann 4777199d4cdd8485f802df3e1bc131245c69009b9a4Arnd Bergmann return compat_blkdev_driver_ioctl(inode, file, disk, cmd, arg); 478f58c4c0a17e500e767473598b3deafaa1d64051dArnd Bergmann} 479