[PATCH] mtdpart: More flexible dynamic partitioning

Boris Brezillon boris.brezillon at free-electrons.com
Tue Feb 10 23:52:42 PST 2015


Hi Dan,

On Thu,  5 Feb 2015 10:48:01 -0800
Dan Ehrenberg <dehrenberg at chromium.org> wrote:

> MTD allows dynamic partitioning by the BLKPG ioctl.
> This patch makes dynamic partitioning more flexible by:
> - Allowing addition of a partition to be added on top of another
>   partition. The two partitions compose naturally: the offsets are added
>   and lengths are checked to be in bounds. This is useful when
>   repartitioning an existing partitioned device since the underlying
>   device doesn't exist to add partitions to.
> - Removing overlap checks for dynamic partitions. I don't see any
>   particular reason why overlapping dynamic partitions should be
>   prohibited while static partitions are allowed to overlap freely, and
>   this is useful for users who want one additional partition to span
>   over the whole device.
> - Allowing partitions to be deleted by referencing any partition with
>   the same master. For example, if you have /dev/mtd0 and /dev/mtd1 both
>   partitions on the same underlying device, then you can call
>   BLKPG_DEL_PARTITION with an fd of /dev/mtd0 and pno of /dev/mtd1, and
>   /dev/mtd1 will be deleted (as opposed to returning EINVAL to signal a
>   missing partition, which it did previously).
> 
> Signed-off-by: Dan Ehrenberg <dehrenberg at chromium.org>
> ---
>  drivers/mtd/mtdchar.c |  4 ----
>  drivers/mtd/mtdpart.c | 32 ++++++++++++++++----------------
>  2 files changed, 16 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> index 5356395..30215c7 100644
> --- a/drivers/mtd/mtdchar.c
> +++ b/drivers/mtd/mtdchar.c
> @@ -545,10 +545,6 @@ static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
>  	switch (a.op) {
>  	case BLKPG_ADD_PARTITION:
>  
> -		/* Only master mtd device must be used to add partitions */
> -		if (mtd_is_partition(mtd))
> -			return -EINVAL;
> -
>  		/* Sanitize user input */
>  		p.devname[BLKPG_DEVNAMELTH - 1] = '\0';
>  
> diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
> index a3e3a7d..7874bbd 100644
> --- a/drivers/mtd/mtdpart.c
> +++ b/drivers/mtd/mtdpart.c
> @@ -551,7 +551,7 @@ int mtd_add_partition(struct mtd_info *master, const char *name,

Since you no longer require the first argument to be a master mtd
device maybe you should rename it.

>  		      long long offset, long long length)
>  {
>  	struct mtd_partition part;
> -	struct mtd_part *p, *new;
> +	struct mtd_part *new;
>  	uint64_t start, end;
>  	int ret = 0;
>  
> @@ -566,6 +566,12 @@ int mtd_add_partition(struct mtd_info *master, const char *name,
>  	if (length <= 0)
>  		return -EINVAL;
>  
> +	if (mtd_is_partition(master)) {
> +		struct mtd_part *master_partition = PART(master);
> +		offset += master_partition->offset;
> +		master = master_partition->master;
> +	}
> +
>  	part.name = name;
>  	part.size = length;
>  	part.offset = offset;
> @@ -580,27 +586,12 @@ int mtd_add_partition(struct mtd_info *master, const char *name,
>  	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_GPL(mtd_add_partition);
>  
> @@ -609,6 +600,15 @@ int mtd_del_partition(struct mtd_info *master, int partno)

Ditto.

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com



More information about the linux-mtd mailing list