From: Yue Hu <[email protected]>

We should reuse the main part of erofs_read_raw_data() and
z_erofs_read_data() to avoid duplicated code.

Note that fragment feature is supported correspondingly as well after
this change.

Signed-off-by: Yue Hu <[email protected]>
---
 fsck/main.c              | 149 +++++++++++++++++----------------------
 include/erofs/internal.h |   4 ++
 lib/data.c               |   8 +--
 3 files changed, 71 insertions(+), 90 deletions(-)

diff --git a/fsck/main.c b/fsck/main.c
index 2a9c501..6c43816 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -361,36 +361,14 @@ out:
        return ret;
 }
 
-static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
+static int erofs_verify_inode_data_mapping(struct erofs_inode *inode,
+                                          bool compressed)
 {
        struct erofs_map_blocks map = {
                .index = UINT_MAX,
        };
-       struct erofs_map_dev mdev;
        int ret = 0;
-       bool compressed;
        erofs_off_t pos = 0;
-       u64 pchunk_len = 0;
-       unsigned int raw_size = 0, buffer_size = 0;
-       char *raw = NULL, *buffer = NULL;
-
-       erofs_dbg("verify data chunk of nid(%llu): type(%d)",
-                 inode->nid | 0ULL, inode->datalayout);
-
-       switch (inode->datalayout) {
-       case EROFS_INODE_FLAT_PLAIN:
-       case EROFS_INODE_FLAT_INLINE:
-       case EROFS_INODE_CHUNK_BASED:
-               compressed = false;
-               break;
-       case EROFS_INODE_FLAT_COMPRESSION_LEGACY:
-       case EROFS_INODE_FLAT_COMPRESSION:
-               compressed = true;
-               break;
-       default:
-               erofs_err("unknown datalayout");
-               return -EINVAL;
-       }
 
        while (pos < inode->i_size) {
                map.m_la = pos;
@@ -401,102 +379,101 @@ static int erofs_verify_inode_data(struct erofs_inode 
*inode, int outfd)
                        ret = erofs_map_blocks(inode, &map,
                                        EROFS_GET_BLOCKS_FIEMAP);
                if (ret)
-                       goto out;
+                       return ret;
 
                if (!compressed && map.m_llen != map.m_plen) {
                        erofs_err("broken chunk length m_la %" PRIu64 " m_llen 
%" PRIu64 " m_plen %" PRIu64,
                                  map.m_la, map.m_llen, map.m_plen);
-                       ret = -EFSCORRUPTED;
-                       goto out;
+                       return -EFSCORRUPTED;
                }
 
                /* the last lcluster can be divided into 3 parts */
                if (map.m_la + map.m_llen > inode->i_size)
                        map.m_llen = inode->i_size - map.m_la;
 
-               pchunk_len += map.m_plen;
                pos += map.m_llen;
+       }
+       return 0;
+}
 
-               /* should skip decomp? */
-               if (!(map.m_flags & EROFS_MAP_MAPPED) || !fsckcfg.check_decomp)
-                       continue;
+static int erofs_do_verify_inode_data(struct erofs_inode *inode, int outfd,
+                                     bool compressed)
+{
+       int ret = 0;
+       erofs_off_t pos = 0;
+       unsigned int buffer_size = 0;
+       char *buffer = NULL;
 
-               if (map.m_plen > raw_size) {
-                       raw_size = map.m_plen;
-                       raw = realloc(raw, raw_size);
-                       BUG_ON(!raw);
-               }
+       /* no option --extract */
+       if (!fsckcfg.check_decomp)
+               return erofs_verify_inode_data_mapping(inode, compressed);
 
-               mdev = (struct erofs_map_dev) {
-                       .m_deviceid = map.m_deviceid,
-                       .m_pa = map.m_pa,
-               };
-               ret = erofs_map_dev(&sbi, &mdev);
-               if (ret) {
-                       erofs_err("failed to map device of m_pa %" PRIu64 ", 
m_deviceid %u @ nid %llu: %d",
-                                 map.m_pa, map.m_deviceid, inode->nid | 0ULL,
-                                 ret);
-                       goto out;
-               }
+       while (pos < inode->i_size) {
+               erofs_off_t maxsize = min_t(erofs_off_t, inode->i_size - pos,
+                                           EROFS_CONFIG_COMPR_MAX_SZ);
 
-               if (compressed && map.m_llen > buffer_size) {
-                       buffer_size = map.m_llen;
+               if (maxsize > buffer_size) {
+                       buffer_size = maxsize;
                        buffer = realloc(buffer, buffer_size);
                        BUG_ON(!buffer);
                }
 
-               ret = dev_read(mdev.m_deviceid, raw, mdev.m_pa, map.m_plen);
-               if (ret < 0) {
-                       erofs_err("failed to read data of m_pa %" PRIu64 ", 
m_plen %" PRIu64 " @ nid %llu: %d",
-                                 mdev.m_pa, map.m_plen, inode->nid | 0ULL,
-                                 ret);
+               if (compressed)
+                       ret = z_erofs_read_data(inode, buffer, maxsize, pos);
+               else
+                       ret = erofs_read_raw_data(inode, buffer, maxsize, pos);
+               if (ret)
                        goto out;
-               }
 
-               if (compressed) {
-                       struct z_erofs_decompress_req rq = {
-                               .in = raw,
-                               .out = buffer,
-                               .decodedskip = 0,
-                               .interlaced_offset =
-                                       map.m_algorithmformat == 
Z_EROFS_COMPRESSION_INTERLACED ?
-                                               erofs_blkoff(map.m_la) : 0,
-                               .inputsize = map.m_plen,
-                               .decodedlength = map.m_llen,
-                               .alg = map.m_algorithmformat,
-                               .partial_decoding = 0
-                       };
-
-                       ret = z_erofs_decompress(&rq);
-                       if (ret < 0) {
-                               erofs_err("failed to decompress data of m_pa %" 
PRIu64 ", m_plen %" PRIu64 " @ nid %llu: %s",
-                                         mdev.m_pa, map.m_plen,
-                                         inode->nid | 0ULL, strerror(-ret));
-                               goto out;
-                       }
-               }
+               pos += maxsize;
 
-               if (outfd >= 0 && write(outfd, compressed ? buffer : raw,
-                                       map.m_llen) < 0) {
+               if (outfd >= 0 && write(outfd, buffer, maxsize) < 0) {
                        erofs_err("I/O error occurred when verifying data chunk 
@ nid %llu",
                                  inode->nid | 0ULL);
                        ret = -EIO;
                        goto out;
                }
        }
-
-       if (fsckcfg.print_comp_ratio) {
-               fsckcfg.logical_blocks += BLK_ROUND_UP(inode->i_size);
-               fsckcfg.physical_blocks += BLK_ROUND_UP(pchunk_len);
-       }
 out:
-       if (raw)
-               free(raw);
        if (buffer)
                free(buffer);
        return ret < 0 ? ret : 0;
 }
 
+static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
+{
+       int ret;
+       bool compressed;
+
+       erofs_dbg("verify data chunk of nid(%llu): type(%d)",
+                 inode->nid | 0ULL, inode->datalayout);
+
+       switch (inode->datalayout) {
+       case EROFS_INODE_FLAT_PLAIN:
+       case EROFS_INODE_FLAT_INLINE:
+       case EROFS_INODE_CHUNK_BASED:
+               compressed = false;
+               break;
+       case EROFS_INODE_FLAT_COMPRESSION_LEGACY:
+       case EROFS_INODE_FLAT_COMPRESSION:
+               compressed = true;
+               break;
+       default:
+               erofs_err("unknown datalayout");
+               return -EINVAL;
+       }
+       ret = erofs_do_verify_inode_data(inode, outfd, compressed);
+       if (ret < 0)
+               return ret;
+
+       if (fsckcfg.print_comp_ratio) {
+               fsckcfg.logical_blocks += BLK_ROUND_UP(inode->i_size);
+               fsckcfg.physical_blocks += compressed ? inode->u.i_blocks :
+                                          BLK_ROUND_UP(inode->i_size);
+       }
+       return 0;
+}
+
 static inline int erofs_extract_dir(struct erofs_inode *inode)
 {
        int ret;
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 947894d..4b962af 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -352,6 +352,10 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi);
 /* data.c */
 int erofs_pread(struct erofs_inode *inode, char *buf,
                erofs_off_t count, erofs_off_t offset);
+int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
+                        erofs_off_t size, erofs_off_t offset);
+int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
+                      erofs_off_t size, erofs_off_t offset);
 int erofs_map_blocks(struct erofs_inode *inode,
                struct erofs_map_blocks *map, int flags);
 int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map);
diff --git a/lib/data.c b/lib/data.c
index 76a6677..a9b2240 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -158,8 +158,8 @@ int erofs_map_dev(struct erofs_sb_info *sbi, struct 
erofs_map_dev *map)
        return 0;
 }
 
-static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
-                              erofs_off_t size, erofs_off_t offset)
+int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
+                       erofs_off_t size, erofs_off_t offset)
 {
        struct erofs_map_blocks map = {
                .index = UINT_MAX,
@@ -217,8 +217,8 @@ static int erofs_read_raw_data(struct erofs_inode *inode, 
char *buffer,
        return 0;
 }
 
-static int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
-                            erofs_off_t size, erofs_off_t offset)
+int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
+                     erofs_off_t size, erofs_off_t offset)
 {
        erofs_off_t end, length, skip;
        struct erofs_map_blocks map = {
-- 
2.17.1

Reply via email to