Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1697266 > unrolled thread

[PATCH] f2fs-tools: support inode checksum

Started byChao Yu <chao@kernel.org>
First post2017-07-26 17:10 +0200
Last post2017-07-27 00:30 +0200
Articles 3 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] f2fs-tools: support inode checksum Chao Yu <chao@kernel.org> - 2017-07-26 17:10 +0200
    Re: [PATCH] f2fs-tools: support inode checksum Jaegeuk Kim <jaegeuk@kernel.org> - 2017-07-26 23:50 +0200
      Re: [PATCH] f2fs-tools: support inode checksum Chao Yu <chao@kernel.org> - 2017-07-27 00:30 +0200

#1697266 — [PATCH] f2fs-tools: support inode checksum

FromChao Yu <chao@kernel.org>
Date2017-07-26 17:10 +0200
Subject[PATCH] f2fs-tools: support inode checksum
Message-ID<u7w6J-1UZ-9@gated-at.bofh.it>
From: Chao Yu <yuchao0@huawei.com>

This patch introduce a new option 'inode_checksum' for enabling inode
checksum functionality in mkfs/fsck/sload.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fsck/dir.c              |  4 ++++
 fsck/fsck.c             | 27 +++++++++++++++++++++++++--
 fsck/mount.c            |  9 +++++++++
 fsck/segment.c          |  4 ++++
 include/f2fs_fs.h       |  5 +++++
 lib/libf2fs.c           | 22 ++++++++++++++++++++++
 mkfs/f2fs_format.c      |  8 ++++++++
 mkfs/f2fs_format_main.c |  7 +++++++
 8 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/fsck/dir.c b/fsck/dir.c
index 3aa67ec..bbf28aa 100644
--- a/fsck/dir.c
+++ b/fsck/dir.c
@@ -447,6 +447,10 @@ static void init_inode_block(struct f2fs_sb_info *sbi,
 		make_empty_dir(sbi, node_blk);
 	else if (S_ISLNK(mode))
 		page_symlink(sbi, node_blk, de->link, size);
+
+	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+		node_blk->i.i_inode_checksum =
+			cpu_to_le32(f2fs_inode_chksum(node_blk));
 }
 
 int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 7a81855..2787b35 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -857,9 +857,32 @@ skip_blkcnt_fix:
 					nid, i_links);
 		}
 	}
-	if (need_fix && !c.ro) {
-		/* drop extent information to avoid potential wrong access */
+
+	/* drop extent information to avoid potential wrong access */
+	if (need_fix && !c.ro)
 		node_blk->i.i_ext.len = 0;
+
+	if ((c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) &&
+				f2fs_has_extra_isize(&node_blk->i)) {
+		__u32 provided, calculated;
+
+		provided = le32_to_cpu(node_blk->i.i_inode_checksum);
+		calculated = f2fs_inode_chksum(node_blk);
+
+		if (provided != calculated) {
+			ASSERT_MSG("ino: 0x%x chksum:0x%x, but calculated one is: 0x%x",
+				nid, provided, calculated);
+			if (c.fix_on) {
+				node_blk->i.i_inode_checksum =
+							cpu_to_le32(calculated);
+				need_fix = 1;
+				FIX_MSG("ino: 0x%x recover, i_inode_checksum= 0x%x -> 0x%x",
+						provided, calculated);
+			}
+		}
+	}
+
+	if (need_fix && !c.ro) {
 		ret = dev_write_block(node_blk, ni->blk_addr);
 		ASSERT(ret >= 0);
 	}
diff --git a/fsck/mount.c b/fsck/mount.c
index 0453f64..8b30264 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -91,6 +91,7 @@ void print_inode_info(struct f2fs_inode *inode, int name)
 	DISP_u16(inode, i_extra_isize);
 	DISP_u16(inode, i_padding);
 	DISP_u32(inode, i_projid);
+	DISP_u32(inode, i_inode_checksum);
 
 	DISP_u32(inode, i_addr[ofs]);		/* Pointers to data blocks */
 	DISP_u32(inode, i_addr[ofs + 1]);	/* Pointers to data blocks */
@@ -291,6 +292,9 @@ void print_sb_state(struct f2fs_super_block *sb)
 	if (f & cpu_to_le32(F2FS_FEATURE_PRJQUOTA)) {
 		MSG(0, "%s", " project quota");
 	}
+	if (f & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) {
+		MSG(0, "%s", " inode checksum");
+	}
 	MSG(0, "\n");
 	MSG(0, "Info: superblock encrypt level = %d, salt = ",
 					sb->encryption_level);
@@ -2157,6 +2161,11 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
 	}
 
 	c.bug_on = 0;
+	c.feature = sb->feature;
+
+	/* precompute checksum seed for metadata */
+	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+		c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
 
 	sbi->total_valid_node_count = get_cp(valid_node_count);
 	sbi->total_valid_inode_count = get_cp(valid_inode_count);
diff --git a/fsck/segment.c b/fsck/segment.c
index 5e23b6b..d568d61 100644
--- a/fsck/segment.c
+++ b/fsck/segment.c
@@ -206,6 +206,10 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
 
 		node_blk->i.i_size = cpu_to_le64(de->size);
 
+		if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+			node_blk->i.i_inode_checksum =
+				cpu_to_le32(f2fs_inode_chksum(node_blk));
+
 		ret = dev_write_block(node_blk, ni.blk_addr);
 		ASSERT(ret >= 0);
 		free(node_blk);
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 380bc2a..dfbe36d 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -316,6 +316,9 @@ struct f2fs_configuration {
 	/* sload parameters */
 	char *from_dir;
 	char *mount_point;
+
+	/* precomputed fs UUID checksum for seeding other checksums */
+	u_int32_t chksum_seed;
 };
 
 #ifdef CONFIG_64BIT
@@ -473,6 +476,7 @@ enum {
 #define F2FS_FEATURE_ATOMIC_WRITE	0x0004
 #define F2FS_FEATURE_EXTRA_ATTR		0x0008
 #define F2FS_FEATURE_PRJQUOTA		0x0010
+#define F2FS_FEATURE_INODE_CHKSUM	0x0020
 
 #define MAX_VOLUME_NAME		512
 
@@ -683,6 +687,7 @@ struct f2fs_inode {
 			__le16 i_extra_isize;	/* extra inode attribute size */
 			__le16 i_padding;	/* padding */
 			__le32 i_projid;	/* project id */
+			__le32 i_inode_checksum;/* inode meta checksum */
 			__le32 i_extra_end[0];	/* for attribute size calculation */
 		};
 		__le32 i_addr[DEF_ADDRS_PER_INODE];	/* Pointers to data blocks */
diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index a3091bb..3c0465c 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -493,6 +493,28 @@ int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
 	return 0;
 }
 
+__u32 f2fs_inode_chksum(struct f2fs_node *node)
+{
+	struct f2fs_inode *ri = &node->i;
+	__le32 ino = node->footer.ino;
+	__le32 gen = ri->i_generation;
+	__u32 chksum, chksum_seed;
+	__u32 dummy_cs = 0;
+	unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
+	unsigned int cs_size = sizeof(dummy_cs);
+
+	chksum = f2fs_cal_crc32(c.chksum_seed, (__u8 *)&ino,
+							sizeof(ino));
+	chksum_seed = f2fs_cal_crc32(chksum, (__u8 *)&gen, sizeof(gen));
+
+	chksum = f2fs_cal_crc32(chksum_seed, (__u8 *)ri, offset);
+	chksum = f2fs_cal_crc32(chksum, (__u8 *)&dummy_cs, cs_size);
+	offset += cs_size;
+	chksum = f2fs_cal_crc32(chksum, (__u8 *)ri + offset,
+						F2FS_BLKSIZE - offset);
+	return chksum;
+}
+
 /*
  * try to identify the root device
  */
diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
index 8e068e9..92876b8 100644
--- a/mkfs/f2fs_format.c
+++ b/mkfs/f2fs_format.c
@@ -369,6 +369,10 @@ static int f2fs_prepare_super_block(void)
 
 	uuid_generate(sb->uuid);
 
+	/* precompute checksum seed for metadata */
+	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+		c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
+
 	utf8_to_utf16(sb->volume_name, (const char *)c.vol_label,
 				MAX_VOLUME_NAME, strlen(c.vol_label));
 	set_sb(node_ino, 1);
@@ -940,6 +944,10 @@ static int f2fs_write_root_inode(void)
 	raw_node->i.i_ext.blk_addr = 0;
 	raw_node->i.i_ext.len = 0;
 
+	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
+		raw_node->i.i_inode_checksum =
+			cpu_to_le32(f2fs_inode_chksum(raw_node));
+
 	main_area_node_seg_blk_offset = get_sb(main_blkaddr);
 	main_area_node_seg_blk_offset += c.cur_seg[CURSEG_HOT_NODE] *
 					c.blks_per_seg;
diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
index 39e8e3f..adbbff9 100644
--- a/mkfs/f2fs_format_main.c
+++ b/mkfs/f2fs_format_main.c
@@ -84,6 +84,8 @@ static void parse_feature(const char *features)
 		c.feature |= cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR);
 	} else if (!strcmp(features, "project_quota")) {
 		c.feature |= cpu_to_le32(F2FS_FEATURE_PRJQUOTA);
+	} else if (!strcmp(features, "inode_checksum")) {
+		c.feature |= cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM);
 	} else {
 		MSG(0, "Error: Wrong features\n");
 		mkfs_usage();
@@ -169,6 +171,11 @@ static void f2fs_parse_options(int argc, char *argv[])
 				"enabled with extra attr feature\n");
 			exit(1);
 		}
+		if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) {
+			MSG(0, "\tInfo: inode checksum feature should always been"
+				"enabled with extra attr feature\n");
+			exit(1);
+		}
 	}
 
 	if (optind >= argc) {
-- 
2.13.0.90.g1eb437020

[toc] | [next] | [standalone]


#1697584

FromJaegeuk Kim <jaegeuk@kernel.org>
Date2017-07-26 23:50 +0200
Message-ID<u7ClQ-5Jg-9@gated-at.bofh.it>
In reply to#1697266
Hi Chao,

Just for testing purpose, I filed them in dev-test.git.
Note that, I fixed two build errors below.

Thanks,

On 07/26, Chao Yu wrote:
> From: Chao Yu <yuchao0@huawei.com>
> 
> This patch introduce a new option 'inode_checksum' for enabling inode
> checksum functionality in mkfs/fsck/sload.
> 
> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> ---
>  fsck/dir.c              |  4 ++++
>  fsck/fsck.c             | 27 +++++++++++++++++++++++++--
>  fsck/mount.c            |  9 +++++++++
>  fsck/segment.c          |  4 ++++
>  include/f2fs_fs.h       |  5 +++++
>  lib/libf2fs.c           | 22 ++++++++++++++++++++++
>  mkfs/f2fs_format.c      |  8 ++++++++
>  mkfs/f2fs_format_main.c |  7 +++++++
>  8 files changed, 84 insertions(+), 2 deletions(-)
> 
> diff --git a/fsck/dir.c b/fsck/dir.c
> index 3aa67ec..bbf28aa 100644
> --- a/fsck/dir.c
> +++ b/fsck/dir.c
> @@ -447,6 +447,10 @@ static void init_inode_block(struct f2fs_sb_info *sbi,
>  		make_empty_dir(sbi, node_blk);
>  	else if (S_ISLNK(mode))
>  		page_symlink(sbi, node_blk, de->link, size);
> +
> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
> +		node_blk->i.i_inode_checksum =
> +			cpu_to_le32(f2fs_inode_chksum(node_blk));
>  }
>  
>  int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
> diff --git a/fsck/fsck.c b/fsck/fsck.c
> index 7a81855..2787b35 100644
> --- a/fsck/fsck.c
> +++ b/fsck/fsck.c
> @@ -857,9 +857,32 @@ skip_blkcnt_fix:
>  					nid, i_links);
>  		}
>  	}
> -	if (need_fix && !c.ro) {
> -		/* drop extent information to avoid potential wrong access */
> +
> +	/* drop extent information to avoid potential wrong access */
> +	if (need_fix && !c.ro)
>  		node_blk->i.i_ext.len = 0;
> +
> +	if ((c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) &&
> +				f2fs_has_extra_isize(&node_blk->i)) {
> +		__u32 provided, calculated;
> +
> +		provided = le32_to_cpu(node_blk->i.i_inode_checksum);
> +		calculated = f2fs_inode_chksum(node_blk);
> +
> +		if (provided != calculated) {
> +			ASSERT_MSG("ino: 0x%x chksum:0x%x, but calculated one is: 0x%x",
> +				nid, provided, calculated);
> +			if (c.fix_on) {
> +				node_blk->i.i_inode_checksum =
> +							cpu_to_le32(calculated);
> +				need_fix = 1;
> +				FIX_MSG("ino: 0x%x recover, i_inode_checksum= 0x%x -> 0x%x",
> +						provided, calculated);

						nid, provided, calculated);

Thanks,

> +			}
> +		}
> +	}
> +
> +	if (need_fix && !c.ro) {
>  		ret = dev_write_block(node_blk, ni->blk_addr);
>  		ASSERT(ret >= 0);
>  	}
> diff --git a/fsck/mount.c b/fsck/mount.c
> index 0453f64..8b30264 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -91,6 +91,7 @@ void print_inode_info(struct f2fs_inode *inode, int name)
>  	DISP_u16(inode, i_extra_isize);
>  	DISP_u16(inode, i_padding);
>  	DISP_u32(inode, i_projid);
> +	DISP_u32(inode, i_inode_checksum);
>  
>  	DISP_u32(inode, i_addr[ofs]);		/* Pointers to data blocks */
>  	DISP_u32(inode, i_addr[ofs + 1]);	/* Pointers to data blocks */
> @@ -291,6 +292,9 @@ void print_sb_state(struct f2fs_super_block *sb)
>  	if (f & cpu_to_le32(F2FS_FEATURE_PRJQUOTA)) {
>  		MSG(0, "%s", " project quota");
>  	}
> +	if (f & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) {
> +		MSG(0, "%s", " inode checksum");
> +	}
>  	MSG(0, "\n");
>  	MSG(0, "Info: superblock encrypt level = %d, salt = ",
>  					sb->encryption_level);
> @@ -2157,6 +2161,11 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
>  	}
>  
>  	c.bug_on = 0;
> +	c.feature = sb->feature;
> +
> +	/* precompute checksum seed for metadata */
> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
> +		c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
>  
>  	sbi->total_valid_node_count = get_cp(valid_node_count);
>  	sbi->total_valid_inode_count = get_cp(valid_inode_count);
> diff --git a/fsck/segment.c b/fsck/segment.c
> index 5e23b6b..d568d61 100644
> --- a/fsck/segment.c
> +++ b/fsck/segment.c
> @@ -206,6 +206,10 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
>  
>  		node_blk->i.i_size = cpu_to_le64(de->size);
>  
> +		if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
> +			node_blk->i.i_inode_checksum =
> +				cpu_to_le32(f2fs_inode_chksum(node_blk));
> +
>  		ret = dev_write_block(node_blk, ni.blk_addr);
>  		ASSERT(ret >= 0);
>  		free(node_blk);
> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
> index 380bc2a..dfbe36d 100644
> --- a/include/f2fs_fs.h
> +++ b/include/f2fs_fs.h
> @@ -316,6 +316,9 @@ struct f2fs_configuration {
>  	/* sload parameters */
>  	char *from_dir;
>  	char *mount_point;
> +
> +	/* precomputed fs UUID checksum for seeding other checksums */
> +	u_int32_t chksum_seed;
>  };
>  
>  #ifdef CONFIG_64BIT
> @@ -473,6 +476,7 @@ enum {
>  #define F2FS_FEATURE_ATOMIC_WRITE	0x0004
>  #define F2FS_FEATURE_EXTRA_ATTR		0x0008
>  #define F2FS_FEATURE_PRJQUOTA		0x0010
> +#define F2FS_FEATURE_INODE_CHKSUM	0x0020
>  
>  #define MAX_VOLUME_NAME		512
>  
> @@ -683,6 +687,7 @@ struct f2fs_inode {
>  			__le16 i_extra_isize;	/* extra inode attribute size */
>  			__le16 i_padding;	/* padding */
>  			__le32 i_projid;	/* project id */
> +			__le32 i_inode_checksum;/* inode meta checksum */
>  			__le32 i_extra_end[0];	/* for attribute size calculation */
>  		};
>  		__le32 i_addr[DEF_ADDRS_PER_INODE];	/* Pointers to data blocks */
> diff --git a/lib/libf2fs.c b/lib/libf2fs.c
> index a3091bb..3c0465c 100644
> --- a/lib/libf2fs.c
> +++ b/lib/libf2fs.c
> @@ -493,6 +493,28 @@ int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
>  	return 0;
>  }
>  
> +__u32 f2fs_inode_chksum(struct f2fs_node *node)

Declare this in f2fs_fs.h.

> +{
> +	struct f2fs_inode *ri = &node->i;
> +	__le32 ino = node->footer.ino;
> +	__le32 gen = ri->i_generation;
> +	__u32 chksum, chksum_seed;
> +	__u32 dummy_cs = 0;
> +	unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
> +	unsigned int cs_size = sizeof(dummy_cs);
> +
> +	chksum = f2fs_cal_crc32(c.chksum_seed, (__u8 *)&ino,
> +							sizeof(ino));
> +	chksum_seed = f2fs_cal_crc32(chksum, (__u8 *)&gen, sizeof(gen));
> +
> +	chksum = f2fs_cal_crc32(chksum_seed, (__u8 *)ri, offset);
> +	chksum = f2fs_cal_crc32(chksum, (__u8 *)&dummy_cs, cs_size);
> +	offset += cs_size;
> +	chksum = f2fs_cal_crc32(chksum, (__u8 *)ri + offset,
> +						F2FS_BLKSIZE - offset);
> +	return chksum;
> +}
> +
>  /*
>   * try to identify the root device
>   */
> diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
> index 8e068e9..92876b8 100644
> --- a/mkfs/f2fs_format.c
> +++ b/mkfs/f2fs_format.c
> @@ -369,6 +369,10 @@ static int f2fs_prepare_super_block(void)
>  
>  	uuid_generate(sb->uuid);
>  
> +	/* precompute checksum seed for metadata */
> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
> +		c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
> +
>  	utf8_to_utf16(sb->volume_name, (const char *)c.vol_label,
>  				MAX_VOLUME_NAME, strlen(c.vol_label));
>  	set_sb(node_ino, 1);
> @@ -940,6 +944,10 @@ static int f2fs_write_root_inode(void)
>  	raw_node->i.i_ext.blk_addr = 0;
>  	raw_node->i.i_ext.len = 0;
>  
> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
> +		raw_node->i.i_inode_checksum =
> +			cpu_to_le32(f2fs_inode_chksum(raw_node));
> +
>  	main_area_node_seg_blk_offset = get_sb(main_blkaddr);
>  	main_area_node_seg_blk_offset += c.cur_seg[CURSEG_HOT_NODE] *
>  					c.blks_per_seg;
> diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
> index 39e8e3f..adbbff9 100644
> --- a/mkfs/f2fs_format_main.c
> +++ b/mkfs/f2fs_format_main.c
> @@ -84,6 +84,8 @@ static void parse_feature(const char *features)
>  		c.feature |= cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR);
>  	} else if (!strcmp(features, "project_quota")) {
>  		c.feature |= cpu_to_le32(F2FS_FEATURE_PRJQUOTA);
> +	} else if (!strcmp(features, "inode_checksum")) {
> +		c.feature |= cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM);
>  	} else {
>  		MSG(0, "Error: Wrong features\n");
>  		mkfs_usage();
> @@ -169,6 +171,11 @@ static void f2fs_parse_options(int argc, char *argv[])
>  				"enabled with extra attr feature\n");
>  			exit(1);
>  		}
> +		if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) {
> +			MSG(0, "\tInfo: inode checksum feature should always been"
> +				"enabled with extra attr feature\n");
> +			exit(1);
> +		}
>  	}
>  
>  	if (optind >= argc) {
> -- 
> 2.13.0.90.g1eb437020

[toc] | [prev] | [next] | [standalone]


#1697598

FromChao Yu <chao@kernel.org>
Date2017-07-27 00:30 +0200
Message-ID<u7CYy-6ee-15@gated-at.bofh.it>
In reply to#1697584
Hi Jaegeuk,

On 2017/7/27 5:40, Jaegeuk Kim wrote:
> Hi Chao,
> 
> Just for testing purpose, I filed them in dev-test.git.
> Note that, I fixed two build errors below.

Oops, my bad, actually I just note that there is warning in compile flow,
I need -Werror anyway during compiling.

Thanks for fixing.

Thanks,

> 
> Thanks,
> 
> On 07/26, Chao Yu wrote:
>> From: Chao Yu <yuchao0@huawei.com>
>>
>> This patch introduce a new option 'inode_checksum' for enabling inode
>> checksum functionality in mkfs/fsck/sload.
>>
>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
>> ---
>>  fsck/dir.c              |  4 ++++
>>  fsck/fsck.c             | 27 +++++++++++++++++++++++++--
>>  fsck/mount.c            |  9 +++++++++
>>  fsck/segment.c          |  4 ++++
>>  include/f2fs_fs.h       |  5 +++++
>>  lib/libf2fs.c           | 22 ++++++++++++++++++++++
>>  mkfs/f2fs_format.c      |  8 ++++++++
>>  mkfs/f2fs_format_main.c |  7 +++++++
>>  8 files changed, 84 insertions(+), 2 deletions(-)
>>
>> diff --git a/fsck/dir.c b/fsck/dir.c
>> index 3aa67ec..bbf28aa 100644
>> --- a/fsck/dir.c
>> +++ b/fsck/dir.c
>> @@ -447,6 +447,10 @@ static void init_inode_block(struct f2fs_sb_info *sbi,
>>  		make_empty_dir(sbi, node_blk);
>>  	else if (S_ISLNK(mode))
>>  		page_symlink(sbi, node_blk, de->link, size);
>> +
>> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
>> +		node_blk->i.i_inode_checksum =
>> +			cpu_to_le32(f2fs_inode_chksum(node_blk));
>>  }
>>  
>>  int convert_inline_dentry(struct f2fs_sb_info *sbi, struct f2fs_node *node,
>> diff --git a/fsck/fsck.c b/fsck/fsck.c
>> index 7a81855..2787b35 100644
>> --- a/fsck/fsck.c
>> +++ b/fsck/fsck.c
>> @@ -857,9 +857,32 @@ skip_blkcnt_fix:
>>  					nid, i_links);
>>  		}
>>  	}
>> -	if (need_fix && !c.ro) {
>> -		/* drop extent information to avoid potential wrong access */
>> +
>> +	/* drop extent information to avoid potential wrong access */
>> +	if (need_fix && !c.ro)
>>  		node_blk->i.i_ext.len = 0;
>> +
>> +	if ((c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) &&
>> +				f2fs_has_extra_isize(&node_blk->i)) {
>> +		__u32 provided, calculated;
>> +
>> +		provided = le32_to_cpu(node_blk->i.i_inode_checksum);
>> +		calculated = f2fs_inode_chksum(node_blk);
>> +
>> +		if (provided != calculated) {
>> +			ASSERT_MSG("ino: 0x%x chksum:0x%x, but calculated one is: 0x%x",
>> +				nid, provided, calculated);
>> +			if (c.fix_on) {
>> +				node_blk->i.i_inode_checksum =
>> +							cpu_to_le32(calculated);
>> +				need_fix = 1;
>> +				FIX_MSG("ino: 0x%x recover, i_inode_checksum= 0x%x -> 0x%x",
>> +						provided, calculated);
> 
> 						nid, provided, calculated);
> 
> Thanks,
> 
>> +			}
>> +		}
>> +	}
>> +
>> +	if (need_fix && !c.ro) {
>>  		ret = dev_write_block(node_blk, ni->blk_addr);
>>  		ASSERT(ret >= 0);
>>  	}
>> diff --git a/fsck/mount.c b/fsck/mount.c
>> index 0453f64..8b30264 100644
>> --- a/fsck/mount.c
>> +++ b/fsck/mount.c
>> @@ -91,6 +91,7 @@ void print_inode_info(struct f2fs_inode *inode, int name)
>>  	DISP_u16(inode, i_extra_isize);
>>  	DISP_u16(inode, i_padding);
>>  	DISP_u32(inode, i_projid);
>> +	DISP_u32(inode, i_inode_checksum);
>>  
>>  	DISP_u32(inode, i_addr[ofs]);		/* Pointers to data blocks */
>>  	DISP_u32(inode, i_addr[ofs + 1]);	/* Pointers to data blocks */
>> @@ -291,6 +292,9 @@ void print_sb_state(struct f2fs_super_block *sb)
>>  	if (f & cpu_to_le32(F2FS_FEATURE_PRJQUOTA)) {
>>  		MSG(0, "%s", " project quota");
>>  	}
>> +	if (f & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) {
>> +		MSG(0, "%s", " inode checksum");
>> +	}
>>  	MSG(0, "\n");
>>  	MSG(0, "Info: superblock encrypt level = %d, salt = ",
>>  					sb->encryption_level);
>> @@ -2157,6 +2161,11 @@ int f2fs_do_mount(struct f2fs_sb_info *sbi)
>>  	}
>>  
>>  	c.bug_on = 0;
>> +	c.feature = sb->feature;
>> +
>> +	/* precompute checksum seed for metadata */
>> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
>> +		c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
>>  
>>  	sbi->total_valid_node_count = get_cp(valid_node_count);
>>  	sbi->total_valid_inode_count = get_cp(valid_inode_count);
>> diff --git a/fsck/segment.c b/fsck/segment.c
>> index 5e23b6b..d568d61 100644
>> --- a/fsck/segment.c
>> +++ b/fsck/segment.c
>> @@ -206,6 +206,10 @@ int f2fs_build_file(struct f2fs_sb_info *sbi, struct dentry *de)
>>  
>>  		node_blk->i.i_size = cpu_to_le64(de->size);
>>  
>> +		if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
>> +			node_blk->i.i_inode_checksum =
>> +				cpu_to_le32(f2fs_inode_chksum(node_blk));
>> +
>>  		ret = dev_write_block(node_blk, ni.blk_addr);
>>  		ASSERT(ret >= 0);
>>  		free(node_blk);
>> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
>> index 380bc2a..dfbe36d 100644
>> --- a/include/f2fs_fs.h
>> +++ b/include/f2fs_fs.h
>> @@ -316,6 +316,9 @@ struct f2fs_configuration {
>>  	/* sload parameters */
>>  	char *from_dir;
>>  	char *mount_point;
>> +
>> +	/* precomputed fs UUID checksum for seeding other checksums */
>> +	u_int32_t chksum_seed;
>>  };
>>  
>>  #ifdef CONFIG_64BIT
>> @@ -473,6 +476,7 @@ enum {
>>  #define F2FS_FEATURE_ATOMIC_WRITE	0x0004
>>  #define F2FS_FEATURE_EXTRA_ATTR		0x0008
>>  #define F2FS_FEATURE_PRJQUOTA		0x0010
>> +#define F2FS_FEATURE_INODE_CHKSUM	0x0020
>>  
>>  #define MAX_VOLUME_NAME		512
>>  
>> @@ -683,6 +687,7 @@ struct f2fs_inode {
>>  			__le16 i_extra_isize;	/* extra inode attribute size */
>>  			__le16 i_padding;	/* padding */
>>  			__le32 i_projid;	/* project id */
>> +			__le32 i_inode_checksum;/* inode meta checksum */
>>  			__le32 i_extra_end[0];	/* for attribute size calculation */
>>  		};
>>  		__le32 i_addr[DEF_ADDRS_PER_INODE];	/* Pointers to data blocks */
>> diff --git a/lib/libf2fs.c b/lib/libf2fs.c
>> index a3091bb..3c0465c 100644
>> --- a/lib/libf2fs.c
>> +++ b/lib/libf2fs.c
>> @@ -493,6 +493,28 @@ int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len)
>>  	return 0;
>>  }
>>  
>> +__u32 f2fs_inode_chksum(struct f2fs_node *node)
> 
> Declare this in f2fs_fs.h.
> 
>> +{
>> +	struct f2fs_inode *ri = &node->i;
>> +	__le32 ino = node->footer.ino;
>> +	__le32 gen = ri->i_generation;
>> +	__u32 chksum, chksum_seed;
>> +	__u32 dummy_cs = 0;
>> +	unsigned int offset = offsetof(struct f2fs_inode, i_inode_checksum);
>> +	unsigned int cs_size = sizeof(dummy_cs);
>> +
>> +	chksum = f2fs_cal_crc32(c.chksum_seed, (__u8 *)&ino,
>> +							sizeof(ino));
>> +	chksum_seed = f2fs_cal_crc32(chksum, (__u8 *)&gen, sizeof(gen));
>> +
>> +	chksum = f2fs_cal_crc32(chksum_seed, (__u8 *)ri, offset);
>> +	chksum = f2fs_cal_crc32(chksum, (__u8 *)&dummy_cs, cs_size);
>> +	offset += cs_size;
>> +	chksum = f2fs_cal_crc32(chksum, (__u8 *)ri + offset,
>> +						F2FS_BLKSIZE - offset);
>> +	return chksum;
>> +}
>> +
>>  /*
>>   * try to identify the root device
>>   */
>> diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c
>> index 8e068e9..92876b8 100644
>> --- a/mkfs/f2fs_format.c
>> +++ b/mkfs/f2fs_format.c
>> @@ -369,6 +369,10 @@ static int f2fs_prepare_super_block(void)
>>  
>>  	uuid_generate(sb->uuid);
>>  
>> +	/* precompute checksum seed for metadata */
>> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
>> +		c.chksum_seed = f2fs_cal_crc32(~0, sb->uuid, sizeof(sb->uuid));
>> +
>>  	utf8_to_utf16(sb->volume_name, (const char *)c.vol_label,
>>  				MAX_VOLUME_NAME, strlen(c.vol_label));
>>  	set_sb(node_ino, 1);
>> @@ -940,6 +944,10 @@ static int f2fs_write_root_inode(void)
>>  	raw_node->i.i_ext.blk_addr = 0;
>>  	raw_node->i.i_ext.len = 0;
>>  
>> +	if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM))
>> +		raw_node->i.i_inode_checksum =
>> +			cpu_to_le32(f2fs_inode_chksum(raw_node));
>> +
>>  	main_area_node_seg_blk_offset = get_sb(main_blkaddr);
>>  	main_area_node_seg_blk_offset += c.cur_seg[CURSEG_HOT_NODE] *
>>  					c.blks_per_seg;
>> diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c
>> index 39e8e3f..adbbff9 100644
>> --- a/mkfs/f2fs_format_main.c
>> +++ b/mkfs/f2fs_format_main.c
>> @@ -84,6 +84,8 @@ static void parse_feature(const char *features)
>>  		c.feature |= cpu_to_le32(F2FS_FEATURE_EXTRA_ATTR);
>>  	} else if (!strcmp(features, "project_quota")) {
>>  		c.feature |= cpu_to_le32(F2FS_FEATURE_PRJQUOTA);
>> +	} else if (!strcmp(features, "inode_checksum")) {
>> +		c.feature |= cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM);
>>  	} else {
>>  		MSG(0, "Error: Wrong features\n");
>>  		mkfs_usage();
>> @@ -169,6 +171,11 @@ static void f2fs_parse_options(int argc, char *argv[])
>>  				"enabled with extra attr feature\n");
>>  			exit(1);
>>  		}
>> +		if (c.feature & cpu_to_le32(F2FS_FEATURE_INODE_CHKSUM)) {
>> +			MSG(0, "\tInfo: inode checksum feature should always been"
>> +				"enabled with extra attr feature\n");
>> +			exit(1);
>> +		}
>>  	}
>>  
>>  	if (optind >= argc) {
>> -- 
>> 2.13.0.90.g1eb437020

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web