diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-01-16 11:06:55 -0500 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-01-18 07:27:41 -0500 |
commit | f429b2ea8eadb5a576542a70f7fd6f5c2a7455e1 (patch) | |
tree | 6ab9541042979cc7bdcb0257dfdd6435577ad3a8 /drivers | |
parent | 4d187a88d3ee3be6a1a0b6859eb00f70e1601b5e (diff) |
UBI: add ioctl compatibility
UBI ioctl's do not work when running 64-bit kernel and 32-bit
user-land. Fix this by adding the compat_ioctl method.
Also, UBI serializes all ioctls, so more than one ioctl at a time
is not a problem. Amd UBI does not seem to depend on anything else,
so use unlocked_ioctl instead of ioctl (no BKL needed).
Reported-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index d99935c0f3c6..0a2d835fec80 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/ioctl.h> | 40 | #include <linux/ioctl.h> |
41 | #include <linux/capability.h> | 41 | #include <linux/capability.h> |
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <linux/compat.h> | ||
43 | #include <mtd/ubi-user.h> | 44 | #include <mtd/ubi-user.h> |
44 | #include <asm/div64.h> | 45 | #include <asm/div64.h> |
45 | #include "ubi.h" | 46 | #include "ubi.h" |
@@ -401,8 +402,8 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, | |||
401 | return count; | 402 | return count; |
402 | } | 403 | } |
403 | 404 | ||
404 | static int vol_cdev_ioctl(struct inode *inode, struct file *file, | 405 | static long vol_cdev_ioctl(struct file *file, unsigned int cmd, |
405 | unsigned int cmd, unsigned long arg) | 406 | unsigned long arg) |
406 | { | 407 | { |
407 | int err = 0; | 408 | int err = 0; |
408 | struct ubi_volume_desc *desc = file->private_data; | 409 | struct ubi_volume_desc *desc = file->private_data; |
@@ -800,8 +801,8 @@ out_free: | |||
800 | return err; | 801 | return err; |
801 | } | 802 | } |
802 | 803 | ||
803 | static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | 804 | static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, |
804 | unsigned int cmd, unsigned long arg) | 805 | unsigned long arg) |
805 | { | 806 | { |
806 | int err = 0; | 807 | int err = 0; |
807 | struct ubi_device *ubi; | 808 | struct ubi_device *ubi; |
@@ -811,7 +812,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
811 | if (!capable(CAP_SYS_RESOURCE)) | 812 | if (!capable(CAP_SYS_RESOURCE)) |
812 | return -EPERM; | 813 | return -EPERM; |
813 | 814 | ||
814 | ubi = ubi_get_by_major(imajor(inode)); | 815 | ubi = ubi_get_by_major(imajor(file->f_mapping->host)); |
815 | if (!ubi) | 816 | if (!ubi) |
816 | return -ENODEV; | 817 | return -ENODEV; |
817 | 818 | ||
@@ -947,8 +948,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
947 | return err; | 948 | return err; |
948 | } | 949 | } |
949 | 950 | ||
950 | static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, | 951 | static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, |
951 | unsigned int cmd, unsigned long arg) | 952 | unsigned long arg) |
952 | { | 953 | { |
953 | int err = 0; | 954 | int err = 0; |
954 | void __user *argp = (void __user *)arg; | 955 | void __user *argp = (void __user *)arg; |
@@ -1024,26 +1025,59 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, | |||
1024 | return err; | 1025 | return err; |
1025 | } | 1026 | } |
1026 | 1027 | ||
1027 | /* UBI control character device operations */ | 1028 | #ifdef CONFIG_COMPAT |
1028 | const struct file_operations ubi_ctrl_cdev_operations = { | 1029 | static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd, |
1029 | .ioctl = ctrl_cdev_ioctl, | 1030 | unsigned long arg) |
1030 | .owner = THIS_MODULE, | 1031 | { |
1032 | unsigned long translated_arg = (unsigned long)compat_ptr(arg); | ||
1033 | |||
1034 | return vol_cdev_ioctl(file, cmd, translated_arg); | ||
1035 | } | ||
1036 | |||
1037 | static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd, | ||
1038 | unsigned long arg) | ||
1039 | { | ||
1040 | unsigned long translated_arg = (unsigned long)compat_ptr(arg); | ||
1041 | |||
1042 | return ubi_cdev_ioctl(file, cmd, translated_arg); | ||
1043 | } | ||
1044 | |||
1045 | static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd, | ||
1046 | unsigned long arg) | ||
1047 | { | ||
1048 | unsigned long translated_arg = (unsigned long)compat_ptr(arg); | ||
1049 | |||
1050 | return ctrl_cdev_ioctl(file, cmd, translated_arg); | ||
1051 | } | ||
1052 | #else | ||
1053 | #define vol_cdev_compat_ioctl NULL | ||
1054 | #define ubi_cdev_compat_ioctl NULL | ||
1055 | #define ctrl_cdev_compat_ioctl NULL | ||
1056 | #endif | ||
1057 | |||
1058 | /* UBI volume character device operations */ | ||
1059 | const struct file_operations ubi_vol_cdev_operations = { | ||
1060 | .owner = THIS_MODULE, | ||
1061 | .open = vol_cdev_open, | ||
1062 | .release = vol_cdev_release, | ||
1063 | .llseek = vol_cdev_llseek, | ||
1064 | .read = vol_cdev_read, | ||
1065 | .write = vol_cdev_write, | ||
1066 | .unlocked_ioctl = vol_cdev_ioctl, | ||
1067 | .compat_ioctl = vol_cdev_compat_ioctl, | ||
1031 | }; | 1068 | }; |
1032 | 1069 | ||
1033 | /* UBI character device operations */ | 1070 | /* UBI character device operations */ |
1034 | const struct file_operations ubi_cdev_operations = { | 1071 | const struct file_operations ubi_cdev_operations = { |
1035 | .owner = THIS_MODULE, | 1072 | .owner = THIS_MODULE, |
1036 | .ioctl = ubi_cdev_ioctl, | 1073 | .llseek = no_llseek, |
1037 | .llseek = no_llseek, | 1074 | .unlocked_ioctl = ubi_cdev_ioctl, |
1075 | .compat_ioctl = ubi_cdev_compat_ioctl, | ||
1038 | }; | 1076 | }; |
1039 | 1077 | ||
1040 | /* UBI volume character device operations */ | 1078 | /* UBI control character device operations */ |
1041 | const struct file_operations ubi_vol_cdev_operations = { | 1079 | const struct file_operations ubi_ctrl_cdev_operations = { |
1042 | .owner = THIS_MODULE, | 1080 | .owner = THIS_MODULE, |
1043 | .open = vol_cdev_open, | 1081 | .unlocked_ioctl = ctrl_cdev_ioctl, |
1044 | .release = vol_cdev_release, | 1082 | .compat_ioctl = ctrl_cdev_compat_ioctl, |
1045 | .llseek = vol_cdev_llseek, | ||
1046 | .read = vol_cdev_read, | ||
1047 | .write = vol_cdev_write, | ||
1048 | .ioctl = vol_cdev_ioctl, | ||
1049 | }; | 1083 | }; |