diff options
author | Arnd Bergmann <arnd@arndb.de> | 2007-10-09 13:23:53 +0200 |
---|---|---|
committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2007-10-10 09:26:00 +0200 |
commit | 171044d449611c6e5040b37210ff6aba47f33ee4 (patch) | |
tree | 74a380863b395f9db13f2da333e91cd817dc4970 /block/compat_ioctl.c | |
parent | 7199d4cdd8485f802df3e1bc131245c69009b9a4 (diff) | |
download | lwn-171044d449611c6e5040b37210ff6aba47f33ee4.tar.gz lwn-171044d449611c6e5040b37210ff6aba47f33ee4.zip |
compat_ioctl: handle blk_trace ioctls
blk_trace_setup is broken on x86_64 compat systems,
this makes the code work correctly on all 64 bit architectures
in compat mode.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/compat_ioctl.c')
-rw-r--r-- | block/compat_ioctl.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index 500cc9e761c1..219b7e76e8ad 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -40,6 +40,53 @@ static int compat_put_u64(unsigned long arg, u64 val) #define BLKBSZSET_32 _IOW(0x12, 113, int) #define BLKGETSIZE64_32 _IOR(0x12, 114, int) +struct compat_blk_user_trace_setup { + char name[32]; + u16 act_mask; + u32 buf_size; + u32 buf_nr; + compat_u64 start_lba; + compat_u64 end_lba; + u32 pid; +}; +#define BLKTRACESETUP32 _IOWR(0x12, 115, struct compat_blk_user_trace_setup) + +static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) +{ + struct blk_user_trace_setup buts; + struct compat_blk_user_trace_setup cbuts; + struct request_queue *q; + int ret; + + q = bdev_get_queue(bdev); + if (!q) + return -ENXIO; + + if (copy_from_user(&cbuts, arg, sizeof(cbuts))) + return -EFAULT; + + buts = (struct blk_user_trace_setup) { + .act_mask = cbuts.act_mask, + .buf_size = cbuts.buf_size, + .buf_nr = cbuts.buf_nr, + .start_lba = cbuts.start_lba, + .end_lba = cbuts.end_lba, + .pid = cbuts.pid, + }; + memcpy(&buts.name, &cbuts.name, 32); + + mutex_lock(&bdev->bd_mutex); + ret = do_blk_trace_setup(q, bdev, &buts); + mutex_unlock(&bdev->bd_mutex); + if (ret) + return ret; + + if (copy_to_user(arg, &buts.name, 32)) + return -EFAULT; + + return 0; +} + static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file, struct gendisk *disk, unsigned cmd, unsigned long arg) { @@ -197,6 +244,13 @@ static int compat_blkdev_locked_ioctl(struct inode *inode, struct file *file, case BLKGETSIZE64_32: return compat_put_u64(arg, bdev->bd_inode->i_size); + + case BLKTRACESETUP32: + return compat_blk_trace_setup(bdev, compat_ptr(arg)); + case BLKTRACESTART: /* compatible */ + case BLKTRACESTOP: /* compatible */ + case BLKTRACETEARDOWN: /* compatible */ + return blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); } return -ENOIOCTLCMD; } |