blk: blkmap: Add linear device mapping support

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>
This commit is contained in:
Tobias Waldekranz 2023-02-16 16:33:51 +01:00 committed by Tom Rini
parent 15d9e99a27
commit 762dc78bde
2 changed files with 84 additions and 0 deletions

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

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