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

Commit d0f7959e authored by Roman Tereshonkov's avatar Roman Tereshonkov Committed by David Woodhouse
Browse files

mtd: add BLKPG API based repartition support



Add support for mtd repartition based on the block
device BLKPG interface:
BLKPG_ADD_PARTITION - for partition creation;
BLKPG_DEL_PARTITION - for partition delete

The usage is based on BLKPG ioctl called with
struct blkpg_ioctl_arg argument which includes the
reference to struct blkpg_partition discribing the
partition offset and length.

Disadvantage: there is no implementation for mtd
flags control. The flags are always borrowed from
the master device.

Signed-off-by: default avatarRoman Tereshonkov <roman.tereshonkov@nokia.com>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 5daa7b21
Loading
Loading
Loading
Loading
+58 −2
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@
#include <linux/backing-dev.h>
#include <linux/compat.h>
#include <linux/mount.h>

#include <linux/blkpg.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/map.h>

#include <asm/uaccess.h>
@@ -510,6 +511,45 @@ static int shrink_ecclayout(const struct nand_ecclayout *from,
	return 0;
}

#ifdef CONFIG_MTD_PARTITIONS
static int mtd_blkpg_ioctl(struct mtd_info *mtd,
			   struct blkpg_ioctl_arg __user *arg)
{
	struct blkpg_ioctl_arg a;
	struct blkpg_partition p;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	/* Only master mtd device must be used to control partitions */
	if (!mtd_is_master(mtd))
		return -EINVAL;

	if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
		return -EFAULT;

	if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
		return -EFAULT;

	switch (a.op) {
	case BLKPG_ADD_PARTITION:

		return mtd_add_partition(mtd, p.devname, p.start, p.length);

	case BLKPG_DEL_PARTITION:

		if (p.pno < 0)
			return -EINVAL;

		return mtd_del_partition(mtd, p.pno);

	default:
		return -EINVAL;
	}
}
#endif


static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
{
	struct mtd_file_info *mfi = file->private_data;
@@ -900,6 +940,22 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
		break;
	}

#ifdef CONFIG_MTD_PARTITIONS
	case BLKPG:
	{
		ret = mtd_blkpg_ioctl(mtd,
		      (struct blkpg_ioctl_arg __user *)arg);
		break;
	}

	case BLKRRPART:
	{
		/* No reread partition feature. Just return ok */
		ret = 0;
		break;
	}
#endif

	default:
		ret = -ENOTTY;
	}