]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
blk: blkmap: Add linear device mapping support
authorTobias Waldekranz <tobias@waldekranz.com>
Thu, 16 Feb 2023 15:33:51 +0000 (16:33 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 5 Apr 2023 14:54:47 +0000 (10:54 -0400)
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@waldekranz.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
drivers/block/blkmap.c
include/blkmap.h

index 6d6eed889e35b0a4bcbe44d51e74c083a8a3411d..2bb0acc20f2cb20250ddf7bb67059a83778d848a 100644 (file)
@@ -130,6 +130,77 @@ static int blkmap_slice_add(struct blkmap *bm, struct blkmap_slice *new)
        return 0;
 }
 
+/**
+ * struct blkmap_linear - Linear mapping to other block device
+ *
+ * @slice: Common map data
+ * @blk: Target block device of this mapping
+ * @blknr: Start block number of the target device
+ */
+struct blkmap_linear {
+       struct blkmap_slice slice;
+
+       struct udevice *blk;
+       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_read(bml->blk, 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_write(bml->blk, bml->blknr + blknr, blkcnt, buffer);
+}
+
+int blkmap_map_linear(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                     struct udevice *lblk, lbaint_t lblknr)
+{
+       struct blkmap *bm = dev_get_plat(dev);
+       struct blkmap_linear *linear;
+       struct blk_desc *bd, *lbd;
+       int err;
+
+       bd = dev_get_uclass_plat(bm->blk);
+       lbd = dev_get_uclass_plat(lblk);
+       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,
+               },
+
+               .blk = lblk,
+               .blknr = lblknr,
+       };
+
+       err = blkmap_slice_add(bm, &linear->slice);
+       if (err)
+               free(linear);
+
+       return err;
+}
+
 /**
  * struct blkmap_mem - Memory mapping
  *
index 74baeb19f8135db9561e2cd35c04dac93d0bf8c3..af54583c7dd3051a7266f5cfe4fe9e1a0eb26fd5 100644 (file)
@@ -7,6 +7,19 @@
 #ifndef _BLKMAP_H
 #define _BLKMAP_H
 
+/**
+ * blkmap_map_linear() - Map region of other block device
+ *
+ * @dev: Blkmap to create the mapping on
+ * @blknr: Start block number of the mapping
+ * @blkcnt: Number of blocks to map
+ * @lblk: The target block device of the mapping
+ * @lblknr: The start block number of the target device
+ * Returns: 0 on success, negative error code on failure
+ */
+int blkmap_map_linear(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
+                     struct udevice *lblk, lbaint_t lblknr);
+
 /**
  * blkmap_map_mem() - Map region of memory
  *