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>hifive-unleashed-5.1
parent
7199d4cdd8
commit
171044d449
|
@ -312,33 +312,26 @@ static struct rchan_callbacks blk_relay_callbacks = {
|
||||||
/*
|
/*
|
||||||
* Setup everything required to start tracing
|
* Setup everything required to start tracing
|
||||||
*/
|
*/
|
||||||
static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
|
int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev,
|
||||||
char __user *arg)
|
struct blk_user_trace_setup *buts)
|
||||||
{
|
{
|
||||||
struct blk_user_trace_setup buts;
|
|
||||||
struct blk_trace *old_bt, *bt = NULL;
|
struct blk_trace *old_bt, *bt = NULL;
|
||||||
struct dentry *dir = NULL;
|
struct dentry *dir = NULL;
|
||||||
char b[BDEVNAME_SIZE];
|
char b[BDEVNAME_SIZE];
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
if (copy_from_user(&buts, arg, sizeof(buts)))
|
if (!buts->buf_size || !buts->buf_nr)
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
if (!buts.buf_size || !buts.buf_nr)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
strcpy(buts.name, bdevname(bdev, b));
|
strcpy(buts->name, bdevname(bdev, b));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* some device names have larger paths - convert the slashes
|
* some device names have larger paths - convert the slashes
|
||||||
* to underscores for this to work as expected
|
* to underscores for this to work as expected
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < strlen(buts.name); i++)
|
for (i = 0; i < strlen(buts->name); i++)
|
||||||
if (buts.name[i] == '/')
|
if (buts->name[i] == '/')
|
||||||
buts.name[i] = '_';
|
buts->name[i] = '_';
|
||||||
|
|
||||||
if (copy_to_user(arg, &buts, sizeof(buts)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
bt = kzalloc(sizeof(*bt), GFP_KERNEL);
|
bt = kzalloc(sizeof(*bt), GFP_KERNEL);
|
||||||
|
@ -350,7 +343,7 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
dir = blk_create_tree(buts.name);
|
dir = blk_create_tree(buts->name);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -363,20 +356,21 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
|
||||||
if (!bt->dropped_file)
|
if (!bt->dropped_file)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
bt->rchan = relay_open("trace", dir, buts.buf_size, buts.buf_nr, &blk_relay_callbacks, bt);
|
bt->rchan = relay_open("trace", dir, buts->buf_size,
|
||||||
|
buts->buf_nr, &blk_relay_callbacks, bt);
|
||||||
if (!bt->rchan)
|
if (!bt->rchan)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
bt->act_mask = buts.act_mask;
|
bt->act_mask = buts->act_mask;
|
||||||
if (!bt->act_mask)
|
if (!bt->act_mask)
|
||||||
bt->act_mask = (u16) -1;
|
bt->act_mask = (u16) -1;
|
||||||
|
|
||||||
bt->start_lba = buts.start_lba;
|
bt->start_lba = buts->start_lba;
|
||||||
bt->end_lba = buts.end_lba;
|
bt->end_lba = buts->end_lba;
|
||||||
if (!bt->end_lba)
|
if (!bt->end_lba)
|
||||||
bt->end_lba = -1ULL;
|
bt->end_lba = -1ULL;
|
||||||
|
|
||||||
bt->pid = buts.pid;
|
bt->pid = buts->pid;
|
||||||
bt->trace_state = Blktrace_setup;
|
bt->trace_state = Blktrace_setup;
|
||||||
|
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
@ -401,6 +395,26 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
|
||||||
|
char __user *arg)
|
||||||
|
{
|
||||||
|
struct blk_user_trace_setup buts;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = copy_from_user(&buts, arg, sizeof(buts));
|
||||||
|
if (ret)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
ret = do_blk_trace_setup(q, bdev, &buts);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (copy_to_user(arg, &buts, sizeof(buts)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int blk_trace_startstop(struct request_queue *q, int start)
|
static int blk_trace_startstop(struct request_queue *q, int start)
|
||||||
{
|
{
|
||||||
struct blk_trace *bt;
|
struct blk_trace *bt;
|
||||||
|
|
|
@ -40,6 +40,53 @@ static int compat_put_u64(unsigned long arg, u64 val)
|
||||||
#define BLKBSZSET_32 _IOW(0x12, 113, int)
|
#define BLKBSZSET_32 _IOW(0x12, 113, int)
|
||||||
#define BLKGETSIZE64_32 _IOR(0x12, 114, 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,
|
static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
|
||||||
struct gendisk *disk, unsigned cmd, unsigned long arg)
|
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:
|
case BLKGETSIZE64_32:
|
||||||
return compat_put_u64(arg, bdev->bd_inode->i_size);
|
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;
|
return -ENOIOCTLCMD;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,6 @@
|
||||||
#include <linux/i2c-dev.h>
|
#include <linux/i2c-dev.h>
|
||||||
#include <linux/wireless.h>
|
#include <linux/wireless.h>
|
||||||
#include <linux/atalk.h>
|
#include <linux/atalk.h>
|
||||||
#include <linux/blktrace_api.h>
|
|
||||||
#include <linux/loop.h>
|
#include <linux/loop.h>
|
||||||
|
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
|
@ -2477,13 +2476,6 @@ COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */
|
||||||
/* 0x00 */
|
/* 0x00 */
|
||||||
COMPATIBLE_IOCTL(FIBMAP)
|
COMPATIBLE_IOCTL(FIBMAP)
|
||||||
COMPATIBLE_IOCTL(FIGETBSZ)
|
COMPATIBLE_IOCTL(FIGETBSZ)
|
||||||
/* 0x12 */
|
|
||||||
#ifdef CONFIG_BLOCK
|
|
||||||
COMPATIBLE_IOCTL(BLKTRACESTART)
|
|
||||||
COMPATIBLE_IOCTL(BLKTRACESTOP)
|
|
||||||
COMPATIBLE_IOCTL(BLKTRACESETUP)
|
|
||||||
COMPATIBLE_IOCTL(BLKTRACETEARDOWN)
|
|
||||||
#endif
|
|
||||||
/* RAID */
|
/* RAID */
|
||||||
COMPATIBLE_IOCTL(RAID_VERSION)
|
COMPATIBLE_IOCTL(RAID_VERSION)
|
||||||
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
|
COMPATIBLE_IOCTL(GET_ARRAY_INFO)
|
||||||
|
|
|
@ -142,10 +142,14 @@ struct blk_user_trace_setup {
|
||||||
u32 pid;
|
u32 pid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
#if defined(CONFIG_BLK_DEV_IO_TRACE)
|
#if defined(CONFIG_BLK_DEV_IO_TRACE)
|
||||||
extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
|
extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
|
||||||
extern void blk_trace_shutdown(struct request_queue *);
|
extern void blk_trace_shutdown(struct request_queue *);
|
||||||
extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *);
|
extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *);
|
||||||
|
extern int do_blk_trace_setup(struct request_queue *q,
|
||||||
|
struct block_device *bdev, struct blk_user_trace_setup *buts);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* blk_add_trace_rq - Add a trace for a request oriented action
|
* blk_add_trace_rq - Add a trace for a request oriented action
|
||||||
|
@ -286,6 +290,7 @@ static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
|
||||||
#define blk_add_trace_generic(q, rq, rw, what) do { } while (0)
|
#define blk_add_trace_generic(q, rq, rw, what) do { } while (0)
|
||||||
#define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0)
|
#define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0)
|
||||||
#define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0)
|
#define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0)
|
||||||
|
#define do_blk_trace_setup(q, bdev, buts) do {} while (0)
|
||||||
#endif /* CONFIG_BLK_DEV_IO_TRACE */
|
#endif /* CONFIG_BLK_DEV_IO_TRACE */
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue