Source kernel commit: fdf80a4793021c2f27953b3075f401a497519ba4 Source kernel commit: 469ad583c1293f5d9f45183050b3beeb4a8c3475 Source kernel commit: e09815446d6944fc5590a6e5f15dd51697202441
Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- include/erofs/internal.h | 14 ++++++++++++++ lib/data.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/erofs/internal.h b/include/erofs/internal.h index 1431c16d..b61fe716 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -46,6 +46,14 @@ typedef u64 erofs_blk_t; /* global sbi */ extern struct erofs_sb_info g_sbi; +struct erofs_buf { + struct erofs_sb_info *sbi; + struct erofs_vfile *vf; + erofs_blk_t blocknr; + u8 base[EROFS_MAX_BLOCK_SIZE]; +}; +#define __EROFS_BUF_INITIALIZER ((struct erofs_buf){.blocknr = ~0ULL}) + #define erofs_blksiz(sbi) (1u << (sbi)->blkszbits) #define erofs_blknr(sbi, pos) ((pos) >> (sbi)->blkszbits) #define erofs_blkoff(sbi, pos) ((pos) & (erofs_blksiz(sbi) - 1)) @@ -427,6 +435,12 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi); int erofs_ilookup(const char *path, struct erofs_inode *vi); /* data.c */ +static inline void erofs_unmap_metabuf(struct erofs_buf *buf) {} +static inline void erofs_put_metabuf(struct erofs_buf *buf) {} +void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap); +void erofs_init_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi); +void *erofs_read_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi, + erofs_off_t offset); int erofs_pread(struct erofs_inode *inode, char *buf, erofs_off_t count, erofs_off_t offset); int erofs_map_blocks(struct erofs_inode *inode, diff --git a/lib/data.c b/lib/data.c index e2d9b5eb..d2558254 100644 --- a/lib/data.c +++ b/lib/data.c @@ -10,6 +10,42 @@ #include "erofs/decompress.h" #include "erofs/fragments.h" +void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap) +{ + struct erofs_sb_info *sbi = buf->sbi; + u32 blksiz = erofs_blksiz(sbi); + erofs_blk_t blknr; + int err; + + if (!need_kmap) + return NULL; + blknr = erofs_blknr(sbi, offset); + if (blknr != buf->blocknr) { + buf->blocknr = ~0ULL; + err = erofs_io_pread(buf->vf, buf->base, blksiz, + round_down(offset, blksiz)); + if (err < 0) + return ERR_PTR(err); + if (err != blksiz) + return ERR_PTR(-EIO); + buf->blocknr = blknr; + } + return buf->base + erofs_blkoff(sbi, offset); +} + +void erofs_init_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi) +{ + buf->sbi = sbi; + buf->vf = &sbi->bdev; +} + +void *erofs_read_metabuf(struct erofs_buf *buf, struct erofs_sb_info *sbi, + erofs_off_t offset) +{ + erofs_init_metabuf(buf, sbi); + return erofs_bread(buf, offset, true); +} + int __erofs_map_blocks(struct erofs_inode *inode, struct erofs_map_blocks *map, int flags) { -- 2.43.5