summaryrefslogtreecommitdiffstats
path: root/block/blktrace.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2007-10-09 13:23:53 +0200
committerJens Axboe <axboe@carl.home.kernel.dk>2007-10-10 09:26:00 +0200
commit171044d449611c6e5040b37210ff6aba47f33ee4 (patch)
tree74a380863b395f9db13f2da333e91cd817dc4970 /block/blktrace.c
parent7199d4cdd8485f802df3e1bc131245c69009b9a4 (diff)
downloadlinux-171044d449611c6e5040b37210ff6aba47f33ee4.tar.bz2
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/blktrace.c')
-rw-r--r--block/blktrace.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/block/blktrace.c b/block/blktrace.c
index 20fa034ea4a2..775471ef84a5 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -312,33 +312,26 @@ static struct rchan_callbacks blk_relay_callbacks = {
/*
* Setup everything required to start tracing
*/
-static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
- char __user *arg)
+int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev,
+ struct blk_user_trace_setup *buts)
{
- struct blk_user_trace_setup buts;
struct blk_trace *old_bt, *bt = NULL;
struct dentry *dir = NULL;
char b[BDEVNAME_SIZE];
int ret, i;
- if (copy_from_user(&buts, arg, sizeof(buts)))
- return -EFAULT;
-
- if (!buts.buf_size || !buts.buf_nr)
+ if (!buts->buf_size || !buts->buf_nr)
return -EINVAL;
- strcpy(buts.name, bdevname(bdev, b));
+ strcpy(buts->name, bdevname(bdev, b));
/*
* some device names have larger paths - convert the slashes
* to underscores for this to work as expected
*/
- for (i = 0; i < strlen(buts.name); i++)
- if (buts.name[i] == '/')
- buts.name[i] = '_';
-
- if (copy_to_user(arg, &buts, sizeof(buts)))
- return -EFAULT;
+ for (i = 0; i < strlen(buts->name); i++)
+ if (buts->name[i] == '/')
+ buts->name[i] = '_';
ret = -ENOMEM;
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;
ret = -ENOENT;
- dir = blk_create_tree(buts.name);
+ dir = blk_create_tree(buts->name);
if (!dir)
goto err;
@@ -363,20 +356,21 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev,
if (!bt->dropped_file)
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)
goto err;
- bt->act_mask = buts.act_mask;
+ bt->act_mask = buts->act_mask;
if (!bt->act_mask)
bt->act_mask = (u16) -1;
- bt->start_lba = buts.start_lba;
- bt->end_lba = buts.end_lba;
+ bt->start_lba = buts->start_lba;
+ bt->end_lba = buts->end_lba;
if (!bt->end_lba)
bt->end_lba = -1ULL;
- bt->pid = buts.pid;
+ bt->pid = buts->pid;
bt->trace_state = Blktrace_setup;
ret = -EBUSY;
@@ -401,6 +395,26 @@ err:
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)
{
struct blk_trace *bt;