aboutsummaryrefslogtreecommitdiff
path: root/mkfs/main.c
diff options
context:
space:
mode:
authorPratik Shinde <pratikshinde320@gmail.com>2019-11-07 12:03:26 +0800
committerGao Xiang <hsiangkao@aol.com>2019-11-08 21:50:24 +0800
commitfb757ede69e7f310e2c91cd3672e2e4049a1d348 (patch)
tree991208d72a7514f2ca24a7f8685d58026ad5daf3 /mkfs/main.c
parenta34f86beb16b25cb0f44c85934acb93749fc844c (diff)
downloaderofs-utils-fb757ede69e7f310e2c91cd3672e2e4049a1d348.tar.gz
erofs-utils: support calculating checksum of superblock
Added code for calculating crc of superblock. Note that the first 1024 bytes are not checksummed to allow for the installation of x86 boot sectors and other oddities. Fill 'feature_compat' field of erofs_super_block so that it can be used on kernel side. also fixing one typo. Link: https://lore.kernel.org/r/20191107040327.93369-1-gaoxiang25@huawei.com Signed-off-by: Pratik Shinde <pratikshinde320@gmail.com> Reviewed-by: Chao Yu <yuchao0@huawei.com> Reviewed-by: Li Guifu <blucerlee@gmail.com> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
Diffstat (limited to 'mkfs/main.c')
-rw-r--r--mkfs/main.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/mkfs/main.c b/mkfs/main.c
index ab57896..9187c43 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -109,6 +109,12 @@ static int parse_extended_opts(const char *opts)
return -EINVAL;
cfg.c_force_inodeversion = FORCE_INODE_EXTENDED;
}
+
+ if (MATCH_EXTENTED_OPT("nosbcrc", token, keylen)) {
+ if (vallen)
+ return -EINVAL;
+ sbi.feature_compat &= ~EROFS_FEATURE_COMPAT_SB_CHKSUM;
+ }
}
return 0;
}
@@ -218,6 +224,8 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
.meta_blkaddr = sbi.meta_blkaddr,
.xattr_blkaddr = sbi.xattr_blkaddr,
.feature_incompat = cpu_to_le32(sbi.feature_incompat),
+ .feature_compat = cpu_to_le32(sbi.feature_compat &
+ ~EROFS_FEATURE_COMPAT_SB_CHKSUM),
};
const unsigned int sb_blksize =
round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
@@ -240,6 +248,63 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
return 0;
}
+#define CRC32C_POLY_LE 0x82F63B78
+static inline u32 crc32c(u32 crc, const u8 *in, size_t len)
+{
+ int i;
+
+ while (len--) {
+ crc ^= *in++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? CRC32C_POLY_LE : 0);
+ }
+ return crc;
+}
+
+static int erofs_mkfs_superblock_csum_set(void)
+{
+ int ret;
+ u8 buf[EROFS_BLKSIZ];
+ u32 crc;
+ struct erofs_super_block *sb;
+
+ ret = blk_read(buf, 0, 1);
+ if (ret) {
+ erofs_err("failed to read superblock to set checksum: %s",
+ erofs_strerror(ret));
+ return ret;
+ }
+
+ /*
+ * skip the first 1024 bytes, to allow for the installation
+ * of x86 boot sectors and other oddities.
+ */
+ sb = (struct erofs_super_block *)(buf + EROFS_SUPER_OFFSET);
+
+ if (le32_to_cpu(sb->magic) != EROFS_SUPER_MAGIC_V1) {
+ erofs_err("internal error: not an erofs valid image");
+ return -EFAULT;
+ }
+
+ /* turn on checksum feature */
+ sb->feature_compat = cpu_to_le32(le32_to_cpu(sb->feature_compat) |
+ EROFS_FEATURE_COMPAT_SB_CHKSUM);
+ crc = crc32c(~0, (u8 *)sb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET);
+
+ /* set up checksum field to erofs_super_block */
+ sb->checksum = cpu_to_le32(crc);
+
+ ret = blk_write(buf, 0, 1);
+ if (ret) {
+ erofs_err("failed to write checksummed superblock: %s",
+ erofs_strerror(ret));
+ return ret;
+ }
+
+ erofs_info("superblock checksum 0x%08x written", crc);
+ return 0;
+}
+
int main(int argc, char **argv)
{
int err = 0;
@@ -255,6 +320,7 @@ int main(int argc, char **argv)
cfg.c_legacy_compress = false;
sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
+ sbi.feature_compat = EROFS_FEATURE_COMPAT_SB_CHKSUM;
err = mkfs_parse_options_cfg(argc, argv);
if (err) {
@@ -337,6 +403,9 @@ int main(int argc, char **argv)
err = -EIO;
else
err = dev_resize(nblocks);
+
+ if (!err && (sbi.feature_compat & EROFS_FEATURE_COMPAT_SB_CHKSUM))
+ err = erofs_mkfs_superblock_csum_set();
exit:
z_erofs_compress_exit();
dev_close();