[PATCH 5/8] blk: blkmap: Add linear device mapping support
Tobias Waldekranz
tobias at waldekranz.com
Wed Feb 1 19:10:13 CET 2023
Allow a slice of an existing block device to be mapped to a
blkmap. This means that filesystems that are not stored at exact
partition boundaries can be accessed by remapping a slice of the
existing device to a blkmap device.
Signed-off-by: Tobias Waldekranz <tobias at waldekranz.com>
---
drivers/block/blkmap.c | 71 ++++++++++++++++++++++++++++++++++++++++++
include/blkmap.h | 2 ++
2 files changed, 73 insertions(+)
diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
index c8c2dcac11..14d2ec3f78 100644
--- a/drivers/block/blkmap.c
+++ b/drivers/block/blkmap.c
@@ -94,6 +94,77 @@ static int blkmap_add(struct blkmap *bm, struct blkmap_slice *new)
return 0;
}
+struct blkmap_linear {
+ struct blkmap_slice slice;
+
+ struct blk_desc *bd;
+ lbaint_t blknr;
+};
+
+static ulong blkmap_linear_read(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt, void *buffer)
+{
+ struct blkmap_linear *bml = container_of(bms, struct blkmap_linear, slice);
+
+ return blk_dread(bml->bd, bml->blknr + blknr, blkcnt, buffer);
+}
+
+static ulong blkmap_linear_write(struct blkmap *bm, struct blkmap_slice *bms,
+ lbaint_t blknr, lbaint_t blkcnt,
+ const void *buffer)
+{
+ struct blkmap_linear *bml = container_of(bms, struct blkmap_linear, slice);
+
+ return blk_dwrite(bml->bd, bml->blknr + blknr, blkcnt, buffer);
+}
+
+int blkmap_map_linear(int devnum, lbaint_t blknr, lbaint_t blkcnt,
+ enum uclass_id lcls, int ldevnum, lbaint_t lblknr)
+{
+ struct blkmap_linear *linear;
+ struct blk_desc *bd, *lbd;
+ struct blkmap *bm;
+ int err;
+
+ bm = blkmap_from_devnum(devnum);
+ if (!bm)
+ return -ENODEV;
+
+ bd = dev_get_uclass_plat(bm->dev);
+ lbd = blk_get_devnum_by_uclass_id(lcls, ldevnum);
+ if (!lbd)
+ return -ENODEV;
+
+ if (lbd->blksz != bd->blksz)
+ /* We could support block size translation, but we
+ * don't yet.
+ */
+ return -EINVAL;
+
+ linear = malloc(sizeof(*linear));
+ if (!linear)
+ return -ENOMEM;
+
+ *linear = (struct blkmap_linear) {
+ .slice = {
+ .blknr = blknr,
+ .blkcnt = blkcnt,
+
+ .read = blkmap_linear_read,
+ .write = blkmap_linear_write,
+ },
+
+ .bd = lbd,
+ .blknr = lblknr,
+ };
+
+ err = blkmap_add(bm, &linear->slice);
+ if (err)
+ free(linear);
+
+ return err;
+}
+
struct blkmap_mem {
struct blkmap_slice slice;
void *addr;
diff --git a/include/blkmap.h b/include/blkmap.h
index a93611ff62..dca6e3fe6a 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -9,6 +9,8 @@
#include <stdbool.h>
+int blkmap_map_linear(int devnum, lbaint_t blknr, lbaint_t blkcnt,
+ enum uclass_id lcls, int ldevnum, lbaint_t lblknr);
int blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr);
int blkmap_map_pmem(int devnum, lbaint_t blknr, lbaint_t blkcnt,
phys_addr_t paddr);
--
2.34.1
More information about the U-Boot
mailing list