diff options
-rw-r--r-- | block/compat_ioctl.c | 56 | ||||
-rw-r--r-- | block/ioctl.c | 2 | ||||
-rw-r--r-- | include/linux/blktrace_api.h | 12 | ||||
-rw-r--r-- | kernel/trace/blktrace.c | 43 |
4 files changed, 55 insertions, 58 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index f26051f44681..d53085637731 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -535,56 +535,6 @@ out: | |||
535 | return err; | 535 | return err; |
536 | } | 536 | } |
537 | 537 | ||
538 | struct compat_blk_user_trace_setup { | ||
539 | char name[32]; | ||
540 | u16 act_mask; | ||
541 | u32 buf_size; | ||
542 | u32 buf_nr; | ||
543 | compat_u64 start_lba; | ||
544 | compat_u64 end_lba; | ||
545 | u32 pid; | ||
546 | }; | ||
547 | #define BLKTRACESETUP32 _IOWR(0x12, 115, struct compat_blk_user_trace_setup) | ||
548 | |||
549 | static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) | ||
550 | { | ||
551 | struct blk_user_trace_setup buts; | ||
552 | struct compat_blk_user_trace_setup cbuts; | ||
553 | struct request_queue *q; | ||
554 | char b[BDEVNAME_SIZE]; | ||
555 | int ret; | ||
556 | |||
557 | q = bdev_get_queue(bdev); | ||
558 | if (!q) | ||
559 | return -ENXIO; | ||
560 | |||
561 | if (copy_from_user(&cbuts, arg, sizeof(cbuts))) | ||
562 | return -EFAULT; | ||
563 | |||
564 | bdevname(bdev, b); | ||
565 | |||
566 | buts = (struct blk_user_trace_setup) { | ||
567 | .act_mask = cbuts.act_mask, | ||
568 | .buf_size = cbuts.buf_size, | ||
569 | .buf_nr = cbuts.buf_nr, | ||
570 | .start_lba = cbuts.start_lba, | ||
571 | .end_lba = cbuts.end_lba, | ||
572 | .pid = cbuts.pid, | ||
573 | }; | ||
574 | memcpy(&buts.name, &cbuts.name, 32); | ||
575 | |||
576 | mutex_lock(&bdev->bd_mutex); | ||
577 | ret = do_blk_trace_setup(q, b, bdev->bd_dev, bdev, &buts); | ||
578 | mutex_unlock(&bdev->bd_mutex); | ||
579 | if (ret) | ||
580 | return ret; | ||
581 | |||
582 | if (copy_to_user(arg, &buts.name, 32)) | ||
583 | return -EFAULT; | ||
584 | |||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, | 538 | static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, |
589 | unsigned cmd, unsigned long arg) | 539 | unsigned cmd, unsigned long arg) |
590 | { | 540 | { |
@@ -802,16 +752,10 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
802 | return compat_put_u64(arg, bdev->bd_inode->i_size); | 752 | return compat_put_u64(arg, bdev->bd_inode->i_size); |
803 | 753 | ||
804 | case BLKTRACESETUP32: | 754 | case BLKTRACESETUP32: |
805 | lock_kernel(); | ||
806 | ret = compat_blk_trace_setup(bdev, compat_ptr(arg)); | ||
807 | unlock_kernel(); | ||
808 | return ret; | ||
809 | case BLKTRACESTART: /* compatible */ | 755 | case BLKTRACESTART: /* compatible */ |
810 | case BLKTRACESTOP: /* compatible */ | 756 | case BLKTRACESTOP: /* compatible */ |
811 | case BLKTRACETEARDOWN: /* compatible */ | 757 | case BLKTRACETEARDOWN: /* compatible */ |
812 | lock_kernel(); | ||
813 | ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); | 758 | ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); |
814 | unlock_kernel(); | ||
815 | return ret; | 759 | return ret; |
816 | default: | 760 | default: |
817 | if (disk->fops->compat_ioctl) | 761 | if (disk->fops->compat_ioctl) |
diff --git a/block/ioctl.c b/block/ioctl.c index 1cfa8d449d90..9d91e830b320 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -320,9 +320,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
320 | case BLKTRACESTOP: | 320 | case BLKTRACESTOP: |
321 | case BLKTRACESETUP: | 321 | case BLKTRACESETUP: |
322 | case BLKTRACETEARDOWN: | 322 | case BLKTRACETEARDOWN: |
323 | lock_kernel(); | ||
324 | ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg); | 323 | ret = blk_trace_ioctl(bdev, cmd, (char __user *) arg); |
325 | unlock_kernel(); | ||
326 | break; | 324 | break; |
327 | default: | 325 | default: |
328 | ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); | 326 | ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg); |
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 23faa67e8022..07c698621ad0 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #ifdef __KERNEL__ | 5 | #ifdef __KERNEL__ |
6 | #include <linux/blkdev.h> | 6 | #include <linux/blkdev.h> |
7 | #include <linux/relay.h> | 7 | #include <linux/relay.h> |
8 | #include <linux/compat.h> | ||
8 | #endif | 9 | #endif |
9 | 10 | ||
10 | /* | 11 | /* |
@@ -203,6 +204,17 @@ extern int blk_trace_init_sysfs(struct device *dev); | |||
203 | 204 | ||
204 | extern struct attribute_group blk_trace_attr_group; | 205 | extern struct attribute_group blk_trace_attr_group; |
205 | 206 | ||
207 | struct compat_blk_user_trace_setup { | ||
208 | char name[32]; | ||
209 | u16 act_mask; | ||
210 | u32 buf_size; | ||
211 | u32 buf_nr; | ||
212 | compat_u64 start_lba; | ||
213 | compat_u64 end_lba; | ||
214 | u32 pid; | ||
215 | }; | ||
216 | #define BLKTRACESETUP32 _IOWR(0x12, 115, struct compat_blk_user_trace_setup) | ||
217 | |||
206 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ | 218 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ |
207 | # define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) | 219 | # define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) |
208 | # define blk_trace_shutdown(q) do { } while (0) | 220 | # define blk_trace_shutdown(q) do { } while (0) |
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 | ||