public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] mtdpart: More flexible dynamic partitioning
@ 2015-02-05 18:48 Dan Ehrenberg
  2015-02-10 21:50 ` Ezequiel Garcia
  2015-02-11  7:52 ` Boris Brezillon
  0 siblings, 2 replies; 3+ messages in thread
From: Dan Ehrenberg @ 2015-02-05 18:48 UTC (permalink / raw)
  To: linux-mtd, richard.weinberger; +Cc: namnguyen, grundler, gwendal, Dan Ehrenberg

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@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,
 		      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)
 	struct mtd_part *slave, *next;
 	int ret = -EINVAL;
 
+	/* If del_partition was called as a partition, just treat
+	 * this as if it were called on its master. This is a harmless
+	 * generalization and lets partitions be deleted in a system
+	 * where they are sometimes already present on boot */
+	if (mtd_is_partition(master)) {
+		struct mtd_part *master_partition = PART(master);
+		master = master_partition->master;
+	}
+
 	mutex_lock(&mtd_partitions_mutex);
 	list_for_each_entry_safe(slave, next, &mtd_partitions, list)
 		if ((slave->master == master) &&
-- 
2.2.0.rc0.207.ga3a616c

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

end of thread, other threads:[~2015-02-11  7:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-05 18:48 [PATCH] mtdpart: More flexible dynamic partitioning Dan Ehrenberg
2015-02-10 21:50 ` Ezequiel Garcia
2015-02-11  7:52 ` Boris Brezillon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox