[PATCH v2 1/2] erofs-utils: fsck: cleanup erofs_verify_inode_data()
Yue Hu
zbestahu at gmail.com
Fri Jan 6 14:06:13 AEDT 2023
From: Yue Hu <huyue2 at coolpad.com>
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 <huyue2 at coolpad.com>
---
v2: use erofs_pread() directly
fsck/main.c | 146 +++++++++++++++++++++-------------------------------
1 file changed, 60 insertions(+), 86 deletions(-)
diff --git a/fsck/main.c b/fsck/main.c
index 2a9c501..0c47d23 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,98 @@ 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);
+ ret = erofs_pread(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;
--
2.17.1
More information about the Linux-erofs
mailing list