linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] mtd: add BLKPG API based repartition support
@ 2010-09-17 10:31 Roman Tereshonkov
  2010-09-17 10:31 ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Roman Tereshonkov
  2010-09-20 12:42 ` [PATCH 0/2] mtd: add BLKPG API based repartition support Artem Bityutskiy
  0 siblings, 2 replies; 6+ messages in thread
From: Roman Tereshonkov @ 2010-09-17 10:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: dwmw2, Roman Tereshonkov


    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. This structure includes the
    reference to struct blkpg_partition discribing the
    partition name, offset and length for partition creation
    and partition number for its deletion.

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

Roman Tereshonkov (2):
  mtd: prepare partition add and del functions for ioctl requests
  mtd: add BLKPG API based repartition support

 drivers/mtd/mtdchar.c          |   62 ++++++++++++++++-
 drivers/mtd/mtdpart.c          |  154 +++++++++++++++++++++++++++++++++++-----
 include/linux/mtd/partitions.h |    5 ++
 3 files changed, 201 insertions(+), 20 deletions(-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests
  2010-09-17 10:31 [PATCH 0/2] mtd: add BLKPG API based repartition support Roman Tereshonkov
@ 2010-09-17 10:31 ` Roman Tereshonkov
  2010-09-17 10:31   ` [PATCH 2/2] mtd: add BLKPG API based repartition support Roman Tereshonkov
  2010-09-20  8:50   ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Artem Bityutskiy
  2010-09-20 12:42 ` [PATCH 0/2] mtd: add BLKPG API based repartition support Artem Bityutskiy
  1 sibling, 2 replies; 6+ messages in thread
From: Roman Tereshonkov @ 2010-09-17 10:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: dwmw2, Roman Tereshonkov

mtd_is_master, mtd_add_partition and mtd_del_partition functions
are added to give the possibility of partition manipulation
by ioctl request.

The old partition add function is modified to fit the dynamic
allocation.

Signed-off-by: Roman Tereshonkov <roman.tereshonkov@nokia.com>
---
 drivers/mtd/mtdpart.c          |  154 +++++++++++++++++++++++++++++++++++-----
 include/linux/mtd/partitions.h |    5 ++
 2 files changed, 141 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index dc65585..726c287 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -29,9 +29,11 @@
 #include <linux/kmod.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/err.h>
 
 /* Our partition linked list */
 static LIST_HEAD(mtd_partitions);
+static DEFINE_MUTEX(mtd_partitions_mutex);
 
 /* Our partition node structure */
 struct mtd_part {
@@ -326,6 +328,12 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	return res;
 }
 
+static inline void free_partition(struct mtd_part *p)
+{
+	kfree(p->mtd.name);
+	kfree(p);
+}
+
 /*
  * This function unregisters and destroy all slave MTD objects which are
  * attached to the given master MTD object.
@@ -334,33 +342,42 @@ static int part_block_markbad(struct mtd_info *mtd, loff_t ofs)
 int del_mtd_partitions(struct mtd_info *master)
 {
 	struct mtd_part *slave, *next;
+	int ret, err = 0;
 
+	mutex_lock(&mtd_partitions_mutex);
 	list_for_each_entry_safe(slave, next, &mtd_partitions, list)
 		if (slave->master == master) {
+			ret = del_mtd_device(&slave->mtd);
+			if (ret < 0) {
+				err = ret;
+				continue;
+			}
 			list_del(&slave->list);
-			del_mtd_device(&slave->mtd);
-			kfree(slave);
+			free_partition(slave);
 		}
+	mutex_unlock(&mtd_partitions_mutex);
 
-	return 0;
+	return err;
 }
 EXPORT_SYMBOL(del_mtd_partitions);
 
-static struct mtd_part *add_one_partition(struct mtd_info *master,
-		const struct mtd_partition *part, int partno,
-		uint64_t cur_offset)
+static struct mtd_part *allocate_partition(struct mtd_info *master,
+			const struct mtd_partition *part, int partno,
+			uint64_t cur_offset)
 {
 	struct mtd_part *slave;
+	char *name;
 
 	/* allocate the partition structure */
 	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
-	if (!slave) {
+	name = kstrdup(part->name, GFP_KERNEL);
+	if (!name || !slave) {
 		printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n",
-			master->name);
-		del_mtd_partitions(master);
-		return NULL;
+		       master->name);
+		kfree(name);
+		kfree(slave);
+		return ERR_PTR(-ENOMEM);
 	}
-	list_add(&slave->list, &mtd_partitions);
 
 	/* set up the MTD object for this partition */
 	slave->mtd.type = master->type;
@@ -371,7 +388,7 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
 	slave->mtd.oobavail = master->oobavail;
 	slave->mtd.subpage_sft = master->subpage_sft;
 
-	slave->mtd.name = part->name;
+	slave->mtd.name = name;
 	slave->mtd.owner = master->owner;
 	slave->mtd.backing_dev_info = master->backing_dev_info;
 
@@ -518,12 +535,89 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
 	}
 
 out_register:
-	/* register our partition */
-	add_mtd_device(&slave->mtd);
-
 	return slave;
 }
 
+int mtd_add_partition(struct mtd_info *master, char *name,
+		      long long offset, long long length)
+{
+	struct mtd_partition part;
+	struct mtd_part *p, *new;
+	uint64_t start, end;
+	int ret = 0;
+
+	/* the direct offset is expected */
+	if (offset == MTDPART_OFS_APPEND ||
+	    offset == MTDPART_OFS_NXTBLK)
+		return -EINVAL;
+
+	if (length == MTDPART_SIZ_FULL)
+		length = master->size - offset;
+
+	if (length <= 0)
+		return -EINVAL;
+
+	part.name = name;
+	part.size = length;
+	part.offset = offset;
+	part.mask_flags = 0;
+	part.ecclayout = NULL;
+
+	new = allocate_partition(master, &part, -1, offset);
+	if (IS_ERR(new))
+		return PTR_ERR(new);
+
+	start = offset;
+	end = offset + length;
+
+	mutex_lock(&mtd_partitions_mutex);
+	list_for_each_entry(p, &mtd_partitions, list)
+		if (p->master == master) {
+			if ((start >= p->offset) &&
+			    (start < (p->offset + p->mtd.size)))
+				goto err_inv;
+
+			if ((end >= p->offset) &&
+			    (end < (p->offset + p->mtd.size)))
+				goto err_inv;
+		}
+
+	list_add(&new->list, &mtd_partitions);
+	mutex_unlock(&mtd_partitions_mutex);
+
+	add_mtd_device(&new->mtd);
+
+	return ret;
+err_inv:
+	mutex_unlock(&mtd_partitions_mutex);
+	free_partition(new);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(mtd_add_partition);
+
+int mtd_del_partition(struct mtd_info *master, int partno)
+{
+	struct mtd_part *slave, *next;
+	int ret = -EINVAL;
+
+	mutex_lock(&mtd_partitions_mutex);
+	list_for_each_entry_safe(slave, next, &mtd_partitions, list)
+		if ((slave->master == master) &&
+		    (slave->mtd.index == partno)) {
+			ret = del_mtd_device(&slave->mtd);
+			if (ret < 0)
+				break;
+
+			list_del(&slave->list);
+			free_partition(slave);
+			break;
+		}
+	mutex_unlock(&mtd_partitions_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(mtd_del_partition);
+
 /*
  * This function, given a master MTD object and a partition table, creates
  * and registers slave MTD objects which are bound to the master according to
@@ -544,9 +638,16 @@ int add_mtd_partitions(struct mtd_info *master,
 	printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
 
 	for (i = 0; i < nbparts; i++) {
-		slave = add_one_partition(master, parts + i, i, cur_offset);
-		if (!slave)
-			return -ENOMEM;
+		slave = allocate_partition(master, parts + i, i, cur_offset);
+		if (IS_ERR(slave))
+			return PTR_ERR(slave);
+
+		mutex_lock(&mtd_partitions_mutex);
+		list_add(&slave->list, &mtd_partitions);
+		mutex_unlock(&mtd_partitions_mutex);
+
+		add_mtd_device(&slave->mtd);
+
 		cur_offset = slave->offset + slave->mtd.size;
 	}
 
@@ -618,3 +719,20 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
 	return ret;
 }
 EXPORT_SYMBOL_GPL(parse_mtd_partitions);
+
+int mtd_is_master(struct mtd_info *mtd)
+{
+	struct mtd_part *part;
+	int nopart = 0;
+
+	mutex_lock(&mtd_partitions_mutex);
+	list_for_each_entry(part, &mtd_partitions, list)
+		if (&part->mtd == mtd) {
+			nopart = 1;
+			break;
+		}
+	mutex_unlock(&mtd_partitions_mutex);
+
+	return nopart;
+}
+EXPORT_SYMBOL(mtd_is_master);
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 274b619..ffab9a6 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -89,4 +89,9 @@ static inline int mtd_has_cmdlinepart(void) { return 1; }
 static inline int mtd_has_cmdlinepart(void) { return 0; }
 #endif
 
+int mtd_is_master(struct mtd_info *mtd);
+int mtd_add_partition(struct mtd_info *master, char *name,
+		      long long offset, long long length);
+int mtd_del_partition(struct mtd_info *master, int partno);
+
 #endif
-- 
1.6.2.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] mtd: add BLKPG API based repartition support
  2010-09-17 10:31 ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Roman Tereshonkov
@ 2010-09-17 10:31   ` Roman Tereshonkov
  2010-09-20  8:50   ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Artem Bityutskiy
  1 sibling, 0 replies; 6+ messages in thread
From: Roman Tereshonkov @ 2010-09-17 10:31 UTC (permalink / raw)
  To: linux-mtd; +Cc: dwmw2, Roman Tereshonkov

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: Roman Tereshonkov <roman.tereshonkov@nokia.com>
---
 drivers/mtd/mtdchar.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a825002..3171a4d 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -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>
@@ -477,6 +478,47 @@ static int mtd_do_readoob(struct mtd_info *mtd, uint64_t start,
 	return ret;
 }
 
+#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 -EACCES;
+
+	if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
+		return -EFAULT;
+
+	if (!access_ok(VERIFY_READ, a.data, sizeof(struct blkpg_partition)))
+		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;
@@ -855,6 +897,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;
 	}
@@ -1033,7 +1091,7 @@ static int mtd_inodefs_get_sb(struct file_system_type *fs_type, int flags,
                                const char *dev_name, void *data,
                                struct vfsmount *mnt)
 {
-        return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC,
+	return get_sb_pseudo(fs_type, "mtd_inode:", NULL, MTD_INODE_FS_MAGIC,
                              mnt);
 }
 
-- 
1.6.2.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests
  2010-09-17 10:31 ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Roman Tereshonkov
  2010-09-17 10:31   ` [PATCH 2/2] mtd: add BLKPG API based repartition support Roman Tereshonkov
@ 2010-09-20  8:50   ` Artem Bityutskiy
  2010-09-20 12:00     ` Artem Bityutskiy
  1 sibling, 1 reply; 6+ messages in thread
From: Artem Bityutskiy @ 2010-09-20  8:50 UTC (permalink / raw)
  To: Roman Tereshonkov; +Cc: dwmw2, linux-mtd

On Fri, 2010-09-17 at 13:31 +0300, Roman Tereshonkov wrote:
> +       list_for_each_entry(p, &mtd_partitions, list)
> +               if (p->master == master) {
> +                           (start < (p->offset + p->mtd.size)))
> +                               goto err_inv; 

Pardon?

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests
  2010-09-20  8:50   ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Artem Bityutskiy
@ 2010-09-20 12:00     ` Artem Bityutskiy
  0 siblings, 0 replies; 6+ messages in thread
From: Artem Bityutskiy @ 2010-09-20 12:00 UTC (permalink / raw)
  To: Roman Tereshonkov; +Cc: dwmw2, linux-mtd

On Mon, 2010-09-20 at 11:50 +0300, Artem Bityutskiy wrote:
> On Fri, 2010-09-17 at 13:31 +0300, Roman Tereshonkov wrote:
> > +       list_for_each_entry(p, &mtd_partitions, list)
> > +               if (p->master == master) {
> > +                           (start < (p->offset + p->mtd.size)))
> > +                               goto err_inv; 
> 
> Pardon?

Sorry, it is some Evolution (e-mail client) bug. The code is different,
it displays it incorrectly. I do not really why. The code is actually
different:

+               if (p->master == master) {
+                       if ((start >= p->offset) &&
+                           (start < (p->offset + p->mtd.size)))
+                               goto err_inv;

I really do not know why Evolution decided to kill the "if" line...

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] mtd: add BLKPG API based repartition support
  2010-09-17 10:31 [PATCH 0/2] mtd: add BLKPG API based repartition support Roman Tereshonkov
  2010-09-17 10:31 ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Roman Tereshonkov
@ 2010-09-20 12:42 ` Artem Bityutskiy
  1 sibling, 0 replies; 6+ messages in thread
From: Artem Bityutskiy @ 2010-09-20 12:42 UTC (permalink / raw)
  To: Roman Tereshonkov; +Cc: dwmw2, linux-mtd

On Fri, 2010-09-17 at 13:31 +0300, Roman Tereshonkov wrote:
> 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. This structure includes the
>     reference to struct blkpg_partition discribing the
>     partition name, offset and length for partition creation
>     and partition number for its deletion.
> 
>     Disadvantage: there is no implementation for mtd
>     flags control. The flags are always borrowed from
>     the master device.
> 
> Roman Tereshonkov (2):
>   mtd: prepare partition add and del functions for ioctl requests
>   mtd: add BLKPG API based repartition support
> 
>  drivers/mtd/mtdchar.c          |   62 ++++++++++++++++-
>  drivers/mtd/mtdpart.c          |  154 +++++++++++++++++++++++++++++++++++-----
>  include/linux/mtd/partitions.h |    5 ++
>  3 files changed, 201 insertions(+), 20 deletions(-)

The patches look good. Pushed to the l2-mtd-2.6.git tree with my
signature, thanks!

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-09-20 12:44 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-17 10:31 [PATCH 0/2] mtd: add BLKPG API based repartition support Roman Tereshonkov
2010-09-17 10:31 ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Roman Tereshonkov
2010-09-17 10:31   ` [PATCH 2/2] mtd: add BLKPG API based repartition support Roman Tereshonkov
2010-09-20  8:50   ` [PATCH 1/2] mtd: prepare partition add and del functions for ioctl requests Artem Bityutskiy
2010-09-20 12:00     ` Artem Bityutskiy
2010-09-20 12:42 ` [PATCH 0/2] mtd: add BLKPG API based repartition support Artem Bityutskiy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).