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