kernel: backport 2 mtd partitioning fixes

This improves handling of subpartitions.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2018-12-03 10:33:36 +01:00
parent 675eb747aa
commit e24983e710
10 changed files with 133 additions and 20 deletions

View file

@ -0,0 +1,58 @@
From 1186af457cc186c5ed01708da71b1ffbdf0a2638 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 20 Nov 2018 09:55:45 +0100
Subject: [PATCH] mtd: keep original flags for every struct mtd_info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When allocating a new partition mtd subsystem runs internal tests in the
allocate_partition(). They may result in modifying specified flags (e.g.
dropping some /features/ like write access).
Those constraints don't have to be necessary true for subpartitions. It
may happen parent partition isn't block aligned (effectively disabling
write access) while subpartition may fit blocks nicely. In such case all
checks should be run again (starting with original flags value).
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
---
drivers/mtd/mtdcore.c | 2 ++
drivers/mtd/mtdpart.c | 3 ++-
include/linux/mtd/mtd.h | 1 +
3 files changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -650,6 +650,8 @@ static void mtd_set_dev_defaults(struct
} else {
pr_debug("mtd device won't show a device symlink in sysfs\n");
}
+
+ mtd->orig_flags = mtd->flags;
}
/**
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -394,7 +394,8 @@ static struct mtd_part *allocate_partiti
/* set up the MTD object for this partition */
slave->mtd.type = parent->type;
- slave->mtd.flags = parent->flags & ~part->mask_flags;
+ slave->mtd.flags = parent->orig_flags & ~part->mask_flags;
+ slave->mtd.orig_flags = slave->mtd.flags;
slave->mtd.size = part->size;
slave->mtd.writesize = parent->writesize;
slave->mtd.writebufsize = parent->writebufsize;
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -218,6 +218,7 @@ struct mtd_debug_info {
struct mtd_info {
u_char type;
uint32_t flags;
+ uint32_t orig_flags; /* Flags as before running mtd checks */
uint64_t size; // Total size of the MTD
/* "Major" erase size for the device. Naïve users may take this

View file

@ -0,0 +1,55 @@
From 6750f61a13a0197c40e4a40739117493b15f19e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 20 Nov 2018 10:24:09 +0100
Subject: [PATCH] mtd: improve calculating partition boundaries when checking
for alignment
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When checking for alignment mtd should check absolute offsets. It's
important for subpartitions as it doesn't make sense to check their
relative addresses.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
---
drivers/mtd/mtdpart.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -61,6 +61,15 @@ static inline struct mtd_part *mtd_to_pa
return container_of(mtd, struct mtd_part, mtd);
}
+static u64 part_absolute_offset(struct mtd_info *mtd)
+{
+ struct mtd_part *part = mtd_to_part(mtd);
+
+ if (!mtd_is_partition(mtd))
+ return 0;
+
+ return part_absolute_offset(part->parent) + part->offset;
+}
/*
* MTD methods which simply translate the effective address and pass through
@@ -562,7 +571,7 @@ static struct mtd_part *allocate_partiti
if (!(slave->mtd.flags & MTD_NO_ERASE))
wr_alignment = slave->mtd.erasesize;
- tmp = slave->offset;
+ tmp = part_absolute_offset(parent) + slave->offset;
remainder = do_div(tmp, wr_alignment);
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
/* Doesn't start on a boundary of major erase size */
@@ -573,7 +582,7 @@ static struct mtd_part *allocate_partiti
part->name);
}
- tmp = slave->mtd.size;
+ tmp = part_absolute_offset(parent) + slave->mtd.size;
remainder = do_div(tmp, wr_alignment);
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
slave->mtd.flags &= ~MTD_WRITEABLE;

View file

@ -110,7 +110,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h> #include <linux/of.h>
@@ -834,6 +835,37 @@ void deregister_mtd_parser(struct mtd_pa @@ -844,6 +845,37 @@ void deregister_mtd_parser(struct mtd_pa
} }
EXPORT_SYMBOL_GPL(deregister_mtd_parser); EXPORT_SYMBOL_GPL(deregister_mtd_parser);
@ -148,7 +148,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
/* /*
* Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
* are changing this array! * are changing this array!
@@ -983,6 +1015,13 @@ int parse_mtd_partitions(struct mtd_info @@ -993,6 +1025,13 @@ int parse_mtd_partitions(struct mtd_info
struct mtd_partitions pparts = { }; struct mtd_partitions pparts = { };
struct mtd_part_parser *parser; struct mtd_part_parser *parser;
int ret, err = 0; int ret, err = 0;
@ -162,7 +162,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
if (!types) if (!types)
types = mtd_is_partition(master) ? default_subpartition_types : types = mtd_is_partition(master) ? default_subpartition_types :
@@ -1024,6 +1063,7 @@ int parse_mtd_partitions(struct mtd_info @@ -1034,6 +1073,7 @@ int parse_mtd_partitions(struct mtd_info
if (ret < 0 && !err) if (ret < 0 && !err)
err = ret; err = ret;
} }

View file

@ -60,7 +60,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* /*
* Given a pointer to the MTD object in the mtd_part structure, we can retrieve * Given a pointer to the MTD object in the mtd_part structure, we can retrieve
* the pointer to that structure. * the pointer to that structure.
@@ -658,6 +662,7 @@ int mtd_add_partition(struct mtd_info *p @@ -668,6 +672,7 @@ int mtd_add_partition(struct mtd_info *p
mutex_unlock(&mtd_partitions_mutex); mutex_unlock(&mtd_partitions_mutex);
add_mtd_device(&new->mtd); add_mtd_device(&new->mtd);
@ -68,7 +68,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
mtd_add_partition_attrs(new); mtd_add_partition_attrs(new);
@@ -736,6 +741,29 @@ int mtd_del_partition(struct mtd_info *m @@ -746,6 +751,29 @@ int mtd_del_partition(struct mtd_info *m
} }
EXPORT_SYMBOL_GPL(mtd_del_partition); EXPORT_SYMBOL_GPL(mtd_del_partition);
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* /*
* This function, given a master MTD object and a partition table, creates * 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 * and registers slave MTD objects which are bound to the master according to
@@ -767,6 +795,7 @@ int add_mtd_partitions(struct mtd_info * @@ -777,6 +805,7 @@ int add_mtd_partitions(struct mtd_info *
mutex_unlock(&mtd_partitions_mutex); mutex_unlock(&mtd_partitions_mutex);
add_mtd_device(&slave->mtd); add_mtd_device(&slave->mtd);

View file

@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
/* /*
* Given a pointer to the MTD object in the mtd_part structure, we can retrieve * Given a pointer to the MTD object in the mtd_part structure, we can retrieve
@@ -741,6 +745,36 @@ int mtd_del_partition(struct mtd_info *m @@ -751,6 +755,36 @@ int mtd_del_partition(struct mtd_info *m
} }
EXPORT_SYMBOL_GPL(mtd_del_partition); EXPORT_SYMBOL_GPL(mtd_del_partition);
@ -57,7 +57,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME #define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
#else #else
@@ -1112,6 +1146,61 @@ void mtd_part_parser_cleanup(struct mtd_ @@ -1122,6 +1156,61 @@ void mtd_part_parser_cleanup(struct mtd_
} }
} }

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c
@@ -783,6 +783,7 @@ run_parsers_by_type(struct mtd_part *sla @@ -793,6 +793,7 @@ run_parsers_by_type(struct mtd_part *sla
static void split_firmware(struct mtd_info *master, struct mtd_part *part) static void split_firmware(struct mtd_info *master, struct mtd_part *part)
{ {
@ -18,7 +18,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
} }
static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part)
@@ -792,6 +793,12 @@ static void mtd_partition_split(struct m @@ -802,6 +803,12 @@ static void mtd_partition_split(struct m
if (rootfs_found) if (rootfs_found)
return; return;

View file

@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c
@@ -1225,6 +1225,24 @@ int mtd_is_partition(const struct mtd_in @@ -1235,6 +1235,24 @@ int mtd_is_partition(const struct mtd_in
} }
EXPORT_SYMBOL_GPL(mtd_is_partition); EXPORT_SYMBOL_GPL(mtd_is_partition);
@ -38,7 +38,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
{ {
--- a/include/linux/mtd/mtd.h --- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h
@@ -493,6 +493,24 @@ static inline uint32_t mtd_mod_by_eb(uin @@ -494,6 +494,24 @@ static inline uint32_t mtd_mod_by_eb(uin
return do_div(sz, mtd->erasesize); return do_div(sz, mtd->erasesize);
} }

View file

@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
/* Our partition linked list */ /* Our partition linked list */
static LIST_HEAD(mtd_partitions); static LIST_HEAD(mtd_partitions);
static DEFINE_MUTEX(mtd_partitions_mutex); static DEFINE_MUTEX(mtd_partitions_mutex);
@@ -246,13 +248,61 @@ static int part_erase(struct mtd_info *m @@ -255,13 +257,61 @@ static int part_erase(struct mtd_info *m
struct mtd_part *part = mtd_to_part(mtd); struct mtd_part *part = mtd_to_part(mtd);
int ret; int ret;
@ -81,7 +81,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return ret; return ret;
} }
@@ -260,6 +310,25 @@ void mtd_erase_callback(struct erase_inf @@ -269,6 +319,25 @@ void mtd_erase_callback(struct erase_inf
{ {
if (instr->mtd->_erase == part_erase) { if (instr->mtd->_erase == part_erase) {
struct mtd_part *part = mtd_to_part(instr->mtd); struct mtd_part *part = mtd_to_part(instr->mtd);
@ -107,7 +107,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr -= part->offset; instr->fail_addr -= part->offset;
@@ -574,19 +643,22 @@ static struct mtd_part *allocate_partiti @@ -584,19 +653,22 @@ static struct mtd_part *allocate_partiti
remainder = do_div(tmp, wr_alignment); remainder = do_div(tmp, wr_alignment);
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
/* Doesn't start on a boundary of major erase size */ /* Doesn't start on a boundary of major erase size */
@ -123,8 +123,8 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
+ slave->mtd.erasesize = slave->mtd.size; + slave->mtd.erasesize = slave->mtd.size;
} }
- tmp = slave->mtd.size; - tmp = part_absolute_offset(parent) + slave->mtd.size;
+ tmp = slave->offset + slave->mtd.size; + tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
remainder = do_div(tmp, wr_alignment); remainder = do_div(tmp, wr_alignment);
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
- slave->mtd.flags &= ~MTD_WRITEABLE; - slave->mtd.flags &= ~MTD_WRITEABLE;

View file

@ -20,7 +20,7 @@ Signed-off-by: Tim Harvey <tharvey@gateworks.com>
--- a/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c
@@ -348,7 +348,16 @@ static int part_lock(struct mtd_info *mt @@ -357,7 +357,16 @@ static int part_lock(struct mtd_info *mt
static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{ {
struct mtd_part *part = mtd_to_part(mtd); struct mtd_part *part = mtd_to_part(mtd);

View file

@ -17,7 +17,7 @@ Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
--- a/drivers/mtd/mtdcore.c --- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c
@@ -922,6 +922,44 @@ out_unlock: @@ -924,6 +924,44 @@ out_unlock:
} }
EXPORT_SYMBOL_GPL(get_mtd_device_nm); EXPORT_SYMBOL_GPL(get_mtd_device_nm);
@ -64,7 +64,7 @@ Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
mutex_lock(&mtd_table_mutex); mutex_lock(&mtd_table_mutex);
--- a/include/linux/mtd/mtd.h --- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h
@@ -579,6 +579,8 @@ extern struct mtd_info *get_mtd_device(s @@ -580,6 +580,8 @@ extern struct mtd_info *get_mtd_device(s
extern int __get_mtd_device(struct mtd_info *mtd); extern int __get_mtd_device(struct mtd_info *mtd);
extern void __put_mtd_device(struct mtd_info *mtd); extern void __put_mtd_device(struct mtd_info *mtd);
extern struct mtd_info *get_mtd_device_nm(const char *name); extern struct mtd_info *get_mtd_device_nm(const char *name);