* [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).