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


Reply via email to