[PATCH] erofs-utils: erofs debug utility.
Pratik Shinde
pratikshinde320 at gmail.com
Thu Aug 22 02:38:08 AEST 2019
Hello Maintainers,
After going through the recent mail thread between linux's filesystem folks
on erofs channel, I felt erofs needs an interactive debug utility (like xfs_db)
which can be used to examine erofs images & can also be used to inject errors OR
fuzzing for testing purpose & dumping different erofs meta data structures
for debugging.
In order to demonstrate above I wrote an experimental patch that simply dumps
the superblock of an image after mkfs completes.the full fletch utility will run
independently and be able to seek / print / modify any byte of an erofs image,
dump structures/lists/directory content of an image.
NOTE:This is an experimental patch just to demonstrate the purpose. The patch
lacks a lot of things like coding standard, and new code runs in the context
of mkfs itself.kindly ignore it.
kindly provide your feedback on this.
Signed-off-by: Pratik Shinde <pratikshinde320 at gmail.com>
---
include/erofs/io.h | 8 ++++++++
lib/io.c | 27 +++++++++++++++++++++++++++
mkfs/main.c | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
diff --git a/include/erofs/io.h b/include/erofs/io.h
index 4b574bd..e91d6ee 100644
--- a/include/erofs/io.h
+++ b/include/erofs/io.h
@@ -18,6 +18,7 @@
int dev_open(const char *devname);
void dev_close(void);
+int dev_read(void *buf, u64 offset, size_t len);
int dev_write(const void *buf, u64 offset, size_t len);
int dev_fillzero(u64 offset, size_t len, bool padding);
int dev_fsync(void);
@@ -30,5 +31,12 @@ static inline int blk_write(const void *buf, erofs_blk_t blkaddr,
blknr_to_addr(nblocks));
}
+static inline int blk_read(void *buf, erofs_blk_t blkaddr,
+ u32 nblocks)
+{
+ return dev_read(buf, blknr_to_addr(blkaddr),
+ blknr_to_addr(nblocks));
+}
+
#endif
diff --git a/lib/io.c b/lib/io.c
index 15c5a35..87d7d6c 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -109,6 +109,33 @@ u64 dev_length(void)
return erofs_devsz;
}
+int dev_read(void *buf, u64 offset, size_t len)
+{
+ int ret;
+
+ if (cfg.c_dry_run)
+ return 0;
+
+ if (!buf) {
+ erofs_err("buf is NULL");
+ return -EINVAL;
+ }
+ if (offset >= erofs_devsz || len > erofs_devsz ||
+ offset > erofs_devsz - len) {
+ erofs_err("read posion[%" PRIu64 ", %zd] is too large beyond the end of device(%" PRIu64 ").",
+ offset, len, erofs_devsz);
+ return -EINVAL;
+ }
+
+ ret = pread64(erofs_devfd, buf, len, (off64_t)offset);
+ if (ret != (int)len) {
+ erofs_err("Failed to read data from device - %s:[%" PRIu64 ", %zd].",
+ erofs_devname, offset, len);
+ return -errno;
+ }
+ return 0;
+}
+
int dev_write(const void *buf, u64 offset, size_t len)
{
int ret;
diff --git a/mkfs/main.c b/mkfs/main.c
index f127fe1..109486e 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -182,6 +182,41 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
return 0;
}
+void erofs_dump_super(char *img_path)
+{
+ struct erofs_super_block *sb;
+ char buf[EROFS_BLKSIZ];
+ unsigned int blksz;
+ int ret = 0;
+
+ if (img_path == NULL) {
+ erofs_err("image path cannot be null");
+ return;
+ }
+ ret = blk_read(buf, 0, 1);
+ if (ret) {
+ erofs_err("error reading super-block structure");
+ return;
+ }
+
+ sb = (struct erofs_super_block *)((u8 *)buf + EROFS_SUPER_OFFSET);
+ if (le32_to_cpu(sb->magic) != EROFS_SUPER_MAGIC_V1) {
+ erofs_err("not a erofs image");
+ return;
+ }
+
+ erofs_dump("magic: 0x%x\n", le32_to_cpu(sb->magic));
+ blksz = 1 << sb->blkszbits;
+ erofs_dump("block size: %d\n", blksz);
+ erofs_dump("root inode: %d\n", le32_to_cpu(sb->root_nid));
+ erofs_dump("inodes: %llu\n", le64_to_cpu(sb->inos));
+ erofs_dump("build time: %u\n", le32_to_cpu(sb->build_time));
+ erofs_dump("blocks: %u\n", le32_to_cpu(sb->blocks));
+ erofs_dump("meta block: %u\n", le32_to_cpu(sb->meta_blkaddr));
+ erofs_dump("xattr block: %u\n", le32_to_cpu(sb->xattr_blkaddr));
+ erofs_dump("requirements: 0x%x\n", le32_to_cpu(sb->requirements));
+}
+
int main(int argc, char **argv)
{
int err = 0;
@@ -268,6 +303,7 @@ int main(int argc, char **argv)
err = -EIO;
exit:
z_erofs_compress_exit();
+ erofs_dump_super("dummy");
dev_close();
erofs_exit_configure();
--
2.9.3
More information about the Linux-erofs
mailing list