aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-01-16 11:06:55 -0500
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-01-18 07:27:41 -0500
commitf429b2ea8eadb5a576542a70f7fd6f5c2a7455e1 (patch)
tree6ab9541042979cc7bdcb0257dfdd6435577ad3a8 /drivers/mtd
parent4d187a88d3ee3be6a1a0b6859eb00f70e1601b5e (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/mtd')
-rw-r--r--drivers/mtd/ubi/cdev.c80
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
404static int vol_cdev_ioctl(struct inode *inode, struct file *file, 405static 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
803static int ubi_cdev_ioctl(struct inode *inode, struct file *file, 804static 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
950static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, 951static 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
1028const struct file_operations ubi_ctrl_cdev_operations = { 1029static 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
1037static 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
1045static 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 */
1059const 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 */
1034const struct file_operations ubi_cdev_operations = { 1071const 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 */
1041const struct file_operations ubi_vol_cdev_operations = { 1079const 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};