Signed-off-by: Gao Xiang <hsiang...@aol.com>
---
 fuse/Makefile.am         |  2 +-
 fuse/namei.c             | 17 ++++++--
 fuse/read.c              | 87 +++++++++++-----------------------------
 include/erofs/internal.h | 22 ++++++++--
 lib/Makefile.am          |  2 +-
 lib/data.c               | 73 +++++++++++++++++++++++++++++++++
 {fuse => lib}/zmap.c     | 36 ++++++++---------
 7 files changed, 147 insertions(+), 92 deletions(-)
 rename {fuse => lib}/zmap.c (94%)

diff --git a/fuse/Makefile.am b/fuse/Makefile.am
index 84e5f834d6a4..d6e6d60cbfdc 100644
--- a/fuse/Makefile.am
+++ b/fuse/Makefile.am
@@ -3,7 +3,7 @@
 
 AUTOMAKE_OPTIONS = foreign
 bin_PROGRAMS     = erofsfuse
-erofsfuse_SOURCES = main.c namei.c read.c readir.c zmap.c
+erofsfuse_SOURCES = main.c namei.c read.c readir.c
 erofsfuse_CFLAGS = -Wall -Werror \
                    -I$(top_srcdir)/include \
                    $(shell pkg-config fuse --cflags) \
diff --git a/fuse/namei.c b/fuse/namei.c
index 37cf549cd2a6..fd5ae7bfc410 100644
--- a/fuse/namei.c
+++ b/fuse/namei.c
@@ -71,9 +71,20 @@ static int erofs_iget_by_nid(erofs_nid_t nid, struct 
erofs_vnode *vi)
        }
 
        vi->z_inited = false;
-       if (erofs_inode_is_data_compressed(vi->datalayout))
-               z_erofs_fill_inode(vi);
-
+       if (erofs_inode_is_data_compressed(vi->datalayout)) {
+               struct erofs_inode ei = { .datalayout = vi->datalayout };
+
+               z_erofs_fill_inode(&ei);
+
+               /* XXX: will be dropped after erofs_vnode is removed */
+               vi->z_advise = ei.z_advise;
+               vi->z_algorithmtype[0] = ei.z_algorithmtype[0];
+               vi->z_algorithmtype[1] = ei.z_algorithmtype[1];
+               vi->z_logical_clusterbits = ei.z_logical_clusterbits;
+               vi->z_physical_clusterbits[0] = ei.z_physical_clusterbits[0];
+               vi->z_physical_clusterbits[1] = ei.z_physical_clusterbits[1];
+               vi->z_inited = (ei.flags != 0);
+       }
        return 0;
 }
 
diff --git a/fuse/read.c b/fuse/read.c
index aa5221a60d4e..21fbd2eea662 100644
--- a/fuse/read.c
+++ b/fuse/read.c
@@ -43,72 +43,31 @@ size_t erofs_read_data_wrapper(struct erofs_vnode *vnode, 
char *buffer,
 size_t erofs_read_data_compression(struct erofs_vnode *vnode, char *buffer,
                                   erofs_off_t size, erofs_off_t offset)
 {
-       int ret;
-       erofs_off_t end, length, skip;
-       struct erofs_map_blocks map = {
-               .index = UINT_MAX,
+       struct erofs_inode tmp = {
+               .nid = vnode->nid,
+               .i_size = vnode->i_size,
+               .datalayout = vnode->datalayout,
+               .inode_isize = vnode->inode_isize,
+               .xattr_isize = vnode->xattr_isize,
+               .z_advise = vnode->z_advise,
+               .z_algorithmtype = {
+                       [0] = vnode->z_algorithmtype[0],
+                       [1] = vnode->z_algorithmtype[1],
+               },
+               .z_logical_clusterbits = vnode->z_logical_clusterbits,
+               .z_physical_clusterbits = {
+                       [0] = vnode->z_physical_clusterbits[0],
+                       [1] = vnode->z_physical_clusterbits[1],
+               },
        };
-       bool partial;
-       unsigned int algorithmformat;
-       char raw[EROFS_BLKSIZ];
-
-       end = offset + size;
-       while (end > offset) {
-               map.m_la = end - 1;
-
-               ret = z_erofs_map_blocks_iter(vnode, &map);
-               if (ret)
-                       return ret;
-
-               if (!(map.m_flags & EROFS_MAP_MAPPED)) {
-                       end = map.m_la;
-                       continue;
-               }
-
-               ret = dev_read(raw, map.m_pa, EROFS_BLKSIZ);
-               if (ret < 0)
-                       return -EIO;
-
-               algorithmformat = map.m_flags & EROFS_MAP_ZIPPED ?
-                                               Z_EROFS_COMPRESSION_LZ4 :
-                                               Z_EROFS_COMPRESSION_SHIFTED;
-
-               /*
-                * trim to the needed size if the returned extent is quite
-                * larger than requested, and set up partial flag as well.
-                */
-               if (end < map.m_la + map.m_llen) {
-                       length = end - map.m_la;
-                       partial = true;
-               } else {
-                       DBG_BUGON(end != map.m_la + map.m_llen);
-                       length = map.m_llen;
-                       partial = !(map.m_flags & EROFS_MAP_FULL_MAPPED);
-               }
-
-               if (map.m_la < offset) {
-                       skip = offset - map.m_la;
-                       end = offset;
-               } else {
-                       skip = 0;
-                       end = map.m_la;
-               }
-
-               ret = z_erofs_decompress(&(struct z_erofs_decompress_req) {
-                                       .in = raw,
-                                       .out = buffer + end - offset,
-                                       .decodedskip = skip,
-                                       .inputsize = map.m_plen,
-                                       .decodedlength = length,
-                                       .alg = algorithmformat,
-                                       .partial_decoding = partial
-                                        });
-               if (ret < 0)
-                       return ret;
-       }
 
-       erofs_info("nid:%llu size=%zd offset=%llu done",
-            (unsigned long long)vnode->nid, size, (long long)offset);
+       if (vnode->z_inited)
+               tmp.flags |= EROFS_I_Z_INITED;
+
+       int ret = z_erofs_read_data(&tmp, buffer, offset, size);
+       if (ret)
+               return ret;
+
        return size;
 }
 
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index fc28d82490a1..98e1263fa19c 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -108,9 +108,13 @@ static inline void erofs_sb_clear_##name(void) \
 EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_LZ4_0PADDING)
 EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
 
+#define EROFS_I_EA_INITED      (1 << 0)
+#define EROFS_I_Z_INITED       (1 << 1)
+
 struct erofs_inode {
        struct list_head i_hash, i_subdirs, i_xattrs;
 
+       unsigned int flags;
        unsigned int i_count;
        struct erofs_inode *i_parent;
 
@@ -145,7 +149,16 @@ struct erofs_inode {
        struct erofs_buffer_head *bh_inline, *bh_data;
 
        void *idata;
-       void *compressmeta;
+
+       union {
+               void *compressmeta;
+               struct {
+                       uint16_t z_advise;
+                       uint8_t  z_algorithmtype[2];
+                       uint8_t  z_logical_clusterbits;
+                       uint8_t  z_physical_clusterbits[2];
+               };
+       };
 #ifdef WITH_ANDROID
        uint64_t capabilities;
 #endif
@@ -265,10 +278,11 @@ int erofs_read_superblock(void);
 /* data.c */
 int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
                        erofs_off_t offset, erofs_off_t size);
-
+int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
+                     erofs_off_t size, erofs_off_t offset);
 /* zmap.c */
-int z_erofs_fill_inode(struct erofs_vnode *vi);
-int z_erofs_map_blocks_iter(struct erofs_vnode *vi,
+int z_erofs_fill_inode(struct erofs_inode *vi);
+int z_erofs_map_blocks_iter(struct erofs_inode *vi,
                            struct erofs_map_blocks *map);
 
 #define EFSCORRUPTED   EUCLEAN         /* Filesystem is corrupted */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 487c4944479d..7d9446b3cbcf 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -3,7 +3,7 @@
 
 noinst_LTLIBRARIES = liberofs.la
 liberofs_la_SOURCES = config.c io.c cache.c super.c inode.c xattr.c exclude.c \
-                     data.c compress.c compressor.c decompress.c
+                     data.c compress.c compressor.c zmap.c decompress.c
 liberofs_la_CFLAGS = -Wall -Werror -I$(top_srcdir)/include
 if ENABLE_LZ4
 liberofs_la_CFLAGS += ${LZ4_CFLAGS}
diff --git a/lib/data.c b/lib/data.c
index 56b208513980..62fd057185ee 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -3,11 +3,13 @@
  * erofs-utils/lib/data.c
  *
  * Copyright (C) 2020 Gao Xiang <hsiang...@aol.com>
+ * Compression support by Huang Jianan <huangjia...@oppo.com>
  */
 #include "erofs/print.h"
 #include "erofs/internal.h"
 #include "erofs/io.h"
 #include "erofs/trace.h"
+#include "erofs/decompress.h"
 
 static int erofs_map_blocks_flatmode(struct erofs_inode *inode,
                                     struct erofs_map_blocks *map,
@@ -115,3 +117,74 @@ int erofs_read_raw_data(struct erofs_inode *inode, char 
*buffer,
        return 0;
 }
 
+int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
+                     erofs_off_t offset, erofs_off_t size)
+{
+       int ret;
+       erofs_off_t end, length, skip;
+       struct erofs_map_blocks map = {
+               .index = UINT_MAX,
+       };
+       bool partial;
+       unsigned int algorithmformat;
+       char raw[EROFS_BLKSIZ];
+
+       end = offset + size;
+       while (end > offset) {
+               map.m_la = end - 1;
+
+               ret = z_erofs_map_blocks_iter(inode, &map);
+               if (ret)
+                       return ret;
+
+               if (!(map.m_flags & EROFS_MAP_MAPPED)) {
+                       end = map.m_la;
+                       continue;
+               }
+
+               ret = dev_read(raw, map.m_pa, EROFS_BLKSIZ);
+               if (ret < 0)
+                       return -EIO;
+
+               algorithmformat = map.m_flags & EROFS_MAP_ZIPPED ?
+                                               Z_EROFS_COMPRESSION_LZ4 :
+                                               Z_EROFS_COMPRESSION_SHIFTED;
+
+               /*
+                * trim to the needed size if the returned extent is quite
+                * larger than requested, and set up partial flag as well.
+                */
+               if (end < map.m_la + map.m_llen) {
+                       length = end - map.m_la;
+                       partial = true;
+               } else {
+                       DBG_BUGON(end != map.m_la + map.m_llen);
+                       length = map.m_llen;
+                       partial = !(map.m_flags & EROFS_MAP_FULL_MAPPED);
+               }
+
+               if (map.m_la < offset) {
+                       skip = offset - map.m_la;
+                       end = offset;
+               } else {
+                       skip = 0;
+                       end = map.m_la;
+               }
+
+               ret = z_erofs_decompress(&(struct z_erofs_decompress_req) {
+                                       .in = raw,
+                                       .out = buffer + end - offset,
+                                       .decodedskip = skip,
+                                       .inputsize = map.m_plen,
+                                       .decodedlength = length,
+                                       .alg = algorithmformat,
+                                       .partial_decoding = partial
+                                        });
+               if (ret < 0)
+                       return ret;
+       }
+       erofs_dbg("nid:%llu size=%zd offset=%llu done",
+                 inode->nid | 0ULL, size, (long long)offset);
+       return 0;
+}
+
diff --git a/fuse/zmap.c b/lib/zmap.c
similarity index 94%
rename from fuse/zmap.c
rename to lib/zmap.c
index ba5c457278a8..ee63de74cab2 100644
--- a/fuse/zmap.c
+++ b/lib/zmap.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * erofs-utils/fuse/zmap.c
+ * erofs-utils/lib/zmap.c
  *
  * (a large amount of code was adapted from Linux kernel. )
  *
@@ -12,7 +12,7 @@
 #include "erofs/io.h"
 #include "erofs/print.h"
 
-int z_erofs_fill_inode(struct erofs_vnode *vi)
+int z_erofs_fill_inode(struct erofs_inode *vi)
 {
        if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
                vi->z_advise = 0;
@@ -21,27 +21,26 @@ int z_erofs_fill_inode(struct erofs_vnode *vi)
                vi->z_logical_clusterbits = LOG_BLOCK_SIZE;
                vi->z_physical_clusterbits[0] = vi->z_logical_clusterbits;
                vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits;
-               vi->z_inited = true;
-       }
 
+               vi->flags |= EROFS_I_Z_INITED;
+       }
        return 0;
 }
 
-static int z_erofs_fill_inode_lazy(struct erofs_vnode *vi)
+static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
 {
        int ret;
        erofs_off_t pos;
        struct z_erofs_map_header *h;
-       char buf[8];
+       char buf[sizeof(struct z_erofs_map_header)];
 
-       if (vi->z_inited)
+       if (vi->flags & EROFS_I_Z_INITED)
                return 0;
 
        DBG_BUGON(vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY);
-
        pos = round_up(iloc(vi->nid) + vi->inode_isize + vi->xattr_isize, 8);
 
-       ret = dev_read(buf, pos, 8);
+       ret = dev_read(buf, pos, sizeof(buf));
        if (ret < 0)
                return -EIO;
 
@@ -68,13 +67,12 @@ static int z_erofs_fill_inode_lazy(struct erofs_vnode *vi)
 
        vi->z_physical_clusterbits[1] = vi->z_logical_clusterbits +
                                        ((h->h_clusterbits >> 5) & 7);
-       vi->z_inited = true;
-
+       vi->flags |= EROFS_I_Z_INITED;
        return 0;
 }
 
 struct z_erofs_maprecorder {
-       struct erofs_vnode *vnode;
+       struct erofs_inode *inode;
        struct erofs_map_blocks *map;
        void *kaddr;
 
@@ -108,7 +106,7 @@ static int z_erofs_reload_indexes(struct 
z_erofs_maprecorder *m,
 static int legacy_load_cluster_from_disk(struct z_erofs_maprecorder *m,
                                         unsigned long lcn)
 {
-       struct erofs_vnode *const vi = m->vnode;
+       struct erofs_inode *const vi = m->inode;
        const erofs_off_t ibase = iloc(vi->nid);
        const erofs_off_t pos =
                Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize +
@@ -162,7 +160,7 @@ static int unpack_compacted_index(struct 
z_erofs_maprecorder *m,
                                  unsigned int amortizedshift,
                                  unsigned int eofs)
 {
-       struct erofs_vnode *const vi = m->vnode;
+       struct erofs_inode *const vi = m->inode;
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        const unsigned int lomask = (1 << lclusterbits) - 1;
        unsigned int vcnt, base, lo, encodebits, nblk;
@@ -225,7 +223,7 @@ static int unpack_compacted_index(struct 
z_erofs_maprecorder *m,
 static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
                                            unsigned long lcn)
 {
-       struct erofs_vnode *const vi = m->vnode;
+       struct erofs_inode *const vi = m->inode;
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        const erofs_off_t ebase = round_up(iloc(vi->nid) + vi->inode_isize +
                                           vi->xattr_isize, 8) +
@@ -279,7 +277,7 @@ out:
 static int z_erofs_load_cluster_from_disk(struct z_erofs_maprecorder *m,
                                          unsigned int lcn)
 {
-       const unsigned int datamode = m->vnode->datalayout;
+       const unsigned int datamode = m->inode->datalayout;
 
        if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
                return legacy_load_cluster_from_disk(m, lcn);
@@ -293,7 +291,7 @@ static int z_erofs_load_cluster_from_disk(struct 
z_erofs_maprecorder *m,
 static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
                                   unsigned int lookback_distance)
 {
-       struct erofs_vnode *const vi = m->vnode;
+       struct erofs_inode *const vi = m->inode;
        struct erofs_map_blocks *const map = m->map;
        const unsigned int lclusterbits = vi->z_logical_clusterbits;
        unsigned long lcn = m->lcn;
@@ -335,11 +333,11 @@ static int z_erofs_extent_lookback(struct 
z_erofs_maprecorder *m,
        return 0;
 }
 
-int z_erofs_map_blocks_iter(struct erofs_vnode *vi,
+int z_erofs_map_blocks_iter(struct erofs_inode *vi,
                            struct erofs_map_blocks *map)
 {
        struct z_erofs_maprecorder m = {
-               .vnode = vi,
+               .inode = vi,
                .map = map,
                .kaddr = map->mpage,
        };
-- 
2.24.0

Reply via email to