[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