diff options
Diffstat (limited to 'kernel/trace/blktrace.c')
-rw-r--r-- | kernel/trace/blktrace.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 3b4a695051b6..82499a5bdcb7 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -552,6 +552,41 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
552 | } | 552 | } |
553 | EXPORT_SYMBOL_GPL(blk_trace_setup); | 553 | EXPORT_SYMBOL_GPL(blk_trace_setup); |
554 | 554 | ||
555 | #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64) | ||
556 | static int compat_blk_trace_setup(struct request_queue *q, char *name, | ||
557 | dev_t dev, struct block_device *bdev, | ||
558 | char __user *arg) | ||
559 | { | ||
560 | struct blk_user_trace_setup buts; | ||
561 | struct compat_blk_user_trace_setup cbuts; | ||
562 | int ret; | ||
563 | |||
564 | if (copy_from_user(&cbuts, arg, sizeof(cbuts))) | ||
565 | return -EFAULT; | ||
566 | |||
567 | buts = (struct blk_user_trace_setup) { | ||
568 | .act_mask = cbuts.act_mask, | ||
569 | .buf_size = cbuts.buf_size, | ||
570 | .buf_nr = cbuts.buf_nr, | ||
571 | .start_lba = cbuts.start_lba, | ||
572 | .end_lba = cbuts.end_lba, | ||
573 | .pid = cbuts.pid, | ||
574 | }; | ||
575 | memcpy(&buts.name, &cbuts.name, 32); | ||
576 | |||
577 | ret = do_blk_trace_setup(q, name, dev, bdev, &buts); | ||
578 | if (ret) | ||
579 | return ret; | ||
580 | |||
581 | if (copy_to_user(arg, &buts.name, 32)) { | ||
582 | blk_trace_remove(q); | ||
583 | return -EFAULT; | ||
584 | } | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | #endif | ||
589 | |||
555 | int blk_trace_startstop(struct request_queue *q, int start) | 590 | int blk_trace_startstop(struct request_queue *q, int start) |
556 | { | 591 | { |
557 | int ret; | 592 | int ret; |
@@ -604,6 +639,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) | |||
604 | if (!q) | 639 | if (!q) |
605 | return -ENXIO; | 640 | return -ENXIO; |
606 | 641 | ||
642 | lock_kernel(); | ||
607 | mutex_lock(&bdev->bd_mutex); | 643 | mutex_lock(&bdev->bd_mutex); |
608 | 644 | ||
609 | switch (cmd) { | 645 | switch (cmd) { |
@@ -611,6 +647,12 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) | |||
611 | bdevname(bdev, b); | 647 | bdevname(bdev, b); |
612 | ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); | 648 | ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); |
613 | break; | 649 | break; |
650 | #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64) | ||
651 | case BLKTRACESETUP32: | ||
652 | bdevname(bdev, b); | ||
653 | ret = compat_blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); | ||
654 | break; | ||
655 | #endif | ||
614 | case BLKTRACESTART: | 656 | case BLKTRACESTART: |
615 | start = 1; | 657 | start = 1; |
616 | case BLKTRACESTOP: | 658 | case BLKTRACESTOP: |
@@ -625,6 +667,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) | |||
625 | } | 667 | } |
626 | 668 | ||
627 | mutex_unlock(&bdev->bd_mutex); | 669 | mutex_unlock(&bdev->bd_mutex); |
670 | unlock_kernel(); | ||
628 | return ret; | 671 | return ret; |
629 | } | 672 | } |
630 | 673 | ||