All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.