[source] kernel: backport upstream mtd support for partition parsers

LEDE Commits lede-commits at lists.infradead.org
Fri Jun 23 02:55:58 PDT 2017


rmilecki pushed a commit to source.git, branch master:
https://git.lede-project.org/4d5f296af857ecbd3916d1d156d1bc63c998995a

commit 4d5f296af857ecbd3916d1d156d1bc63c998995a
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Fri Jun 23 10:47:18 2017 +0200

    kernel: backport upstream mtd support for partition parsers
    
    In a log term it should replace our implementation. For now both can
    coexist.
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 ...-partitions-add-support-for-subpartitions.patch |  96 ++++++++++++++++++
 ...titions-add-support-for-partition-parsers.patch | 110 +++++++++++++++++++++
 ...t-add-generic-parsing-of-linux-part-probe.patch |   6 +-
 .../400-mtd-add-rootfs-split-support.patch         |  12 +--
 ...port-for-different-partition-parser-types.patch |   8 +-
 ...mtd-parsers-for-rootfs-and-firmware-split.patch |   8 +-
 .../404-mtd-add-more-helper-functions.patch        |   6 +-
 ...ve-forward-declaration-of-struct-mtd_info.patch |   4 +-
 .../411-mtd-partial_eraseblock_write.patch         |   2 +-
 9 files changed, 229 insertions(+), 23 deletions(-)

diff --git a/target/linux/generic/patches-4.9/065-v4.13-0006-mtd-partitions-add-support-for-subpartitions.patch b/target/linux/generic/patches-4.9/065-v4.13-0006-mtd-partitions-add-support-for-subpartitions.patch
new file mode 100644
index 0000000..0d3e10a
--- /dev/null
+++ b/target/linux/generic/patches-4.9/065-v4.13-0006-mtd-partitions-add-support-for-subpartitions.patch
@@ -0,0 +1,96 @@
+From 97519dc52b44af054d7654776e78eaa211cf1842 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 21 Jun 2017 08:26:45 +0200
+Subject: [PATCH] mtd: partitions: add support for subpartitions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some flash device partitions can be containers with extra subpartitions
+(volumes). All callbacks are already capable of this additional level of
+indirection.
+
+This patch makes sure we always display subpartitions using a tree
+structure and takes care of deleting subpartitions when parent gets
+removed.
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Signed-off-by: Brian Norris <computersforpeace at gmail.com>
+---
+ drivers/mtd/mtdpart.c | 23 ++++++++++++++++-------
+ 1 file changed, 16 insertions(+), 7 deletions(-)
+
+--- a/drivers/mtd/mtdpart.c
++++ b/drivers/mtd/mtdpart.c
+@@ -413,7 +413,7 @@ static struct mtd_part *allocate_partiti
+ 	 * parent conditional on that option. Note, this is a way to
+ 	 * distinguish between the master and the partition in sysfs.
+ 	 */
+-	slave->mtd.dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) ?
++	slave->mtd.dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd_is_partition(parent) ?
+ 				&parent->dev :
+ 				parent->dev.parent;
+ 	slave->mtd.dev.of_node = part->of_node;
+@@ -664,8 +664,17 @@ EXPORT_SYMBOL_GPL(mtd_add_partition);
+  */
+ static int __mtd_del_partition(struct mtd_part *priv)
+ {
++	struct mtd_part *child, *next;
+ 	int err;
+ 
++	list_for_each_entry_safe(child, next, &mtd_partitions, list) {
++		if (child->parent == &priv->mtd) {
++			err = __mtd_del_partition(child);
++			if (err)
++				return err;
++		}
++	}
++
+ 	sysfs_remove_files(&priv->mtd.dev.kobj, mtd_partition_attrs);
+ 
+ 	err = del_mtd_device(&priv->mtd);
+@@ -680,16 +689,16 @@ static int __mtd_del_partition(struct mt
+ 
+ /*
+  * This function unregisters and destroy all slave MTD objects which are
+- * attached to the given master MTD object.
++ * attached to the given MTD object.
+  */
+-int del_mtd_partitions(struct mtd_info *master)
++int del_mtd_partitions(struct mtd_info *mtd)
+ {
+ 	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->parent == master) {
++		if (slave->parent == mtd) {
+ 			ret = __mtd_del_partition(slave);
+ 			if (ret < 0)
+ 				err = ret;
+@@ -699,14 +708,14 @@ int del_mtd_partitions(struct mtd_info *
+ 	return err;
+ }
+ 
+-int mtd_del_partition(struct mtd_info *master, int partno)
++int mtd_del_partition(struct mtd_info *mtd, 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->parent == master) &&
++		if ((slave->parent == mtd) &&
+ 		    (slave->mtd.index == partno)) {
+ 			ret = __mtd_del_partition(slave);
+ 			break;
+@@ -939,6 +948,6 @@ uint64_t mtd_get_device_size(const struc
+ 	if (!mtd_is_partition(mtd))
+ 		return mtd->size;
+ 
+-	return mtd_to_part(mtd)->parent->size;
++	return mtd_get_device_size(mtd_to_part(mtd)->parent);
+ }
+ EXPORT_SYMBOL_GPL(mtd_get_device_size);
diff --git a/target/linux/generic/patches-4.9/065-v4.13-0007-mtd-partitions-add-support-for-partition-parsers.patch b/target/linux/generic/patches-4.9/065-v4.13-0007-mtd-partitions-add-support-for-partition-parsers.patch
new file mode 100644
index 0000000..a28ee31
--- /dev/null
+++ b/target/linux/generic/patches-4.9/065-v4.13-0007-mtd-partitions-add-support-for-partition-parsers.patch
@@ -0,0 +1,110 @@
+From 1a0915be192606fee64830b9c5d70b7ed59426b6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 21 Jun 2017 08:26:46 +0200
+Subject: [PATCH] mtd: partitions: add support for partition parsers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Some devices have partitions that are kind of containers with extra
+subpartitions / volumes instead of e.g. a simple filesystem data. To
+support such cases we need to first create normal flash device
+partitions and then take care of these special ones.
+
+It's very common case for home routers. Depending on the vendor there
+are formats like TRX, Seama, TP-Link, WRGG & more. All of them are used
+to embed few partitions into a single one / single firmware file.
+
+Ideally all vendors would use some well documented / standardized format
+like UBI (and some probably start doing so), but there are still
+countless devices on the market using these poor vendor specific
+formats.
+
+This patch extends MTD subsystem by allowing to specify list of parsers
+that should be tried for a given partition. Supporting such poor formats
+is highly unlikely to be the top priority so these changes try to
+minimize maintenance cost to the minimum. It reuses existing code for
+these new parsers and just adds a one property and one new function.
+
+This implementation requires setting partition parsers in a flash
+parser. A proper change of bcm47xxpart will follow and in the future we
+will hopefully also find a solution for doing it with ofpart
+("fixed-partitions").
+
+Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
+Signed-off-by: Brian Norris <computersforpeace at gmail.com>
+---
+ drivers/mtd/mtdpart.c          | 31 +++++++++++++++++++++++++++++++
+ include/linux/mtd/partitions.h |  7 +++++++
+ 2 files changed, 38 insertions(+)
+
+--- a/drivers/mtd/mtdpart.c
++++ b/drivers/mtd/mtdpart.c
+@@ -369,6 +369,35 @@ static inline void free_partition(struct
+ 	kfree(p);
+ }
+ 
++/**
++ * mtd_parse_part - parse MTD partition looking for subpartitions
++ *
++ * @slave: part that is supposed to be a container and should be parsed
++ * @types: NULL-terminated array with names of partition parsers to try
++ *
++ * Some partitions are kind of containers with extra subpartitions (volumes).
++ * There can be various formats of such containers. This function tries to use
++ * specified parsers to analyze given partition and registers found
++ * subpartitions on success.
++ */
++static int mtd_parse_part(struct mtd_part *slave, const char *const *types)
++{
++	struct mtd_partitions parsed;
++	int err;
++
++	err = parse_mtd_partitions(&slave->mtd, types, &parsed, NULL);
++	if (err)
++		return err;
++	else if (!parsed.nr_parts)
++		return -ENOENT;
++
++	err = add_mtd_partitions(&slave->mtd, parsed.parts, parsed.nr_parts);
++
++	mtd_part_parser_cleanup(&parsed);
++
++	return err;
++}
++
+ static struct mtd_part *allocate_partition(struct mtd_info *parent,
+ 			const struct mtd_partition *part, int partno,
+ 			uint64_t cur_offset)
+@@ -758,6 +787,8 @@ int add_mtd_partitions(struct mtd_info *
+ 
+ 		add_mtd_device(&slave->mtd);
+ 		mtd_add_partition_attrs(slave);
++		if (parts[i].types)
++			mtd_parse_part(slave, parts[i].types);
+ 
+ 		cur_offset = slave->offset + slave->mtd.size;
+ 	}
+--- a/include/linux/mtd/partitions.h
++++ b/include/linux/mtd/partitions.h
+@@ -20,6 +20,12 @@
+  *
+  * For each partition, these fields are available:
+  * name: string that will be used to label the partition's MTD device.
++ * types: some partitions can be containers using specific format to describe
++ *	embedded subpartitions / volumes. E.g. many home routers use "firmware"
++ *	partition that contains at least kernel and rootfs. In such case an
++ *	extra parser is needed that will detect these dynamic partitions and
++ *	report them to the MTD subsystem. If set this property stores an array
++ *	of parser names to use when looking for subpartitions.
+  * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition
+  * 	will extend to the end of the master MTD device.
+  * offset: absolute starting position within the master MTD device; if
+@@ -38,6 +44,7 @@
+ 
+ struct mtd_partition {
+ 	const char *name;		/* identifier string */
++	const char *const *types;	/* names of parsers to use if any */
+ 	uint64_t size;			/* partition size */
+ 	uint64_t offset;		/* offset within the master MTD space */
+ 	uint32_t mask_flags;		/* master MTD flags to mask out for this partition */
diff --git a/target/linux/generic/patches-4.9/160-mtd-part-add-generic-parsing-of-linux-part-probe.patch b/target/linux/generic/patches-4.9/160-mtd-part-add-generic-parsing-of-linux-part-probe.patch
index 8bca58a..41609d5 100644
--- a/target/linux/generic/patches-4.9/160-mtd-part-add-generic-parsing-of-linux-part-probe.patch
+++ b/target/linux/generic/patches-4.9/160-mtd-part-add-generic-parsing-of-linux-part-probe.patch
@@ -116,7 +116,7 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
  #include <linux/err.h>
  
  #include "mtdcore.h"
-@@ -815,6 +816,42 @@ void deregister_mtd_parser(struct mtd_pa
+@@ -855,6 +856,42 @@ void deregister_mtd_parser(struct mtd_pa
  EXPORT_SYMBOL_GPL(deregister_mtd_parser);
  
  /*
@@ -159,7 +159,7 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
   * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
   * are changing this array!
   */
-@@ -872,6 +909,13 @@ int parse_mtd_partitions(struct mtd_info
+@@ -912,6 +949,13 @@ int parse_mtd_partitions(struct mtd_info
  {
  	struct mtd_part_parser *parser;
  	int ret, err = 0;
@@ -173,7 +173,7 @@ Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
  
  	if (!types)
  		types = default_mtd_part_types;
-@@ -897,6 +941,7 @@ int parse_mtd_partitions(struct mtd_info
+@@ -937,6 +981,7 @@ int parse_mtd_partitions(struct mtd_info
  		if (ret < 0 && !err)
  			err = ret;
  	}
diff --git a/target/linux/generic/patches-4.9/400-mtd-add-rootfs-split-support.patch b/target/linux/generic/patches-4.9/400-mtd-add-rootfs-split-support.patch
index bc402a2..96a50c8 100644
--- a/target/linux/generic/patches-4.9/400-mtd-add-rootfs-split-support.patch
+++ b/target/linux/generic/patches-4.9/400-mtd-add-rootfs-split-support.patch
@@ -48,7 +48,7 @@
  /*
   * Given a pointer to the MTD object in the mtd_part structure, we can retrieve
   * the pointer to that structure.
-@@ -649,6 +653,7 @@ int mtd_add_partition(struct mtd_info *p
+@@ -678,6 +682,7 @@ int mtd_add_partition(struct mtd_info *p
  	mutex_unlock(&mtd_partitions_mutex);
  
  	add_mtd_device(&new->mtd);
@@ -56,7 +56,7 @@
  
  	mtd_add_partition_attrs(new);
  
-@@ -718,6 +723,35 @@ int mtd_del_partition(struct mtd_info *m
+@@ -756,6 +761,35 @@ int mtd_del_partition(struct mtd_info *m
  }
  EXPORT_SYMBOL_GPL(mtd_del_partition);
  
@@ -92,17 +92,17 @@
  /*
   * 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
-@@ -749,6 +783,7 @@ int add_mtd_partitions(struct mtd_info *
+@@ -787,6 +821,7 @@ int add_mtd_partitions(struct mtd_info *
  		mutex_unlock(&mtd_partitions_mutex);
  
  		add_mtd_device(&slave->mtd);
 +		mtd_partition_split(master, slave);
  		mtd_add_partition_attrs(slave);
- 
- 		cur_offset = slave->offset + slave->mtd.size;
+ 		if (parts[i].types)
+ 			mtd_parse_part(slave, parts[i].types);
 --- a/include/linux/mtd/partitions.h
 +++ b/include/linux/mtd/partitions.h
-@@ -102,5 +102,7 @@ int mtd_add_partition(struct mtd_info *m
+@@ -109,5 +109,7 @@ int mtd_add_partition(struct mtd_info *m
  		      long long offset, long long length);
  int mtd_del_partition(struct mtd_info *master, int partno);
  uint64_t mtd_get_device_size(const struct mtd_info *mtd);
diff --git a/target/linux/generic/patches-4.9/401-mtd-add-support-for-different-partition-parser-types.patch b/target/linux/generic/patches-4.9/401-mtd-add-support-for-different-partition-parser-types.patch
index 71a97a0..2cf69ff 100644
--- a/target/linux/generic/patches-4.9/401-mtd-add-support-for-different-partition-parser-types.patch
+++ b/target/linux/generic/patches-4.9/401-mtd-add-support-for-different-partition-parser-types.patch
@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
 
 --- a/drivers/mtd/mtdpart.c
 +++ b/drivers/mtd/mtdpart.c
-@@ -996,6 +996,62 @@ void mtd_part_parser_cleanup(struct mtd_
+@@ -1036,6 +1036,62 @@ void mtd_part_parser_cleanup(struct mtd_
  	}
  }
  
@@ -76,7 +76,7 @@ Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
  	struct mtd_part *part;
 --- a/include/linux/mtd/partitions.h
 +++ b/include/linux/mtd/partitions.h
-@@ -61,11 +61,14 @@ struct mtd_part_parser_data {
+@@ -68,11 +68,14 @@ struct mtd_part_parser_data {
  	unsigned long origin;
  };
  
@@ -92,7 +92,7 @@ Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
  struct mtd_part_parser {
  	struct list_head list;
  	struct module *owner;
-@@ -73,6 +76,7 @@ struct mtd_part_parser {
+@@ -80,6 +83,7 @@ struct mtd_part_parser {
  	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
  			struct mtd_part_parser_data *);
  	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
@@ -100,7 +100,7 @@ Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
  };
  
  /* Container for passing around a set of parsed partitions */
-@@ -105,4 +109,9 @@ uint64_t mtd_get_device_size(const struc
+@@ -112,4 +116,9 @@ uint64_t mtd_get_device_size(const struc
  extern void __weak arch_split_mtd_part(struct mtd_info *master,
  				       const char *name, int offset, int size);
  
diff --git a/target/linux/generic/patches-4.9/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch b/target/linux/generic/patches-4.9/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch
index 02fb9cc..490107e 100644
--- a/target/linux/generic/patches-4.9/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch
+++ b/target/linux/generic/patches-4.9/402-mtd-use-typed-mtd-parsers-for-rootfs-and-firmware-split.patch
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/mtdpart.c
 +++ b/drivers/mtd/mtdpart.c
-@@ -723,6 +723,36 @@ int mtd_del_partition(struct mtd_info *m
+@@ -761,6 +761,36 @@ int mtd_del_partition(struct mtd_info *m
  }
  EXPORT_SYMBOL_GPL(mtd_del_partition);
  
@@ -37,7 +37,7 @@
  #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
  #define SPLIT_FIRMWARE_NAME	CONFIG_MTD_SPLIT_FIRMWARE_NAME
  #else
-@@ -731,6 +761,7 @@ EXPORT_SYMBOL_GPL(mtd_del_partition);
+@@ -769,6 +799,7 @@ EXPORT_SYMBOL_GPL(mtd_del_partition);
  
  static void split_firmware(struct mtd_info *master, struct mtd_part *part)
  {
@@ -45,7 +45,7 @@
  }
  
  void __weak arch_split_mtd_part(struct mtd_info *master, const char *name,
-@@ -745,6 +776,12 @@ static void mtd_partition_split(struct m
+@@ -783,6 +814,12 @@ static void mtd_partition_split(struct m
  	if (rootfs_found)
  		return;
  
@@ -60,7 +60,7 @@
  		split_firmware(master, part);
 --- a/include/linux/mtd/partitions.h
 +++ b/include/linux/mtd/partitions.h
-@@ -67,6 +67,8 @@ struct mtd_part_parser_data {
+@@ -74,6 +74,8 @@ struct mtd_part_parser_data {
  
  enum mtd_parser_type {
  	MTD_PARSER_TYPE_DEVICE = 0,
diff --git a/target/linux/generic/patches-4.9/404-mtd-add-more-helper-functions.patch b/target/linux/generic/patches-4.9/404-mtd-add-more-helper-functions.patch
index 319a22a..ef7b671 100644
--- a/target/linux/generic/patches-4.9/404-mtd-add-more-helper-functions.patch
+++ b/target/linux/generic/patches-4.9/404-mtd-add-more-helper-functions.patch
@@ -1,6 +1,6 @@
 --- a/drivers/mtd/mtdpart.c
 +++ b/drivers/mtd/mtdpart.c
-@@ -753,6 +753,17 @@ run_parsers_by_type(struct mtd_part *sla
+@@ -791,6 +791,17 @@ run_parsers_by_type(struct mtd_part *sla
  	return nr_parts;
  }
  
@@ -18,7 +18,7 @@
  #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
  #define SPLIT_FIRMWARE_NAME	CONFIG_MTD_SPLIT_FIRMWARE_NAME
  #else
-@@ -1106,6 +1117,24 @@ int mtd_is_partition(const struct mtd_in
+@@ -1146,6 +1157,24 @@ int mtd_is_partition(const struct mtd_in
  }
  EXPORT_SYMBOL_GPL(mtd_is_partition);
  
@@ -45,7 +45,7 @@
  {
 --- a/include/linux/mtd/partitions.h
 +++ b/include/linux/mtd/partitions.h
-@@ -107,6 +107,8 @@ int mtd_is_partition(const struct mtd_in
+@@ -114,6 +114,8 @@ int mtd_is_partition(const struct mtd_in
  int mtd_add_partition(struct mtd_info *master, const char *name,
  		      long long offset, long long length);
  int mtd_del_partition(struct mtd_info *master, int partno);
diff --git a/target/linux/generic/patches-4.9/410-mtd-move-forward-declaration-of-struct-mtd_info.patch b/target/linux/generic/patches-4.9/410-mtd-move-forward-declaration-of-struct-mtd_info.patch
index 78ebbf8..7c92735 100644
--- a/target/linux/generic/patches-4.9/410-mtd-move-forward-declaration-of-struct-mtd_info.patch
+++ b/target/linux/generic/patches-4.9/410-mtd-move-forward-declaration-of-struct-mtd_info.patch
@@ -1,6 +1,6 @@
 --- a/include/linux/mtd/partitions.h
 +++ b/include/linux/mtd/partitions.h
-@@ -35,6 +35,7 @@
+@@ -41,6 +41,7 @@
   * Note: writeable partitions require their size and offset be
   * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
   */
@@ -8,7 +8,7 @@
  
  struct mtd_partition {
  	const char *name;		/* identifier string */
-@@ -50,7 +51,6 @@ struct mtd_partition {
+@@ -57,7 +58,6 @@ struct mtd_partition {
  #define MTDPART_SIZ_FULL	(0)
  
  
diff --git a/target/linux/generic/patches-4.9/411-mtd-partial_eraseblock_write.patch b/target/linux/generic/patches-4.9/411-mtd-partial_eraseblock_write.patch
index 0e2d492..359eb5a 100644
--- a/target/linux/generic/patches-4.9/411-mtd-partial_eraseblock_write.patch
+++ b/target/linux/generic/patches-4.9/411-mtd-partial_eraseblock_write.patch
@@ -97,7 +97,7 @@
  
  		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
  			instr->fail_addr -= part->offset;
-@@ -561,19 +630,22 @@ static struct mtd_part *allocate_partiti
+@@ -590,19 +659,22 @@ static struct mtd_part *allocate_partiti
  	remainder = do_div(tmp, wr_alignment);
  	if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
  		/* Doesn't start on a boundary of major erase size */



More information about the lede-commits mailing list