Hi Yue,

在 2022/12/24 17:43, Yue Hu 写道:
From: Yue Hu <[email protected]>

Add compressed fragments support for fsck.erofs.

Signed-off-by: Yue Hu <[email protected]>
---
  fsck/main.c | 41 +++++++++++++++++++++++++++++++++++++++--
  lib/zmap.c  |  1 +
  2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/fsck/main.c b/fsck/main.c
index 2a9c501..9babc61 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -421,6 +421,31 @@ static int erofs_verify_inode_data(struct erofs_inode 
*inode, int outfd)
                if (!(map.m_flags & EROFS_MAP_MAPPED) || !fsckcfg.check_decomp)
                        continue;
+ if (map.m_flags & EROFS_MAP_FRAGMENT) {
+                       struct erofs_inode packed_inode = {
+                               .nid = sbi.packed_nid,
+                       };

Sorry for late response.

a question... why don't we just rely on z_erofs_read_data()?


Thanks,
Gao Xiang

+
+                       ret = erofs_read_inode_from_disk(&packed_inode);
+                       if (ret) {
+                               erofs_err("failed to read packed inode from 
disk");
+                               goto out;
+                       }
+
+                       if (!buffer || map.m_llen > buffer_size) {
+                               buffer_size = map.m_llen;
+                               buffer = realloc(buffer, map.m_llen);
+                               BUG_ON(!buffer);
+                       }
+                       ret = erofs_pread(&packed_inode, buffer, map.m_llen,
+                                         inode->fragmentoff);
+                       if (ret)
+                               goto out;
+
+                       compressed = true;      /* force using buffer */
+                       goto write_outfd;
+               }
+
                if (map.m_plen > raw_size) {
                        raw_size = map.m_plen;
                        raw = realloc(raw, raw_size);
@@ -476,6 +501,7 @@ static int erofs_verify_inode_data(struct erofs_inode 
*inode, int outfd)
                        }
                }
+write_outfd:
                if (outfd >= 0 && write(outfd, compressed ? buffer : raw,
                                        map.m_llen) < 0) {
                        erofs_err("I/O error occurred when verifying data chunk @ 
nid %llu",
@@ -486,8 +512,9 @@ static int erofs_verify_inode_data(struct erofs_inode 
*inode, int outfd)
        }
if (fsckcfg.print_comp_ratio) {
-               fsckcfg.logical_blocks += BLK_ROUND_UP(inode->i_size);
                fsckcfg.physical_blocks += BLK_ROUND_UP(pchunk_len);
+               if (!erofs_is_packed_inode(inode))
+                       fsckcfg.logical_blocks += BLK_ROUND_UP(inode->i_size);
        }
  out:
        if (raw)
@@ -732,6 +759,8 @@ static int erofsfsck_check_inode(erofs_nid_t pnid, 
erofs_nid_t nid)
                        ret = erofs_extract_dir(&inode);
                        break;
                case S_IFREG:
+                       if (erofs_is_packed_inode(&inode))
+                               goto verify;
                        ret = erofs_extract_file(&inode);
                        break;
                case S_IFLNK:
@@ -767,7 +796,7 @@ verify:
                ret = erofs_iterate_dir(&ctx, true);
        }
- if (!ret)
+       if (!ret && !erofs_is_packed_inode(&inode))
                erofsfsck_set_attributes(&inode, fsckcfg.extract_path);
if (ret == -ECANCELED)
@@ -822,6 +851,14 @@ int main(int argc, char **argv)
                goto exit_put_super;
        }
+ if (erofs_sb_has_fragments()) {
+               err = erofsfsck_check_inode(sbi.packed_nid, sbi.packed_nid);
+               if (err) {
+                       erofs_err("failed to verify packed file");
+                       goto exit_put_super;
+               }
+       }
+
        err = erofsfsck_check_inode(sbi.root_nid, sbi.root_nid);
        if (fsckcfg.corrupted) {
                if (!fsckcfg.extract_path)
diff --git a/lib/zmap.c b/lib/zmap.c
index 41e0713..ca65038 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -639,6 +639,7 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi,
                map->m_plen = vi->z_idata_size;
        } else if (fragment && m.lcn == vi->z_tailextent_headlcn) {
                map->m_flags |= EROFS_MAP_FRAGMENT;
+               map->m_plen = 0;
        } else {
                map->m_pa = blknr_to_addr(m.pblk);
                err = z_erofs_get_extent_compressedlen(&m, initial_lcn);

Reply via email to