diff mbox series

[5/8] blk: blkmap: Add linear device mapping support

Message ID 20230201181016.4145834-6-tobias@waldekranz.com
State Superseded
Delegated to: Tom Rini
Headers show
Series blk: blkmap: Composable virtual block devices | expand

Commit Message

Tobias Waldekranz Feb. 1, 2023, 6:10 p.m. UTC
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>
---
 drivers/block/blkmap.c | 71 ++++++++++++++++++++++++++++++++++++++++++
 include/blkmap.h       |  2 ++
 2 files changed, 73 insertions(+)

Comments

Simon Glass Feb. 1, 2023, 8:21 p.m. UTC | #1
Hi Tobias,

On Wed, 1 Feb 2023 at 11:10, Tobias Waldekranz <tobias@waldekranz.com> wrote:
>
> 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>
> ---
>  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;

Please store the udevice * here. We are trying to avoid external use
of blk_desc.

> +       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);

blk_read()

> +}
> +
> +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);

blk_write()

> +}
> +
> +int blkmap_map_linear(int devnum, lbaint_t blknr, lbaint_t blkcnt,

should take a struct udevice *, not a devnum

Finding should happen in the cmd.

> +                     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);

comments again

>  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
>

Regards,
Simon
diff mbox series

Patch

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);