aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-07-07 10:51:23 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:24:31 -0400
commit34484062445fe905bf02c72f87ddda21881acda3 (patch)
treed1eb872d04cc06b474d299746207864f0e085bd8
parent610a63498f7f366031a6327eaaa9963ffa110b2b (diff)
scsi/i2o_block: cleanup ioctl handling
This fixes the ioctl function of the i2o_block driver, which has multiple problems: * The BLKI2OSRSTRAT and BLKI2OSWSTRAT commands always return -ENOTTY on success, where they should return 0. * Support for 32 bit compat is missing * The driver should use the .ioctl function and because .locked_ioctl is going away. The use of the big kernel lock remains for now, but gets made explictit in the ioctl function. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r--drivers/message/i2o/i2o_block.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 108f0c2b2bfd..b8233ff863e3 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -53,6 +53,7 @@
53#include <linux/module.h> 53#include <linux/module.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/i2o.h> 55#include <linux/i2o.h>
56#include <linux/smp_lock.h>
56 57
57#include <linux/mempool.h> 58#include <linux/mempool.h>
58 59
@@ -652,30 +653,40 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode,
652{ 653{
653 struct gendisk *disk = bdev->bd_disk; 654 struct gendisk *disk = bdev->bd_disk;
654 struct i2o_block_device *dev = disk->private_data; 655 struct i2o_block_device *dev = disk->private_data;
656 int ret = -ENOTTY;
655 657
656 /* Anyone capable of this syscall can do *real bad* things */ 658 /* Anyone capable of this syscall can do *real bad* things */
657 659
658 if (!capable(CAP_SYS_ADMIN)) 660 if (!capable(CAP_SYS_ADMIN))
659 return -EPERM; 661 return -EPERM;
660 662
663 lock_kernel();
661 switch (cmd) { 664 switch (cmd) {
662 case BLKI2OGRSTRAT: 665 case BLKI2OGRSTRAT:
663 return put_user(dev->rcache, (int __user *)arg); 666 ret = put_user(dev->rcache, (int __user *)arg);
667 break;
664 case BLKI2OGWSTRAT: 668 case BLKI2OGWSTRAT:
665 return put_user(dev->wcache, (int __user *)arg); 669 ret = put_user(dev->wcache, (int __user *)arg);
670 break;
666 case BLKI2OSRSTRAT: 671 case BLKI2OSRSTRAT:
672 ret = -EINVAL;
667 if (arg < 0 || arg > CACHE_SMARTFETCH) 673 if (arg < 0 || arg > CACHE_SMARTFETCH)
668 return -EINVAL; 674 break;
669 dev->rcache = arg; 675 dev->rcache = arg;
676 ret = 0;
670 break; 677 break;
671 case BLKI2OSWSTRAT: 678 case BLKI2OSWSTRAT:
679 ret = -EINVAL;
672 if (arg != 0 680 if (arg != 0
673 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) 681 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK))
674 return -EINVAL; 682 break;
675 dev->wcache = arg; 683 dev->wcache = arg;
684 ret = 0;
676 break; 685 break;
677 } 686 }
678 return -ENOTTY; 687 unlock_kernel();
688
689 return ret;
679}; 690};
680 691
681/** 692/**
@@ -930,7 +941,8 @@ static const struct block_device_operations i2o_block_fops = {
930 .owner = THIS_MODULE, 941 .owner = THIS_MODULE,
931 .open = i2o_block_open, 942 .open = i2o_block_open,
932 .release = i2o_block_release, 943 .release = i2o_block_release,
933 .locked_ioctl = i2o_block_ioctl, 944 .ioctl = i2o_block_ioctl,
945 .compat_ioctl = i2o_block_ioctl,
934 .getgeo = i2o_block_getgeo, 946 .getgeo = i2o_block_getgeo,
935 .media_changed = i2o_block_media_changed 947 .media_changed = i2o_block_media_changed
936}; 948};