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:
parent
675eb747aa
commit
e24983e710
10 changed files with 133 additions and 20 deletions
|
@ -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
|
|
@ -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;
|
|
@ -110,7 +110,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
|||
#include <linux/err.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);
|
||||
|
||||
|
@ -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
|
||||
* 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_part_parser *parser;
|
||||
int ret, err = 0;
|
||||
|
@ -162,7 +162,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
|||
|
||||
if (!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)
|
||||
err = ret;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* 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);
|
||||
|
||||
add_mtd_device(&new->mtd);
|
||||
|
@ -68,7 +68,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||
|
||||
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);
|
||||
|
||||
|
@ -98,7 +98,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||
/*
|
||||
* 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
|
||||
@@ -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);
|
||||
|
||||
add_mtd_device(&slave->mtd);
|
||||
|
|
|
@ -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
|
||||
@@ -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);
|
||||
|
||||
|
@ -57,7 +57,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
|||
#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
|
||||
#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME
|
||||
#else
|
||||
@@ -1112,6 +1146,61 @@ void mtd_part_parser_cleanup(struct mtd_
|
||||
@@ -1122,6 +1156,61 @@ void mtd_part_parser_cleanup(struct mtd_
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
|||
|
||||
--- a/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)
|
||||
{
|
||||
|
@ -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)
|
||||
@@ -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)
|
||||
return;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
|||
|
||||
--- a/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);
|
||||
|
||||
|
@ -38,7 +38,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
|||
{
|
||||
--- a/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);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||
/* Our partition linked list */
|
||||
static LIST_HEAD(mtd_partitions);
|
||||
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);
|
||||
int ret;
|
||||
|
||||
|
@ -81,7 +81,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||
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) {
|
||||
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)
|
||||
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);
|
||||
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
- tmp = slave->mtd.size;
|
||||
+ tmp = slave->offset + slave->mtd.size;
|
||||
- tmp = part_absolute_offset(parent) + slave->mtd.size;
|
||||
+ tmp = part_absolute_offset(parent) + slave->offset + slave->mtd.size;
|
||||
remainder = do_div(tmp, wr_alignment);
|
||||
if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) {
|
||||
- slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
|
|
|
@ -20,7 +20,7 @@ Signed-off-by: Tim Harvey <tharvey@gateworks.com>
|
|||
|
||||
--- a/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)
|
||||
{
|
||||
struct mtd_part *part = mtd_to_part(mtd);
|
||||
|
|
|
@ -17,7 +17,7 @@ Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|||
|
||||
--- a/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);
|
||||
|
||||
|
@ -64,7 +64,7 @@ Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|||
mutex_lock(&mtd_table_mutex);
|
||||
--- a/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 void __put_mtd_device(struct mtd_info *mtd);
|
||||
extern struct mtd_info *get_mtd_device_nm(const char *name);
|
||||
|
|
Loading…
Reference in a new issue