diff options
author | Arnd Bergmann <arnd@arndb.de> | 2007-10-09 07:23:53 -0400 |
---|---|---|
committer | Jens Axboe <axboe@carl.home.kernel.dk> | 2007-10-10 03:26:00 -0400 |
commit | 171044d449611c6e5040b37210ff6aba47f33ee4 (patch) | |
tree | 74a380863b395f9db13f2da333e91cd817dc4970 /block/blktrace.c | |
parent | 7199d4cdd8485f802df3e1bc131245c69009b9a4 (diff) |
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.c | 54 |
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 = { | |||
312 | /* | 312 | /* |
313 | * Setup everything required to start tracing | 313 | * Setup everything required to start tracing |
314 | */ | 314 | */ |
315 | static int blk_trace_setup(struct request_queue *q, struct block_device *bdev, | 315 | int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev, |
316 | char __user *arg) | 316 | struct blk_user_trace_setup *buts) |
317 | { | 317 | { |
318 | struct blk_user_trace_setup buts; | ||
319 | struct blk_trace *old_bt, *bt = NULL; | 318 | struct blk_trace *old_bt, *bt = NULL; |
320 | struct dentry *dir = NULL; | 319 | struct dentry *dir = NULL; |
321 | char b[BDEVNAME_SIZE]; | 320 | char b[BDEVNAME_SIZE]; |
322 | int ret, i; | 321 | int ret, i; |
323 | 322 | ||
324 | if (copy_from_user(&buts, arg, sizeof(buts))) | 323 | if (!buts->buf_size || !buts->buf_nr) |
325 | return -EFAULT; | ||
326 | |||
327 | if (!buts.buf_size || !buts.buf_nr) | ||
328 | return -EINVAL; | 324 | return -EINVAL; |
329 | 325 | ||
330 | strcpy(buts.name, bdevname(bdev, b)); | 326 | strcpy(buts->name, bdevname(bdev, b)); |
331 | 327 | ||
332 | /* | 328 | /* |
333 | * some device names have larger paths - convert the slashes | 329 | * some device names have larger paths - convert the slashes |
334 | * to underscores for this to work as expected | 330 | * to underscores for this to work as expected |
335 | */ | 331 | */ |
336 | for (i = 0; i < strlen(buts.name); i++) | 332 | for (i = 0; i < strlen(buts->name); i++) |
337 | if (buts.name[i] == '/') | 333 | if (buts->name[i] == '/') |
338 | buts.name[i] = '_'; | 334 | buts->name[i] = '_'; |
339 | |||
340 | if (copy_to_user(arg, &buts, sizeof(buts))) | ||
341 | return -EFAULT; | ||
342 | 335 | ||
343 | ret = -ENOMEM; | 336 | ret = -ENOMEM; |
344 | bt = kzalloc(sizeof(*bt), GFP_KERNEL); | 337 | bt = kzalloc(sizeof(*bt), GFP_KERNEL); |
@@ -350,7 +343,7 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev, | |||
350 | goto err; | 343 | goto err; |
351 | 344 | ||
352 | ret = -ENOENT; | 345 | ret = -ENOENT; |
353 | dir = blk_create_tree(buts.name); | 346 | dir = blk_create_tree(buts->name); |
354 | if (!dir) | 347 | if (!dir) |
355 | goto err; | 348 | goto err; |
356 | 349 | ||
@@ -363,20 +356,21 @@ static int blk_trace_setup(struct request_queue *q, struct block_device *bdev, | |||
363 | if (!bt->dropped_file) | 356 | if (!bt->dropped_file) |
364 | goto err; | 357 | goto err; |
365 | 358 | ||
366 | bt->rchan = relay_open("trace", dir, buts.buf_size, buts.buf_nr, &blk_relay_callbacks, bt); | 359 | bt->rchan = relay_open("trace", dir, buts->buf_size, |
360 | buts->buf_nr, &blk_relay_callbacks, bt); | ||
367 | if (!bt->rchan) | 361 | if (!bt->rchan) |
368 | goto err; | 362 | goto err; |
369 | 363 | ||
370 | bt->act_mask = buts.act_mask; | 364 | bt->act_mask = buts->act_mask; |
371 | if (!bt->act_mask) | 365 | if (!bt->act_mask) |
372 | bt->act_mask = (u16) -1; | 366 | bt->act_mask = (u16) -1; |
373 | 367 | ||
374 | bt->start_lba = buts.start_lba; | 368 | bt->start_lba = buts->start_lba; |
375 | bt->end_lba = buts.end_lba; | 369 | bt->end_lba = buts->end_lba; |
376 | if (!bt->end_lba) | 370 | if (!bt->end_lba) |
377 | bt->end_lba = -1ULL; | 371 | bt->end_lba = -1ULL; |
378 | 372 | ||
379 | bt->pid = buts.pid; | 373 | bt->pid = buts->pid; |
380 | bt->trace_state = Blktrace_setup; | 374 | bt->trace_state = Blktrace_setup; |
381 | 375 | ||
382 | ret = -EBUSY; | 376 | ret = -EBUSY; |
@@ -401,6 +395,26 @@ err: | |||
401 | return ret; | 395 | return ret; |
402 | } | 396 | } |
403 | 397 | ||
398 | static int blk_trace_setup(struct request_queue *q, struct block_device *bdev, | ||
399 | char __user *arg) | ||
400 | { | ||
401 | struct blk_user_trace_setup buts; | ||
402 | int ret; | ||
403 | |||
404 | ret = copy_from_user(&buts, arg, sizeof(buts)); | ||
405 | if (ret) | ||
406 | return -EFAULT; | ||
407 | |||
408 | ret = do_blk_trace_setup(q, bdev, &buts); | ||
409 | if (ret) | ||
410 | return ret; | ||
411 | |||
412 | if (copy_to_user(arg, &buts, sizeof(buts))) | ||
413 | return -EFAULT; | ||
414 | |||
415 | return 0; | ||
416 | } | ||
417 | |||
404 | static int blk_trace_startstop(struct request_queue *q, int start) | 418 | static int blk_trace_startstop(struct request_queue *q, int start) |
405 | { | 419 | { |
406 | struct blk_trace *bt; | 420 | struct blk_trace *bt; |