aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/compat_ioctl.c56
-rw-r--r--block/ioctl.c2
-rw-r--r--include/linux/blktrace_api.h12
-rw-r--r--kernel/trace/blktrace.c43
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
538struct 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
549static 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
588static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, 538static 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
204extern struct attribute_group blk_trace_attr_group; 205extern struct attribute_group blk_trace_attr_group;
205 206
207struct 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}
553EXPORT_SYMBOL_GPL(blk_trace_setup); 553EXPORT_SYMBOL_GPL(blk_trace_setup);
554 554
555#if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
556static 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
555int blk_trace_startstop(struct request_queue *q, int start) 590int 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