Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1697266 > unrolled thread
| Started by | Chao Yu <chao@kernel.org> |
|---|---|
| First post | 2017-07-26 17:10 +0200 |
| Last post | 2017-07-27 00:30 +0200 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
[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
| From | Chao Yu <chao@kernel.org> |
|---|---|
| Date | 2017-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]
| From | Jaegeuk Kim <jaegeuk@kernel.org> |
|---|---|
| Date | 2017-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]
| From | Chao Yu <chao@kernel.org> |
|---|---|
| Date | 2017-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