[PATCH V5 2/4] mtd: partitions: add support for allocating subpartition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




From: Rafał Miłecki <rafal@xxxxxxxxxx>

Some flash device partitions can be containers with extra subpartitions
(volumes). When allocating subpartition it should be validated against
its parent but its master pointer has to point flash device. It's needed
to make all callbacks like part_read work as expected. It also has to
have offset calculated correctly.

This patch modifies allocate_partition to detect if provided parent is
an existing partition and sets "master" and "offset" correctly if so.

Signed-off-by: Rafał Miłecki <rafal@xxxxxxxxxx>
---
V5: Introduction of this patch to handle offset in allocate_partition
    and avoid casting const to non-const in mtd_parse_part.
---
 drivers/mtd/mtdpart.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 92acd89e07cb..8a0629449804 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -37,7 +37,13 @@
 static LIST_HEAD(mtd_partitions);
 static DEFINE_MUTEX(mtd_partitions_mutex);
 
-/* Our partition node structure */
+/**
+ * struct mtd_part - our partition node structure
+ *
+ * @mtd: struct holding partition details
+ * @master: pointer to the flash device MTD struct
+ * @offset: partition offset relative to the *flash device*
+ */
 struct mtd_part {
 	struct mtd_info mtd;
 	struct mtd_info *master;
@@ -393,9 +399,18 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
 			const struct mtd_partition *part, int partno,
 			uint64_t cur_offset)
 {
+	struct mtd_info *master = parent;
 	struct mtd_part *slave;
+	uint64_t parent_offset = 0;
 	char *name;
 
+	if (mtd_is_partition(parent)) {
+		struct mtd_part *parent_part = mtd_to_part(parent);
+
+		master = parent_part->master;
+		parent_offset = parent_part->offset;
+	}
+
 	/* allocate the partition structure */
 	slave = kzalloc(sizeof(*slave), GFP_KERNEL);
 	name = kstrdup(part->name, GFP_KERNEL);
@@ -493,12 +508,12 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
 		slave->mtd._put_device = part_put_device;
 
 	slave->mtd._erase = part_erase;
-	slave->master = parent;
-	slave->offset = part->offset;
+	slave->master = master;
+	slave->offset = parent_offset + part->offset;
 
-	if (slave->offset == MTDPART_OFS_APPEND)
+	if (part->offset == MTDPART_OFS_APPEND)
 		slave->offset = cur_offset;
-	if (slave->offset == MTDPART_OFS_NXTBLK) {
+	if (part->offset == MTDPART_OFS_NXTBLK) {
 		slave->offset = cur_offset;
 		if (mtd_mod_by_eb(cur_offset, parent) != 0) {
 			/* Round up to next erasesize */
@@ -508,7 +523,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
 			       (unsigned long long)cur_offset, (unsigned long long)slave->offset);
 		}
 	}
-	if (slave->offset == MTDPART_OFS_RETAIN) {
+	if (part->offset == MTDPART_OFS_RETAIN) {
 		slave->offset = cur_offset;
 		if (parent->size - slave->offset >= slave->mtd.size) {
 			slave->mtd.size = parent->size - slave->offset
@@ -536,8 +551,8 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
 			part->name);
 		goto out_register;
 	}
-	if (slave->offset + slave->mtd.size > parent->size) {
-		slave->mtd.size = parent->size - slave->offset;
+	if (slave->offset + slave->mtd.size > parent_offset + parent->size) {
+		slave->mtd.size = parent_offset + parent->size - slave->offset;
 		printk(KERN_WARNING"mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#llx\n",
 			part->name, parent->name, (unsigned long long)slave->mtd.size);
 	}
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux