Linux-EROFS Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks.
@ 2019-10-14 14:59 Pratik Shinde
  2019-10-14 23:45 ` Gao Xiang via Linux-erofs
  0 siblings, 1 reply; 5+ messages in thread
From: Pratik Shinde @ 2019-10-14 14:59 UTC (permalink / raw)
  To: linux-erofs, bluce.liguifu, miaoxie, fangwei1

Added code for calculating crc of erofs blocks (4K size).for now it calculates
checksum of first block. but can modified to calculate crc for any no. of blocks

modified patch based on review comments.

Signed-off-by: Pratik Shinde <pratikshinde320@gmail.com>
---
 include/erofs/internal.h |  1 +
 include/erofs/io.h       |  8 +++++
 lib/io.c                 | 27 +++++++++++++++++
 mkfs/main.c              | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 112 insertions(+)

diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 5384946..53335bc 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -55,6 +55,7 @@ struct erofs_sb_info {
 	u32 feature_incompat;
 	u64 build_time;
 	u32 build_time_nsec;
+	u32 feature;
 };
 
 /* global sbi */
diff --git a/include/erofs/io.h b/include/erofs/io.h
index 9775047..e0ca8d9 100644
--- a/include/erofs/io.h
+++ b/include/erofs/io.h
@@ -19,6 +19,7 @@
 int dev_open(const char *devname);
 void dev_close(void);
 int dev_write(const void *buf, u64 offset, size_t len);
+int dev_read(void *buf, u64 offset, size_t len);
 int dev_fillzero(u64 offset, size_t len, bool padding);
 int dev_fsync(void);
 int dev_resize(erofs_blk_t nblocks);
@@ -31,5 +32,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 start,
+			    u32 nblocks)
+{
+	return dev_read(buf, blknr_to_addr(start),
+			 blknr_to_addr(nblocks));
+}
+
 #endif
 
diff --git a/lib/io.c b/lib/io.c
index 7f5f94d..52f9424 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -207,3 +207,30 @@ int dev_resize(unsigned int blocks)
 	return dev_fillzero(st.st_size, length, true);
 }
 
+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;
+}
diff --git a/mkfs/main.c b/mkfs/main.c
index 91a018f..baaf02a 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -22,6 +22,10 @@
 
 #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
 
+/* number of blocks for calculating checksum */
+#define EROFS_CKSUM_BLOCKS	1
+#define EROFS_FEATURE_SB_CHKSUM	0x0001
+
 static void usage(void)
 {
 	fprintf(stderr, "usage: [options] FILE DIRECTORY\n\n");
@@ -85,6 +89,10 @@ static int parse_extended_opts(const char *opts)
 				return -EINVAL;
 			cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;
 		}
+
+		if (MATCH_EXTENTED_OPT("nocrc", token, keylen)) {
+			sbi.feature &= ~EROFS_FEATURE_SB_CHKSUM;
+		}
 	}
 	return 0;
 }
@@ -180,6 +188,7 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
 		.meta_blkaddr  = sbi.meta_blkaddr,
 		.xattr_blkaddr = 0,
 		.feature_incompat = cpu_to_le32(sbi.feature_incompat),
+		.checksum = 0
 	};
 	const unsigned int sb_blksize =
 		round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
@@ -202,6 +211,70 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
 	return 0;
 }
 
+#define CRCPOLY	0x82F63B78
+static inline u32 crc32c(u32 seed, unsigned char const *in, size_t len)
+{
+	int i;
+	u32 crc = seed;
+
+	while (len--) {
+		crc ^= *in++;
+		for (i = 0; i < 8; i++) {
+			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
+		}
+	}
+	return crc;
+}
+
+/* calculate checksum for first n blocks */
+u32 erofs_calc_blk_checksum(erofs_blk_t nblks, u32 *crc)
+{
+	char *buf;
+	int err = 0;
+
+	buf = malloc(nblks * EROFS_BLKSIZ);
+	err = blk_read(buf, 0, nblks);
+	if (err) {
+		erofs_err("Failed to calculate erofs checksum - %s",
+			  erofs_strerror(err));
+		return err;
+	}
+	*crc = crc32c(0, (const unsigned char *)buf, nblks * EROFS_BLKSIZ);
+	free(buf);
+	return 0;
+}
+
+void erofs_write_checksum()
+{
+	struct erofs_super_block *sb;
+	char buf[EROFS_BLKSIZ];
+	int ret = 0;
+	u32 crc;
+
+	ret = erofs_calc_blk_checksum(EROFS_CKSUM_BLOCKS, &crc);
+	if (ret) {
+		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 an erofs image");
+		return;
+	}
+	sb->checksum = cpu_to_le32(crc);
+	ret = blk_write(buf, 0, 1);
+	if (ret) {
+		erofs_err("error writing 0th block to disk - %s",
+			  erofs_strerror(ret));
+		return;
+	}
+}
+
 int main(int argc, char **argv)
 {
 	int err = 0;
@@ -217,6 +290,7 @@ int main(int argc, char **argv)
 
 	cfg.c_legacy_compress = false;
 	sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
+	sbi.feature = EROFS_FEATURE_SB_CHKSUM;
 
 	err = mkfs_parse_options_cfg(argc, argv);
 	if (err) {
@@ -301,6 +375,8 @@ int main(int argc, char **argv)
 		err = -EIO;
 	else
 		err = dev_resize(nblocks);
+	if (sbi.feature & EROFS_FEATURE_SB_CHKSUM)
+		erofs_write_checksum();
 exit:
 	z_erofs_compress_exit();
 	dev_close();
-- 
2.9.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks.
  2019-10-14 14:59 [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks Pratik Shinde
@ 2019-10-14 23:45 ` Gao Xiang via Linux-erofs
  2019-10-15  1:33   ` Gao Xiang
  2019-10-15  2:00   ` Pratik Shinde
  0 siblings, 2 replies; 5+ messages in thread
From: Gao Xiang via Linux-erofs @ 2019-10-14 23:45 UTC (permalink / raw)
  To: Pratik Shinde; +Cc: miaoxie, linux-erofs

Hi Pratik,

Some nitpick comments... Let me know if you have other thoughts

On Mon, Oct 14, 2019 at 08:29:43PM +0530, Pratik Shinde wrote:
> Added code for calculating crc of erofs blocks (4K size).for now it calculates
> checksum of first block. but can modified to calculate crc for any no. of blocks
> 
> modified patch based on review comments.
> 
> Signed-off-by: Pratik Shinde <pratikshinde320@gmail.com>
> ---
>  include/erofs/internal.h |  1 +
>  include/erofs/io.h       |  8 +++++
>  lib/io.c                 | 27 +++++++++++++++++
>  mkfs/main.c              | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 112 insertions(+)
> 
> diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> index 5384946..53335bc 100644
> --- a/include/erofs/internal.h
> +++ b/include/erofs/internal.h
> @@ -55,6 +55,7 @@ struct erofs_sb_info {
>  	u32 feature_incompat;
>  	u64 build_time;
>  	u32 build_time_nsec;
> +	u32 feature;
>  };
>  
>  /* global sbi */
> diff --git a/include/erofs/io.h b/include/erofs/io.h
> index 9775047..e0ca8d9 100644
> --- a/include/erofs/io.h
> +++ b/include/erofs/io.h
> @@ -19,6 +19,7 @@
>  int dev_open(const char *devname);
>  void dev_close(void);
>  int dev_write(const void *buf, u64 offset, size_t len);
> +int dev_read(void *buf, u64 offset, size_t len);
>  int dev_fillzero(u64 offset, size_t len, bool padding);
>  int dev_fsync(void);
>  int dev_resize(erofs_blk_t nblocks);
> @@ -31,5 +32,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 start,
> +			    u32 nblocks)
> +{
> +	return dev_read(buf, blknr_to_addr(start),
> +			 blknr_to_addr(nblocks));
> +}
> +
>  #endif
>  
> diff --git a/lib/io.c b/lib/io.c
> index 7f5f94d..52f9424 100644
> --- a/lib/io.c
> +++ b/lib/io.c
> @@ -207,3 +207,30 @@ int dev_resize(unsigned int blocks)
>  	return dev_fillzero(st.st_size, length, true);
>  }
>  
> +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;
> +}
> diff --git a/mkfs/main.c b/mkfs/main.c
> index 91a018f..baaf02a 100644
> --- a/mkfs/main.c
> +++ b/mkfs/main.c
> @@ -22,6 +22,10 @@
>  
>  #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
>  
> +/* number of blocks for calculating checksum */
> +#define EROFS_CKSUM_BLOCKS	1
> +#define EROFS_FEATURE_SB_CHKSUM	0x0001

How about Moving EROFS_FEATURE_SB_CHKSUM to erofs_fs.h since it's
an on-disk definition,

> +
>  static void usage(void)
>  {
>  	fprintf(stderr, "usage: [options] FILE DIRECTORY\n\n");
> @@ -85,6 +89,10 @@ static int parse_extended_opts(const char *opts)
>  				return -EINVAL;
>  			cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;
>  		}
> +
> +		if (MATCH_EXTENTED_OPT("nocrc", token, keylen)) {
> +			sbi.feature &= ~EROFS_FEATURE_SB_CHKSUM;
> +		}
>  	}
>  	return 0;
>  }
> @@ -180,6 +188,7 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
>  		.meta_blkaddr  = sbi.meta_blkaddr,
>  		.xattr_blkaddr = 0,
>  		.feature_incompat = cpu_to_le32(sbi.feature_incompat),
> +		.checksum = 0
>  	};
>  	const unsigned int sb_blksize =
>  		round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
> @@ -202,6 +211,70 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
>  	return 0;
>  }
>  
> +#define CRCPOLY	0x82F63B78
> +static inline u32 crc32c(u32 seed, unsigned char const *in, size_t len)
> +{
> +	int i;
> +	u32 crc = seed;
> +
> +	while (len--) {
> +		crc ^= *in++;
> +		for (i = 0; i < 8; i++) {
> +			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
> +		}
> +	}
> +	return crc;
> +}
> +
> +/* calculate checksum for first n blocks */
> +u32 erofs_calc_blk_checksum(erofs_blk_t nblks, u32 *crc)
> +{
> +	char *buf;
> +	int err = 0;
> +
> +	buf = malloc(nblks * EROFS_BLKSIZ);
> +	err = blk_read(buf, 0, nblks);
> +	if (err) {
> +		erofs_err("Failed to calculate erofs checksum - %s",
> +			  erofs_strerror(err));
> +		return err;
> +	}
> +	*crc = crc32c(0, (const unsigned char *)buf, nblks * EROFS_BLKSIZ);
> +	free(buf);
> +	return 0;
> +}
> +
> +void erofs_write_checksum()

How about naming write_sb_checksum?
My idea is that this is a checksum in super block (rather than
a checksum only for super block [0th block])

Let me know if you have another thought...

> +{
> +	struct erofs_super_block *sb;
> +	char buf[EROFS_BLKSIZ];
> +	int ret = 0;
> +	u32 crc;
> +
> +	ret = erofs_calc_blk_checksum(EROFS_CKSUM_BLOCKS, &crc);
> +	if (ret) {
> +		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 an erofs image");

As the previous comments, I am little care about these print messages
since users will only see this and "error reading super-block structure"
"not an erofs image" makes confused for them... (They don't know what
the internal process is doing)

BTW, it looks good to me as a whole... Do you have some time on
kernel side as well? :)

Thanks,
Gao Xiang

> +		return;
> +	}
> +	sb->checksum = cpu_to_le32(crc);
> +	ret = blk_write(buf, 0, 1);
> +	if (ret) {
> +		erofs_err("error writing 0th block to disk - %s",
> +			  erofs_strerror(ret));
> +		return;
> +	}
> +}
> +
>  int main(int argc, char **argv)
>  {
>  	int err = 0;
> @@ -217,6 +290,7 @@ int main(int argc, char **argv)
>  
>  	cfg.c_legacy_compress = false;
>  	sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
> +	sbi.feature = EROFS_FEATURE_SB_CHKSUM;
>  
>  	err = mkfs_parse_options_cfg(argc, argv);
>  	if (err) {
> @@ -301,6 +375,8 @@ int main(int argc, char **argv)
>  		err = -EIO;
>  	else
>  		err = dev_resize(nblocks);
> +	if (sbi.feature & EROFS_FEATURE_SB_CHKSUM)
> +		erofs_write_checksum();
>  exit:
>  	z_erofs_compress_exit();
>  	dev_close();
> -- 
> 2.9.3
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks.
  2019-10-14 23:45 ` Gao Xiang via Linux-erofs
@ 2019-10-15  1:33   ` Gao Xiang
  2019-10-15  2:00   ` Pratik Shinde
  1 sibling, 0 replies; 5+ messages in thread
From: Gao Xiang @ 2019-10-15  1:33 UTC (permalink / raw)
  To: Gao Xiang; +Cc: linux-erofs, miaoxie

On Tue, Oct 15, 2019 at 07:45:17AM +0800, Gao Xiang via Linux-erofs wrote:
> Hi Pratik,
> 
> Some nitpick comments... Let me know if you have other thoughts
> 
> On Mon, Oct 14, 2019 at 08:29:43PM +0530, Pratik Shinde wrote:
> > Added code for calculating crc of erofs blocks (4K size).for now it calculates
> > checksum of first block. but can modified to calculate crc for any no. of blocks
> > 
> > modified patch based on review comments.
> > 
> > Signed-off-by: Pratik Shinde <pratikshinde320@gmail.com>
> > ---
> >  include/erofs/internal.h |  1 +
> >  include/erofs/io.h       |  8 +++++
> >  lib/io.c                 | 27 +++++++++++++++++
> >  mkfs/main.c              | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 112 insertions(+)
> > 
> > diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> > index 5384946..53335bc 100644
> > --- a/include/erofs/internal.h
> > +++ b/include/erofs/internal.h
> > @@ -55,6 +55,7 @@ struct erofs_sb_info {
> >  	u32 feature_incompat;
> >  	u64 build_time;
> >  	u32 build_time_nsec;
> > +	u32 feature;
> >  };

Oh, I missed one thing, we need to add another field to on-disk
erofs_super_block as well.

 21 /* 128-byte erofs on-disk super block */
 22 struct erofs_super_block {
 23         __le32 magic;           /* file system magic number */
 24         __le32 checksum;        /* crc32c(super_block) */
 25         __le32 feature_compat;
 26         __u8 blkszbits;         /* support block_size == PAGE_SIZE only */
 27         __u8 reserved;
 28
 29         __le16 root_nid;        /* nid of root directory */
 30         __le64 inos;            /* total valid ino # (== f_files - f_favail) */
 31
 32         __le64 build_time;      /* inode v1 time derivation */
 33         __le32 build_time_nsec; /* inode v1 time derivation in nano scale */
 34         __le32 blocks;          /* used for statfs */
 35         __le32 meta_blkaddr;    /* start block address of metadata area */
 36         __le32 xattr_blkaddr;   /* start block address of shared xattr area */
 37         __u8 uuid[16];          /* 128-bit uuid for volume */
 38         __u8 volume_name[16];   /* volume name */
 39         __le32 feature_incompat;

            __le32 chksum_blocks;

In order for kernel to know how many blocks it needs to be checked...

 40
 41         __u8 reserved2[44];
 42 };


Thanks,
Gao Xiang

> >  
> >  /* global sbi */
> > diff --git a/include/erofs/io.h b/include/erofs/io.h
> > index 9775047..e0ca8d9 100644
> > --- a/include/erofs/io.h
> > +++ b/include/erofs/io.h
> > @@ -19,6 +19,7 @@
> >  int dev_open(const char *devname);
> >  void dev_close(void);
> >  int dev_write(const void *buf, u64 offset, size_t len);
> > +int dev_read(void *buf, u64 offset, size_t len);
> >  int dev_fillzero(u64 offset, size_t len, bool padding);
> >  int dev_fsync(void);
> >  int dev_resize(erofs_blk_t nblocks);
> > @@ -31,5 +32,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 start,
> > +			    u32 nblocks)
> > +{
> > +	return dev_read(buf, blknr_to_addr(start),
> > +			 blknr_to_addr(nblocks));
> > +}
> > +
> >  #endif
> >  
> > diff --git a/lib/io.c b/lib/io.c
> > index 7f5f94d..52f9424 100644
> > --- a/lib/io.c
> > +++ b/lib/io.c
> > @@ -207,3 +207,30 @@ int dev_resize(unsigned int blocks)
> >  	return dev_fillzero(st.st_size, length, true);
> >  }
> >  
> > +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;
> > +}
> > diff --git a/mkfs/main.c b/mkfs/main.c
> > index 91a018f..baaf02a 100644
> > --- a/mkfs/main.c
> > +++ b/mkfs/main.c
> > @@ -22,6 +22,10 @@
> >  
> >  #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
> >  
> > +/* number of blocks for calculating checksum */
> > +#define EROFS_CKSUM_BLOCKS	1
> > +#define EROFS_FEATURE_SB_CHKSUM	0x0001
> 
> How about Moving EROFS_FEATURE_SB_CHKSUM to erofs_fs.h since it's
> an on-disk definition,
> 
> > +
> >  static void usage(void)
> >  {
> >  	fprintf(stderr, "usage: [options] FILE DIRECTORY\n\n");
> > @@ -85,6 +89,10 @@ static int parse_extended_opts(const char *opts)
> >  				return -EINVAL;
> >  			cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;
> >  		}
> > +
> > +		if (MATCH_EXTENTED_OPT("nocrc", token, keylen)) {
> > +			sbi.feature &= ~EROFS_FEATURE_SB_CHKSUM;
> > +		}
> >  	}
> >  	return 0;
> >  }
> > @@ -180,6 +188,7 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
> >  		.meta_blkaddr  = sbi.meta_blkaddr,
> >  		.xattr_blkaddr = 0,
> >  		.feature_incompat = cpu_to_le32(sbi.feature_incompat),
> > +		.checksum = 0
> >  	};
> >  	const unsigned int sb_blksize =
> >  		round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
> > @@ -202,6 +211,70 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
> >  	return 0;
> >  }
> >  
> > +#define CRCPOLY	0x82F63B78
> > +static inline u32 crc32c(u32 seed, unsigned char const *in, size_t len)
> > +{
> > +	int i;
> > +	u32 crc = seed;
> > +
> > +	while (len--) {
> > +		crc ^= *in++;
> > +		for (i = 0; i < 8; i++) {
> > +			crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
> > +		}
> > +	}
> > +	return crc;
> > +}
> > +
> > +/* calculate checksum for first n blocks */
> > +u32 erofs_calc_blk_checksum(erofs_blk_t nblks, u32 *crc)
> > +{
> > +	char *buf;
> > +	int err = 0;
> > +
> > +	buf = malloc(nblks * EROFS_BLKSIZ);
> > +	err = blk_read(buf, 0, nblks);
> > +	if (err) {
> > +		erofs_err("Failed to calculate erofs checksum - %s",
> > +			  erofs_strerror(err));
> > +		return err;
> > +	}
> > +	*crc = crc32c(0, (const unsigned char *)buf, nblks * EROFS_BLKSIZ);
> > +	free(buf);
> > +	return 0;
> > +}
> > +
> > +void erofs_write_checksum()
> 
> How about naming write_sb_checksum?
> My idea is that this is a checksum in super block (rather than
> a checksum only for super block [0th block])
> 
> Let me know if you have another thought...
> 
> > +{
> > +	struct erofs_super_block *sb;
> > +	char buf[EROFS_BLKSIZ];
> > +	int ret = 0;
> > +	u32 crc;
> > +
> > +	ret = erofs_calc_blk_checksum(EROFS_CKSUM_BLOCKS, &crc);
> > +	if (ret) {
> > +		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 an erofs image");
> 
> As the previous comments, I am little care about these print messages
> since users will only see this and "error reading super-block structure"
> "not an erofs image" makes confused for them... (They don't know what
> the internal process is doing)
> 
> BTW, it looks good to me as a whole... Do you have some time on
> kernel side as well? :)
> 
> Thanks,
> Gao Xiang
> 
> > +		return;
> > +	}
> > +	sb->checksum = cpu_to_le32(crc);
> > +	ret = blk_write(buf, 0, 1);
> > +	if (ret) {
> > +		erofs_err("error writing 0th block to disk - %s",
> > +			  erofs_strerror(ret));
> > +		return;
> > +	}
> > +}
> > +
> >  int main(int argc, char **argv)
> >  {
> >  	int err = 0;
> > @@ -217,6 +290,7 @@ int main(int argc, char **argv)
> >  
> >  	cfg.c_legacy_compress = false;
> >  	sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
> > +	sbi.feature = EROFS_FEATURE_SB_CHKSUM;
> >  
> >  	err = mkfs_parse_options_cfg(argc, argv);
> >  	if (err) {
> > @@ -301,6 +375,8 @@ int main(int argc, char **argv)
> >  		err = -EIO;
> >  	else
> >  		err = dev_resize(nblocks);
> > +	if (sbi.feature & EROFS_FEATURE_SB_CHKSUM)
> > +		erofs_write_checksum();
> >  exit:
> >  	z_erofs_compress_exit();
> >  	dev_close();
> > -- 
> > 2.9.3
> > 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks.
  2019-10-14 23:45 ` Gao Xiang via Linux-erofs
  2019-10-15  1:33   ` Gao Xiang
@ 2019-10-15  2:00   ` Pratik Shinde
  2019-10-15  2:09     ` Gao Xiang
  1 sibling, 1 reply; 5+ messages in thread
From: Pratik Shinde @ 2019-10-15  2:00 UTC (permalink / raw)
  To: Gao Xiang; +Cc: miaoxie, linux-erofs

[-- Attachment #1: Type: text/plain, Size: 8070 bytes --]

Hi Gao,

okay. I will make those changes. Yes I would like to do kernel side changes
too. Which branch to use for this? kernel's master?

-Pratik

On Tue, 15 Oct, 2019, 5:15 AM Gao Xiang, <hsiangkao@aol.com> wrote:

> Hi Pratik,
>
> Some nitpick comments... Let me know if you have other thoughts
>
> On Mon, Oct 14, 2019 at 08:29:43PM +0530, Pratik Shinde wrote:
> > Added code for calculating crc of erofs blocks (4K size).for now it
> calculates
> > checksum of first block. but can modified to calculate crc for any no.
> of blocks
> >
> > modified patch based on review comments.
> >
> > Signed-off-by: Pratik Shinde <pratikshinde320@gmail.com>
> > ---
> >  include/erofs/internal.h |  1 +
> >  include/erofs/io.h       |  8 +++++
> >  lib/io.c                 | 27 +++++++++++++++++
> >  mkfs/main.c              | 76
> ++++++++++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 112 insertions(+)
> >
> > diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> > index 5384946..53335bc 100644
> > --- a/include/erofs/internal.h
> > +++ b/include/erofs/internal.h
> > @@ -55,6 +55,7 @@ struct erofs_sb_info {
> >       u32 feature_incompat;
> >       u64 build_time;
> >       u32 build_time_nsec;
> > +     u32 feature;
> >  };
> >
> >  /* global sbi */
> > diff --git a/include/erofs/io.h b/include/erofs/io.h
> > index 9775047..e0ca8d9 100644
> > --- a/include/erofs/io.h
> > +++ b/include/erofs/io.h
> > @@ -19,6 +19,7 @@
> >  int dev_open(const char *devname);
> >  void dev_close(void);
> >  int dev_write(const void *buf, u64 offset, size_t len);
> > +int dev_read(void *buf, u64 offset, size_t len);
> >  int dev_fillzero(u64 offset, size_t len, bool padding);
> >  int dev_fsync(void);
> >  int dev_resize(erofs_blk_t nblocks);
> > @@ -31,5 +32,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 start,
> > +                         u32 nblocks)
> > +{
> > +     return dev_read(buf, blknr_to_addr(start),
> > +                      blknr_to_addr(nblocks));
> > +}
> > +
> >  #endif
> >
> > diff --git a/lib/io.c b/lib/io.c
> > index 7f5f94d..52f9424 100644
> > --- a/lib/io.c
> > +++ b/lib/io.c
> > @@ -207,3 +207,30 @@ int dev_resize(unsigned int blocks)
> >       return dev_fillzero(st.st_size, length, true);
> >  }
> >
> > +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;
> > +}
> > diff --git a/mkfs/main.c b/mkfs/main.c
> > index 91a018f..baaf02a 100644
> > --- a/mkfs/main.c
> > +++ b/mkfs/main.c
> > @@ -22,6 +22,10 @@
> >
> >  #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct
> erofs_super_block))
> >
> > +/* number of blocks for calculating checksum */
> > +#define EROFS_CKSUM_BLOCKS   1
> > +#define EROFS_FEATURE_SB_CHKSUM      0x0001
>
> How about Moving EROFS_FEATURE_SB_CHKSUM to erofs_fs.h since it's
> an on-disk definition,
>
> > +
> >  static void usage(void)
> >  {
> >       fprintf(stderr, "usage: [options] FILE DIRECTORY\n\n");
> > @@ -85,6 +89,10 @@ static int parse_extended_opts(const char *opts)
> >                               return -EINVAL;
> >                       cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;
> >               }
> > +
> > +             if (MATCH_EXTENTED_OPT("nocrc", token, keylen)) {
> > +                     sbi.feature &= ~EROFS_FEATURE_SB_CHKSUM;
> > +             }
> >       }
> >       return 0;
> >  }
> > @@ -180,6 +188,7 @@ int erofs_mkfs_update_super_block(struct
> erofs_buffer_head *bh,
> >               .meta_blkaddr  = sbi.meta_blkaddr,
> >               .xattr_blkaddr = 0,
> >               .feature_incompat = cpu_to_le32(sbi.feature_incompat),
> > +             .checksum = 0
> >       };
> >       const unsigned int sb_blksize =
> >               round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
> > @@ -202,6 +211,70 @@ int erofs_mkfs_update_super_block(struct
> erofs_buffer_head *bh,
> >       return 0;
> >  }
> >
> > +#define CRCPOLY      0x82F63B78
> > +static inline u32 crc32c(u32 seed, unsigned char const *in, size_t len)
> > +{
> > +     int i;
> > +     u32 crc = seed;
> > +
> > +     while (len--) {
> > +             crc ^= *in++;
> > +             for (i = 0; i < 8; i++) {
> > +                     crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
> > +             }
> > +     }
> > +     return crc;
> > +}
> > +
> > +/* calculate checksum for first n blocks */
> > +u32 erofs_calc_blk_checksum(erofs_blk_t nblks, u32 *crc)
> > +{
> > +     char *buf;
> > +     int err = 0;
> > +
> > +     buf = malloc(nblks * EROFS_BLKSIZ);
> > +     err = blk_read(buf, 0, nblks);
> > +     if (err) {
> > +             erofs_err("Failed to calculate erofs checksum - %s",
> > +                       erofs_strerror(err));
> > +             return err;
> > +     }
> > +     *crc = crc32c(0, (const unsigned char *)buf, nblks * EROFS_BLKSIZ);
> > +     free(buf);
> > +     return 0;
> > +}
> > +
> > +void erofs_write_checksum()
>
> How about naming write_sb_checksum?
> My idea is that this is a checksum in super block (rather than
> a checksum only for super block [0th block])
>
> Let me know if you have another thought...
>
> > +{
> > +     struct erofs_super_block *sb;
> > +     char buf[EROFS_BLKSIZ];
> > +     int ret = 0;
> > +     u32 crc;
> > +
> > +     ret = erofs_calc_blk_checksum(EROFS_CKSUM_BLOCKS, &crc);
> > +     if (ret) {
> > +             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 an erofs image");
>
> As the previous comments, I am little care about these print messages
> since users will only see this and "error reading super-block structure"
> "not an erofs image" makes confused for them... (They don't know what
> the internal process is doing)
>
> BTW, it looks good to me as a whole... Do you have some time on
> kernel side as well? :)
>
> Thanks,
> Gao Xiang
>
> > +             return;
> > +     }
> > +     sb->checksum = cpu_to_le32(crc);
> > +     ret = blk_write(buf, 0, 1);
> > +     if (ret) {
> > +             erofs_err("error writing 0th block to disk - %s",
> > +                       erofs_strerror(ret));
> > +             return;
> > +     }
> > +}
> > +
> >  int main(int argc, char **argv)
> >  {
> >       int err = 0;
> > @@ -217,6 +290,7 @@ int main(int argc, char **argv)
> >
> >       cfg.c_legacy_compress = false;
> >       sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
> > +     sbi.feature = EROFS_FEATURE_SB_CHKSUM;
> >
> >       err = mkfs_parse_options_cfg(argc, argv);
> >       if (err) {
> > @@ -301,6 +375,8 @@ int main(int argc, char **argv)
> >               err = -EIO;
> >       else
> >               err = dev_resize(nblocks);
> > +     if (sbi.feature & EROFS_FEATURE_SB_CHKSUM)
> > +             erofs_write_checksum();
> >  exit:
> >       z_erofs_compress_exit();
> >       dev_close();
> > --
> > 2.9.3
> >
>

[-- Attachment #2: Type: text/html, Size: 10708 bytes --]

<div dir="auto">Hi Gao, <div dir="auto"><br></div><div dir="auto">okay. I will make those changes. Yes I would like to do kernel side changes too. Which branch to use for this? kernel&#39;s master?</div><div dir="auto"><br></div><div dir="auto">-Pratik</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 15 Oct, 2019, 5:15 AM Gao Xiang, &lt;<a href="mailto:hsiangkao@aol.com">hsiangkao@aol.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Pratik,<br>
<br>
Some nitpick comments... Let me know if you have other thoughts<br>
<br>
On Mon, Oct 14, 2019 at 08:29:43PM +0530, Pratik Shinde wrote:<br>
&gt; Added code for calculating crc of erofs blocks (4K size).for now it calculates<br>
&gt; checksum of first block. but can modified to calculate crc for any no. of blocks<br>
&gt; <br>
&gt; modified patch based on review comments.<br>
&gt; <br>
&gt; Signed-off-by: Pratik Shinde &lt;<a href="mailto:pratikshinde320@gmail.com" target="_blank" rel="noreferrer">pratikshinde320@gmail.com</a>&gt;<br>
&gt; ---<br>
&gt;  include/erofs/internal.h |  1 +<br>
&gt;  include/erofs/io.h       |  8 +++++<br>
&gt;  lib/io.c                 | 27 +++++++++++++++++<br>
&gt;  mkfs/main.c              | 76 ++++++++++++++++++++++++++++++++++++++++++++++++<br>
&gt;  4 files changed, 112 insertions(+)<br>
&gt; <br>
&gt; diff --git a/include/erofs/internal.h b/include/erofs/internal.h<br>
&gt; index 5384946..53335bc 100644<br>
&gt; --- a/include/erofs/internal.h<br>
&gt; +++ b/include/erofs/internal.h<br>
&gt; @@ -55,6 +55,7 @@ struct erofs_sb_info {<br>
&gt;       u32 feature_incompat;<br>
&gt;       u64 build_time;<br>
&gt;       u32 build_time_nsec;<br>
&gt; +     u32 feature;<br>
&gt;  };<br>
&gt;  <br>
&gt;  /* global sbi */<br>
&gt; diff --git a/include/erofs/io.h b/include/erofs/io.h<br>
&gt; index 9775047..e0ca8d9 100644<br>
&gt; --- a/include/erofs/io.h<br>
&gt; +++ b/include/erofs/io.h<br>
&gt; @@ -19,6 +19,7 @@<br>
&gt;  int dev_open(const char *devname);<br>
&gt;  void dev_close(void);<br>
&gt;  int dev_write(const void *buf, u64 offset, size_t len);<br>
&gt; +int dev_read(void *buf, u64 offset, size_t len);<br>
&gt;  int dev_fillzero(u64 offset, size_t len, bool padding);<br>
&gt;  int dev_fsync(void);<br>
&gt;  int dev_resize(erofs_blk_t nblocks);<br>
&gt; @@ -31,5 +32,12 @@ static inline int blk_write(const void *buf, erofs_blk_t blkaddr,<br>
&gt;                        blknr_to_addr(nblocks));<br>
&gt;  }<br>
&gt;  <br>
&gt; +static inline int blk_read(void *buf, erofs_blk_t start,<br>
&gt; +                         u32 nblocks)<br>
&gt; +{<br>
&gt; +     return dev_read(buf, blknr_to_addr(start),<br>
&gt; +                      blknr_to_addr(nblocks));<br>
&gt; +}<br>
&gt; +<br>
&gt;  #endif<br>
&gt;  <br>
&gt; diff --git a/lib/io.c b/lib/io.c<br>
&gt; index 7f5f94d..52f9424 100644<br>
&gt; --- a/lib/io.c<br>
&gt; +++ b/lib/io.c<br>
&gt; @@ -207,3 +207,30 @@ int dev_resize(unsigned int blocks)<br>
&gt;       return dev_fillzero(st.st_size, length, true);<br>
&gt;  }<br>
&gt;  <br>
&gt; +int dev_read(void *buf, u64 offset, size_t len)<br>
&gt; +{<br>
&gt; +     int ret;<br>
&gt; +<br>
&gt; +     if (cfg.c_dry_run)<br>
&gt; +             return 0;<br>
&gt; +<br>
&gt; +     if (!buf) {<br>
&gt; +             erofs_err(&quot;buf is NULL&quot;);<br>
&gt; +             return -EINVAL;<br>
&gt; +     }<br>
&gt; +     if (offset &gt;= erofs_devsz || len &gt; erofs_devsz ||<br>
&gt; +         offset &gt; erofs_devsz - len) {<br>
&gt; +             erofs_err(&quot;read posion[%&quot; PRIu64 &quot;, %zd] is too large beyond&quot;<br>
&gt; +                       &quot;the end of device(%&quot; PRIu64 &quot;).&quot;,<br>
&gt; +                       offset, len, erofs_devsz);<br>
&gt; +             return -EINVAL;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     ret = pread64(erofs_devfd, buf, len, (off64_t)offset);<br>
&gt; +     if (ret != (int)len) {<br>
&gt; +             erofs_err(&quot;Failed to read data from device - %s:[%&quot; PRIu64 &quot;, %zd].&quot;,<br>
&gt; +                       erofs_devname, offset, len);<br>
&gt; +             return -errno;<br>
&gt; +     }<br>
&gt; +     return 0;<br>
&gt; +}<br>
&gt; diff --git a/mkfs/main.c b/mkfs/main.c<br>
&gt; index 91a018f..baaf02a 100644<br>
&gt; --- a/mkfs/main.c<br>
&gt; +++ b/mkfs/main.c<br>
&gt; @@ -22,6 +22,10 @@<br>
&gt;  <br>
&gt;  #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))<br>
&gt;  <br>
&gt; +/* number of blocks for calculating checksum */<br>
&gt; +#define EROFS_CKSUM_BLOCKS   1<br>
&gt; +#define EROFS_FEATURE_SB_CHKSUM      0x0001<br>
<br>
How about Moving EROFS_FEATURE_SB_CHKSUM to erofs_fs.h since it&#39;s<br>
an on-disk definition,<br>
<br>
&gt; +<br>
&gt;  static void usage(void)<br>
&gt;  {<br>
&gt;       fprintf(stderr, &quot;usage: [options] FILE DIRECTORY\n\n&quot;);<br>
&gt; @@ -85,6 +89,10 @@ static int parse_extended_opts(const char *opts)<br>
&gt;                               return -EINVAL;<br>
&gt;                       cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;<br>
&gt;               }<br>
&gt; +<br>
&gt; +             if (MATCH_EXTENTED_OPT(&quot;nocrc&quot;, token, keylen)) {<br>
&gt; +                     sbi.feature &amp;= ~EROFS_FEATURE_SB_CHKSUM;<br>
&gt; +             }<br>
&gt;       }<br>
&gt;       return 0;<br>
&gt;  }<br>
&gt; @@ -180,6 +188,7 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,<br>
&gt;               .meta_blkaddr  = sbi.meta_blkaddr,<br>
&gt;               .xattr_blkaddr = 0,<br>
&gt;               .feature_incompat = cpu_to_le32(sbi.feature_incompat),<br>
&gt; +             .checksum = 0<br>
&gt;       };<br>
&gt;       const unsigned int sb_blksize =<br>
&gt;               round_up(EROFS_SUPER_END, EROFS_BLKSIZ);<br>
&gt; @@ -202,6 +211,70 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,<br>
&gt;       return 0;<br>
&gt;  }<br>
&gt;  <br>
&gt; +#define CRCPOLY      0x82F63B78<br>
&gt; +static inline u32 crc32c(u32 seed, unsigned char const *in, size_t len)<br>
&gt; +{<br>
&gt; +     int i;<br>
&gt; +     u32 crc = seed;<br>
&gt; +<br>
&gt; +     while (len--) {<br>
&gt; +             crc ^= *in++;<br>
&gt; +             for (i = 0; i &lt; 8; i++) {<br>
&gt; +                     crc = (crc &gt;&gt; 1) ^ ((crc &amp; 1) ? CRCPOLY : 0);<br>
&gt; +             }<br>
&gt; +     }<br>
&gt; +     return crc;<br>
&gt; +}<br>
&gt; +<br>
&gt; +/* calculate checksum for first n blocks */<br>
&gt; +u32 erofs_calc_blk_checksum(erofs_blk_t nblks, u32 *crc)<br>
&gt; +{<br>
&gt; +     char *buf;<br>
&gt; +     int err = 0;<br>
&gt; +<br>
&gt; +     buf = malloc(nblks * EROFS_BLKSIZ);<br>
&gt; +     err = blk_read(buf, 0, nblks);<br>
&gt; +     if (err) {<br>
&gt; +             erofs_err(&quot;Failed to calculate erofs checksum - %s&quot;,<br>
&gt; +                       erofs_strerror(err));<br>
&gt; +             return err;<br>
&gt; +     }<br>
&gt; +     *crc = crc32c(0, (const unsigned char *)buf, nblks * EROFS_BLKSIZ);<br>
&gt; +     free(buf);<br>
&gt; +     return 0;<br>
&gt; +}<br>
&gt; +<br>
&gt; +void erofs_write_checksum()<br>
<br>
How about naming write_sb_checksum?<br>
My idea is that this is a checksum in super block (rather than<br>
a checksum only for super block [0th block])<br>
<br>
Let me know if you have another thought...<br>
<br>
&gt; +{<br>
&gt; +     struct erofs_super_block *sb;<br>
&gt; +     char buf[EROFS_BLKSIZ];<br>
&gt; +     int ret = 0;<br>
&gt; +     u32 crc;<br>
&gt; +<br>
&gt; +     ret = erofs_calc_blk_checksum(EROFS_CKSUM_BLOCKS, &amp;crc);<br>
&gt; +     if (ret) {<br>
&gt; +             return;<br>
&gt; +     }<br>
&gt; +     ret = blk_read(buf, 0, 1);<br>
&gt; +     if (ret) {<br>
&gt; +             erofs_err(&quot;error reading super-block structure&quot;);<br>
&gt; +             return;<br>
&gt; +     }<br>
&gt; +<br>
&gt; +     sb = (struct erofs_super_block *)((u8 *)buf + EROFS_SUPER_OFFSET);<br>
&gt; +     if (le32_to_cpu(sb-&gt;magic) != EROFS_SUPER_MAGIC_V1) {<br>
&gt; +             erofs_err(&quot;not an erofs image&quot;);<br>
<br>
As the previous comments, I am little care about these print messages<br>
since users will only see this and &quot;error reading super-block structure&quot;<br>
&quot;not an erofs image&quot; makes confused for them... (They don&#39;t know what<br>
the internal process is doing)<br>
<br>
BTW, it looks good to me as a whole... Do you have some time on<br>
kernel side as well? :)<br>
<br>
Thanks,<br>
Gao Xiang<br>
<br>
&gt; +             return;<br>
&gt; +     }<br>
&gt; +     sb-&gt;checksum = cpu_to_le32(crc);<br>
&gt; +     ret = blk_write(buf, 0, 1);<br>
&gt; +     if (ret) {<br>
&gt; +             erofs_err(&quot;error writing 0th block to disk - %s&quot;,<br>
&gt; +                       erofs_strerror(ret));<br>
&gt; +             return;<br>
&gt; +     }<br>
&gt; +}<br>
&gt; +<br>
&gt;  int main(int argc, char **argv)<br>
&gt;  {<br>
&gt;       int err = 0;<br>
&gt; @@ -217,6 +290,7 @@ int main(int argc, char **argv)<br>
&gt;  <br>
&gt;       cfg.c_legacy_compress = false;<br>
&gt;       sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;<br>
&gt; +     sbi.feature = EROFS_FEATURE_SB_CHKSUM;<br>
&gt;  <br>
&gt;       err = mkfs_parse_options_cfg(argc, argv);<br>
&gt;       if (err) {<br>
&gt; @@ -301,6 +375,8 @@ int main(int argc, char **argv)<br>
&gt;               err = -EIO;<br>
&gt;       else<br>
&gt;               err = dev_resize(nblocks);<br>
&gt; +     if (sbi.feature &amp; EROFS_FEATURE_SB_CHKSUM)<br>
&gt; +             erofs_write_checksum();<br>
&gt;  exit:<br>
&gt;       z_erofs_compress_exit();<br>
&gt;       dev_close();<br>
&gt; -- <br>
&gt; 2.9.3<br>
&gt; <br>
</blockquote></div>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks.
  2019-10-15  2:00   ` Pratik Shinde
@ 2019-10-15  2:09     ` Gao Xiang
  0 siblings, 0 replies; 5+ messages in thread
From: Gao Xiang @ 2019-10-15  2:09 UTC (permalink / raw)
  To: Pratik Shinde; +Cc: linux-erofs, miaoxie

Hi Pratik,

On Tue, Oct 15, 2019 at 07:30:38AM +0530, Pratik Shinde wrote:
> Hi Gao,
> 
> okay. I will make those changes. Yes I would like to do kernel side changes
> too. Which branch to use for this? kernel's master?

erofs development tree is better,
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git -b dev

erofs is now an independent tree, and I will collect all kernel patches
(including features, bugfixes and cleanups) for linux-next then.

p.s. kind reminder, don't forgot add a chksum_blocks field to on-disk
erofs_super_block
as well.

Thanks,
Goa Xiang

> 
> -Pratik
> 
> On Tue, 15 Oct, 2019, 5:15 AM Gao Xiang, <hsiangkao@aol.com> wrote:
> 
> > Hi Pratik,
> >
> > Some nitpick comments... Let me know if you have other thoughts
> >
> > On Mon, Oct 14, 2019 at 08:29:43PM +0530, Pratik Shinde wrote:
> > > Added code for calculating crc of erofs blocks (4K size).for now it
> > calculates
> > > checksum of first block. but can modified to calculate crc for any no.
> > of blocks
> > >
> > > modified patch based on review comments.
> > >
> > > Signed-off-by: Pratik Shinde <pratikshinde320@gmail.com>
> > > ---
> > >  include/erofs/internal.h |  1 +
> > >  include/erofs/io.h       |  8 +++++
> > >  lib/io.c                 | 27 +++++++++++++++++
> > >  mkfs/main.c              | 76
> > ++++++++++++++++++++++++++++++++++++++++++++++++
> > >  4 files changed, 112 insertions(+)
> > >
> > > diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> > > index 5384946..53335bc 100644
> > > --- a/include/erofs/internal.h
> > > +++ b/include/erofs/internal.h
> > > @@ -55,6 +55,7 @@ struct erofs_sb_info {
> > >       u32 feature_incompat;
> > >       u64 build_time;
> > >       u32 build_time_nsec;
> > > +     u32 feature;
> > >  };
> > >
> > >  /* global sbi */
> > > diff --git a/include/erofs/io.h b/include/erofs/io.h
> > > index 9775047..e0ca8d9 100644
> > > --- a/include/erofs/io.h
> > > +++ b/include/erofs/io.h
> > > @@ -19,6 +19,7 @@
> > >  int dev_open(const char *devname);
> > >  void dev_close(void);
> > >  int dev_write(const void *buf, u64 offset, size_t len);
> > > +int dev_read(void *buf, u64 offset, size_t len);
> > >  int dev_fillzero(u64 offset, size_t len, bool padding);
> > >  int dev_fsync(void);
> > >  int dev_resize(erofs_blk_t nblocks);
> > > @@ -31,5 +32,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 start,
> > > +                         u32 nblocks)
> > > +{
> > > +     return dev_read(buf, blknr_to_addr(start),
> > > +                      blknr_to_addr(nblocks));
> > > +}
> > > +
> > >  #endif
> > >
> > > diff --git a/lib/io.c b/lib/io.c
> > > index 7f5f94d..52f9424 100644
> > > --- a/lib/io.c
> > > +++ b/lib/io.c
> > > @@ -207,3 +207,30 @@ int dev_resize(unsigned int blocks)
> > >       return dev_fillzero(st.st_size, length, true);
> > >  }
> > >
> > > +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;
> > > +}
> > > diff --git a/mkfs/main.c b/mkfs/main.c
> > > index 91a018f..baaf02a 100644
> > > --- a/mkfs/main.c
> > > +++ b/mkfs/main.c
> > > @@ -22,6 +22,10 @@
> > >
> > >  #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct
> > erofs_super_block))
> > >
> > > +/* number of blocks for calculating checksum */
> > > +#define EROFS_CKSUM_BLOCKS   1
> > > +#define EROFS_FEATURE_SB_CHKSUM      0x0001
> >
> > How about Moving EROFS_FEATURE_SB_CHKSUM to erofs_fs.h since it's
> > an on-disk definition,
> >
> > > +
> > >  static void usage(void)
> > >  {
> > >       fprintf(stderr, "usage: [options] FILE DIRECTORY\n\n");
> > > @@ -85,6 +89,10 @@ static int parse_extended_opts(const char *opts)
> > >                               return -EINVAL;
> > >                       cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;
> > >               }
> > > +
> > > +             if (MATCH_EXTENTED_OPT("nocrc", token, keylen)) {
> > > +                     sbi.feature &= ~EROFS_FEATURE_SB_CHKSUM;
> > > +             }
> > >       }
> > >       return 0;
> > >  }
> > > @@ -180,6 +188,7 @@ int erofs_mkfs_update_super_block(struct
> > erofs_buffer_head *bh,
> > >               .meta_blkaddr  = sbi.meta_blkaddr,
> > >               .xattr_blkaddr = 0,
> > >               .feature_incompat = cpu_to_le32(sbi.feature_incompat),
> > > +             .checksum = 0
> > >       };
> > >       const unsigned int sb_blksize =
> > >               round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
> > > @@ -202,6 +211,70 @@ int erofs_mkfs_update_super_block(struct
> > erofs_buffer_head *bh,
> > >       return 0;
> > >  }
> > >
> > > +#define CRCPOLY      0x82F63B78
> > > +static inline u32 crc32c(u32 seed, unsigned char const *in, size_t len)
> > > +{
> > > +     int i;
> > > +     u32 crc = seed;
> > > +
> > > +     while (len--) {
> > > +             crc ^= *in++;
> > > +             for (i = 0; i < 8; i++) {
> > > +                     crc = (crc >> 1) ^ ((crc & 1) ? CRCPOLY : 0);
> > > +             }
> > > +     }
> > > +     return crc;
> > > +}
> > > +
> > > +/* calculate checksum for first n blocks */
> > > +u32 erofs_calc_blk_checksum(erofs_blk_t nblks, u32 *crc)
> > > +{
> > > +     char *buf;
> > > +     int err = 0;
> > > +
> > > +     buf = malloc(nblks * EROFS_BLKSIZ);
> > > +     err = blk_read(buf, 0, nblks);
> > > +     if (err) {
> > > +             erofs_err("Failed to calculate erofs checksum - %s",
> > > +                       erofs_strerror(err));
> > > +             return err;
> > > +     }
> > > +     *crc = crc32c(0, (const unsigned char *)buf, nblks * EROFS_BLKSIZ);
> > > +     free(buf);
> > > +     return 0;
> > > +}
> > > +
> > > +void erofs_write_checksum()
> >
> > How about naming write_sb_checksum?
> > My idea is that this is a checksum in super block (rather than
> > a checksum only for super block [0th block])
> >
> > Let me know if you have another thought...
> >
> > > +{
> > > +     struct erofs_super_block *sb;
> > > +     char buf[EROFS_BLKSIZ];
> > > +     int ret = 0;
> > > +     u32 crc;
> > > +
> > > +     ret = erofs_calc_blk_checksum(EROFS_CKSUM_BLOCKS, &crc);
> > > +     if (ret) {
> > > +             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 an erofs image");
> >
> > As the previous comments, I am little care about these print messages
> > since users will only see this and "error reading super-block structure"
> > "not an erofs image" makes confused for them... (They don't know what
> > the internal process is doing)
> >
> > BTW, it looks good to me as a whole... Do you have some time on
> > kernel side as well? :)
> >
> > Thanks,
> > Gao Xiang
> >
> > > +             return;
> > > +     }
> > > +     sb->checksum = cpu_to_le32(crc);
> > > +     ret = blk_write(buf, 0, 1);
> > > +     if (ret) {
> > > +             erofs_err("error writing 0th block to disk - %s",
> > > +                       erofs_strerror(ret));
> > > +             return;
> > > +     }
> > > +}
> > > +
> > >  int main(int argc, char **argv)
> > >  {
> > >       int err = 0;
> > > @@ -217,6 +290,7 @@ int main(int argc, char **argv)
> > >
> > >       cfg.c_legacy_compress = false;
> > >       sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
> > > +     sbi.feature = EROFS_FEATURE_SB_CHKSUM;
> > >
> > >       err = mkfs_parse_options_cfg(argc, argv);
> > >       if (err) {
> > > @@ -301,6 +375,8 @@ int main(int argc, char **argv)
> > >               err = -EIO;
> > >       else
> > >               err = dev_resize(nblocks);
> > > +     if (sbi.feature & EROFS_FEATURE_SB_CHKSUM)
> > > +             erofs_write_checksum();
> > >  exit:
> > >       z_erofs_compress_exit();
> > >       dev_close();
> > > --
> > > 2.9.3
> > >
> >

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-14 14:59 [PATCH-v2] erofs-utils:code for calculating crc checksum of erofs blocks Pratik Shinde
2019-10-14 23:45 ` Gao Xiang via Linux-erofs
2019-10-15  1:33   ` Gao Xiang
2019-10-15  2:00   ` Pratik Shinde
2019-10-15  2:09     ` Gao Xiang

Linux-EROFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-erofs/0 linux-erofs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-erofs linux-erofs/ https://lore.kernel.org/linux-erofs \
		linux-erofs@lists.ozlabs.org linux-erofs@ozlabs.org
	public-inbox-index linux-erofs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.ozlabs.lists.linux-erofs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git