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:
parent
15d9e99a27
commit
762dc78bde
2 changed files with 84 additions and 0 deletions
|
@ -130,6 +130,77 @@ static int blkmap_slice_add(struct blkmap *bm, struct blkmap_slice *new)
|
||||||
return 0;
|
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
|
* struct blkmap_mem - Memory mapping
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,6 +7,19 @@
|
||||||
#ifndef _BLKMAP_H
|
#ifndef _BLKMAP_H
|
||||||
#define _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
|
* blkmap_map_mem() - Map region of memory
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue