diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2018-11-20 10:24:09 +0100 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-12-02 09:32:44 +0100 |
commit | 6750f61a13a0197c40e4a40739117493b15f19e8 (patch) | |
tree | b8bb14ab4178689a2b1e396d2606c02581f95d66 /drivers/mtd/mtdpart.c | |
parent | 1186af457cc186c5ed01708da71b1ffbdf0a2638 (diff) | |
download | linux-6750f61a13a0197c40e4a40739117493b15f19e8.tar.bz2 |
mtd: improve calculating partition boundaries when checking for alignment
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>
Diffstat (limited to 'drivers/mtd/mtdpart.c')
-rw-r--r-- | drivers/mtd/mtdpart.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 2b6e53af47da..b6af41b04622 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -61,6 +61,15 @@ static inline struct mtd_part *mtd_to_part(const struct mtd_info *mtd) 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 @@ -514,7 +523,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent, 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 */ @@ -525,7 +534,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent, 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; |