Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f429b2ea authored by Artem Bityutskiy's avatar Artem Bityutskiy
Browse files

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: default avatarGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 4d187a88
Loading
Loading
Loading
Loading
+57 −23
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <linux/ioctl.h>
#include <linux/capability.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <mtd/ubi-user.h>
#include <asm/div64.h>
#include "ubi.h"
@@ -401,8 +402,8 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf,
	return count;
}

static int vol_cdev_ioctl(struct inode *inode, struct file *file,
			  unsigned int cmd, unsigned long arg)
static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
			   unsigned long arg)
{
	int err = 0;
	struct ubi_volume_desc *desc = file->private_data;
@@ -800,8 +801,8 @@ static int rename_volumes(struct ubi_device *ubi,
	return err;
}

static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
			  unsigned int cmd, unsigned long arg)
static long ubi_cdev_ioctl(struct file *file, unsigned int cmd,
			   unsigned long arg)
{
	int err = 0;
	struct ubi_device *ubi;
@@ -811,7 +812,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
	if (!capable(CAP_SYS_RESOURCE))
		return -EPERM;

	ubi = ubi_get_by_major(imajor(inode));
	ubi = ubi_get_by_major(imajor(file->f_mapping->host));
	if (!ubi)
		return -ENODEV;

@@ -947,8 +948,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file,
	return err;
}

static int ctrl_cdev_ioctl(struct inode *inode, struct file *file,
			   unsigned int cmd, unsigned long arg)
static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd,
			    unsigned long arg)
{
	int err = 0;
	void __user *argp = (void __user *)arg;
@@ -1024,18 +1025,35 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file,
	return err;
}

/* UBI control character device operations */
const struct file_operations ubi_ctrl_cdev_operations = {
	.ioctl = ctrl_cdev_ioctl,
	.owner = THIS_MODULE,
};
#ifdef CONFIG_COMPAT
static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	unsigned long translated_arg = (unsigned long)compat_ptr(arg);

/* UBI character device operations */
const struct file_operations ubi_cdev_operations = {
	.owner = THIS_MODULE,
	.ioctl = ubi_cdev_ioctl,
	.llseek = no_llseek,
};
	return vol_cdev_ioctl(file, cmd, translated_arg);
}

static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd,
				  unsigned long arg)
{
	unsigned long translated_arg = (unsigned long)compat_ptr(arg);

	return ubi_cdev_ioctl(file, cmd, translated_arg);
}

static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd,
				   unsigned long arg)
{
	unsigned long translated_arg = (unsigned long)compat_ptr(arg);

	return ctrl_cdev_ioctl(file, cmd, translated_arg);
}
#else
#define vol_cdev_compat_ioctl  NULL
#define ubi_cdev_compat_ioctl  NULL
#define ctrl_cdev_compat_ioctl NULL
#endif

/* UBI volume character device operations */
const struct file_operations ubi_vol_cdev_operations = {
@@ -1045,5 +1063,21 @@ const struct file_operations ubi_vol_cdev_operations = {
	.llseek         = vol_cdev_llseek,
	.read           = vol_cdev_read,
	.write          = vol_cdev_write,
	.ioctl   = vol_cdev_ioctl,
	.unlocked_ioctl = vol_cdev_ioctl,
	.compat_ioctl   = vol_cdev_compat_ioctl,
};

/* UBI character device operations */
const struct file_operations ubi_cdev_operations = {
	.owner          = THIS_MODULE,
	.llseek         = no_llseek,
	.unlocked_ioctl = ubi_cdev_ioctl,
	.compat_ioctl   = ubi_cdev_compat_ioctl,
};

/* UBI control character device operations */
const struct file_operations ubi_ctrl_cdev_operations = {
	.owner          = THIS_MODULE,
	.unlocked_ioctl = ctrl_cdev_ioctl,
	.compat_ioctl   = ctrl_cdev_compat_ioctl,
};