* [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases
@ 2025-06-10 12:37 Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 01/32] fsck.f2fs: do not finish/reset zone if dry-run is true Sheng Yong
` (32 more replies)
0 siblings, 33 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
Hi, folks,
This patchset tries to add an auto testsuit for f2fs-tools, including
fsck.f2fs, inject.f2fs for now.
The patchset can splited into 3 parts:
PATCH 1~9: is a preparation for testcases. It fixes some errors in
fsck and inject, and do some cleanup and improvement for
f2fs-tools.
PATCH 10~13: add new injection members
PATCH 14~32: add testcases
thanks,
shengyong
-8<-
The following is almost quoted from v1:
The basic idea of these testcases are:
1. create f2fs image
2. corrupt the image by inject specific fields
3. fsck fixes the image
4. verify fsck output with expected message
Some helper scripts are provided:
* test_config.in: is used to derive basic configurations of all
testcases.
* runtests.in: is used to derive `runtests' which is used to run
testcases.
* filter.sed: removes unnecessary messages and cleanup arbitrary
values.
* helpers: provides helper functions
The usage of `runtests':
* run all testcases:
runtests
* run one testcase:
runtests <testcase directory path>
* cleanup previous results:
runtests clean
To run the testcases on Android, only have to change settings in
test_config:
* set path of $META and $DATA
* set path of tools
* push tests directory to an Android phone
NOTE TAHT: the testcases will format $META!!!
Some testcase requires root permission to mount the image and create
files.
Each testcase should have a sub-directory, where three files are needed:
* README: describe information of the testcase
* script: testcase itself
* expect.in: is used to derive expected output message
New files are generated in the testcase directory after test:
* log: output in detail
* expect: derived from expect.in
* out: output that will be compared with expect
* PASS: testcase is passed
* FAIL: testcase is failed, in which differ of out and expect is saved
The name of testcase directory has some optional prefix:
* f_: fsck testcase
* i_: inject testcase
* m_: mkfs testcase
But there are only fsck and inject testcases for now.
To run testcases, it's better to compile fsck.f2fs as statically linked
executable, or `make install' installs tools and libraries. Otherwise,
libtool compiles f2fs-tools in debug mode and create a wrapper script
to locate elf executable and libraries. However, dump.f2fs and
inject.f2fs cannot be used in the wrapper way.
v2: * add some fix and cleanup
* remove img.tar.gz from testcases
* add testcases for injection
* cleanup helpers script and simplify filter.sed and expected.in
v1: https://lore.kernel.org/linux-f2fs-devel/20241029120956.4186731-1-shengyong@oppo.com/
Sheng Yong (32):
fsck.f2fs: do not finish/reset zone if dry-run is true
f2fs-tools: add option N to answer no for all questions
f2fs-tools: cleanup {nid|segno}_in_journal
fsck.f2fs: fix invalidate checkpoint
dump.f2fs: print more info
f2fs-tools: add and export lookup_sit_in_journal
inject.f2fs: fix injecting sit/nat in journal
inject.f2fs: fix injection on zoned device
inject.f2fs: fix and cleanup parsing numeric options
inject.f2fs: add members in inject_cp
inject.f2fs: add member `feature' in inject_sb
inject.f2fs: add members in inject_node
inject.f2fs: add member `filename' in inject_dentry
tests: prepare helper scripts for testcases
tests: add fsck testcase of fixing bad super magic
tests: add fsck testcase of fixing errors recorded in sb
tests: add fsck testcase of fixing cp crc
tests: add fsck testcase of fixing nat entry with invalid ino
tests: add fsck testcase of fixing nat entry with invalid blkaddr
tests: add fsck testcase of fixing sit entry type
tests: add fsck testcase of fixing sit entry vblocks
tests: add fsck testcase of fixing sit entry valid_map
tests: add fsck testcase of fixing sum entry nid
tests: add fsck testcase of fixing sum footer type
tests: add fsck testcase of fixing sum entry ofs_in_node
tests: add fsck testcase of fixing inode invalid i_addr
tests: add fsck testcase of fixing dentry hash code
tests: add fsck testcase of fixing lost dots
tests: add fsck testcase of fixing duplicated dots
tests: add fsck testcase of fixing loop fsync dnodes
tests: add inject testcase of injecting META area
tests: add inject testcase of injecting node block
.gitignore | 14 +
Makefile.am | 2 +-
configure.ac | 1 +
fsck/dump.c | 15 +-
fsck/f2fs.h | 12 +-
fsck/fsck.c | 2 +-
fsck/fsck.h | 4 +-
fsck/inject.c | 438 +++++++++++++++++++++-----
fsck/inject.h | 1 +
fsck/main.c | 14 +-
fsck/mount.c | 61 ++--
include/f2fs_fs.h | 1 +
lib/libf2fs_zoned.c | 6 +-
man/inject.f2fs.8 | 43 ++-
tests/Makefile.am | 26 ++
tests/f_cp_bad_crc/README | 5 +
tests/f_cp_bad_crc/expect.in | 4 +
tests/f_cp_bad_crc/script | 38 +++
tests/f_dentry_bad_hash/README | 8 +
tests/f_dentry_bad_hash/expect.in | 8 +
tests/f_dentry_bad_hash/script | 56 ++++
tests/f_dentry_dup_dots/README | 11 +
tests/f_dentry_dup_dots/expect.in | 26 ++
tests/f_dentry_dup_dots/script | 49 +++
tests/f_dentry_lost_dots/README | 7 +
tests/f_dentry_lost_dots/expect.in | 16 +
tests/f_dentry_lost_dots/script | 37 +++
tests/f_inode_bad_iaddr/README | 6 +
tests/f_inode_bad_iaddr/expect.in | 13 +
tests/f_inode_bad_iaddr/script | 50 +++
tests/f_loop_fsync_dnodes/README | 5 +
tests/f_loop_fsync_dnodes/expect.in | 6 +
tests/f_loop_fsync_dnodes/script | 46 +++
tests/f_nat_bad_blkaddr/README | 4 +
tests/f_nat_bad_blkaddr/expect.in | 12 +
tests/f_nat_bad_blkaddr/script | 25 ++
tests/f_nat_bad_ino/README | 4 +
tests/f_nat_bad_ino/expect.in | 12 +
tests/f_nat_bad_ino/script | 31 ++
tests/f_sb_bad_magic/README | 3 +
tests/f_sb_bad_magic/expect.in | 5 +
tests/f_sb_bad_magic/script | 15 +
tests/f_sb_errors/README | 5 +
tests/f_sb_errors/expect.in | 7 +
tests/f_sb_errors/script | 22 ++
tests/f_sit_bad_type/README | 5 +
tests/f_sit_bad_type/expect.in | 3 +
tests/f_sit_bad_type/script | 38 +++
tests/f_sit_bad_valid_map/README | 5 +
tests/f_sit_bad_valid_map/expect.in | 4 +
tests/f_sit_bad_valid_map/script | 43 +++
tests/f_sit_bad_vblocks/README | 5 +
tests/f_sit_bad_vblocks/expect.in | 3 +
tests/f_sit_bad_vblocks/script | 38 +++
tests/f_ssa_bad_nid/README | 5 +
tests/f_ssa_bad_nid/expect.in | 3 +
tests/f_ssa_bad_nid/script | 36 +++
tests/f_ssa_bad_ofs_in_node/README | 5 +
tests/f_ssa_bad_ofs_in_node/expect.in | 3 +
tests/f_ssa_bad_ofs_in_node/script | 36 +++
tests/f_ssa_bad_type/README | 5 +
tests/f_ssa_bad_type/expect.in | 3 +
tests/f_ssa_bad_type/script | 31 ++
tests/filter.sed | 69 ++++
tests/helpers | 269 ++++++++++++++++
tests/i_meta/README | 5 +
tests/i_meta/expect.in | 60 ++++
tests/i_meta/script | 212 +++++++++++++
tests/i_node/README | 5 +
tests/i_node/expect.in | 66 ++++
tests/i_node/script | 166 ++++++++++
tests/runtests.in | 48 +++
tests/test_config.in | 53 ++++
73 files changed, 2284 insertions(+), 116 deletions(-)
create mode 100644 tests/Makefile.am
create mode 100644 tests/f_cp_bad_crc/README
create mode 100644 tests/f_cp_bad_crc/expect.in
create mode 100644 tests/f_cp_bad_crc/script
create mode 100644 tests/f_dentry_bad_hash/README
create mode 100644 tests/f_dentry_bad_hash/expect.in
create mode 100644 tests/f_dentry_bad_hash/script
create mode 100644 tests/f_dentry_dup_dots/README
create mode 100644 tests/f_dentry_dup_dots/expect.in
create mode 100644 tests/f_dentry_dup_dots/script
create mode 100644 tests/f_dentry_lost_dots/README
create mode 100644 tests/f_dentry_lost_dots/expect.in
create mode 100644 tests/f_dentry_lost_dots/script
create mode 100644 tests/f_inode_bad_iaddr/README
create mode 100644 tests/f_inode_bad_iaddr/expect.in
create mode 100644 tests/f_inode_bad_iaddr/script
create mode 100644 tests/f_loop_fsync_dnodes/README
create mode 100644 tests/f_loop_fsync_dnodes/expect.in
create mode 100644 tests/f_loop_fsync_dnodes/script
create mode 100644 tests/f_nat_bad_blkaddr/README
create mode 100644 tests/f_nat_bad_blkaddr/expect.in
create mode 100644 tests/f_nat_bad_blkaddr/script
create mode 100644 tests/f_nat_bad_ino/README
create mode 100644 tests/f_nat_bad_ino/expect.in
create mode 100644 tests/f_nat_bad_ino/script
create mode 100644 tests/f_sb_bad_magic/README
create mode 100644 tests/f_sb_bad_magic/expect.in
create mode 100644 tests/f_sb_bad_magic/script
create mode 100644 tests/f_sb_errors/README
create mode 100644 tests/f_sb_errors/expect.in
create mode 100644 tests/f_sb_errors/script
create mode 100644 tests/f_sit_bad_type/README
create mode 100644 tests/f_sit_bad_type/expect.in
create mode 100644 tests/f_sit_bad_type/script
create mode 100644 tests/f_sit_bad_valid_map/README
create mode 100644 tests/f_sit_bad_valid_map/expect.in
create mode 100644 tests/f_sit_bad_valid_map/script
create mode 100644 tests/f_sit_bad_vblocks/README
create mode 100644 tests/f_sit_bad_vblocks/expect.in
create mode 100644 tests/f_sit_bad_vblocks/script
create mode 100644 tests/f_ssa_bad_nid/README
create mode 100644 tests/f_ssa_bad_nid/expect.in
create mode 100644 tests/f_ssa_bad_nid/script
create mode 100644 tests/f_ssa_bad_ofs_in_node/README
create mode 100644 tests/f_ssa_bad_ofs_in_node/expect.in
create mode 100644 tests/f_ssa_bad_ofs_in_node/script
create mode 100644 tests/f_ssa_bad_type/README
create mode 100644 tests/f_ssa_bad_type/expect.in
create mode 100644 tests/f_ssa_bad_type/script
create mode 100644 tests/filter.sed
create mode 100644 tests/helpers
create mode 100644 tests/i_meta/README
create mode 100644 tests/i_meta/expect.in
create mode 100644 tests/i_meta/script
create mode 100644 tests/i_node/README
create mode 100644 tests/i_node/expect.in
create mode 100644 tests/i_node/script
create mode 100644 tests/runtests.in
create mode 100644 tests/test_config.in
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 01/32] fsck.f2fs: do not finish/reset zone if dry-run is true
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions Sheng Yong
` (31 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
lib/libf2fs_zoned.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/libf2fs_zoned.c b/lib/libf2fs_zoned.c
index 6730bba0da82..92791a768807 100644
--- a/lib/libf2fs_zoned.c
+++ b/lib/libf2fs_zoned.c
@@ -429,7 +429,7 @@ int f2fs_reset_zone(int i, void *blkzone)
struct blk_zone_range range;
int ret;
- if (!blk_zone_seq(blkz) || blk_zone_empty(blkz))
+ if (!blk_zone_seq(blkz) || blk_zone_empty(blkz) || c.dry_run)
return 0;
/* Non empty sequential zone: reset */
@@ -484,7 +484,7 @@ int f2fs_reset_zones(int j)
blkz = (struct blk_zone *)(rep + 1);
for (i = 0; i < rep->nr_zones && sector < total_sectors; i++) {
if (blk_zone_seq(blkz) &&
- !blk_zone_empty(blkz)) {
+ !blk_zone_empty(blkz) && !c.dry_run) {
/* Non empty sequential zone: reset */
range.sector = blk_zone_sector(blkz);
range.nr_sectors = blk_zone_length(blkz);
@@ -513,7 +513,7 @@ int f2fs_finish_zone(int i, void *blkzone)
struct blk_zone_range range;
int ret;
- if (!blk_zone_seq(blkz) || !blk_zone_open(blkz))
+ if (!blk_zone_seq(blkz) || !blk_zone_open(blkz) || c.dry_run)
return 0;
/* Non empty sequential zone: finish */
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 01/32] fsck.f2fs: do not finish/reset zone if dry-run is true Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-11 9:22 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 03/32] f2fs-tools: cleanup {nid|segno}_in_journal Sheng Yong
` (30 subsequent siblings)
32 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
In some scenario, such as autotest, it is not expected to answer
question from fsck or dump. To simply answer no to all these questions,
this patch adds an option `N' to do that.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/dump.c | 3 +++
fsck/fsck.c | 2 +-
fsck/main.c | 14 +++++++++++---
include/f2fs_fs.h | 1 +
4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/fsck/dump.c b/fsck/dump.c
index 66d6c791ae09..10df7e593bfe 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -681,6 +681,9 @@ static int dump_filesystem(struct f2fs_sb_info *sbi, struct node_info *ni,
if (c.show_file_map)
return dump_inode_blk(sbi, ni->ino, node_blk);
+ if (c.answer_no)
+ return 0;
+
printf("Do you want to dump this %s into %s/? [Y/N] ",
S_ISDIR(imode) ? "folder" : "file",
base_path);
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 4d05e1b4a21b..14677128dc2d 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -3834,7 +3834,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
}
#ifndef WITH_ANDROID
- if (nr_unref_nid && !c.ro) {
+ if (nr_unref_nid && !c.ro && !c.answer_no) {
char ans[255] = {0};
int res;
diff --git a/fsck/main.c b/fsck/main.c
index c5d41597934a..b01a22c8cf53 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -86,6 +86,7 @@ void fsck_usage()
MSG(0, " -t show directory tree\n");
MSG(0, " -q preserve quota limits\n");
MSG(0, " -y fix all the time\n");
+ MSG(0, " -N answer \"No\" for all questions\n");
MSG(0, " -V print the version number and exit\n");
MSG(0, " --dry-run do not really fix corruptions\n");
MSG(0, " --no-kernel-check skips detecting kernel change\n");
@@ -114,6 +115,7 @@ void dump_usage()
MSG(0, " -f do not prompt before dumping\n");
MSG(0, " -H support write hint\n");
MSG(0, " -y alias for -f\n");
+ MSG(0, " -N answer \"No\" for all questions\n");
MSG(0, " -o dump inodes to the given path\n");
MSG(0, " -P preserve mode/owner/group for dumped inode\n");
MSG(0, " -L Preserves symlinks. Otherwise symlinks are dumped as regular files.\n");
@@ -263,7 +265,7 @@ void f2fs_parse_options(int argc, char *argv[])
}
if (!strcmp("fsck.f2fs", prog)) {
- const char *option_string = ":aC:c:m:Md:fg:HlO:p:q:StyV";
+ const char *option_string = ":aC:c:m:Md:fg:HlO:p:q:StyNV";
int opt = 0, val;
char *token;
struct option long_opt[] = {
@@ -396,6 +398,9 @@ void f2fs_parse_options(int argc, char *argv[])
c.force = 1;
MSG(0, "Info: Force to fix corruption\n");
break;
+ case 'N':
+ c.answer_no = true;
+ break;
case 'q':
c.preserve_limits = atoi(optarg);
MSG(0, "Info: Preserve quota limits = %d\n",
@@ -449,7 +454,7 @@ void f2fs_parse_options(int argc, char *argv[])
}
} else if (!strcmp("dump.f2fs", prog)) {
#ifdef WITH_DUMP
- const char *option_string = "d:fi:I:n:LMo:Prs:Sa:b:Vy";
+ const char *option_string = "d:fi:I:n:LMo:Prs:Sa:b:VyN";
static struct dump_option dump_opt = {
.nid = 0, /* default root ino */
.start_nat = -1,
@@ -527,6 +532,9 @@ void f2fs_parse_options(int argc, char *argv[])
case 'f':
c.force = 1;
break;
+ case 'N':
+ c.answer_no = true;
+ break;
case 'r':
dump_opt.use_root_nid = 1;
break;
@@ -1369,7 +1377,7 @@ fsck_again:
f2fs_do_umount(sbi);
- if (c.func == FSCK && c.bug_on) {
+ if (c.func == FSCK && c.bug_on && !c.answer_no) {
if (!c.ro && c.fix_on == 0 && c.auto_fix == 0 && !c.dry_run) {
char ans[255] = {0};
retry:
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index f7268d1e90ff..5cd4ad666c06 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -1593,6 +1593,7 @@ struct f2fs_configuration {
int whint;
int aliased_devices;
uint32_t aliased_segments;
+ bool answer_no;
/* mkfs parameters */
int fake_seed;
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 03/32] f2fs-tools: cleanup {nid|segno}_in_journal
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 01/32] fsck.f2fs: do not finish/reset zone if dry-run is true Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 04/32] fsck.f2fs: fix invalidate checkpoint Sheng Yong
` (29 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/f2fs.h | 4 ++--
fsck/mount.c | 14 +++++++-------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 187e73cf9aec..4c6c0c48b9ee 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -504,9 +504,9 @@ struct fsync_inode_entry {
#define sits_in_cursum(jnl) (le16_to_cpu(jnl->n_sits))
#define nat_in_journal(jnl, i) (jnl->nat_j.entries[i].ne)
-#define nid_in_journal(jnl, i) (jnl->nat_j.entries[i].nid)
+#define nid_in_journal(jnl, i) (le32_to_cpu(jnl->nat_j.entries[i].nid))
#define sit_in_journal(jnl, i) (jnl->sit_j.entries[i].se)
-#define segno_in_journal(jnl, i) (jnl->sit_j.entries[i].segno)
+#define segno_in_journal(jnl, i) (le32_to_cpu(jnl->sit_j.entries[i].segno))
#define SIT_ENTRY_OFFSET(sit_i, segno) \
((segno) % sit_i->sents_per_block)
diff --git a/fsck/mount.c b/fsck/mount.c
index a7f16e78bae7..337acb6f8ff8 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1687,7 +1687,7 @@ static int f2fs_early_init_nid_bitmap(struct f2fs_sb_info *sbi)
continue;
}
- nid = le32_to_cpu(nid_in_journal(journal, i));
+ nid = nid_in_journal(journal, i);
if (!IS_VALID_NID(sbi, nid)) {
MSG(0, "\tError: f2fs_init_nid_bitmap: nid(%u) is invalid!!!\n", nid);
journal->n_nats = cpu_to_le16(i);
@@ -2566,7 +2566,7 @@ void update_nat_blkaddr(struct f2fs_sb_info *sbi, nid_t ino,
int ret, i;
for (i = 0; i < nats_in_cursum(journal); i++) {
- if (le32_to_cpu(nid_in_journal(journal, i)) == nid) {
+ if (nid_in_journal(journal, i) == nid) {
entry = &nat_in_journal(journal, i);
entry->block_addr = cpu_to_le32(newaddr);
if (ino)
@@ -2670,7 +2670,7 @@ static int build_sit_entries(struct f2fs_sb_info *sbi)
}
for (i = 0; i < sits_in_cursum(journal); i++) {
- segno = le32_to_cpu(segno_in_journal(journal, i));
+ segno = segno_in_journal(journal, i);
if (segno >= MAIN_SEGS(sbi)) {
MSG(0, "\tError: build_sit_entries: segno(%u) is invalid!!!\n", segno);
@@ -2876,7 +2876,7 @@ next:
return i;
}
- nid = le32_to_cpu(nid_in_journal(journal, i));
+ nid = nid_in_journal(journal, i);
entry_off = nid % NAT_ENTRY_PER_BLOCK;
block_addr = current_nat_addr(sbi, nid, NULL);
@@ -3275,7 +3275,7 @@ int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
int i = 0;
for (i = 0; i < nats_in_cursum(journal); i++) {
- if (le32_to_cpu(nid_in_journal(journal, i)) == nid) {
+ if (nid_in_journal(journal, i) == nid) {
memcpy(raw_nat, &nat_in_journal(journal, i),
sizeof(struct f2fs_nat_entry));
DBG(3, "==> Found nid [0x%x] in nat cache\n", nid);
@@ -3300,7 +3300,7 @@ void nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid)
/* check in journal */
for (i = 0; i < nats_in_cursum(journal); i++) {
- if (le32_to_cpu(nid_in_journal(journal, i)) == nid) {
+ if (nid_in_journal(journal, i) == nid) {
memset(&nat_in_journal(journal, i), 0,
sizeof(struct f2fs_nat_entry));
FIX_MSG("Remove nid [0x%x] in nat journal", nid);
@@ -3604,7 +3604,7 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
/* Traverse nat journal, update the corresponding entries */
for (i = 0; i < nats_in_cursum(journal); i++) {
struct f2fs_nat_entry raw_nat;
- nid = le32_to_cpu(nid_in_journal(journal, i));
+ nid = nid_in_journal(journal, i);
ni.nid = nid;
DBG(3, "==> Found nid [0x%x] in nat cache, update it\n", nid);
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 04/32] fsck.f2fs: fix invalidate checkpoint
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (2 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 03/32] f2fs-tools: cleanup {nid|segno}_in_journal Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 05/32] dump.f2fs: print more info Sheng Yong
` (28 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
If one cp is invalidate, set CP_FSCK_FLAG to allow fsck_verify() to
fixing cp at the end of check.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/f2fs.h | 6 ++++++
fsck/mount.c | 11 ++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index 4c6c0c48b9ee..a4888a817284 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -346,6 +346,12 @@ static inline __u64 cur_cp_crc(struct f2fs_checkpoint *cp)
return le32_to_cpu(*((__le32 *)((unsigned char *)cp + crc_offset)));
}
+static inline void set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
+{
+ unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
+ cp->ckpt_flags = cpu_to_le32(ckpt_flags | f);
+}
+
static inline bool is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
{
unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
diff --git a/fsck/mount.c b/fsck/mount.c
index 337acb6f8ff8..b1f8e98dd7f0 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1352,8 +1352,11 @@ void *validate_checkpoint(struct f2fs_sb_info *sbi, block_t cp_addr,
return NULL;
cp = (struct f2fs_checkpoint *)cp_page_1;
- if (get_cp(cp_pack_total_block_count) > sbi->blocks_per_seg)
+ if (get_cp(cp_pack_total_block_count) > sbi->blocks_per_seg) {
+ MSG(0, "\tInvalid CP pack block count: %u\n",
+ get_cp(cp_pack_total_block_count));
goto invalid_cp1;
+ }
pre_version = get_cp(checkpoint_ver);
@@ -1417,14 +1420,16 @@ int get_valid_checkpoint(struct f2fs_sb_info *sbi)
sbi->cur_cp = 1;
version = cp1_version;
}
- } else if (cp1) {
+ } else if (cp1) { // cp2 is invalidate
cur_page = cp1;
sbi->cur_cp = 1;
version = cp1_version;
- } else if (cp2) {
+ set_ckpt_flags(cp1, CP_FSCK_FLAG);
+ } else if (cp2) { // cp1 is invalidate
cur_page = cp2;
sbi->cur_cp = 2;
version = cp2_version;
+ set_ckpt_flags(cp2, CP_FSCK_FLAG);
} else
goto fail_no_cp;
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 05/32] dump.f2fs: print more info
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (3 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 04/32] fsck.f2fs: fix invalidate checkpoint Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 06/32] f2fs-tools: add and export lookup_sit_in_journal Sheng Yong
` (27 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
dump.f2fs shows more info:
* nat entry version
* sit entry mtime
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/dump.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/fsck/dump.c b/fsck/dump.c
index 10df7e593bfe..21de2acf80b5 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -70,10 +70,10 @@ void nat_dump(struct f2fs_sb_info *sbi, nid_t start_nat, nid_t end_nat)
ASSERT(ret >= 0);
if (ni.blk_addr != 0x0) {
len = snprintf(buf, BUF_SZ,
- "nid:%5u\tino:%5u\toffset:%5u"
+ "nid:%5u\tino:%5u\tver:%3d\toffset:%5u"
"\tblkaddr:%10u\tpack:%d"
"\tcp_ver:0x%" PRIx64 "\n",
- ni.nid, ni.ino,
+ ni.nid, ni.ino, ni.version,
le32_to_cpu(footer->flag) >> OFFSET_BIT_SHIFT,
ni.blk_addr, pack,
le64_to_cpu(footer->cp_ver));
@@ -91,10 +91,10 @@ void nat_dump(struct f2fs_sb_info *sbi, nid_t start_nat, nid_t end_nat)
ret = dev_read_block(node_block, ni.blk_addr);
ASSERT(ret >= 0);
len = snprintf(buf, BUF_SZ,
- "nid:%5u\tino:%5u\toffset:%5u"
+ "nid:%5u\tino:%5u\tver:%3d\toffset:%5u"
"\tblkaddr:%10u\tpack:%d"
"\tcp_ver:0x%" PRIx64 "\n",
- ni.nid, ni.ino,
+ ni.nid, ni.ino, ni.version,
le32_to_cpu(footer->flag) >> OFFSET_BIT_SHIFT,
ni.blk_addr, pack,
le64_to_cpu(footer->cp_ver));
@@ -135,8 +135,10 @@ void sit_dump(struct f2fs_sb_info *sbi, unsigned int start_sit,
offset = SIT_BLOCK_OFFSET(sit_i, segno);
memset(buf, 0, BUF_SZ);
snprintf(buf, BUF_SZ,
- "\nsegno:%8u\tvblocks:%3u\tseg_type:%d\tsit_pack:%d\n\n",
+ "\nsegno:%8u\tvblocks:%3u\tseg_type:%d\tmtime:%llu\t"
+ "sit_pack:%d\n\n",
segno, se->valid_blocks, se->type,
+ (unsigned long long)se->mtime,
f2fs_test_bit(offset, sit_i->sit_bitmap) ? 2 : 1);
ret = write(fd, buf, strlen(buf));
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 06/32] f2fs-tools: add and export lookup_sit_in_journal
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (4 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 05/32] dump.f2fs: print more info Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 07/32] inject.f2fs: fix injecting sit/nat in journal Sheng Yong
` (26 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Add lookup_sit_in_journal() which is similar to lookup_nat_in_journal()
to get the raw sit entry from journal if exist.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/f2fs.h | 2 ++
fsck/mount.c | 18 ++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/fsck/f2fs.h b/fsck/f2fs.h
index a4888a817284..60e3a2ebb0ee 100644
--- a/fsck/f2fs.h
+++ b/fsck/f2fs.h
@@ -613,6 +613,8 @@ static inline int inline_xattr_size(struct f2fs_inode *inode)
}
extern int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid, struct f2fs_nat_entry *ne);
+extern int lookup_sit_in_journal(struct f2fs_sb_info *sbi, unsigned int segno,
+ struct f2fs_sit_entry *raw_sit);
#define IS_SUM_NODE_SEG(sum) (F2FS_SUMMARY_BLOCK_FOOTER(sum)->entry_type == SUM_TYPE_NODE)
#define IS_SUM_DATA_SEG(sum) (F2FS_SUMMARY_BLOCK_FOOTER(sum)->entry_type == SUM_TYPE_DATA)
diff --git a/fsck/mount.c b/fsck/mount.c
index b1f8e98dd7f0..1f2cc960b9c0 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -3290,6 +3290,24 @@ int lookup_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
return -1;
}
+int lookup_sit_in_journal(struct f2fs_sb_info *sbi, unsigned int segno,
+ struct f2fs_sit_entry *raw_sit)
+{
+ struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
+ struct f2fs_journal *journal = F2FS_SUMMARY_BLOCK_JOURNAL(curseg->sum_blk);
+ int i;
+
+ for (i = 0; i < sits_in_cursum(journal); i++) {
+ if (segno_in_journal(journal, i) == segno) {
+ memcpy(raw_sit, &sit_in_journal(journal, i),
+ sizeof(struct f2fs_sit_entry));
+ DBG(3, "==> Found sit [0x%x] in sit cache\n", segno);
+ return i;
+ }
+ }
+ return -1;
+}
+
void nullify_nat_entry(struct f2fs_sb_info *sbi, u32 nid)
{
struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 07/32] inject.f2fs: fix injecting sit/nat in journal
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (5 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 06/32] f2fs-tools: add and export lookup_sit_in_journal Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-11 11:42 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 08/32] inject.f2fs: fix injection on zoned device Sheng Yong
` (25 subsequent siblings)
32 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Previously when injecting sit/nat entry, we only inject SIT/NAT pack.
If the valid target is in journal, the injection has no effect. So we
have to check whether the valid target is in journal, and inject the
target at its valid position.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/inject.c | 181 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 132 insertions(+), 49 deletions(-)
diff --git a/fsck/inject.c b/fsck/inject.c
index bd6ab8480972..b3228621de48 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -10,6 +10,7 @@
*/
#include <getopt.h>
+#include "f2fs.h"
#include "node.h"
#include "inject.h"
@@ -533,6 +534,31 @@ out:
return ret;
}
+static void rewrite_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
+ struct f2fs_nat_entry *nat)
+{
+ struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+ struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
+ struct f2fs_journal *journal = F2FS_SUMMARY_BLOCK_JOURNAL(curseg->sum_blk);
+ block_t blkaddr;
+ int ret, i;
+
+ for (i = 0; i < nats_in_cursum(journal); i++) {
+ if (nid_in_journal(journal, i) == nid) {
+ memcpy(&nat_in_journal(journal, i), nat, sizeof(*nat));
+ break;
+ }
+ }
+
+ if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG))
+ blkaddr = sum_blk_addr(sbi, NR_CURSEG_TYPE, CURSEG_HOT_DATA);
+ else
+ blkaddr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, CURSEG_HOT_DATA);
+
+ ret = dev_write_block(curseg->sum_blk, blkaddr, WRITE_LIFE_NONE);
+ ASSERT(ret >= 0);
+}
+
static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
{
struct f2fs_nm_info *nm_i = NM_I(sbi);
@@ -541,7 +567,7 @@ static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
struct f2fs_nat_entry *ne;
block_t blk_addr;
unsigned int offs;
- bool is_set;
+ bool is_set, in_journal = false;
int ret;
if (!IS_VALID_NID(sbi, opt->nid)) {
@@ -555,38 +581,49 @@ static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
nat_blk = calloc(F2FS_BLKSIZE, 1);
ASSERT(nat_blk);
- /* change NAT version bitmap temporarily to select specified pack */
- is_set = f2fs_test_bit(opt->nid, nm_i->nat_bitmap);
- if (opt->nat == 0) {
- opt->nat = is_set ? 2 : 1;
+ if (lookup_nat_in_journal(sbi, opt->nid, &nat_blk->entries[0]) >= 0) {
+ offs = 0;
+ in_journal = true;
} else {
- if (opt->nat == 1)
- f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
- else
- f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
+ /*
+ * read nat entry from NAT area, change NAT version bitmap
+ * temporarily to select specified pack
+ */
+ is_set = f2fs_test_bit(opt->nid, nm_i->nat_bitmap);
+ if (opt->nat == 0) {
+ opt->nat = is_set ? 2 : 1;
+ } else {
+ if (opt->nat == 1)
+ f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
+ else
+ f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
+ }
+ blk_addr = current_nat_addr(sbi, opt->nid, NULL);
+ ret = dev_read_block(nat_blk, blk_addr);
+ ASSERT(ret >= 0);
+ offs = opt->nid % NAT_ENTRY_PER_BLOCK;
}
-
- blk_addr = current_nat_addr(sbi, opt->nid, NULL);
-
- ret = dev_read_block(nat_blk, blk_addr);
- ASSERT(ret >= 0);
-
- offs = opt->nid % NAT_ENTRY_PER_BLOCK;
ne = &nat_blk->entries[offs];
if (!strcmp(opt->mb, "version")) {
MSG(0, "Info: inject nat entry version of nid %u "
- "in pack %d: %d -> %d\n", opt->nid, opt->nat,
+ "in %s %d: %d -> %d\n", opt->nid,
+ in_journal ? "journal" : "pack",
+ in_journal ? 0 : opt->nat,
ne->version, (u8)opt->val);
ne->version = (u8)opt->val;
} else if (!strcmp(opt->mb, "ino")) {
MSG(0, "Info: inject nat entry ino of nid %u "
- "in pack %d: %d -> %d\n", opt->nid, opt->nat,
+ "in %s %d: %d -> %d\n", opt->nid,
+ in_journal ? "journal" : "pack",
+ in_journal ? 0 : opt->nat,
le32_to_cpu(ne->ino), (nid_t)opt->val);
ne->ino = cpu_to_le32((nid_t)opt->val);
} else if (!strcmp(opt->mb, "block_addr")) {
MSG(0, "Info: inject nat entry block_addr of nid %u "
- "in pack %d: 0x%x -> 0x%x\n", opt->nid, opt->nat,
+ "in %s %d: 0x%x -> 0x%x\n", opt->nid,
+ in_journal ? "journal" : "pack",
+ in_journal ? 0 : opt->nat,
le32_to_cpu(ne->block_addr), (block_t)opt->val);
ne->block_addr = cpu_to_le32((block_t)opt->val);
} else {
@@ -596,16 +633,45 @@ static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
}
print_raw_nat_entry_info(ne);
- ret = dev_write_block(nat_blk, blk_addr, WRITE_LIFE_NONE);
- ASSERT(ret >= 0);
- /* restore NAT version bitmap */
- if (is_set)
- f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
- else
- f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
+ if (in_journal) {
+ rewrite_nat_in_journal(sbi, opt->nid, ne);
+ } else {
+ ret = dev_write_block(nat_blk, blk_addr, WRITE_LIFE_NONE);
+ ASSERT(ret >= 0);
+ /* restore NAT version bitmap */
+ if (is_set)
+ f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
+ else
+ f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
+ }
free(nat_blk);
- return ret;
+ return 0;
+}
+
+static void rewrite_sit_in_journal(struct f2fs_sb_info *sbi, unsigned int segno,
+ struct f2fs_sit_entry *sit)
+{
+ struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
+ struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
+ struct f2fs_journal *journal = F2FS_SUMMARY_BLOCK_JOURNAL(curseg->sum_blk);
+ block_t blkaddr;
+ int ret, i;
+
+ for (i = 0; i < sits_in_cursum(journal); i++) {
+ if (segno_in_journal(journal, i) == segno) {
+ memcpy(&sit_in_journal(journal, i), sit, sizeof(*sit));
+ break;
+ }
+ }
+
+ if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG))
+ blkaddr = sum_blk_addr(sbi, NR_CURSEG_TYPE, CURSEG_COLD_DATA);
+ else
+ blkaddr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, CURSEG_COLD_DATA);
+
+ ret = dev_write_block(curseg->sum_blk, blkaddr, WRITE_LIFE_NONE);
+ ASSERT(ret >= 0);
}
static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
@@ -614,7 +680,7 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
struct f2fs_sit_block *sit_blk;
struct f2fs_sit_entry *sit;
unsigned int segno, offs;
- bool is_set;
+ bool is_set, in_journal = false;
if (!f2fs_is_valid_blkaddr(sbi, opt->blk, DATA_GENERIC)) {
ERR_MSG("Invalid blkaddr 0x%x (valid range [0x%x:0x%lx])\n",
@@ -627,29 +693,39 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
ASSERT(sit_blk);
segno = GET_SEGNO(sbi, opt->blk);
- /* change SIT version bitmap temporarily to select specified pack */
- is_set = f2fs_test_bit(segno, sit_i->sit_bitmap);
- if (opt->sit == 0) {
- opt->sit = is_set ? 2 : 1;
+ if (lookup_sit_in_journal(sbi, segno, &sit_blk->entries[0]) >= 0) {
+ offs = 0;
+ in_journal = true;
} else {
- if (opt->sit == 1)
- f2fs_clear_bit(segno, sit_i->sit_bitmap);
- else
- f2fs_set_bit(segno, sit_i->sit_bitmap);
+ /*
+ * read sit entry from SIT area, change SIT version bitmap
+ * temporarily to select specified pack
+ */
+ is_set = f2fs_test_bit(segno, sit_i->sit_bitmap);
+ if (opt->sit == 0) {
+ opt->sit = is_set ? 2 : 1;
+ } else {
+ if (opt->sit == 1)
+ f2fs_clear_bit(segno, sit_i->sit_bitmap);
+ else
+ f2fs_set_bit(segno, sit_i->sit_bitmap);
+ }
+ get_current_sit_page(sbi, segno, sit_blk);
+ offs = SIT_ENTRY_OFFSET(sit_i, segno);
}
- get_current_sit_page(sbi, segno, sit_blk);
- offs = SIT_ENTRY_OFFSET(sit_i, segno);
sit = &sit_blk->entries[offs];
if (!strcmp(opt->mb, "vblocks")) {
MSG(0, "Info: inject sit entry vblocks of block 0x%x "
- "in pack %d: %u -> %u\n", opt->blk, opt->sit,
+ "in %s %d: %u -> %u\n", opt->blk,
+ in_journal ? "journal" : "pack",
+ in_journal ? 0 : opt->sit,
le16_to_cpu(sit->vblocks), (u16)opt->val);
sit->vblocks = cpu_to_le16((u16)opt->val);
} else if (!strcmp(opt->mb, "valid_map")) {
if (opt->idx == -1) {
- MSG(0, "Info: auto idx = %u\n", offs);
- opt->idx = offs;
+ opt->idx = OFFSET_IN_SEG(sbi, opt->blk);
+ MSG(0, "Info: auto idx = %u\n", opt->idx);
}
if (opt->idx >= SIT_VBLOCK_MAP_SIZE) {
ERR_MSG("invalid idx %u of valid_map[]\n", opt->idx);
@@ -657,8 +733,10 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
return -ERANGE;
}
MSG(0, "Info: inject sit entry valid_map[%d] of block 0x%x "
- "in pack %d: 0x%02x -> 0x%02x\n", opt->idx, opt->blk,
- opt->sit, sit->valid_map[opt->idx], (u8)opt->val);
+ "in %s %d: 0x%02x -> 0x%02x\n", opt->idx, opt->blk,
+ in_journal ? "journal" : "pack",
+ in_journal ? 0 : opt->sit,
+ sit->valid_map[opt->idx], (u8)opt->val);
sit->valid_map[opt->idx] = (u8)opt->val;
} else if (!strcmp(opt->mb, "mtime")) {
MSG(0, "Info: inject sit entry mtime of block 0x%x "
@@ -672,12 +750,17 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
}
print_raw_sit_entry_info(sit);
- rewrite_current_sit_page(sbi, segno, sit_blk);
- /* restore SIT version bitmap */
- if (is_set)
- f2fs_set_bit(segno, sit_i->sit_bitmap);
- else
- f2fs_clear_bit(segno, sit_i->sit_bitmap);
+ if (in_journal) {
+ rewrite_sit_in_journal(sbi, segno, sit);
+ } else {
+ rewrite_current_sit_page(sbi, segno, sit_blk);
+
+ /* restore SIT version bitmap */
+ if (is_set)
+ f2fs_set_bit(segno, sit_i->sit_bitmap);
+ else
+ f2fs_clear_bit(segno, sit_i->sit_bitmap);
+ }
free(sit_blk);
return 0;
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 08/32] inject.f2fs: fix injection on zoned device
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (6 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 07/32] inject.f2fs: fix injecting sit/nat in journal Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options Sheng Yong
` (24 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Because node and data blocks are updated out of place on zoned device,
sit_area_bitmap and main_area_bitmap are required to record which
blocks are allocated, sit should be flushed to reflect changes in
block address, and checkpoint should be rewritten to update cursegs.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/inject.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/fsck/inject.c b/fsck/inject.c
index b3228621de48..96817a806f8f 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -1172,6 +1172,9 @@ int do_inject(struct f2fs_sb_info *sbi)
struct inject_option *opt = (struct inject_option *)c.private;
int ret = -EINVAL;
+ if (c.zoned_model == F2FS_ZONED_HM)
+ fsck_init(sbi);
+
if (opt->sb >= 0)
ret = inject_sb(sbi, opt);
else if (opt->cp >= 0)
@@ -1187,5 +1190,15 @@ int do_inject(struct f2fs_sb_info *sbi)
else if (opt->dent)
ret = inject_dentry(sbi, opt);
+ if (c.zoned_model == F2FS_ZONED_HM) {
+ if (!ret && (opt->node || opt->dent)) {
+ write_curseg_info(sbi);
+ flush_journal_entries(sbi);
+ flush_sit_entries(sbi);
+ write_checkpoint(sbi);
+ }
+ fsck_free(sbi);
+ }
+
return ret;
}
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (7 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 08/32] inject.f2fs: fix injection on zoned device Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-13 6:08 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 10/32] inject.f2fs: add members in inject_cp Sheng Yong
` (23 subsequent siblings)
32 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
This patch fixes:
* parsing hex optarg of --idx option
* converting -1 to 0xff...ff of --val option
and do a little cleanup of converting string to a long integer.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/inject.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/fsck/inject.c b/fsck/inject.c
index 96817a806f8f..c879ca99c0d8 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -236,8 +236,9 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
while ((o = getopt_long(argc, argv, option_string,
long_opt, NULL)) != EOF) {
- long nid, blk;
+ long long val;
+ errno = 0;
switch (o) {
case 1:
c.dry_run = 1;
@@ -248,18 +249,19 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
MSG(0, "Info: inject member %s\n", optarg);
break;
case 3:
- if (!is_digits(optarg))
- return EWRONG_OPT;
- opt->idx = atoi(optarg);
- MSG(0, "Info: inject slot index %d\n", opt->idx);
+ val = strtoll(optarg, &endptr, 0);
+ if (errno != 0 || val >= UINT_MAX || val < 0 ||
+ *endptr != '\0')
+ return -ERANGE;
+ opt->idx = (unsigned int)val;
+ MSG(0, "Info: inject slot index %u\n", opt->idx);
break;
case 4:
- opt->val = strtoll(optarg, &endptr, 0);
- if (opt->val == LLONG_MAX || opt->val == LLONG_MIN ||
- *endptr != '\0')
+ opt->val = strtoull(optarg, &endptr, 0);
+ if (errno != 0 || *endptr != '\0')
return -ERANGE;
MSG(0, "Info: inject value %lld : 0x%llx\n", opt->val,
- (unsigned long long)opt->val);
+ opt->val);
break;
case 5:
opt->str = strdup(optarg);
@@ -292,11 +294,11 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
MSG(0, "Info: inject nat pack %s\n", pack[opt->nat]);
break;
case 9:
- nid = strtol(optarg, &endptr, 0);
- if (nid >= UINT_MAX || nid < 0 ||
+ val = strtoll(optarg, &endptr, 0);
+ if (errno != 0 || val >= UINT_MAX || val < 0 ||
*endptr != '\0')
return -ERANGE;
- opt->nid = nid;
+ opt->nid = (nid_t)val;
MSG(0, "Info: inject nid %u : 0x%x\n", opt->nid, opt->nid);
break;
case 10:
@@ -308,11 +310,11 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
MSG(0, "Info: inject sit pack %s\n", pack[opt->sit]);
break;
case 11:
- blk = strtol(optarg, &endptr, 0);
- if (blk >= UINT_MAX || blk < 0 ||
+ val = strtoll(optarg, &endptr, 0);
+ if (errno != 0 || val >= UINT_MAX || val < 0 ||
*endptr != '\0')
return -ERANGE;
- opt->blk = blk;
+ opt->blk = (block_t)val;
MSG(0, "Info: inject blkaddr %u : 0x%x\n", opt->blk, opt->blk);
break;
case 12:
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 10/32] inject.f2fs: add members in inject_cp
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (8 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-13 7:30 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 11/32] inject.f2fs: add member `feature' in inject_sb Sheng Yong
` (22 subsequent siblings)
32 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
The following members are added to inject more fields in cp:
* next_blkaddr: inject fsync dnodes
An error is returned if no fsync dnode is found.
However, the injection is not supported on zoned device. This is because
fsync dnodes must remains at the end of current warm node segment, any
dnode change causes all previous dnodes in the chain to be updated
out-of-place, and there may not have enough space left in the curseg.
To simplify the injection, it returns an error on zoned device.
* alloc_type: inject curseg's alloc type
* crc: inject cp's checksum
* elapsed_time: inject cp's mount elapsed time
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/fsck.h | 4 ++-
fsck/inject.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++-
fsck/mount.c | 18 +++++-----
man/inject.f2fs.8 | 11 +++++-
4 files changed, 107 insertions(+), 11 deletions(-)
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 40cb6d9a6417..05daa2de9531 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -223,6 +223,8 @@ extern int f2fs_ra_meta_pages(struct f2fs_sb_info *, block_t, int, int);
extern int f2fs_do_mount(struct f2fs_sb_info *);
extern void f2fs_do_umount(struct f2fs_sb_info *);
extern int f2fs_sparse_initialize_meta(struct f2fs_sb_info *);
+extern int f2fs_find_fsync_inode(struct f2fs_sb_info *, struct list_head *);
+extern void f2fs_destroy_fsync_dnodes(struct list_head *);
extern void flush_journal_entries(struct f2fs_sb_info *);
extern void update_curseg_info(struct f2fs_sb_info *, int);
@@ -239,7 +241,7 @@ extern void duplicate_checkpoint(struct f2fs_sb_info *);
extern void write_checkpoint(struct f2fs_sb_info *);
extern void write_checkpoints(struct f2fs_sb_info *);
extern void write_raw_cp_blocks(struct f2fs_sb_info *sbi,
- struct f2fs_checkpoint *cp, int which);
+ struct f2fs_checkpoint *cp, int which, bool update_crc);
extern void update_superblock(struct f2fs_super_block *, int);
extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t,
struct f2fs_node *);
diff --git a/fsck/inject.c b/fsck/inject.c
index c879ca99c0d8..53667730775f 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -139,6 +139,10 @@ static void inject_cp_usage(void)
MSG(0, " cur_node_blkoff: inject cur_node_blkoff array selected by --idx <index>\n");
MSG(0, " cur_data_segno: inject cur_data_segno array selected by --idx <index>\n");
MSG(0, " cur_data_blkoff: inject cur_data_blkoff array selected by --idx <index>\n");
+ MSG(0, " alloc_type: inject alloc_type array selected by --idx <index>\n");
+ MSG(0, " next_blkaddr: inject next_blkaddr of fsync dnodes selected by --idx <index>\n");
+ MSG(0, " crc: inject crc checksum\n");
+ MSG(0, " elapsed_time: inject elapsed_time\n");
}
static void inject_nat_usage(void)
@@ -443,6 +447,7 @@ out:
static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
{
struct f2fs_checkpoint *cp, *cur_cp = F2FS_CKPT(sbi);
+ bool update_crc = true;
char *buf = NULL;
int ret = 0;
@@ -521,6 +526,84 @@ static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
opt->idx, opt->cp, get_cp(cur_data_blkoff[opt->idx]),
(u16)opt->val);
set_cp(cur_data_blkoff[opt->idx], (u16)opt->val);
+ } else if (!strcmp(opt->mb, "alloc_type")) {
+ if (opt->idx >= MAX_ACTIVE_LOGS) {
+ ERR_MSG("invalid index %u of cp->alloc_type[]\n",
+ opt->idx);
+ ret = -EINVAL;
+ goto out;
+ }
+ MSG(0, "Info: inject alloc_type[%d] of cp %d: 0x%x -> 0x%x\n",
+ opt->idx, opt->cp, cp->alloc_type[opt->idx],
+ (unsigned char)opt->val);
+ cp->alloc_type[opt->idx] = (unsigned char)opt->val;
+ } else if (!strcmp(opt->mb, "next_blkaddr")) {
+ struct fsync_inode_entry *entry;
+ struct list_head inode_list = LIST_HEAD_INIT(inode_list);
+ struct f2fs_node *node;
+ block_t blkaddr;
+ int i = 0;
+
+ if (c.zoned_model == F2FS_ZONED_HM) {
+ ERR_MSG("inject fsync dnodes not supported in "
+ "zoned device\n");
+ ret = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!need_fsync_data_record(sbi)) {
+ ERR_MSG("no need to recover fsync dnodes\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = f2fs_find_fsync_inode(sbi, &inode_list);
+ if (ret) {
+ ERR_MSG("failed to find fsync inodes: %d\n", ret);
+ goto out;
+ }
+
+ list_for_each_entry(entry, &inode_list, list) {
+ if (i == opt->idx)
+ blkaddr = entry->blkaddr;
+ DBG(0, "[%4d] blkaddr:0x%x\n", i++, entry->blkaddr);
+ }
+
+ f2fs_destroy_fsync_dnodes(&inode_list);
+
+ if (opt->idx == 0 || opt->idx >= i) {
+ ERR_MSG("invalid index %u of fsync dnodes range [1, %u]\n",
+ opt->idx, i);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ MSG(0, "Info: inject next_blkaddr[%d] of cp %d: 0x%x -> 0x%x\n",
+ opt->idx, opt->cp, blkaddr, (u32)opt->val);
+
+ node = malloc(F2FS_BLKSIZE);
+ ASSERT(node);
+ ret = dev_read_block(node, blkaddr);
+ ASSERT(ret >= 0);
+ F2FS_NODE_FOOTER(node)->next_blkaddr = cpu_to_le32((u32)opt->val);
+ if (IS_INODE(node))
+ ret = update_inode(sbi, node, &blkaddr);
+ else
+ ret = update_block(sbi, node, &blkaddr, NULL);
+ ASSERT(ret >= 0);
+ goto out;
+ } else if (!strcmp(opt->mb, "crc")) {
+ __le32 *crc = (__le32 *)((unsigned char *)cp +
+ get_cp(checksum_offset));
+
+ MSG(0, "Info: inject crc of cp %d: 0x%x -> 0x%x\n",
+ opt->cp, le32_to_cpu(*crc), (u32)opt->val);
+ *crc = cpu_to_le32((u32)opt->val);
+ update_crc = false;
+ } else if (!strcmp(opt->mb, "elapsed_time")) {
+ MSG(0, "Info: inject elapsed_time of cp %d: %llu -> %"PRIu64"\n",
+ opt->cp, get_cp(elapsed_time), (u64)opt->val);
+ set_cp(elapsed_time, (u64)opt->val);
} else {
ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
ret = -EINVAL;
@@ -528,7 +611,7 @@ static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
}
print_ckpt_info(sbi);
- write_raw_cp_blocks(sbi, cp, opt->cp);
+ write_raw_cp_blocks(sbi, cp, opt->cp, update_crc);
out:
free(buf);
diff --git a/fsck/mount.c b/fsck/mount.c
index 1f2cc960b9c0..eb019ad6826e 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -3503,17 +3503,19 @@ void write_checkpoints(struct f2fs_sb_info *sbi)
write_checkpoint(sbi);
}
-void write_raw_cp_blocks(struct f2fs_sb_info *sbi,
- struct f2fs_checkpoint *cp, int which)
+void write_raw_cp_blocks(struct f2fs_sb_info *sbi, struct f2fs_checkpoint *cp,
+ int which, bool update_crc)
{
struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
uint32_t crc;
block_t cp_blkaddr;
int ret;
- crc = f2fs_checkpoint_chksum(cp);
- *((__le32 *)((unsigned char *)cp + get_cp(checksum_offset))) =
+ if (update_crc) {
+ crc = f2fs_checkpoint_chksum(cp);
+ *((__le32 *)((unsigned char *)cp + get_cp(checksum_offset))) =
cpu_to_le32(crc);
+ }
cp_blkaddr = get_sb(cp_blkaddr);
if (which == 2)
@@ -3747,7 +3749,7 @@ static void del_fsync_inode(struct fsync_inode_entry *entry)
free(entry);
}
-static void destroy_fsync_dnodes(struct list_head *head)
+void f2fs_destroy_fsync_dnodes(struct list_head *head)
{
struct fsync_inode_entry *entry, *tmp;
@@ -3853,7 +3855,7 @@ static int sanity_check_node_chain(struct f2fs_sb_info *sbi,
return 0;
}
-static int find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
+int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
{
struct curseg_info *curseg;
struct f2fs_node *node_blk, *node_blk_fast;
@@ -4049,7 +4051,7 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
if (!need_fsync_data_record(sbi))
return 0;
- ret = find_fsync_inode(sbi, &inode_list);
+ ret = f2fs_find_fsync_inode(sbi, &inode_list);
if (ret)
goto out;
@@ -4064,7 +4066,7 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
ret = traverse_dnodes(sbi, &inode_list);
out:
- destroy_fsync_dnodes(&inode_list);
+ f2fs_destroy_fsync_dnodes(&inode_list);
return ret;
}
diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
index 01d58effbfe4..975d8c65030a 100644
--- a/man/inject.f2fs.8
+++ b/man/inject.f2fs.8
@@ -45,7 +45,7 @@ The available \fImb\fP of \fIsb\fP are:
.RS 1.2i
.TP
.BI magic
-magic numbe.
+magic number.
.TP
.BI s_stop_reason
s_stop_reason array.
@@ -79,6 +79,15 @@ cur_data_segno array.
.TP
.BI cur_data_blkoff
cur_data_blkoff array.
+.TP
+.BI next_blkaddr
+fsync dnodes.
+.TP
+.BI crc
+crc checksum.
+.TP
+.BI elapsed_time
+elapsed mount time.
.RE
.TP
.BI \-\-nat " 0 or 1 or 2"
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 11/32] inject.f2fs: add member `feature' in inject_sb
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (9 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 10/32] inject.f2fs: add members in inject_cp Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 12/32] inject.f2fs: add members in inject_node Sheng Yong
` (21 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
This patch adds a new member `feature' in inject_sb to inject features.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/inject.c | 5 +++++
man/inject.f2fs.8 | 3 +++
2 files changed, 8 insertions(+)
diff --git a/fsck/inject.c b/fsck/inject.c
index 53667730775f..0b5aecbf8061 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -122,6 +122,7 @@ static void inject_sb_usage(void)
MSG(0, " magic: inject magic number\n");
MSG(0, " s_stop_reason: inject s_stop_reason array selected by --idx <index>\n");
MSG(0, " s_errors: inject s_errors array selected by --idx <index>\n");
+ MSG(0, " feature: inject feature\n");
MSG(0, " devs.path: inject path in devs array selected by --idx <index> specified by --str <string>\n");
}
@@ -415,6 +416,10 @@ static int inject_sb(struct f2fs_sb_info *sbi, struct inject_option *opt)
MSG(0, "Info: inject s_errors[%d] of sb %d: %x -> %x\n",
opt->idx, opt->sb, sb->s_errors[opt->idx], (u8)opt->val);
sb->s_errors[opt->idx] = (u8)opt->val;
+ } else if (!strcmp(opt->mb, "feature")) {
+ MSG(0, "Info: inject feature of sb %d: 0x%x -> 0x%x\n",
+ opt->sb, get_sb(feature), (u32)opt->val);
+ set_sb(feature, (u32)opt->val);
} else if (!strcmp(opt->mb, "devs.path")) {
if (opt->idx >= MAX_DEVICES) {
ERR_MSG("invalid index %u of sb->devs[]\n", opt->idx);
diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
index 975d8c65030a..5ae556015a79 100644
--- a/man/inject.f2fs.8
+++ b/man/inject.f2fs.8
@@ -53,6 +53,9 @@ s_stop_reason array.
.BI s_errors
s_errors array.
.TP
+.BI feature
+features.
+.TP
.BI devs.path
path in devs array.
.RE
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 12/32] inject.f2fs: add members in inject_node
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (10 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 11/32] inject.f2fs: add member `feature' in inject_sb Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-13 7:38 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry Sheng Yong
` (20 subsequent siblings)
32 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
This patch adds new members in inject_node to inject inode:
* i_ext.fofs: extent fofs
* i_ext.blk_addr: extent blk_addr
* i_ext.len: extent len
* i_inline_xattr_size: inline xattr size
* i_compr_blocks: compression blocks
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/inject.c | 28 ++++++++++++++++++++++++++++
man/inject.f2fs.8 | 17 ++++++++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/fsck/inject.c b/fsck/inject.c
index 0b5aecbf8061..8c2f8c5dc332 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -198,8 +198,13 @@ static void inject_node_usage(void)
MSG(0, " i_links: inject inode i_links\n");
MSG(0, " i_size: inject inode i_size\n");
MSG(0, " i_blocks: inject inode i_blocks\n");
+ MSG(0, " i_ext.fofs: inject inode i_ext.fofs\n");
+ MSG(0, " i_ext.blk_addr: inject inode i_ext.blk_addr\n");
+ MSG(0, " i_ext.len: inject inode i_ext.len\n");
MSG(0, " i_extra_isize: inject inode i_extra_isize\n");
+ MSG(0, " i_inline_xattr_size: inject inode i_inline_xattr_size\n");
MSG(0, " i_inode_checksum: inject inode i_inode_checksum\n");
+ MSG(0, " i_compr_blocks: inject inode i_compr_blocks\n");
MSG(0, " i_addr: inject inode i_addr array selected by --idx <index>\n");
MSG(0, " i_nid: inject inode i_nid array selected by --idx <index>\n");
MSG(0, " addr: inject {in}direct node nid/addr array selected by --idx <index>\n");
@@ -967,16 +972,39 @@ static int inject_inode(struct f2fs_sb_info *sbi, struct f2fs_node *node,
MSG(0, "Info: inject inode i_blocks of nid %u: %"PRIu64" -> %"PRIu64"\n",
opt->nid, le64_to_cpu(inode->i_blocks), (u64)opt->val);
inode->i_blocks = cpu_to_le64((u64)opt->val);
+ } else if (!strcmp(opt->mb, "i_ext.fofs")) {
+ MSG(0, "Info: inject inode i_ext.fofs of nid %u: %u -> %u\n",
+ opt->nid, le32_to_cpu(inode->i_ext.fofs), (u32)opt->val);
+ inode->i_ext.fofs = cpu_to_le32((u32)opt->val);
+ } else if (!strcmp(opt->mb, "i_ext.blk_addr")) {
+ MSG(0, "Info: inject inode i_ext.blk_addr of nid %u: "
+ "0x%x -> 0x%x\n", opt->nid,
+ le32_to_cpu(inode->i_ext.blk_addr), (u32)opt->val);
+ inode->i_ext.blk_addr = cpu_to_le32((u32)opt->val);
+ } else if (!strcmp(opt->mb, "i_ext.len")) {
+ MSG(0, "Info: inject inode i_ext.len of nid %u: %u -> %u\n",
+ opt->nid, le32_to_cpu(inode->i_ext.len), (u32)opt->val);
+ inode->i_ext.len = cpu_to_le32((u32)opt->val);
} else if (!strcmp(opt->mb, "i_extra_isize")) {
/* do not care if F2FS_EXTRA_ATTR is enabled */
MSG(0, "Info: inject inode i_extra_isize of nid %u: %d -> %d\n",
opt->nid, le16_to_cpu(inode->i_extra_isize), (u16)opt->val);
inode->i_extra_isize = cpu_to_le16((u16)opt->val);
+ } else if (!strcmp(opt->mb, "i_inline_xattr_size")) {
+ MSG(0, "Info: inject inode i_inline_xattr_size of nid %u: "
+ "%d -> %d\n", opt->nid,
+ le16_to_cpu(inode->i_inline_xattr_size), (u16)opt->val);
+ inode->i_inline_xattr_size = cpu_to_le16((u16)opt->val);
} else if (!strcmp(opt->mb, "i_inode_checksum")) {
MSG(0, "Info: inject inode i_inode_checksum of nid %u: "
"0x%x -> 0x%x\n", opt->nid,
le32_to_cpu(inode->i_inode_checksum), (u32)opt->val);
inode->i_inode_checksum = cpu_to_le32((u32)opt->val);
+ } else if (!strcmp(opt->mb, "i_compr_blocks")) {
+ MSG(0, "Info: inject inode i_compr_blocks of nid %u: "
+ "%lu -> %lu\n", opt->nid,
+ le64_to_cpu(inode->i_compr_blocks), (u64)opt->val);
+ inode->i_compr_blocks = cpu_to_le64((u64)opt->val);
} else if (!strcmp(opt->mb, "i_addr")) {
/* do not care if it is inline data */
if (opt->idx >= DEF_ADDRS_PER_INODE) {
diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
index 5ae556015a79..72d1c90f7ce4 100644
--- a/man/inject.f2fs.8
+++ b/man/inject.f2fs.8
@@ -145,7 +145,7 @@ summary entry ofs_in_node.
.RE
.TP
.BI \-\-node
-Inject node block specified by \fInid\P.
+Inject node block specified by \fInid\fP.
The available \fImb\fP of \fInode\fP are:
.RS 1.2i
.TP
@@ -182,12 +182,27 @@ inode i_size.
.BI i_blocks
inode i_blocks.
.TP
+.BI i_ext.fofs
+inode i_ext.fofs.
+.TP
+.BI i_ext.blk_addr
+inode i_ext.blk_addr.
+.TP
+.BI i_ext.len
+inode i_ext.len.
+.TP
.BI i_extra_isize
inode i_extra_isize.
.TP
+.BI i_inline_xattr_size
+inode i_inline_xattr_size.
+.TP
.BI i_inode_checksum
inode i_inode_checksum.
.TP
+.BI i_compr_blocks
+inode i_compr_blocks.
+.TP
.BI i_addr
inode i_addr array specified by \fIidx\fP.
.TP
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (11 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 12/32] inject.f2fs: add members in inject_node Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-13 7:55 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 14/32] tests: prepare helper scripts for testcases Sheng Yong
` (19 subsequent siblings)
32 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
This patch adds a new member `filename' in inject_dentry to inject
dentry filename. The dentry is specified by nid option.
Note that '.' and '..' dentries are special, because they are not in the
parent directory of nid. So this patch also adds a new option `--dots'
to inject these two dentries.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
fsck/inject.c | 94 ++++++++++++++++++++++++++++++++++++++++-------
fsck/inject.h | 1 +
man/inject.f2fs.8 | 12 +++++-
3 files changed, 92 insertions(+), 15 deletions(-)
diff --git a/fsck/inject.c b/fsck/inject.c
index 8c2f8c5dc332..5eb913fefad7 100644
--- a/fsck/inject.c
+++ b/fsck/inject.c
@@ -105,7 +105,7 @@ void inject_usage(void)
MSG(0, " --sit <0|1|2> --mb <name> --blk <blk> [--idx <index>] --val <value> inject sit entry\n");
MSG(0, " --ssa --mb <name> --blk <blk> [--idx <index>] --val <value> inject summary entry\n");
MSG(0, " --node --mb <name> --nid <nid> [--idx <index>] --val <value> inject node\n");
- MSG(0, " --dent --mb <name> --nid <ino> [--idx <index>] --val <value> inject ino's dentry\n");
+ MSG(0, " --dent --mb <name> --nid <ino> [--dots <1|2>] --val/str <value/string> inject ino's dentry\n");
MSG(0, " --dry-run do not really inject\n");
exit(1);
@@ -212,12 +212,16 @@ static void inject_node_usage(void)
static void inject_dent_usage(void)
{
- MSG(0, "inject.f2fs --dent --mb <name> --nid <nid> [--idx <index>] --val <value> inject dentry\n");
+ MSG(0, "inject.f2fs --dent --mb <name> --nid <nid> [--dots <1|2>] --val/str <value/string> inject dentry\n");
+ MSG(0, "[dots]:\n");
+ MSG(0, " 1: inject \".\" in directory which is specified by nid\n");
+ MSG(0, " 2: inject \"..\" in directory which is specified by nid\n");
MSG(0, "[mb]:\n");
MSG(0, " d_bitmap: inject dentry block d_bitmap of nid\n");
MSG(0, " d_hash: inject dentry hash\n");
MSG(0, " d_ino: inject dentry ino\n");
MSG(0, " d_ftype: inject dentry ftype\n");
+ MSG(0, " filename: inject dentry filename, its hash and len are updated implicitly\n");
}
int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
@@ -241,6 +245,7 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
{"ssa", no_argument, 0, 12},
{"node", no_argument, 0, 13},
{"dent", no_argument, 0, 14},
+ {"dots", required_argument, 0, 15},
{0, 0, 0, 0}
};
@@ -339,6 +344,14 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
opt->dent = true;
MSG(0, "Info: inject dentry\n");
break;
+ case 15:
+ opt->dots = atoi(optarg);
+ if (opt->dots != TYPE_DOT &&
+ opt->dots != TYPE_DOTDOT)
+ return -ERANGE;
+ MSG(0, "Info: inject %s dentry\n",
+ opt->dots == TYPE_DOT ? "dot" : "dotdot");
+ break;
case 'd':
if (optarg[0] == '-' || !is_digits(optarg))
return EWRONG_OPT;
@@ -371,6 +384,9 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
} else if (opt->dent) {
inject_dent_usage();
exit(0);
+ } else {
+ MSG(0, "\tError: Wrong option -%c (%d) %s\n",
+ o, o, optarg);
}
return EUNKNOWN_OPT;
}
@@ -1146,12 +1162,12 @@ static int find_dir_entry(struct f2fs_dentry_ptr *d, nid_t ino)
}
de = &d->dentry[slot];
- if (le32_to_cpu(de->ino) == ino && de->hash_code != 0)
- return slot;
if (de->name_len == 0) {
slot++;
continue;
}
+ if (le32_to_cpu(de->ino) == ino)
+ return slot;
slot += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
}
@@ -1164,14 +1180,15 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
struct f2fs_node *node_blk = NULL;
struct f2fs_inode *inode;
struct f2fs_dentry_ptr d;
- void *inline_dentry;
+ void *buf = NULL, *inline_dentry;
struct f2fs_dentry_block *dent_blk = NULL;
block_t addr = 0;
- void *buf = NULL;
struct f2fs_dir_entry *dent = NULL;
struct dnode_of_data dn;
nid_t pino;
- int slot = -ENOENT, ret;
+ int slot = -ENOENT, namelen, namecap, ret;
+ unsigned int dentry_hash;
+ char *name;
node_blk = malloc(F2FS_BLKSIZE);
ASSERT(node_blk != NULL);
@@ -1180,12 +1197,25 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
get_node_info(sbi, opt->nid, &ni);
ret = dev_read_block(node_blk, ni.blk_addr);
ASSERT(ret >= 0);
- pino = le32_to_cpu(node_blk->i.i_pino);
- /* get parent inode */
- get_node_info(sbi, pino, &ni);
- ret = dev_read_block(node_blk, ni.blk_addr);
- ASSERT(ret >= 0);
+ if (opt->dots) {
+ if (!LINUX_S_ISDIR(le16_to_cpu(node_blk->i.i_mode))) {
+ ERR_MSG("ino %u is not a directory, cannot inject "
+ "its %s\n", opt->nid,
+ opt->dots == TYPE_DOT ? "." : "..");
+ ret = -EINVAL;
+ goto out;
+ }
+ /* pino is itself */
+ pino = opt->nid;
+ } else {
+ pino = le32_to_cpu(node_blk->i.i_pino);
+
+ /* get parent inode */
+ get_node_info(sbi, pino, &ni);
+ ret = dev_read_block(node_blk, ni.blk_addr);
+ ASSERT(ret >= 0);
+ }
inode = &node_blk->i;
/* find child dentry */
@@ -1195,7 +1225,10 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
addr = ni.blk_addr;
buf = node_blk;
- slot = find_dir_entry(&d, opt->nid);
+ if (opt->dots == TYPE_DOTDOT)
+ slot = find_dir_entry(&d, le32_to_cpu(node_blk->i.i_pino));
+ else
+ slot = find_dir_entry(&d, opt->nid);
if (slot >= 0)
dent = &d.dentry[slot];
} else {
@@ -1231,7 +1264,10 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
ASSERT(ret >= 0);
make_dentry_ptr(&d, node_blk, dent_blk, 1);
- slot = find_dir_entry(&d, opt->nid);
+ if (opt->dots == TYPE_DOTDOT)
+ slot = find_dir_entry(&d, le32_to_cpu(node_blk->i.i_pino));
+ else
+ slot = find_dir_entry(&d, opt->nid);
if (slot >= 0) {
dent = &d.dentry[slot];
buf = dent_blk;
@@ -1265,6 +1301,36 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
"%d -> %d\n", opt->nid, dent->file_type,
(u8)opt->val);
dent->file_type = (u8)opt->val;
+ } else if (!strcmp(opt->mb, "filename")) {
+ if (!opt->str) {
+ ERR_MSG("option str is needed\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ namecap = ALIGN_UP(le16_to_cpu(dent->name_len), F2FS_SLOT_LEN);
+ namelen = strlen(opt->str);
+ if (namelen > namecap || namelen > F2FS_NAME_LEN) {
+ ERR_MSG("option str too long\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ name = (char *)d.filename[slot];
+ MSG(0, "Info: inject dentry filename of nid %u: "
+ "%.*s -> %s\n", opt->nid, le16_to_cpu(dent->name_len),
+ name, opt->str);
+ memcpy(name, opt->str, namelen);
+ MSG(0, "Info: inject dentry namelen of nid %u: "
+ "%d -> %d\n", opt->nid, le16_to_cpu(dent->name_len),
+ namelen);
+ dent->name_len = cpu_to_le16(namelen);
+ dentry_hash = f2fs_dentry_hash(get_encoding(sbi),
+ IS_CASEFOLDED(inode),
+ (unsigned char *)name,
+ namelen);
+ MSG(0, "Info: inject dentry d_hash of nid %u: "
+ "0x%x -> 0x%x\n", opt->nid, le32_to_cpu(dent->hash_code),
+ dentry_hash);
+ dent->hash_code = cpu_to_le32(dentry_hash);
} else {
ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
ret = -EINVAL;
diff --git a/fsck/inject.h b/fsck/inject.h
index 43c21b56a7eb..706a211bc645 100644
--- a/fsck/inject.h
+++ b/fsck/inject.h
@@ -30,6 +30,7 @@ struct inject_option {
int cp; /* which cp */
int nat; /* which nat pack */
int sit; /* which sit pack */
+ int dots; /* . or .. dentry */
bool ssa;
bool node;
bool dent;
diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
index 72d1c90f7ce4..27b66f59b77d 100644
--- a/man/inject.f2fs.8
+++ b/man/inject.f2fs.8
@@ -214,7 +214,14 @@ inode i_nid array specified by \fIidx\fP.
.RE
.TP
.BI \-\-dent
-Inject dentry block or dir entry specified \fInid\fP.
+Inject dentry block or dir entry specified by \fInid\fP.
+.RS 1.2i
+.TP
+.BI \-\-dots " 1 or 2"
+The option means the "." or ".." directory entry of \fInid\fP is going to be injected.
+.RE
+.TP
+.BI ""
The available \fImb\fP of \fIdent\fP are:
.RS 1.2i
.TP
@@ -229,6 +236,9 @@ dentry ino.
.TP
.BI d_ftype
dentry ftype.
+.TP
+.BI filename
+dentry filename, and corresponding d_hash and namelen are updated implicitly.
.RE
.TP
.BI \-\-dry\-run
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 14/32] tests: prepare helper scripts for testcases
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (12 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 15/32] tests: add fsck testcase of fixing bad super magic Sheng Yong
` (18 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
This patch addes helper scripts for auto testcases, and testcases of
fsck will be submitted in the following commits.
The basic idea of these testcases are:
1. create f2fs image
2. corrupt the image by inject specific fields
3. fsck fixes the corrupted image
4. verify fsck output with expected message
The helper scripts include:
* test_config.in: is used to generate the basic configurations of all
testcases.
* runtests.in: is used to generate `runtests'.
* filter.sed: is used to remove unnecessary messages and cleanup
arbitrary values.
* helpers: provides helper functions
The usage of runtests:
* run all testcases:
runtests
* run one testcase:
runtests <testcase directory path>
* cleanup previous results:
runtests clean
Each testcase should have a sub-directory, where three files should be
included:
* README: describe information of the testcase
* script: testcase itself
* expect.in: expected output message
New files are generated in the testcase directory after test:
* log: output in detail
* expect: derived from expect.in
* out: output that will be compared with expect
* PASS: testcase is passed
* FAIL: testcase is failed
* SKIP: testcase is skipped
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
.gitignore | 14 +++
Makefile.am | 2 +-
configure.ac | 1 +
tests/Makefile.am | 26 +++++
tests/filter.sed | 69 +++++++++++
tests/helpers | 269 +++++++++++++++++++++++++++++++++++++++++++
tests/runtests.in | 48 ++++++++
tests/test_config.in | 53 +++++++++
8 files changed, 481 insertions(+), 1 deletion(-)
create mode 100644 tests/Makefile.am
create mode 100644 tests/filter.sed
create mode 100644 tests/helpers
create mode 100644 tests/runtests.in
create mode 100644 tests/test_config.in
diff --git a/.gitignore b/.gitignore
index 49809446793d..68dbe1c407c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,6 +46,8 @@ stamp-h1
/mkfs/mkfs.f2fs
/fsck/fsck.f2fs
+/fsck/dump.f2fs
+/fsck/inject.f2fs
/tools/fibmap.f2fs
/tools/parse.f2fs
/tools/f2fscrypt
@@ -54,3 +56,15 @@ stamp-h1
# cscope files
cscope.*
ncscope.*
+
+# testcase files
+tests/*/log
+tests/*/out
+tests/*/PASS
+tests/*/FAIL
+tests/*/SKIP
+tests/*/expect
+tests/meta.img
+tests/data.img
+tests/runtests
+tests/test_config
diff --git a/Makefile.am b/Makefile.am
index d2921d626e48..0c9ec66d02b6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,4 +2,4 @@
ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = man lib mkfs fsck tools
+SUBDIRS = man lib mkfs fsck tools tests
diff --git a/configure.ac b/configure.ac
index ddfc3b0f30e2..a819dde93ed1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -265,6 +265,7 @@ AC_CONFIG_FILES([
fsck/Makefile
tools/Makefile
tools/f2fs_io/Makefile
+ tests/Makefile
])
AC_CHECK_MEMBER([struct blk_zone.capacity],
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 000000000000..1b4dfdc70e44
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,26 @@
+## Makefile.am
+
+noinst_SCRIPTS = test_config runtests
+EXTRA_DIST = test_config.in runtests.in
+
+test_config: $(srcdir)/test_config.in
+ @echo "Creating test_config script..."
+ @[ -f test_config ] && chmod u+w test_config || true
+ @echo "#!/bin/bash" > test_config
+ @echo "" >> test_config
+ @echo "TOPDIR=@top_srcdir@" >> test_config
+ @cat $(srcdir)/test_config.in >> test_config
+ @chmod +x-w test_config
+
+runtests: $(srcdir)/runtests.in
+ @echo "Creating runtests script..."
+ @[ -f runtests ] && chmod u+w runtests || true
+ @echo "#!/bin/bash" > runtests
+ @echo "" >> runtests
+ @echo "SRCDIR=@srcdir@" >> runtests
+ @cat $(srcdir)/runtests.in >> runtests
+ @chmod +x-w runtests
+
+clean-local:
+ @[ -f runtests ] && ${SHELL} runtests clean || true
+ @rm -f $(noinst_SCRIPTS)
diff --git a/tests/filter.sed b/tests/filter.sed
new file mode 100644
index 000000000000..b2161a55d454
--- /dev/null
+++ b/tests/filter.sed
@@ -0,0 +1,69 @@
+# output messages that could be removed or ignored
+#
+# Note that some sed only supports POSIX Basic Regular Expression (BRE)
+# syntax. In BRE, metacharacters, for example '|', '\s', '\+', are not
+# supported. So BRE is recommended in this file.
+
+# remove messages which start with "^Info: ", expect for:
+# - Info: Automatic fix mode enabled
+# indicate that fsck -a is used.
+# - Info: Force to fix corruption
+# indicate that fsck -f is used.
+# - Info: No error was reported
+# indicate that fsck does not detect any errors.
+# - Info: checkpoint stop reason
+# - Info: fs errors
+# indicate that fsck detects error recorded in super block.
+/^Info: MKFS version/,+1d
+/^Info: FSCK version/,+2d
+/^Info: Host-managed zoned block device:/,+3d
+/^Info: /{
+ /Info: Automatic fix mode enabled/b out;
+ /Info: Force to fix corruption/b out;
+ /Info: No error was reported/b out;
+ /Info: checkpoint stop reason/b out;
+ /Info: fs errors/b out;
+ d
+}
+# e.g [update_block: 904] Info: Done to update superblock
+/^\[[a-zA-Z_][0-9a-zA-Z_]*:[[:space:]]*[0-9]\{1,\}\] Info: /d
+# e.g [INFO] (fsck_update_sb_flags:2389) --> Casefold: linear_lookup [enable]
+/^\[INFO\]/d
+
+# remove fsck statistics messages
+# e.g [FSCK] valid_block_count matching with CP [Ok..][0xc]
+/^\[FSCK\]/d
+
+# remove trivial messages
+/be careful to overwrite a mounted loopback file/d
+/^Done: [0-9\.]\{1,\} secs/d
+/^update nat(nid:.*) blkaddr \[.*\] in journal/d
+
+# some messages contain arbitrary numeric, ignore them
+# e.g [ASSERT] (is_valid_ssa_data_blk: 340) => [ASSERT] (is_valid_ssa_data_blk: x)
+s/\(\[ASSERT\] ([a-zA-Z_][0-9a-zA-Z_]*:[[:space:]]*\)[0-9]\{1,\})/\1x)/g
+# e.g [FIX] (nullify_nat_entry:3274) => [FIX] (nullify_nat_entry:x)
+s/\(\[FIX\] ([a-zA-Z_][0-9a-zA-Z_]*:[[:space:]]*\)[0-9]\{1,\})/\1x)/g
+# e.g [fsck_chk_quota_files:2242] => [fsck_chk_quota_files:x]
+s/^\(\[[a-zA-Z_][0-9a-zA-Z_]*:[[:space:]]*\)[0-9]\{1,\}\]/\1x\]/g
+
+# exceptions
+# the message is only shown on zoned device, but I don't find a better way
+# to keep this message in expect.in for both zoned and legacy UFS. So remove
+# it for now.
+/Reset write pointer of zone at segment/d
+
+# cut dump messages
+# e.g nid: 7 ino: 7 ver: 0 offset: 0 blkaddr: 28642878 pack:1 cp_ver:0xe42573115ffc7cfc =>
+# nid: 7 ino: 7 ver: 0 offset: 0
+s/\(^nid:.*\) blkaddr:[0-9]\{1,\} pack:[12] cp_ver:0x[0-9a-fA-F]\{1,\}/\1/g
+# e.g segno: 55968 vblocks:512 seg_type:1 mtime:0 sit_pack:2 =>
+# segno: 55968 vblocks:512 seg_type:1 mtime:0
+s/\(^segno:.*\) sit_pack:[12]/\1/g
+
+# keep the following at the end of the file
+:out
+# remove empty lines
+/^$/d
+# remove tail spaces
+s/[[:space:]]\{1,\}$//g
diff --git a/tests/helpers b/tests/helpers
new file mode 100644
index 000000000000..03853f803598
--- /dev/null
+++ b/tests/helpers
@@ -0,0 +1,269 @@
+#!/bin/bash
+
+OUT=$TESTDIR/out
+EXP=$TESTDIR/expect
+LOG=$TESTDIR/log
+
+# $1: string to be trimed
+trim_extra_space() {
+ local line=""
+ while IFS= read -r line; do
+ # trim multiple spaces as one
+ line=`echo "$line" | sed "s/[[:space:]]\{1,\}/ /g"`
+ # delete space in hex values
+ line=`echo "$line" | sed "s/0x /0x/g"`
+ # delete space before and after ":"
+ echo "$line" | sed "s/ *: */:/g"
+ done
+}
+
+# clean up temporary files
+cleanup() {
+ [ -f $TESTDIR/PASS ] && rm $TESTDIR/PASS || true
+ [ -f $TESTDIR/FAIL ] && rm $TESTDIR/FAIL || true
+ [ -f $TESTDIR/SKIP ] && rm $TESTDIR/SKIP || true
+ [ -f $TESTDIR/expect ] && rm $TESTDIR/expect || true
+ [ -f $OUT ] && rm $OUT || true
+ [ -f $LOG ] && rm $LOG || true
+}
+
+# check test result
+check_result() {
+ local NAME=`basename $TESTDIR`
+
+ if [ -e $TESTDIR/SKIP ]; then
+ echo "$NAME: $DESC: skip"
+ return
+ fi
+
+ if [ ! -e $EXP ]; then
+ cp "$EXP".in $EXP
+ fi
+ sed -f $FILTER -i $OUT
+ cmp -s $OUT $EXP
+ if [ x"$?" = x"0" ]; then
+ echo "$NAME: $DESC: pass"
+ touch $TESTDIR/PASS
+ else
+ echo "$NAME: $DESC: fail"
+ echo "diff $EXP $OUT"
+ diff $EXP $OUT > $TESTDIR/FAIL
+ exit
+ fi
+}
+
+# $1: dev path
+is_block_dev() {
+ if [ ! -e $1 ]; then
+ return 0
+ fi
+ local dev_real_path=`realpath $1`
+ if [ -b $dev_real_path ]; then
+ # dev is block device
+ return 1
+ fi
+ # dev is not block device
+ return 0
+}
+
+# $1: path of image file
+# $2: size in MB
+create_img_file() {
+ is_block_dev $1
+ if [ $? -eq 1 ]; then
+ # dev is block device, return directly
+ return
+ fi
+ truncate -s $2"M" $1
+}
+
+make_f2fs() {
+ local metasize=10
+ local datasize=118
+ local opts="$MKFS_OPTS"
+
+ if [ $SEGS_PER_SEC -gt 1 ]; then
+ metasize=$((3 * (SEGS_PER_SEC * 2)))
+ datasize=$((11 * (SEGS_PER_SEC * 2)))
+ opts="$MKFS_OPTS -s $SEGS_PER_SEC"
+ fi
+ if [ $MULTIDEV -eq 1 ]; then
+ create_img_file $META $metasize
+ create_img_file $DATA $datasize
+ opts = "$MKFS_OPTS -c $DATA"
+ else
+ create_img_file $META $((metasize + datasize))
+ fi
+
+ $MKFS $opts $META
+ if [ $? -ne 0 ]; then
+ echo "failed to format f2fs" >&2
+ exit
+ fi
+ $DUMP -d 1 $META
+}
+
+safe_mount() {
+ if [ $MULTIDEV -eq 1 ]; then
+ is_block_dev $DATA
+ if [ $? -eq 0 ]; then
+ # If multiple devices are used and DATA is not
+ # a block device, DATA should be associated to
+ # a loop device in advance.
+ # dump/fsck will check the path of the DATA
+ # device, to make them happy, replace devs[1].path
+ # with the loop device before mount, and restore
+ # it after umount.
+ local dev=`losetup -f`
+ losetup $dev $DATA
+ if [ $? -ne 0 ]; then
+ echo "cannot setup loop dev: losetup $dev $DATA" >&2
+ exit
+ fi
+ $INJECT --sb 1 --mb devs.path --idx 1 --str $dev $META
+ fi
+ fi
+
+ mount -t f2fs $*
+ if [ $? -ne 0 ]; then
+ echo "cannot mount f2fs image" >&2
+ exit
+ fi
+}
+
+# $1: mntpoint
+safe_umount() {
+ local max_retry=10
+ local dev=""
+ local i=0
+
+ umount $1
+ while [ $? -ne 0 ]; do
+ i=$((i + 1))
+ if [ $i -gt $max_retry ]; then
+ echo "cannot umount f2fs image" >&2
+ exit
+ fi
+ echo "cannot umount f2fs image, retry: $i"
+ sleep 1
+ umount $1
+ done
+
+ if [ ! -e $DATA ]; then
+ return
+ fi
+ dev=`losetup -j $DATA | cut -d ":" -f 1`
+ if [ x"$dev" != x"" ]; then
+ losetup -d $dev
+ # restore devs[1].path from $dev to $DATA
+ $INJECT --sb 1 --mb devs.path --idx 1 --str $DATA $META
+ fi
+}
+
+# $1: subject: cp, sb or node
+# $2: member of subject
+# $3: the number of output lines if there are multiple results, default is 1
+get_mb() {
+ if [ x"$3" = x"" ]; then
+ local nth=1
+ else
+ local nth=$3
+ fi
+ echo "$1" | grep "^$2" | awk "NR==$nth" | trim_extra_space
+}
+
+# $1: subject: cp, sb or node
+# $2: member of subject
+# $3: the number of output lines if there are multiple results, default is 1
+get_mb_val() {
+ if [ x"$3" = x"" ]; then
+ local nth=1
+ else
+ local nth=$3
+ fi
+ local val=`echo "$1" | grep "^$2" | awk "NR==$nth" | \
+ sed "s/^$2[[:space:]]*\[\(.*\)\]$/\1/g"`
+ echo "$val" | grep ":" > /dev/null
+ if [ $? -eq 0 ]; then
+ val=`echo $val | sed "s/.*:[[:space:]]*\([0-9]\{1,\}\)$/\1/g"`
+ fi
+ echo $val
+}
+
+# $1: device
+get_sb() {
+ local sb_cp="`$DUMP $DUMP_OPTS -d 1 $1`"
+ local cut_here=`echo "$sb_cp" | awk '/^\| Checkpoint/ {print NR}'`
+ local sb="`echo "$sb_cp" | head -n $((cut_here - 2))`"
+ echo "$sb"
+}
+
+# $1: device
+get_cp() {
+ local sb_cp="`$DUMP $DUMP_OPTS -d 1 $1`"
+ local cut_here=`echo "$sb_cp" | awk '/^\| Checkpoint/ {print NR}'`
+ local cp="`echo "$sb_cp" | tail -n +$((cut_here - 2))`"
+ echo "$cp"
+}
+
+# $1: blkaddr
+get_segno() {
+ local sb=`get_sb $META`
+ local main_blkaddr=`get_mb_val "$sb" main_blkaddr`
+ local log_blks_per_seg=`get_mb_val "$sb" log_blocks_per_seg`
+ echo $((($1 - main_blkaddr) >> log_blks_per_seg))
+}
+
+# $1: segno
+start_block() {
+ local sb=`get_sb $META`
+ local main_blkaddr=`get_mb_val "$sb" main_blkaddr`
+ local log_blks_per_seg=`get_mb_val "$sb" log_blocks_per_seg`
+ echo $((main_blkaddr + ($1 << log_blks_per_seg)))
+}
+
+# $1: blkaddr
+offset_in_seg() {
+ local sb=`get_sb $META`
+ local main_blkaddr=`get_mb_val "$sb" main_blkaddr`
+ local log_blks_per_seg=`get_mb_val "$sb" log_blocks_per_seg`
+ echo $((($1 - main_blkaddr) % (1 << log_blks_per_seg)))
+}
+
+# reference INIT_FEATURE_TABLE
+# $1: feature
+test_sb_feature() {
+ local sb=`get_sb $META`
+ local feats=`get_mb_val "$sb" feature`
+ case $1 in
+ "encrypt")
+ return $((!!(feats & 0x1)));;
+ "blkzoned")
+ return $((!!(feats & 0x2)));;
+ "extra_attr")
+ return $((!!(feats & 0x8)));;
+ "project_quota")
+ return $((!!(feats & 0x10)));;
+ "inode_checksum")
+ return $((!!(feats & 0x20)));;
+ "flexible_inline_xattr")
+ return $((!!(feats & 0x40)));;
+ "quota")
+ return $((!!(feats & 0x80)));;
+ "inode_crtime")
+ return $((!!(feats & 0x100)));;
+ "lost_found")
+ return $((!!(feats & 0x200)));;
+ "verity")
+ return $((!!(feats & 0x400)));;
+ "sb_checksum")
+ return $((!!(feats & 0x800)));;
+ "casefold")
+ return $((!!(feats & 0x1000)));;
+ "compression")
+ return $((!!(feats & 0x2000)));;
+ "ro")
+ return $((!!(feats & 0x4000)));;
+ esac
+ return 0
+}
diff --git a/tests/runtests.in b/tests/runtests.in
new file mode 100644
index 000000000000..29db79a4a95c
--- /dev/null
+++ b/tests/runtests.in
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# run testcases
+#
+# run all testcases:
+# runtests
+#
+# run one testcase:
+# runtests <testcase directory path>
+#
+# cleanup:
+# runtests clean
+#
+
+# clean temporary files
+if [ x"$1" = x"clean" ]; then
+ find $SRCDIR \( -name FAIL -o -name PASS -o -name SKIP -o \
+ -name expect -o -name log -o -name out -o \
+ -name meta.img -o -name data.img \) -exec rm -f {} \;
+ exit
+fi
+
+TEST_CONFIG=$SRCDIR/test_config
+. $TEST_CONFIG
+
+# $1: path of testcase path
+run_one_test() {
+ local subdir=`realpath $1`
+ local name=`basename $subdir`
+ echo "Run testcase: $name ..."
+ TESTDIR=$subdir
+ . $subdir/script
+ echo ""
+}
+
+# run one testcase
+# $1: testcase path
+if [ x"$1" != x"" ]; then
+ run_one_test $1
+ exit
+fi
+
+# run all testcases
+TESTS=`find ./ -type f -name script`
+for testcase in ${TESTS[@]}; do
+ subdir=`dirname $testcase`
+ run_one_test $subdir
+done
diff --git a/tests/test_config.in b/tests/test_config.in
new file mode 100644
index 000000000000..41ce50052197
--- /dev/null
+++ b/tests/test_config.in
@@ -0,0 +1,53 @@
+#!/bin/bash
+#
+# Test Configuration
+#
+
+check_executable() {
+ file $1 | grep ELF > /dev/null
+ [ $? -ne 0 ] && { echo "ERROR: $1 not ELF"; exit; }
+}
+
+check_diff() {
+ diff $1 $2 > /dev/null
+ [ $? -ne 0 ] && { echo "WARNING: $1 and $2 differ"; }
+}
+
+# path of devices
+# If multiple devices are used, META is the first device and DATA is the
+# second device. If there is only one device, META is used only.
+META=`realpath $TOPDIR/tests/meta.img`
+DATA=`realpath $TOPDIR/tests/data.img`
+
+# path of tools
+MKFS="$TOPDIR/mkfs/mkfs.f2fs"
+FSCK="$TOPDIR/fsck/fsck.f2fs"
+DUMP="$TOPDIR/fsck/dump.f2fs"
+INJECT="$TOPDIR/fsck/inject.f2fs"
+F2FS_IO="$TOPDIR/tools/f2fs_io/f2fs_io"
+FILTER="$TOPDIR/tests/filter.sed"
+[ ! -e $MKFS ] && { echo "$MKFS not exist"; exit; }
+[ ! -e $FSCK ] && { echo "$FSCK not exist"; exit; }
+check_executable $FSCK
+[ ! -e $DUMP ] && { cp $FSCK $DUMP; }
+check_executable $DUMP
+check_diff $FSCK $DUMP
+[ ! -e $F2FS_IO ] && { echo "$F2FS_IO not exist"; exit; }
+[ ! -e $INJECT ] && { cp $FSCK $INJECT; }
+check_executable $INJECT
+check_diff $FSCK $INJECT
+
+# config of mkfs
+F2FS_FEATURES="encrypt,quota,project_quota,extra_attr,verity,compression"
+MKFS_OPTS="-O $F2FS_FEATURES -f"
+MULTIDEV=0
+SEGS_PER_SEC=1
+
+# config of fsck
+FSCK_OPTS="--no-kernel-check -N"
+
+# config of dump
+DUMP_OPTS="-N"
+
+# config of mount
+MNT_OPTS=""
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 15/32] tests: add fsck testcase of fixing bad super magic
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (13 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 14/32] tests: prepare helper scripts for testcases Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 16/32] tests: add fsck testcase of fixing errors recorded in sb Sheng Yong
` (17 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_sb_bad_magic/README | 3 +++
tests/f_sb_bad_magic/expect.in | 5 +++++
tests/f_sb_bad_magic/script | 15 +++++++++++++++
3 files changed, 23 insertions(+)
create mode 100644 tests/f_sb_bad_magic/README
create mode 100644 tests/f_sb_bad_magic/expect.in
create mode 100644 tests/f_sb_bad_magic/script
diff --git a/tests/f_sb_bad_magic/README b/tests/f_sb_bad_magic/README
new file mode 100644
index 000000000000..a8887ebd2dfb
--- /dev/null
+++ b/tests/f_sb_bad_magic/README
@@ -0,0 +1,3 @@
+1. create f2fs image
+2. inject magic in sb 1 with value 0x12345
+3. fsck fixes bad magic by copying sb 2
diff --git a/tests/f_sb_bad_magic/expect.in b/tests/f_sb_bad_magic/expect.in
new file mode 100644
index 000000000000..3dcfa1f7e46e
--- /dev/null
+++ b/tests/f_sb_bad_magic/expect.in
@@ -0,0 +1,5 @@
+Info: Force to fix corruption
+Magic Mismatch, valid(0xf2f52010) - read(0x12345)
+ Can't find a valid F2FS superblock at 0x0
+Looking for secondary superblock assuming 4K Block Size
+Info: Force to fix corruption
diff --git a/tests/f_sb_bad_magic/script b/tests/f_sb_bad_magic/script
new file mode 100644
index 000000000000..0a5d708af2d6
--- /dev/null
+++ b/tests/f_sb_bad_magic/script
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+DESC="superblock[1] with invalid magic number"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+$INJECT --sb 1 --mb magic --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 16/32] tests: add fsck testcase of fixing errors recorded in sb
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (14 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 15/32] tests: add fsck testcase of fixing bad super magic Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 17/32] tests: add fsck testcase of fixing cp crc Sheng Yong
` (16 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_sb_errors/README | 5 +++++
tests/f_sb_errors/expect.in | 7 +++++++
tests/f_sb_errors/script | 22 ++++++++++++++++++++++
3 files changed, 34 insertions(+)
create mode 100644 tests/f_sb_errors/README
create mode 100644 tests/f_sb_errors/expect.in
create mode 100644 tests/f_sb_errors/script
diff --git a/tests/f_sb_errors/README b/tests/f_sb_errors/README
new file mode 100644
index 000000000000..df118e825aac
--- /dev/null
+++ b/tests/f_sb_errors/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. inject s_stop_reason in super block
+3. fsck -a detects error and clear the error
+4. inject s_errors in super block
+5. fsck -a detects error and clear the error
diff --git a/tests/f_sb_errors/expect.in b/tests/f_sb_errors/expect.in
new file mode 100644
index 000000000000..7985a28e59ab
--- /dev/null
+++ b/tests/f_sb_errors/expect.in
@@ -0,0 +1,7 @@
+Info: Automatic fix mode enabled.
+Info: checkpoint stop reason: fault_inject(1)
+Info: Automatic fix mode enabled.
+Info: fs errors: fail_decompression
+Info: Automatic fix mode enabled.
+Info: No error was reported
+Info: Force to fix corruption
diff --git a/tests/f_sb_errors/script b/tests/f_sb_errors/script
new file mode 100644
index 000000000000..d625900192ff
--- /dev/null
+++ b/tests/f_sb_errors/script
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+DESC="superblock[1] with s_stop_reason and s_errors"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+$INJECT --sb 1 --mb s_stop_reason --idx 1 --val 1 $META >> $LOG
+$FSCK $FSCK_OPTS -a $META > $OUT
+
+$INJECT --sb 1 --mb s_errors --idx 0 --val 2 $META >> $LOG
+$FSCK $FSCK_OPTS -a $META >> $OUT
+
+# both -a and -f cannot detect errors
+$FSCK $FSCK_OPTS -a $META >> $OUT
+echo "" >> $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 17/32] tests: add fsck testcase of fixing cp crc
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (15 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 16/32] tests: add fsck testcase of fixing errors recorded in sb Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 18/32] tests: add fsck testcase of fixing nat entry with invalid ino Sheng Yong
` (15 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_cp_bad_crc/README | 5 +++++
tests/f_cp_bad_crc/expect.in | 4 ++++
tests/f_cp_bad_crc/script | 38 ++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
create mode 100644 tests/f_cp_bad_crc/README
create mode 100644 tests/f_cp_bad_crc/expect.in
create mode 100644 tests/f_cp_bad_crc/script
diff --git a/tests/f_cp_bad_crc/README b/tests/f_cp_bad_crc/README
new file mode 100644
index 000000000000..250ece3f8b5a
--- /dev/null
+++ b/tests/f_cp_bad_crc/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. create a new file
+3. inject crc in current cp with value 0x12345
+4. fsck fixes bad cp by copying backup cp
+5. compare cp1 version with cp2 version, both cp should have the same version
diff --git a/tests/f_cp_bad_crc/expect.in b/tests/f_cp_bad_crc/expect.in
new file mode 100644
index 000000000000..d21fdab7304a
--- /dev/null
+++ b/tests/f_cp_bad_crc/expect.in
@@ -0,0 +1,4 @@
+Info: Automatic fix mode enabled.
+ Invalid CP CRC: offset:_OFFS_, crc:0x12345, calc:_CRC_
+Info: Automatic fix mode enabled.
+Info: No error was reported
diff --git a/tests/f_cp_bad_crc/script b/tests/f_cp_bad_crc/script
new file mode 100644
index 000000000000..b5181614f537
--- /dev/null
+++ b/tests/f_cp_bad_crc/script
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+DESC="current cp with invalid crc"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+touch $TESTDIR/mntdir/testfile
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+cp=`get_cp $META`
+offs=`get_mb_val "$cp" checksum_offset`
+crc=`get_mb_val "$cp" '\<checksum\>'`
+
+echo "crc:$crc offs:$offs" >> $LOG
+
+$INJECT --cp 0 --mb crc --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -a $META > $OUT
+$FSCK $FSCK_OPTS -a $META >> $OUT
+
+cp1_ver=`$INJECT --cp 1 --mb checkpoint_ver --val 0 --dry-run $META | grep "inject checkpoint_ver of cp" | awk '{print $(NF-2)}'`
+cp2_ver=`$INJECT --cp 2 --mb checkpoint_ver --val 0 --dry-run $META | grep "inject checkpoint_ver of cp" | awk '{print $(NF-2)}'`
+if [ $((cp1_ver)) -ne $((cp2_ver)) ]; then
+ echo "cp1_ver: $cp1_ver" >> $OUT
+ echo "cp2_ver: $cp2_ver" >> $OUT
+fi
+cat $OUT >> $LOG
+
+CRC=`printf "0x%x" $crc`
+sed "s/_CRC_/$CRC/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_OFFS_/$offs/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 18/32] tests: add fsck testcase of fixing nat entry with invalid ino
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (16 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 17/32] tests: add fsck testcase of fixing cp crc Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 19/32] tests: add fsck testcase of fixing nat entry with invalid blkaddr Sheng Yong
` (14 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_nat_bad_ino/README | 4 ++++
tests/f_nat_bad_ino/expect.in | 12 ++++++++++++
tests/f_nat_bad_ino/script | 31 +++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
create mode 100644 tests/f_nat_bad_ino/README
create mode 100644 tests/f_nat_bad_ino/expect.in
create mode 100644 tests/f_nat_bad_ino/script
diff --git a/tests/f_nat_bad_ino/README b/tests/f_nat_bad_ino/README
new file mode 100644
index 000000000000..b97015297b25
--- /dev/null
+++ b/tests/f_nat_bad_ino/README
@@ -0,0 +1,4 @@
+1. create f2fs image
+2. mount f2fs and create a regular file
+3. inject ino in nat entry with value 0x12345 of the regular file
+4. fsck fixes the nat entry by nullifying it
diff --git a/tests/f_nat_bad_ino/expect.in b/tests/f_nat_bad_ino/expect.in
new file mode 100644
index 000000000000..4a70b0b27cff
--- /dev/null
+++ b/tests/f_nat_bad_ino/expect.in
@@ -0,0 +1,12 @@
+Info: Force to fix corruption
+[ASSERT] (sanity_check_nid: x) --> nid[_INO_] nat_entry->ino[0x12345] footer.ino[_INO_]
+[FIX] (__chk_dentries:x) --> Unlink [_INO_] - testfile len[0x8], type[0x1]
+[fsck_chk_quota_files:x] Fixing Quota file ([ 0] ino [0x4])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x4] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 1] ino [0x5])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x5] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 2] ino [0x6])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x6] in NAT
+NID[_INO_] is unreachable, blkaddr:_BLK_
+[FIX] (nullify_nat_entry:x) --> Remove nid [_INO_] in NAT
+Info: Force to fix corruption
diff --git a/tests/f_nat_bad_ino/script b/tests/f_nat_bad_ino/script
new file mode 100644
index 000000000000..ded5b2a602fb
--- /dev/null
+++ b/tests/f_nat_bad_ino/script
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+DESC="nat entry with invalid ino"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+touch $TESTDIR/mntdir/testfile
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+blk=`$DUMP $DUMP_OPTS -i $ino -d 1 $META | grep nat_entry.block_addr | \
+ sed 's/.*nat_entry\.block_addr[[:space:]]*\[\(0x[0-9a-f]\{1,\}\)\]/\1/g'`
+
+echo "ino:$ino blk:$blk" >> $LOG
+
+$INJECT --nat 0 --nid $ino --mb ino --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+INO=`printf "0x%x" $ino`
+sed "s/_INO_/$INO/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_BLK_/$blk/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 19/32] tests: add fsck testcase of fixing nat entry with invalid blkaddr
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (17 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 18/32] tests: add fsck testcase of fixing nat entry with invalid ino Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 20/32] tests: add fsck testcase of fixing sit entry type Sheng Yong
` (13 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_nat_bad_blkaddr/README | 4 ++++
tests/f_nat_bad_blkaddr/expect.in | 12 ++++++++++++
tests/f_nat_bad_blkaddr/script | 25 +++++++++++++++++++++++++
3 files changed, 41 insertions(+)
create mode 100644 tests/f_nat_bad_blkaddr/README
create mode 100644 tests/f_nat_bad_blkaddr/expect.in
create mode 100644 tests/f_nat_bad_blkaddr/script
diff --git a/tests/f_nat_bad_blkaddr/README b/tests/f_nat_bad_blkaddr/README
new file mode 100644
index 000000000000..1545fb0fb342
--- /dev/null
+++ b/tests/f_nat_bad_blkaddr/README
@@ -0,0 +1,4 @@
+1. create f2fs image
+2. mount f2fs and create a regular file
+3. inject block_addr in nat entry with value 0x12345 of the regular file
+4. fsck fixes the nat entry by nullifying it
diff --git a/tests/f_nat_bad_blkaddr/expect.in b/tests/f_nat_bad_blkaddr/expect.in
new file mode 100644
index 000000000000..321aa14887ba
--- /dev/null
+++ b/tests/f_nat_bad_blkaddr/expect.in
@@ -0,0 +1,12 @@
+Info: Force to fix corruption
+[ASSERT] (sanity_check_nat: x) --> blkaddress is not valid. [0x12345]
+[FIX] (__chk_dentries:x) --> Unlink [_INO_] - testfile len[0x8], type[0x1]
+[fsck_chk_quota_files:x] Fixing Quota file ([ 0] ino [0x4])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x4] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 1] ino [0x5])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x5] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 2] ino [0x6])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x6] in NAT
+NID[_INO_] is unreachable, blkaddr:0x12345
+[FIX] (nullify_nat_entry:x) --> Remove nid [_INO_] in NAT
+Info: Force to fix corruption
diff --git a/tests/f_nat_bad_blkaddr/script b/tests/f_nat_bad_blkaddr/script
new file mode 100644
index 000000000000..d3ac65fb4f51
--- /dev/null
+++ b/tests/f_nat_bad_blkaddr/script
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+DESC="nat entry with invalid block_addr"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+touch $TESTDIR/mntdir/testfile
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+$INJECT --nat 0 --nid $ino --mb block_addr --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+INO=`printf "0x%x" $ino`
+sed "s/_INO_/$INO/g" $TESTDIR/expect.in > $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 20/32] tests: add fsck testcase of fixing sit entry type
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (18 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 19/32] tests: add fsck testcase of fixing nat entry with invalid blkaddr Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 21/32] tests: add fsck testcase of fixing sit entry vblocks Sheng Yong
` (12 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_sit_bad_type/README | 5 +++++
tests/f_sit_bad_type/expect.in | 3 +++
tests/f_sit_bad_type/script | 38 ++++++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+)
create mode 100644 tests/f_sit_bad_type/README
create mode 100644 tests/f_sit_bad_type/expect.in
create mode 100644 tests/f_sit_bad_type/script
diff --git a/tests/f_sit_bad_type/README b/tests/f_sit_bad_type/README
new file mode 100644
index 000000000000..e0a1726528c0
--- /dev/null
+++ b/tests/f_sit_bad_type/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject type in the sit entry of the blkaddr and change its type to NODE
+5. fsck fixes the type to DATA
diff --git a/tests/f_sit_bad_type/expect.in b/tests/f_sit_bad_type/expect.in
new file mode 100644
index 000000000000..b207ff7c6c22
--- /dev/null
+++ b/tests/f_sit_bad_type/expect.in
@@ -0,0 +1,3 @@
+Info: Force to fix corruption
+[FIX] (check_sit_types:x) --> Wrong segment type [_SEGNO_] 3 -> 1
+Info: Force to fix corruption
diff --git a/tests/f_sit_bad_type/script b/tests/f_sit_bad_type/script
new file mode 100644
index 000000000000..a1c7c402181d
--- /dev/null
+++ b/tests/f_sit_bad_type/script
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+DESC="sit entry with invalid type"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+
+SIT_VBLOCKS_SHIFT=10
+SIT_VBLOCKS_MASK=$(((1 << SIT_VBLOCKS_SHIFT) - 1))
+val=`$INJECT --dry-run --sit 0 --blk $blkaddr --mb vblocks $META | \
+ grep "inject sit entry vblocks" | awk '{print $(NF-2)}'`
+vblocks=$((val & SIT_VBLOCKS_MASK))
+val=$((vblocks | (0x3 << SIT_VBLOCKS_SHIFT)))
+
+$INJECT --sit 0 --blk $blkaddr --mb vblocks --val $val $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+segno=`get_segno $blkaddr`
+SEGNO=`printf "0x%x" $segno`
+sed "s/_SEGNO_/$SEGNO/g" $TESTDIR/expect.in > $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 21/32] tests: add fsck testcase of fixing sit entry vblocks
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (19 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 20/32] tests: add fsck testcase of fixing sit entry type Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 22/32] tests: add fsck testcase of fixing sit entry valid_map Sheng Yong
` (11 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_sit_bad_vblocks/README | 5 ++++
tests/f_sit_bad_vblocks/expect.in | 3 +++
tests/f_sit_bad_vblocks/script | 38 +++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+)
create mode 100644 tests/f_sit_bad_vblocks/README
create mode 100644 tests/f_sit_bad_vblocks/expect.in
create mode 100644 tests/f_sit_bad_vblocks/script
diff --git a/tests/f_sit_bad_vblocks/README b/tests/f_sit_bad_vblocks/README
new file mode 100644
index 000000000000..4ca21c766b2d
--- /dev/null
+++ b/tests/f_sit_bad_vblocks/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject vblocks in the sit entry of the blkaddr by subtracting 1
+5. fsck fixes the vblocks
diff --git a/tests/f_sit_bad_vblocks/expect.in b/tests/f_sit_bad_vblocks/expect.in
new file mode 100644
index 000000000000..9e31f38c458b
--- /dev/null
+++ b/tests/f_sit_bad_vblocks/expect.in
@@ -0,0 +1,3 @@
+Info: Force to fix corruption
+[ASSERT] (check_block_count:x) --> Wrong SIT valid blocks: segno=_SEGNO_, 511 vs. 512
+Info: Force to fix corruption
diff --git a/tests/f_sit_bad_vblocks/script b/tests/f_sit_bad_vblocks/script
new file mode 100644
index 000000000000..6dd684555011
--- /dev/null
+++ b/tests/f_sit_bad_vblocks/script
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+DESC="sit entry with invalid vblocks"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+
+SIT_VBLOCKS_SHIFT=10
+SIT_VBLOCKS_MASK=$(((1 << SIT_VBLOCKS_SHIFT) - 1))
+val=`$INJECT --dry-run --sit 0 --blk $blkaddr --mb vblocks $META | \
+ grep "inject sit entry vblocks" | awk '{print $(NF-2)}'`
+vblocks=$((val & SIT_VBLOCKS_MASK))
+val=$(((val & ~SIT_VBLOCKS_MASK) | (vblocks - 1)))
+
+$INJECT --sit 0 --blk $blkaddr --mb vblocks --val $val $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+segno=`get_segno $blkaddr`
+SEGNO=`printf "0x%x" $segno`
+sed "s/_SEGNO_/$SEGNO/g" $TESTDIR/expect.in > $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 22/32] tests: add fsck testcase of fixing sit entry valid_map
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (20 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 21/32] tests: add fsck testcase of fixing sit entry vblocks Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 23/32] tests: add fsck testcase of fixing sum entry nid Sheng Yong
` (10 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_sit_bad_valid_map/README | 5 ++++
tests/f_sit_bad_valid_map/expect.in | 4 +++
tests/f_sit_bad_valid_map/script | 43 +++++++++++++++++++++++++++++
3 files changed, 52 insertions(+)
create mode 100644 tests/f_sit_bad_valid_map/README
create mode 100644 tests/f_sit_bad_valid_map/expect.in
create mode 100644 tests/f_sit_bad_valid_map/script
diff --git a/tests/f_sit_bad_valid_map/README b/tests/f_sit_bad_valid_map/README
new file mode 100644
index 000000000000..5306bdd31ae5
--- /dev/null
+++ b/tests/f_sit_bad_valid_map/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject bitmap in the sit entry of the blkaddr by clearing its bit
+5. fsck fixes the bitmap
diff --git a/tests/f_sit_bad_valid_map/expect.in b/tests/f_sit_bad_valid_map/expect.in
new file mode 100644
index 000000000000..b9929839707e
--- /dev/null
+++ b/tests/f_sit_bad_valid_map/expect.in
@@ -0,0 +1,4 @@
+Info: Force to fix corruption
+[ASSERT] (check_block_count:x) --> Wrong SIT valid blocks: segno=_SEGNO_, 512 vs. 511
+[ASSERT] (fsck_chk_data_blk:x) --> SIT bitmap is 0x0. blk_addr[_BLKADDR_]
+Info: Force to fix corruption
diff --git a/tests/f_sit_bad_valid_map/script b/tests/f_sit_bad_valid_map/script
new file mode 100644
index 000000000000..8ce0b2016a9c
--- /dev/null
+++ b/tests/f_sit_bad_valid_map/script
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+DESC="sit entry with invalid valid_map"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+
+offs=`offset_in_seg $blkaddr`
+idx=$((offs >> 3))
+mask=$((1 << (7 - (offs & 0x7))))
+
+val=`$INJECT --dry-run --sit 0 --blk $blkaddr --mb valid_map --idx $idx $META | \
+ grep "inject sit entry valid_map" | awk '{print $(NF-2)}'`
+echo "valid_map:$val mask:$mask" >> $LOG
+val=$((val & (~mask & 0xff)))
+echo "corrupt_map:$val" >> $LOG
+
+$INJECT --sit 0 --blk $blkaddr --mb valid_map --idx $idx --val $val $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+BLKADDR=`printf "0x%x" $blkaddr`
+segno=`get_segno $blkaddr`
+SEGNO=`printf "0x%x" $segno`
+sed "s/_BLKADDR_/$BLKADDR/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_SEGNO_/$SEGNO/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 23/32] tests: add fsck testcase of fixing sum entry nid
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (21 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 22/32] tests: add fsck testcase of fixing sit entry valid_map Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 24/32] tests: add fsck testcase of fixing sum footer type Sheng Yong
` (9 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_ssa_bad_nid/README | 5 +++++
tests/f_ssa_bad_nid/expect.in | 3 +++
tests/f_ssa_bad_nid/script | 36 +++++++++++++++++++++++++++++++++++
3 files changed, 44 insertions(+)
create mode 100644 tests/f_ssa_bad_nid/README
create mode 100644 tests/f_ssa_bad_nid/expect.in
create mode 100644 tests/f_ssa_bad_nid/script
diff --git a/tests/f_ssa_bad_nid/README b/tests/f_ssa_bad_nid/README
new file mode 100644
index 000000000000..d30e41c77c63
--- /dev/null
+++ b/tests/f_ssa_bad_nid/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject nid in the ssa entry of the blkaddr with an unused nid
+5. fsck fixes the ssa entry
diff --git a/tests/f_ssa_bad_nid/expect.in b/tests/f_ssa_bad_nid/expect.in
new file mode 100644
index 000000000000..3164031aebae
--- /dev/null
+++ b/tests/f_ssa_bad_nid/expect.in
@@ -0,0 +1,3 @@
+Info: Force to fix corruption
+[ASSERT] (is_valid_ssa_data_blk: x) --> Set data summary _SEGNO_ -> [_INO_] [0x0] [_OFS_IN_NODE_]
+Info: Force to fix corruption
diff --git a/tests/f_ssa_bad_nid/script b/tests/f_ssa_bad_nid/script
new file mode 100644
index 000000000000..a5322c85956a
--- /dev/null
+++ b/tests/f_ssa_bad_nid/script
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+DESC="ssa entry with invalid nid"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+base=`echo "$node" | grep i_addr | head -n 1 | sed 's/i_addr\[\(0x[0-9a-f]\{1,\}\)\].*$/\1/g'`
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+
+$INJECT --ssa --blk $blkaddr --mb nid --val $((ino + 100)) $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+segno=`get_segno $blkaddr`
+SEGNO=`printf "0x%x" $segno`
+INO=`printf "0x%x" $ino`
+OFS_IN_NODE=`printf "0x%x" $((0x100 - base))`
+sed "s/_SEGNO_/$SEGNO/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_INO_/$INO/g" $TESTDIR/expect
+sed -i "s/_OFS_IN_NODE_/$OFS_IN_NODE/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 24/32] tests: add fsck testcase of fixing sum footer type
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (22 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 23/32] tests: add fsck testcase of fixing sum entry nid Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 25/32] tests: add fsck testcase of fixing sum entry ofs_in_node Sheng Yong
` (8 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_ssa_bad_type/README | 5 +++++
tests/f_ssa_bad_type/expect.in | 3 +++
tests/f_ssa_bad_type/script | 31 +++++++++++++++++++++++++++++++
3 files changed, 39 insertions(+)
create mode 100644 tests/f_ssa_bad_type/README
create mode 100644 tests/f_ssa_bad_type/expect.in
create mode 100644 tests/f_ssa_bad_type/script
diff --git a/tests/f_ssa_bad_type/README b/tests/f_ssa_bad_type/README
new file mode 100644
index 000000000000..358c0c5ab284
--- /dev/null
+++ b/tests/f_ssa_bad_type/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject footer entry_type in the summary block of the blkaddr and change it to NODE
+5. fsck fixes the footer
diff --git a/tests/f_ssa_bad_type/expect.in b/tests/f_ssa_bad_type/expect.in
new file mode 100644
index 000000000000..0b6cd6684a32
--- /dev/null
+++ b/tests/f_ssa_bad_type/expect.in
@@ -0,0 +1,3 @@
+Info: Force to fix corruption
+[ASSERT] (is_valid_ssa_data_blk: x) --> Summary footer indicates a data segment: _SEGNO_
+Info: Force to fix corruption
diff --git a/tests/f_ssa_bad_type/script b/tests/f_ssa_bad_type/script
new file mode 100644
index 000000000000..31c237779d13
--- /dev/null
+++ b/tests/f_ssa_bad_type/script
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+DESC="ssa block footer with invalid type"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+
+$INJECT --ssa --blk $blkaddr --mb entry_type --val 1 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+segno=`get_segno $blkaddr`
+SEGNO=`printf "0x%x" $segno`
+sed "s/_SEGNO_/$SEGNO/g" $TESTDIR/expect.in > $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 25/32] tests: add fsck testcase of fixing sum entry ofs_in_node
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (23 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 24/32] tests: add fsck testcase of fixing sum footer type Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 26/32] tests: add fsck testcase of fixing inode invalid i_addr Sheng Yong
` (7 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_ssa_bad_ofs_in_node/README | 5 ++++
tests/f_ssa_bad_ofs_in_node/expect.in | 3 +++
tests/f_ssa_bad_ofs_in_node/script | 36 +++++++++++++++++++++++++++
3 files changed, 44 insertions(+)
create mode 100644 tests/f_ssa_bad_ofs_in_node/README
create mode 100644 tests/f_ssa_bad_ofs_in_node/expect.in
create mode 100644 tests/f_ssa_bad_ofs_in_node/script
diff --git a/tests/f_ssa_bad_ofs_in_node/README b/tests/f_ssa_bad_ofs_in_node/README
new file mode 100644
index 000000000000..65fbf6aa4f1b
--- /dev/null
+++ b/tests/f_ssa_bad_ofs_in_node/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject ofs_in_node in the ssa entry of the blkaddr
+5. fsck fixes the ssa entry
diff --git a/tests/f_ssa_bad_ofs_in_node/expect.in b/tests/f_ssa_bad_ofs_in_node/expect.in
new file mode 100644
index 000000000000..3164031aebae
--- /dev/null
+++ b/tests/f_ssa_bad_ofs_in_node/expect.in
@@ -0,0 +1,3 @@
+Info: Force to fix corruption
+[ASSERT] (is_valid_ssa_data_blk: x) --> Set data summary _SEGNO_ -> [_INO_] [0x0] [_OFS_IN_NODE_]
+Info: Force to fix corruption
diff --git a/tests/f_ssa_bad_ofs_in_node/script b/tests/f_ssa_bad_ofs_in_node/script
new file mode 100644
index 000000000000..1f5a60a2d342
--- /dev/null
+++ b/tests/f_ssa_bad_ofs_in_node/script
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+DESC="ssa entry with invalid ofs_in_node"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+base=`echo "$node" | grep i_addr | head -n 1 | sed 's/i_addr\[\(0x[0-9a-f]\{1,\}\)\].*$/\1/g'`
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+
+$INJECT --ssa --blk $blkaddr --mb ofs_in_node --val 99 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+segno=`get_segno $blkaddr`
+SEGNO=`printf "0x%x" $segno`
+INO=`printf "0x%x" $ino`
+OFS_IN_NODE=`printf "0x%x" $((0x100 - base))`
+sed "s/_SEGNO_/$SEGNO/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_INO_/$INO/g" $TESTDIR/expect
+sed -i "s/_OFS_IN_NODE_/$OFS_IN_NODE/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 26/32] tests: add fsck testcase of fixing inode invalid i_addr
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (24 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 25/32] tests: add fsck testcase of fixing sum entry ofs_in_node Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 27/32] tests: add fsck testcase of fixing dentry hash code Sheng Yong
` (6 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_inode_bad_iaddr/README | 6 ++++
tests/f_inode_bad_iaddr/expect.in | 13 ++++++++
tests/f_inode_bad_iaddr/script | 50 +++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+)
create mode 100644 tests/f_inode_bad_iaddr/README
create mode 100644 tests/f_inode_bad_iaddr/expect.in
create mode 100644 tests/f_inode_bad_iaddr/script
diff --git a/tests/f_inode_bad_iaddr/README b/tests/f_inode_bad_iaddr/README
new file mode 100644
index 000000000000..5ada3226ab5d
--- /dev/null
+++ b/tests/f_inode_bad_iaddr/README
@@ -0,0 +1,6 @@
+1. create f2fs image
+2. mount f2fs and create a regular file and write data
+3. get a block address by dumping the inode
+4. inject i_addr[0x100] of the inode with an invalid value
+5. fsck fixes the inode by nullify i_addr[0x100]
+6. check if i_addr[0x100] is 0
diff --git a/tests/f_inode_bad_iaddr/expect.in b/tests/f_inode_bad_iaddr/expect.in
new file mode 100644
index 000000000000..4a79f671a651
--- /dev/null
+++ b/tests/f_inode_bad_iaddr/expect.in
@@ -0,0 +1,13 @@
+Info: Force to fix corruption
+[ASSERT] (fsck_chk_data_blk:x) --> blkaddress is not valid. [0x12345]
+[FIX] (fsck_chk_inode_blk:x) --> [_INO_] i_addr[256] = NULL_ADDR
+[ASSERT] (fsck_chk_inode_blk:x) --> ino: _INO_ has wrong ext: [pgofs:_PGOFS_, blk:_BLK_, len:_LEN_]
+[ASSERT] (fsck_chk_inode_blk:x) --> ino: _INO_ has i_blocks: 0x00000202, but has 0x201 blocks
+[FIX] (fsck_chk_inode_blk:x) --> [_INO_] i_blocks=0x00000202 -> 0x201
+[fsck_chk_quota_files:x] Fixing Quota file ([ 0] ino [0x4])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x4] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 1] ino [0x5])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x5] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 2] ino [0x6])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x6] in NAT
+Info: Force to fix corruption
diff --git a/tests/f_inode_bad_iaddr/script b/tests/f_inode_bad_iaddr/script
new file mode 100644
index 000000000000..7c9e67d0eccc
--- /dev/null
+++ b/tests/f_inode_bad_iaddr/script
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+DESC="inode with invalid i_addr"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+ext=`get_mb "$node" 'i_ext:'`
+pgofs=`echo $ext | sed 's/.*fofs:\([0-9a-fA-F]\{1,\}\).*/0x\1/g'`
+blk=`echo $ext | sed 's/.*blkaddr:\([0-9a-fA-F]\{1,\}\).*/0x\1/g'`
+len=`echo $ext | sed 's/.*len:\([0-9a-fA-F]\{1,\}\).*/0x\1/g'`
+echo "ino:$ino blkaddr:$blkaddr ext:$ext" >> $LOG
+
+$INJECT --node --nid $ino --mb i_addr --idx 0x100 --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+INO=`printf "0x%x" $ino`
+PGOFS=$((pgofs))
+BLK=$((blk))
+LEN=$((len))
+sed "s/_INO_/$INO/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_PGOFS_/$PGOFS/g" $TESTDIR/expect
+sed -i "s/_BLK_/$BLK/g" $TESTDIR/expect
+sed -i "s/_LEN_/$LEN/g" $TESTDIR/expect
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+new_blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+
+# if i_addr is 0, dump.f2fs hides this i_addr slot
+if [ x"$new_blkaddr" != x"" ]; then
+ echo "old_blkaddr: $blkaddr" >> $OUT
+ echo "new_blkaddr: $new_blkaddr" >> $OUT
+fi
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 27/32] tests: add fsck testcase of fixing dentry hash code
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (25 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 26/32] tests: add fsck testcase of fixing inode invalid i_addr Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 28/32] tests: add fsck testcase of fixing lost dots Sheng Yong
` (5 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_dentry_bad_hash/README | 8 +++++
tests/f_dentry_bad_hash/expect.in | 8 +++++
tests/f_dentry_bad_hash/script | 56 +++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+)
create mode 100644 tests/f_dentry_bad_hash/README
create mode 100644 tests/f_dentry_bad_hash/expect.in
create mode 100644 tests/f_dentry_bad_hash/script
diff --git a/tests/f_dentry_bad_hash/README b/tests/f_dentry_bad_hash/README
new file mode 100644
index 000000000000..f36c44f7c7bd
--- /dev/null
+++ b/tests/f_dentry_bad_hash/README
@@ -0,0 +1,8 @@
+1. create f2fs image
+2. mount f2fs
+3. create an inline dentry directory, and create a file in it
+4. inject dentry's hash_code of the file
+5. fsck fixes the dentry's hash_code
+6. create a non-inline dentry directory (by converting), and create a file in it
+7. inject dentry's hash_code of the file
+8. fsck fixes the dentry's hash_code
diff --git a/tests/f_dentry_bad_hash/expect.in b/tests/f_dentry_bad_hash/expect.in
new file mode 100644
index 000000000000..074388fa6849
--- /dev/null
+++ b/tests/f_dentry_bad_hash/expect.in
@@ -0,0 +1,8 @@
+Info: Force to fix corruption
+[ASSERT] (f2fs_check_hash_code:x) --> Mismatch hash_code for "testfile1" [12345:_HASH1_]
+[FIX] (f2fs_check_hash_code:x) --> Fix hash_code for "testfile1" from 12345 to _HASH1_
+Info: Force to fix corruption
+Info: Force to fix corruption
+[ASSERT] (f2fs_check_hash_code:x) --> Mismatch hash_code for "testfile2" [12345:_HASH2_]
+[FIX] (f2fs_check_hash_code:x) --> Fix hash_code for "testfile2" from 12345 to _HASH2_
+Info: Force to fix corruption
diff --git a/tests/f_dentry_bad_hash/script b/tests/f_dentry_bad_hash/script
new file mode 100644
index 000000000000..4a2d31198e54
--- /dev/null
+++ b/tests/f_dentry_bad_hash/script
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+DESC="dentry with invalid hash_code"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+# inject inline dentry
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+mkdir $TESTDIR/mntdir/testdir1
+touch $TESTDIR/mntdir/testdir1/testfile1
+ino=`stat -c "%i" $TESTDIR/mntdir/testdir1/testfile1`
+safe_umount $TESTDIR/mntdir >> $LOG
+
+hash_code=`$INJECT --dry-run --dent --nid $ino --mb d_hash $META | \
+ grep "Info: inject dentry d_hash of nid" | awk '{print $(NF-2)}'`
+echo "ino:$ino hash_code:$hash_code" >> $LOG
+
+$INJECT --dent --nid $ino --mb d_hash --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+skip_lines=`wc -l $OUT`
+
+HASH_CODE=`printf "%x" $hash_code`
+sed "s/_HASH1_/$HASH_CODE/g" $TESTDIR/expect.in > $TESTDIR/expect
+
+# inject non-inline dentry
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+mkdir $TESTDIR/mntdir/testdir2
+i=0
+while [ $i -lt 30 ]; do
+ touch $TESTDIR/mntdir/testdir2/loooooooooooooooooooooooooognametestfile$i
+ i=$((i + 1))
+done
+touch $TESTDIR/mntdir/testdir2/testfile2
+ino=`stat -c "%i" $TESTDIR/mntdir/testdir2/testfile2`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+hash_code=`$INJECT --dry-run --dent --nid $ino --mb d_hash $META | \
+ grep "Info: inject dentry d_hash of nid" | awk '{print $(NF-2)}'`
+echo "ino:$ino hash_code:$hash_code" >> $LOG
+
+$INJECT --dent --nid $ino --mb d_hash --val 0x12345 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META >> $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT | tail -n +$skip_lines >> $LOG
+
+HASH_CODE=`printf "%x" $hash_code`
+sed -i "s/_HASH2_/$HASH_CODE/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 28/32] tests: add fsck testcase of fixing lost dots
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (26 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 27/32] tests: add fsck testcase of fixing dentry hash code Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 29/32] tests: add fsck testcase of fixing duplicated dots Sheng Yong
` (4 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_dentry_lost_dots/README | 7 ++++++
tests/f_dentry_lost_dots/expect.in | 16 +++++++++++++
tests/f_dentry_lost_dots/script | 37 ++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+)
create mode 100644 tests/f_dentry_lost_dots/README
create mode 100644 tests/f_dentry_lost_dots/expect.in
create mode 100644 tests/f_dentry_lost_dots/script
diff --git a/tests/f_dentry_lost_dots/README b/tests/f_dentry_lost_dots/README
new file mode 100644
index 000000000000..f07a1165b8cc
--- /dev/null
+++ b/tests/f_dentry_lost_dots/README
@@ -0,0 +1,7 @@
+1. create f2fs image
+2. mount f2fs
+3. create a directory, and create a file in it
+4. inject dot dentry in the directory by invalidating its valid bit
+5. fsck fixes by adding a new dot dentry
+6. inject dotdot dentry in the directory by invalidating its valid bit
+7. fsck fixes by adding a new dotdot dentry
diff --git a/tests/f_dentry_lost_dots/expect.in b/tests/f_dentry_lost_dots/expect.in
new file mode 100644
index 000000000000..c024e683908d
--- /dev/null
+++ b/tests/f_dentry_lost_dots/expect.in
@@ -0,0 +1,16 @@
+Info: Force to fix corruption
+[ASSERT] (fsck_chk_inode_blk:x) --> ino: _INO_HEX_ has no '.' and/or '..' dirents, dot: 0, dotdot: 1
+[FIX] (fsck_chk_inode_blk:x) --> convert inline dentry ino: _INO_DEC_, pino: _PINO_DEC_, ret: 0
+[FIX] (fsck_chk_inode_blk:x) --> add missing '.' dirent in ino: _INO_DEC_, pino: _PINO_DEC_, ret:0
+[fsck_chk_quota_files:x] Fixing Quota file ([ 0] ino [0x4])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x4] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 1] ino [0x5])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x5] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 2] ino [0x6])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x6] in NAT
+Info: Force to fix corruption
+Info: Force to fix corruption
+[ASSERT] (fsck_chk_inode_blk:x) --> ino: _INO_HEX_ has no '.' and/or '..' dirents, dot: 1, dotdot: 0
+[FIX] (fsck_chk_inode_blk:x) --> convert inline dentry ino: _INO_DEC_, pino: _PINO_DEC_, ret: 0
+[FIX] (fsck_chk_inode_blk:x) --> add missing '..' dirent in ino: _INO_DEC_, pino: _PINO_DEC_, ret:0
+Info: Force to fix corruption
diff --git a/tests/f_dentry_lost_dots/script b/tests/f_dentry_lost_dots/script
new file mode 100644
index 000000000000..38bfd36f0266
--- /dev/null
+++ b/tests/f_dentry_lost_dots/script
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+DESC="directory missing dot or dotdot"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+mkdir $TESTDIR/mntdir/testdir
+touch $TESTDIR/mntdir/testdir/testfile
+ino=`stat -c "%i" $TESTDIR/mntdir/testdir`
+pino=`stat -c "%i" $TESTDIR/mntdir/testdir/..`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+echo "ino:$ino pino:$pino" >> $LOG
+
+# inject dot
+$INJECT --dent --nid $ino --mb d_bitmap --dots 1 --val 0 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+
+# inject dotdot
+$INJECT --dent --nid $ino --mb d_bitmap --dots 2 --val 0 $META >> $LOG
+$FSCK $FSCK_OPTS -f $META >> $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+INO_HEX=`printf "0x%x" $ino`
+sed "s/_INO_HEX_/$INO_HEX/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_INO_DEC_/$ino/g" $TESTDIR/expect
+sed -i "s/_PINO_DEC_/$pino/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 29/32] tests: add fsck testcase of fixing duplicated dots
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (27 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 28/32] tests: add fsck testcase of fixing lost dots Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 30/32] tests: add fsck testcase of fixing loop fsync dnodes Sheng Yong
` (3 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_dentry_dup_dots/README | 11 +++++++
tests/f_dentry_dup_dots/expect.in | 26 ++++++++++++++++
tests/f_dentry_dup_dots/script | 49 +++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+)
create mode 100644 tests/f_dentry_dup_dots/README
create mode 100644 tests/f_dentry_dup_dots/expect.in
create mode 100644 tests/f_dentry_dup_dots/script
diff --git a/tests/f_dentry_dup_dots/README b/tests/f_dentry_dup_dots/README
new file mode 100644
index 000000000000..e36526625ca6
--- /dev/null
+++ b/tests/f_dentry_dup_dots/README
@@ -0,0 +1,11 @@
+1. create f2fs image
+2. mount f2fs
+3. create a directory, and create a file in it
+4. inject dot dentry in the directory by changing its d_ino to the dotdot's ino
+5. fsck fixes the dot's d_ino
+6. inject dotdot dentry in the directory by changing its d_ino to the dot's ino
+7. fsck fixes the dotdot's d_ino
+8. inject dot dentry in the directory by changing its filename to ".."
+9. fsck fixes it by deleting duplicated dotdot dentry and adding a new dot dentry
+10. inject dotdot dentry in the directory by changing its filename to "."
+11. fsck fixes it by deleting duplicated dot dentry and adding a new dotdot dentry
diff --git a/tests/f_dentry_dup_dots/expect.in b/tests/f_dentry_dup_dots/expect.in
new file mode 100644
index 000000000000..5af443df7d12
--- /dev/null
+++ b/tests/f_dentry_dup_dots/expect.in
@@ -0,0 +1,26 @@
+Info: Force to fix corruption
+[ASSERT] (__chk_dots_dentries:x) --> Bad inode number[_PINO_HEX_] for '.', parent_ino is [_INO_HEX_]
+Info: Force to fix corruption
+Info: Force to fix corruption
+[ASSERT] (__chk_dots_dentries:x) --> Bad inode number[_INO_HEX_] for '..', parent parent ino is [_PINO_HEX_]
+Info: Force to fix corruption
+Info: Force to fix corruption
+[ASSERT] (__chk_dots_dentries:x) --> Bad inode number[_INO_HEX_] for '..', parent parent ino is [_PINO_HEX_]
+[ASSERT] (__chk_dentries:x) --> More than one '..', should delete the extra one, i: 1, ino:_PINO_DEC_
+[ASSERT] (fsck_chk_inode_blk:x) --> ino: _INO_HEX_ has no '.' and/or '..' dirents, dot: 0, dotdot: 1
+[FIX] (fsck_chk_inode_blk:x) --> convert inline dentry ino: _INO_DEC_, pino: _PINO_DEC_, ret: 0
+[FIX] (fsck_chk_inode_blk:x) --> add missing '.' dirent in ino: _INO_DEC_, pino: _PINO_DEC_, ret:0
+[fsck_chk_quota_files:x] Fixing Quota file ([ 0] ino [0x4])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x4] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 1] ino [0x5])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x5] in NAT
+[fsck_chk_quota_files:x] Fixing Quota file ([ 2] ino [0x6])
+[FIX] (nullify_nat_entry:x) --> Remove nid [0x6] in NAT
+Info: Force to fix corruption
+Info: Force to fix corruption
+[ASSERT] (__chk_dots_dentries:x) --> Bad inode number[_PINO_HEX_] for '.', parent_ino is [_INO_HEX_]
+[ASSERT] (__chk_dentries:x) --> More than one '.', should delete the extra one, i: 1, ino:_INO_DEC_
+[ASSERT] (fsck_chk_inode_blk:x) --> ino: _INO_HEX_ has no '.' and/or '..' dirents, dot: 1, dotdot: 0
+[FIX] (fsck_chk_inode_blk:x) --> convert inline dentry ino: _INO_DEC_, pino: _PINO_DEC_, ret: 0
+[FIX] (fsck_chk_inode_blk:x) --> add missing '..' dirent in ino: _INO_DEC_, pino: _PINO_DEC_, ret:0
+Info: Force to fix corruption
diff --git a/tests/f_dentry_dup_dots/script b/tests/f_dentry_dup_dots/script
new file mode 100644
index 000000000000..881bb50f8705
--- /dev/null
+++ b/tests/f_dentry_dup_dots/script
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+DESC="directory duplicated dot or dotdot"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+mkdir $TESTDIR/mntdir/testdir
+touch $TESTDIR/mntdir/testdir/testfile
+ino=`stat -c "%i" $TESTDIR/mntdir/testdir`
+pino=`stat -c "%i" $TESTDIR/mntdir/testdir/..`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+echo "ino:$ino pino:$pino" >> $LOG
+
+# inject dot's d_ino
+$INJECT --dent --nid $ino --mb d_ino --dots 1 --val $pino $META >> $LOG
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+
+# inject dotdot's d_ino
+$INJECT --dent --nid $ino --mb d_ino --dots 2 --val $ino $META >> $LOG
+$FSCK $FSCK_OPTS -f $META >> $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+
+# inject dot's filename
+$INJECT --dent --nid $ino --mb filename --dots 1 --str ".." $META >> $LOG
+$FSCK $FSCK_OPTS -f $META >> $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+
+# inject dotdot's filename
+$INJECT --dent --nid $ino --mb filename --dots 2 --str "." $META >> $LOG
+$FSCK $FSCK_OPTS -f $META >> $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+INO_HEX=`printf "0x%x" $ino`
+PINO_HEX=`printf "0x%x" $pino`
+sed "s/_INO_DEC_/$ino/g" $TESTDIR/expect.in > $TESTDIR/expect
+sed -i "s/_PINO_DEC_/$pino/g" $TESTDIR/expect
+sed -i "s/_INO_HEX_/$INO_HEX/g" $TESTDIR/expect
+sed -i "s/_PINO_HEX_/$PINO_HEX/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 30/32] tests: add fsck testcase of fixing loop fsync dnodes
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (28 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 29/32] tests: add fsck testcase of fixing duplicated dots Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 31/32] tests: add inject testcase of injecting META area Sheng Yong
` (2 subsequent siblings)
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/f_loop_fsync_dnodes/README | 5 ++++
tests/f_loop_fsync_dnodes/expect.in | 6 ++++
tests/f_loop_fsync_dnodes/script | 46 +++++++++++++++++++++++++++++
3 files changed, 57 insertions(+)
create mode 100644 tests/f_loop_fsync_dnodes/README
create mode 100644 tests/f_loop_fsync_dnodes/expect.in
create mode 100644 tests/f_loop_fsync_dnodes/script
diff --git a/tests/f_loop_fsync_dnodes/README b/tests/f_loop_fsync_dnodes/README
new file mode 100644
index 000000000000..4e864fa8c874
--- /dev/null
+++ b/tests/f_loop_fsync_dnodes/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. mount f2fs and create 10 regular files with O_SYNC
+3. shutdown f2fs without writing checkpoint
+4. inject fsync dnodes to generate a loop
+5. fsck fixes fsync dnodes by breaking the loop
diff --git a/tests/f_loop_fsync_dnodes/expect.in b/tests/f_loop_fsync_dnodes/expect.in
new file mode 100644
index 000000000000..23b7fbfc7e82
--- /dev/null
+++ b/tests/f_loop_fsync_dnodes/expect.in
@@ -0,0 +1,6 @@
+Info: Force to fix corruption
+Info: checkpoint stop reason: shutdown(1)
+[ASSERT] (sanity_check_node_chain:x) --> detect looped node chain, blkaddr:_BLKADDR_
+[FIX] (loop_node_chain_fix:x) --> Fix looped node chain on blkaddr _BLKADDR_
+Info: Force to fix corruption
+Info: checkpoint stop reason: shutdown(1)
diff --git a/tests/f_loop_fsync_dnodes/script b/tests/f_loop_fsync_dnodes/script
new file mode 100644
index 000000000000..b6f64f384a0e
--- /dev/null
+++ b/tests/f_loop_fsync_dnodes/script
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+DESC="recover loop fsync dnodes"
+
+. $TOPDIR/tests/helpers
+
+# if device is a zoned device, this testcase should be skipped
+test_sb_feature blkzoned
+if [ $? -ne 0 ]; then
+ touch $TESTDIR/SKIP
+ check_result
+ return
+fi
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+mkdir $TESTDIR/mntdir/testdir
+touch $TESTDIR/mntdir/testdir/testfile
+$F2FS_IO checkpoint $TESTDIR/mntdir/testdir/testfile >> $LOG
+i=0
+while [ $i -lt 10 ]; do
+ # write one all zero 4K chunk to file with O_SYNC
+ $F2FS_IO write 1 0 1 zero osync $TESTDIR/mntdir/testdir/testfile.$i >> $LOG
+ i=$((i + 1))
+done
+$F2FS_IO shutdown 2 $TESTDIR/mntdir/testdir/testfile >> $LOG
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+addr1=`$INJECT --dry-run --cp 0 --mb next_blkaddr --idx 6 --val 0 $META | \
+ grep "\[.*1\] blkaddr:" | cut -d ":" -f 3`
+addr2=`$INJECT --dry-run --cp 0 --mb next_blkaddr --idx 6 --val 0 $META | \
+ grep "\[.*6\] blkaddr:" | cut -d ":" -f 3`
+echo "addr1:$addr1, addr2:$addr2" >> $LOG
+$INJECT --cp 0 --mb next_blkaddr --idx 6 --val $addr1 $META >> $LOG
+
+$FSCK $FSCK_OPTS -f $META > $OUT
+$FSCK $FSCK_OPTS -f $META >> $OUT
+cat $OUT >> $LOG
+
+sed "s/_BLKADDR_/$((addr2))/g" $TESTDIR/expect.in > $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 31/32] tests: add inject testcase of injecting META area
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (29 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 30/32] tests: add fsck testcase of fixing loop fsync dnodes Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 32/32] tests: add inject testcase of injecting node block Sheng Yong
2025-08-15 10:38 ` [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Chao Yu via Linux-f2fs-devel
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/i_meta/README | 5 +
tests/i_meta/expect.in | 60 ++++++++++++
tests/i_meta/script | 212 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 277 insertions(+)
create mode 100644 tests/i_meta/README
create mode 100644 tests/i_meta/expect.in
create mode 100644 tests/i_meta/script
diff --git a/tests/i_meta/README b/tests/i_meta/README
new file mode 100644
index 000000000000..2ad5bd5d90c5
--- /dev/null
+++ b/tests/i_meta/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. inject members in META area
+3. verify injected fields with dump.f2fs
+4. restore injected fields
+5. fsck checks f2fs image
diff --git a/tests/i_meta/expect.in b/tests/i_meta/expect.in
new file mode 100644
index 000000000000..f9a306eaa918
--- /dev/null
+++ b/tests/i_meta/expect.in
@@ -0,0 +1,60 @@
+original feature:_ORIG_FEATURE_
+inject feature:feature [0x12345:74565]
+restore feature:_ORIG_FEATURE_
+original devs.path:devs[i].path [_ORIG_PATH_]
+inject devs.path:devs[i].path [_INJECT_PATH_]
+restore devs.path:devs[i].path [_ORIG_PATH_]
+original checkpoint_ver:
+checkpoint_ver [_ORIG_CPVER_HEX_:_ORIG_CPVER_DEC_]
+original ckpt_flags:
+ckpt_flags [_ORIG_FLAGS_HEX_:_ORIG_FLAGS_DEC_]
+original cur_node_segno[1]:
+cur_node_segno[1] [_ORIG_CUR_NODE_SEGNO_HEX_:_ORIG_CUR_NODE_SEGNO_DEC_]
+original cur_node_blkoff[1]:
+cur_node_blkoff[1] [_ORIG_CUR_NODE_BLKOFF_HEX_:_ORIG_CUR_NODE_BLKOFF_DEC_]
+original cur_data_segno[2]:
+cur_data_segno[2] [_ORIG_CUR_DATA_SEGNO_HEX_:_ORIG_CUR_DATA_SEGNO_DEC_]
+original cur_data_blkoff[2]:
+cur_data_blkoff[2] [_ORIG_CUR_DATA_BLKOFF_HEX_:_ORIG_CUR_DATA_BLKOFF_DEC_]
+original elapsed_time:
+elapsed_time [_ORIG_ELAPSED_TIME_HEX_:_ORIG_ELAPSED_TIME_DEC_]
+inject checkpoint_ver:
+checkpoint_ver [0xffffffffffffff0:1152921504606846960]
+inject ckpt_flags:
+ckpt_flags [0x12345:74565]
+inject cur_node_segno[1]:
+cur_node_segno[1] [0x1:1]
+inject cur_node_blkoff[1]:
+cur_node_blkoff[1] [0x2:2]
+inject cur_data_segno[2]:
+cur_data_segno[2] [0x3:3]
+inject cur_data_blkoff[2]:
+cur_data_blkoff[2] [0x4:4]
+inject elapsed_time:
+elapsed_time [0xffff0000:4294901760]
+restore checkpoint_ver:
+checkpoint_ver [_ORIG_CPVER_HEX_:_ORIG_CPVER_DEC_]
+restore ckpt_flags:
+ckpt_flags [_ORIG_FLAGS_HEX_:_ORIG_FLAGS_DEC_]
+restore cur_node_segno[1]:
+cur_node_segno[1] [_ORIG_CUR_NODE_SEGNO_HEX_:_ORIG_CUR_NODE_SEGNO_DEC_]
+restore cur_node_blkoff[1]:
+cur_node_blkoff[1] [_ORIG_CUR_NODE_BLKOFF_HEX_:_ORIG_CUR_NODE_BLKOFF_DEC_]
+restore cur_data_segno[2]:
+cur_data_segno[2] [_ORIG_CUR_DATA_SEGNO_HEX_:_ORIG_CUR_DATA_SEGNO_DEC_]
+restore cur_data_blkoff[2]:
+cur_data_blkoff[2] [_ORIG_CUR_DATA_BLKOFF_HEX_:_ORIG_CUR_DATA_BLKOFF_DEC_]
+restore elapsed_time:
+elapsed_time [_ORIG_ELAPSED_TIME_HEX_:_ORIG_ELAPSED_TIME_DEC_]
+original nat entry:
+nid:_INO_ ino:_INO_ ver:0 offset:0
+inject nat entry:
+nid:_INO_ ino:_INO_ ver:18 offset:0
+restore nat entry:
+nid:_INO_ ino:_INO_ ver:0 offset:0
+original sit entry:
+segno:_SEGNO_ vblocks:512 seg_type:1 mtime:0
+inject sit entry:
+segno:_SEGNO_ vblocks:512 seg_type:1 mtime:74565
+restore sit entry:
+segno:_SEGNO_ vblocks:512 seg_type:1 mtime:0
diff --git a/tests/i_meta/script b/tests/i_meta/script
new file mode 100644
index 000000000000..c1484bf470f5
--- /dev/null
+++ b/tests/i_meta/script
@@ -0,0 +1,212 @@
+#!/bin/bash
+
+DESC="verify injecting fields in META area"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+node=`$DUMP $DUMP_OPTS -i $ino $META`
+echo "$node" >> $LOG
+blkaddr=`get_mb_val "$node" 'i_addr\[0x100\]'`
+segno=`get_segno $blkaddr`
+echo "ino:$ino blkaddr:$blkaddr segno:$segno" >> $LOG
+
+## inject super block
+# member "magic", "s_stop_reason" and "s_errors" are verified by
+# f_sb_bad_magic and f_sb_errors
+
+orig_sb=`get_sb $META`
+orig_feats_val=`get_mb_val "$orig_sb" feature`
+orig_path_str=`get_mb_val "$orig_sb" 'devs\[i\]\.path'`
+
+# inject and restore feature
+orig_feats=`echo "$orig_sb" | grep "^feature" | trim_extra_space`
+echo "original feature:$orig_feats" > $OUT
+$INJECT --sb 0 --mb feature --val 0x12345 $META >> $LOG
+cur_sb=`get_sb $META`
+cur_feats=`echo "$cur_sb" | grep "^feature" | trim_extra_space`
+echo "inject feature:$cur_feats" >> $OUT
+$INJECT --sb 0 --mb feature --val $orig_feats_val $META >> $LOG
+cur_sb=`get_sb $META`
+cur_feats=`echo "$cur_sb" | grep "^feature" | trim_extra_space`
+echo "restore feature:$cur_feats" >> $OUT
+
+# inject and restore the first devs.path
+orig_path=`echo "$orig_sb" | grep '^devs\[i\]\.path' | awk "NR==1" | trim_extra_space`
+if [ x"$orig_path" = x"" ]; then
+ echo "original devs.path:devs[i].path []" >> $OUT
+ echo "inject devs.path:devs[i].path []" >> $OUT
+ echo "restore devs.path:devs[i].path []" >> $OUT
+else
+ echo "original devs.path:$orig_path" >> $OUT
+ new_meta_path=$TESTDIR/new_meta
+ rm -f $new_meta_path
+ ln -s $META $new_meta_path
+ $INJECT --sb 0 --mb devs.path --idx 0 --str $new_meta_path $META >> $LOG
+ cur_sb=`get_sb $new_meta_path`
+ cur_path=`echo "$cur_sb" | grep '^devs\[i\]\.path' | awk "NR==1" | trim_extra_space`
+ echo "inject devs.path:$cur_path" >> $OUT
+ $INJECT --sb 0 --mb devs.path --idx 0 --str $orig_path_str $new_meta_path >> $LOG
+ cur_sb=`get_sb $META`
+ cur_path=`echo "$cur_sb" | grep '^devs\[i\]\.path' | awk "NR==1" | trim_extra_space`
+ echo "restore devs.path:$cur_path" >> $OUT
+fi
+
+## inject checkpoint
+# member "next_blkaddr" and "crc" are verified by f_loop_fsync_dnodes and
+# f_cp_bad_crc
+
+# inject and restore cp members
+orig_cp=`get_cp $META`
+echo "original checkpoint_ver:" >> $OUT
+get_mb "$orig_cp" checkpoint_ver >> $OUT
+orig_cpver_val=`get_mb_val "$orig_cp" checkpoint_ver`
+echo "original ckpt_flags:" >> $OUT
+get_mb "$orig_cp" ckpt_flags >> $OUT
+orig_flags_val=`get_mb_val "$orig_cp" ckpt_flags`
+echo "original cur_node_segno[1]:" >> $OUT
+get_mb "$orig_cp" 'cur_node_segno\[1\]' >> $OUT
+orig_cur_node_segno_val=`get_mb_val "$orig_cp" 'cur_node_segno\[1\]'`
+echo "original cur_node_blkoff[1]:" >> $OUT
+get_mb "$orig_cp" 'cur_node_blkoff\[1\]' >> $OUT
+orig_cur_node_blkoff_val=`get_mb_val "$orig_cp" 'cur_node_blkoff\[1\]'`
+echo "original cur_data_segno[2]:" >> $OUT
+get_mb "$orig_cp" 'cur_data_segno\[2\]' >> $OUT
+orig_cur_data_segno_val=`get_mb_val "$orig_cp" 'cur_data_segno\[2\]'`
+echo "original cur_data_blkoff[2]:" >> $OUT
+get_mb "$orig_cp" 'cur_data_blkoff\[2\]' >> $OUT
+orig_cur_data_blkoff_val=`get_mb_val "$orig_cp" 'cur_data_blkoff\[2\]'`
+echo "original elapsed_time:" >> $OUT
+get_mb "$orig_cp" 'elapsed_time' >> $OUT
+orig_elapsed_time_val=`get_mb_val "$orig_cp" elapsed_time`
+$INJECT --cp 0 --mb checkpoint_ver --val 0xffffffffffffff0 $META >> $LOG
+$INJECT --cp 0 --mb ckpt_flags --val 0x12345 $META >> $LOG
+$INJECT --cp 0 --mb cur_node_segno --idx 1 --val 1 $META >> $LOG
+$INJECT --cp 0 --mb cur_node_blkoff --idx 1 --val 2 $META >> $LOG
+$INJECT --cp 0 --mb cur_data_segno --idx 2 --val 3 $META >> $LOG
+$INJECT --cp 0 --mb cur_data_blkoff --idx 2 --val 4 $META >> $LOG
+$INJECT --cp 0 --mb elapsed_time --val 0xffff0000 $META >> $LOG
+cur_cp=`get_cp $META`
+echo "inject checkpoint_ver:" >> $OUT
+get_mb "$cur_cp" checkpoint_ver >> $OUT
+echo "inject ckpt_flags:" >> $OUT
+get_mb "$cur_cp" ckpt_flags >> $OUT
+echo "inject cur_node_segno[1]:" >> $OUT
+get_mb "$cur_cp" 'cur_node_segno\[1\]' >> $OUT
+echo "inject cur_node_blkoff[1]:" >> $OUT
+get_mb "$cur_cp" 'cur_node_blkoff\[1\]' >> $OUT
+echo "inject cur_data_segno[2]:" >> $OUT
+get_mb "$cur_cp" 'cur_data_segno\[2\]' >> $OUT
+echo "inject cur_data_blkoff[2]:" >> $OUT
+get_mb "$cur_cp" 'cur_data_blkoff\[2\]' >> $OUT
+echo "inject elapsed_time:" >> $OUT
+get_mb "$cur_cp" 'elapsed_time' >> $OUT
+$INJECT --cp 0 --mb checkpoint_ver --val $orig_cpver_val $META >> $LOG
+$INJECT --cp 0 --mb ckpt_flags --val $orig_flags_val $META >> $LOG
+$INJECT --cp 0 --mb cur_node_segno --idx 1 --val $orig_cur_node_segno_val $META >> $LOG
+$INJECT --cp 0 --mb cur_node_blkoff --idx 1 --val $orig_cur_node_blkoff_val $META >> $LOG
+$INJECT --cp 0 --mb cur_data_segno --idx 2 --val $orig_cur_data_segno_val $META >> $LOG
+$INJECT --cp 0 --mb cur_data_blkoff --idx 2 --val $orig_cur_data_blkoff_val $META >> $LOG
+$INJECT --cp 0 --mb elapsed_time --val $orig_elapsed_time_val $META >> $LOG
+cur_cp=`get_cp $META`
+echo "restore checkpoint_ver:" >> $OUT
+get_mb "$cur_cp" checkpoint_ver >> $OUT
+echo "restore ckpt_flags:" >> $OUT
+get_mb "$cur_cp" ckpt_flags >> $OUT
+echo "restore cur_node_segno[1]:" >> $OUT
+get_mb "$cur_cp" 'cur_node_segno\[1\]' >> $OUT
+echo "restore cur_node_blkoff[1]:" >> $OUT
+get_mb "$cur_cp" 'cur_node_blkoff\[1\]' >> $OUT
+echo "restore cur_data_segno[2]:" >> $OUT
+get_mb "$cur_cp" 'cur_data_segno\[2\]' >> $OUT
+echo "restore cur_data_blkoff[2]:" >> $OUT
+get_mb "$cur_cp" 'cur_data_blkoff\[2\]' >> $OUT
+echo "restore elapsed_time:" >> $OUT
+get_mb "$cur_cp" 'elapsed_time' >> $OUT
+
+## inject nat entry
+# member "ino" and "block_addr" are verified by f_nat_bad_ino and
+# f_nat_bad_blkaddr
+
+# inject and restore version
+rm -f dump_nat
+$DUMP $DUMP_OPTS -n $ino~$((ino + 1)) $META >> $LOG
+echo "original nat entry:" >> $OUT
+cat dump_nat | trim_extra_space >> $OUT
+orig_ver=0 # orig_ver must be 0 in this testcase
+$INJECT --nat 0 --nid $ino --mb version --val 0x12 $META >> $LOG
+$DUMP $DUMP_OPTS -n $ino~$((ino + 1)) $META >> $LOG
+echo "inject nat entry:" >> $OUT
+cat dump_nat | trim_extra_space >> $OUT
+$INJECT --nat 0 --nid $ino --mb version --val $orig_ver $META >> $LOG
+$DUMP $DUMP_OPTS -n $ino~$((ino + 1)) $META >> $LOG
+echo "restore nat entry:" >> $OUT
+cat dump_nat | trim_extra_space >> $OUT
+
+## inject sit entry
+# member "type", "valid_map" and "vblocks" are verified by f_sit_bad_type,
+# f_sit_bad_valid_blocks and f_sit_bad_vblocks
+
+# inject and restore mtime
+rm -f dump_sit
+$DUMP $DUMP_OPTS -s $segno~$((segno + 1)) $META >> $LOG
+echo "original sit entry:" >> $OUT
+orig_sit=`grep "segno:" dump_sit | trim_extra_space`
+echo "$orig_sit" >> $OUT
+orig_mtime=`echo $orig_sit | sed 's/.* mtime:\([0-9]\{,1\}\) .*/\1/'`
+$INJECT --sit 0 --blk $blkaddr --mb mtime --val 0x12345 $META >> $LOG
+$DUMP $DUMP_OPTS -s $segno~$((segno + 1)) $META >> $LOG
+echo "inject sit entry:" >> $OUT
+grep "segno:" dump_sit | trim_extra_space >> $OUT
+$INJECT --sit 0 --blk $blkaddr --mb mtime --val $orig_mtime $META >> $LOG
+$DUMP $DUMP_OPTS -s $segno~$((segno + 1)) $META >> $LOG
+echo "restore sit entry:" >> $OUT
+grep "segno:" dump_sit | trim_extra_space >> $OUT
+
+## run fsck to check if there are any errors
+$FSCK $FSCK_OPTS -f $META >> $LOG
+if [ $? -ne 0 ]; then
+ echo "fsck fail" >> $OUT
+fi
+
+sed "s/_ORIG_FEATURE_/$orig_feats/g" $TESTDIR/expect.in > $TESTDIR/expect
+# escape '\' in path
+new_meta_path_str=`echo $new_meta_path | sed 's/\\//\\\\\//g'`
+orig_path_str=`echo $orig_path_str | sed 's/\\//\\\\\//g'`
+sed -i "s/_ORIG_PATH_/$orig_path_str/g" $TESTDIR/expect
+sed -i "s/_INJECT_PATH_/$new_meta_path_str/g" $TESTDIR/expect
+dec=$((orig_cpver_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_CPVER_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_CPVER_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_flags_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_FLAGS_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_FLAGS_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_cur_node_segno_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_CUR_NODE_SEGNO_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_CUR_NODE_SEGNO_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_cur_node_blkoff_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_CUR_NODE_BLKOFF_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_CUR_NODE_BLKOFF_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_cur_data_segno_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_CUR_DATA_SEGNO_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_CUR_DATA_SEGNO_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_cur_data_blkoff_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_CUR_DATA_BLKOFF_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_CUR_DATA_BLKOFF_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_elapsed_time_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ORIG_ELAPSED_TIME_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ORIG_ELAPSED_TIME_DEC_/$dec/g" $TESTDIR/expect
+sed -i "s/_INO_/$ino/g" $TESTDIR/expect
+sed -i "s/_SEGNO_/$segno/g" $TESTDIR/expect
+
+check_result
+rm -f $new_meta_path dump_nat dump_sit
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [f2fs-dev] [RFC PATCH v2 32/32] tests: add inject testcase of injecting node block
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (30 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 31/32] tests: add inject testcase of injecting META area Sheng Yong
@ 2025-06-10 12:37 ` Sheng Yong
2025-08-15 10:38 ` [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Chao Yu via Linux-f2fs-devel
32 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-10 12:37 UTC (permalink / raw)
To: jaegeuk, chao; +Cc: shengyong1, linux-f2fs-devel
From: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
---
tests/i_node/README | 5 ++
tests/i_node/expect.in | 66 ++++++++++++++++
tests/i_node/script | 166 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 237 insertions(+)
create mode 100644 tests/i_node/README
create mode 100644 tests/i_node/expect.in
create mode 100644 tests/i_node/script
diff --git a/tests/i_node/README b/tests/i_node/README
new file mode 100644
index 000000000000..c95f0d39df3c
--- /dev/null
+++ b/tests/i_node/README
@@ -0,0 +1,5 @@
+1. create f2fs image
+2. inject members in node
+3. verify injected fields with dump.f2fs
+4. restore injected fields
+5. fsck checks f2fs image
diff --git a/tests/i_node/expect.in b/tests/i_node/expect.in
new file mode 100644
index 000000000000..17f3a2ff3c84
--- /dev/null
+++ b/tests/i_node/expect.in
@@ -0,0 +1,66 @@
+original nid:
+[dump_node: x] node_blk.footer.nid [_INO_]
+original ino:
+[dump_node: x] node_blk.footer.ino [_INO_]
+inject nid:
+[dump_node: x] node_blk.footer.nid [0x123450]
+inject ino:
+[dump_node: x] node_blk.footer.ino [0x123451]
+restore nid:
+[dump_node: x] node_blk.footer.nid [_INO_]
+restore ino:
+[dump_node: x] node_blk.footer.ino [_INO_]
+original i_mode:
+i_mode [_MODE_HEX_:_MODE_DEC_]
+original i_advise:
+i_advise [_ADVISE_HEX_:_ADVISE_DEC_]
+original i_inline:
+i_inline [_INLINE_HEX_:_INLINE_DEC_]
+original i_links:
+i_links [0x1:1]
+original i_size:
+i_size [0x201000:2101248]
+original i_blocks:
+i_blocks [_BLKS_HEX_:_BLKS_DEC_]
+original i_ext:
+i_ext:fofs:_EXT_FOFS_ blkaddr:_EXT_BLKADDR_ len:_EXT_LEN_
+original i_extra_isize:
+i_extra_isize [_EXTRA_HEX_:_EXTRA_DEC_]
+original i_nid[0]:
+i_nid[0] [0x0:0]
+inject i_mode:
+i_mode [0x1:1]
+inject i_advise:
+i_advise [0x2:2]
+inject i_inline:
+i_inline [0x3:3]
+inject i_links:
+i_links [0x4:4]
+inject i_size:
+i_size [0x5:5]
+inject i_blocks:
+i_blocks [0x6:6]
+inject i_ext:
+i_ext:fofs:7 blkaddr:8 len:9
+inject i_extra_isize:
+i_extra_isize [0xa:10]
+inject i_nid[0]:
+i_nid[0] [0xc:12]
+restore i_mode:
+i_mode [_MODE_HEX_:_MODE_DEC_]
+restore i_advise:
+i_advise [_ADVISE_HEX_:_ADVISE_DEC_]
+restore i_inline:
+i_inline [_INLINE_HEX_:_INLINE_DEC_]
+restore i_links:
+i_links [0x1:1]
+restore i_size:
+i_size [0x201000:2101248]
+restore i_blocks:
+i_blocks [_BLKS_HEX_:_BLKS_DEC_]
+restore i_ext:
+i_ext:fofs:_EXT_FOFS_ blkaddr:_EXT_BLKADDR_ len:_EXT_LEN_
+restore i_extra_isize:
+i_extra_isize [_EXTRA_HEX_:_EXTRA_DEC_]
+restore i_nid[0]:
+i_nid[0] [0x0:0]
diff --git a/tests/i_node/script b/tests/i_node/script
new file mode 100644
index 000000000000..2e98cfc56f05
--- /dev/null
+++ b/tests/i_node/script
@@ -0,0 +1,166 @@
+#!/bin/bash
+
+DESC="verify injecting node"
+
+. $TOPDIR/tests/helpers
+
+cleanup
+make_f2fs > $LOG
+
+mkdir $TESTDIR/mntdir
+safe_mount $MNT_OPTS $META $TESTDIR/mntdir >> $LOG
+dd if=/dev/zero of=$TESTDIR/mntdir/testfile bs=4K count=513 status=none
+ino=`stat -c "%i" $TESTDIR/mntdir/testfile`
+safe_umount $TESTDIR/mntdir >> $LOG
+rm -rf $TESTDIR/mntdir
+
+orig_node=`$DUMP $DUMP_OPTS -i $ino -d 1 $META`
+echo "$orig_node" >> $LOG
+blkaddr=`get_mb_val "$orig_node" 'i_addr\[0x100\]'`
+echo "ino:$ino blkaddr:$blkaddr" >> $LOG
+segno=`get_segno $blkaddr`
+
+# inject and restore nid and ino in node footer
+echo "original nid:" > $OUT
+echo "$orig_node" | grep 'node_blk\.footer\.nid' >> $OUT
+echo "original ino:" >> $OUT
+echo "$orig_node" | grep 'node_blk\.footer\.ino' >> $OUT
+$INJECT --node --nid $ino --mb nid --val 0x123450 $META >> $LOG
+$INJECT --node --nid $ino --mb ino --val 0x123451 $META >> $LOG
+cur_node=`$DUMP $DUMP_OPTS -i $ino -d 1 $META`
+echo "inject nid:" >> $OUT
+echo "$cur_node" | grep 'node_blk\.footer\.nid' >> $OUT
+echo "inject ino:" >> $OUT
+echo "$cur_node" | grep 'node_blk\.footer\.ino' >> $OUT
+$INJECT --node --nid $ino --mb nid --val $ino $META >> $LOG
+$INJECT --node --nid $ino --mb ino --val $ino $META >> $LOG
+cur_node=`$DUMP $DUMP_OPTS -i $ino -d 1 $META`
+echo "restore nid:" >> $OUT
+echo "$cur_node" | grep 'node_blk\.footer\.nid' >> $OUT
+echo "restore ino:" >> $OUT
+echo "$cur_node" | grep 'node_blk\.footer\.ino' >> $OUT
+
+# inject and restore inode members
+echo "original i_mode:" >> $OUT
+get_mb "$orig_node" i_mode >> $OUT
+orig_mode_val=`get_mb_val "$orig_node" i_mode`
+echo "original i_advise:" >> $OUT
+get_mb "$orig_node" i_advise >> $OUT
+orig_advise_val=`get_mb_val "$orig_node" i_advise`
+echo "original i_inline:" >> $OUT
+get_mb "$orig_node" i_inline >> $OUT
+orig_inline_val=`get_mb_val "$orig_node" i_inline`
+echo "original i_links:" >> $OUT
+get_mb "$orig_node" i_links >> $OUT
+orig_links_val=`get_mb_val "$orig_node" i_links`
+echo "original i_size:" >> $OUT
+get_mb "$orig_node" i_size >> $OUT
+orig_size_val=`get_mb_val "$orig_node" i_size`
+echo "original i_blocks:" >> $OUT
+get_mb "$orig_node" i_blocks >> $OUT
+orig_blocks_val=`get_mb_val "$orig_node" i_blocks`
+echo "original i_ext:" >> $OUT
+orig_ext=`get_mb "$orig_node" 'i_ext:'`
+echo "$orig_ext" >> $OUT
+orig_ext_fofs_val=`echo "$orig_ext" | sed "s/.*fofs:\([0-9a-fA-F]*\).*/0x\1/g"`
+orig_ext_blkaddr_val=`echo "$orig_ext" | sed "s/.*blkaddr:\([0-9a-fA-F]*\).*/0x\1/g"`
+orig_ext_len_val=`echo "$orig_ext" | sed "s/.*len:\([0-9a-fA-F]*\).*/0x\1/g"`
+echo "original i_extra_isize:" >> $OUT
+get_mb "$orig_node" i_extra_isize >> $OUT
+orig_extra_isize_val=`get_mb_val "$orig_node" i_extra_isize`
+echo "original i_nid[0]:" >> $OUT
+get_mb "$orig_node" 'i_nid\[0\]' >> $OUT
+orig_nid_val=0
+$INJECT --node --nid $ino --mb i_mode --val 0x1 $META >> $LOG
+$INJECT --node --nid $ino --mb i_advise --val 0x2 $META >> $LOG
+$INJECT --node --nid $ino --mb i_inline --val 0x3 $META >> $LOG
+$INJECT --node --nid $ino --mb i_links --val 0x4 $META >> $LOG
+$INJECT --node --nid $ino --mb i_size --val 0x5 $META >> $LOG
+$INJECT --node --nid $ino --mb i_blocks --val 0x6 $META >> $LOG
+$INJECT --node --nid $ino --mb i_ext.fofs --val 0x7 $META >> $LOG
+$INJECT --node --nid $ino --mb i_ext.blk_addr --val 0x8 $META >> $LOG
+$INJECT --node --nid $ino --mb i_ext.len --val 0x9 $META >> $LOG
+$INJECT --node --nid $ino --mb i_extra_isize --val 0xa $META >> $LOG
+$INJECT --node --nid $ino --mb i_inline_xattr_size --val 0xb $META >> $LOG
+$INJECT --node --nid $ino --mb i_nid --idx 0 --val 0xc $META >> $LOG
+cur_node=`$DUMP $DUMP_OPTS -i $ino -d 1 $META`
+echo "inject i_mode:" >> $OUT
+get_mb "$cur_node" i_mode >> $OUT
+echo "inject i_advise:" >> $OUT
+get_mb "$cur_node" i_advise >> $OUT
+echo "inject i_inline:" >> $OUT
+get_mb "$cur_node" i_inline >> $OUT
+echo "inject i_links:" >> $OUT
+get_mb "$cur_node" i_links >> $OUT
+echo "inject i_size:" >> $OUT
+get_mb "$cur_node" i_size >> $OUT
+echo "inject i_blocks:" >> $OUT
+get_mb "$cur_node" i_blocks >> $OUT
+echo "inject i_ext:" >> $OUT
+get_mb "$cur_node" 'i_ext:' >> $OUT
+echo "inject i_extra_isize:" >> $OUT
+get_mb "$cur_node" i_extra_isize >> $OUT
+echo "inject i_nid[0]:" >> $OUT
+get_mb "$cur_node" 'i_nid\[0\]' >> $OUT
+$INJECT --node --nid $ino --mb i_mode --val $orig_mode_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_advise --val $orig_advise_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_inline --val $orig_inline_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_links --val $orig_links_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_size --val $orig_size_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_blocks --val $orig_blocks_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_ext.fofs --val $orig_ext_fofs_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_ext.blk_addr --val $orig_ext_blkaddr_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_ext.len --val $orig_ext_len_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_extra_isize --val $orig_extra_isize_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_inline_xattr_size --val $orig_inline_xattr_size_val $META >> $LOG
+$INJECT --node --nid $ino --mb i_nid --idx 0 --val $orig_nid_val $META >> $LOG
+cur_node=`$DUMP $DUMP_OPTS -i $ino -d 1 $META`
+echo "restore i_mode:" >> $OUT
+get_mb "$cur_node" i_mode >> $OUT
+echo "restore i_advise:" >> $OUT
+get_mb "$cur_node" i_advise >> $OUT
+echo "restore i_inline:" >> $OUT
+get_mb "$cur_node" i_inline >> $OUT
+echo "restore i_links:" >> $OUT
+get_mb "$cur_node" i_links >> $OUT
+echo "restore i_size:" >> $OUT
+get_mb "$cur_node" i_size >> $OUT
+echo "restore i_blocks:" >> $OUT
+get_mb "$cur_node" i_blocks >> $OUT
+echo "restore i_ext:" >> $OUT
+get_mb "$cur_node" 'i_ext:' >> $OUT
+echo "restore i_extra_isize:" >> $OUT
+get_mb "$cur_node" i_extra_isize >> $OUT
+echo "restore i_nid[0]:" >> $OUT
+get_mb "$cur_node" 'i_nid\[0\]' >> $OUT
+
+$FSCK $FSCK_OPTS -f $META >> $LOG
+if [ $? -ne 0 ]; then
+ echo "fsck fail" >> $OUT
+fi
+
+hex=`printf "0x%x" $ino`
+sed "s/_INO_/$hex/g" $TESTDIR/expect.in > $TESTDIR/expect
+dec=$((orig_mode_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_MODE_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_MODE_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_advise_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_ADVISE_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_ADVISE_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_inline_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_INLINE_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_INLINE_DEC_/$dec/g" $TESTDIR/expect
+dec=$((orig_blocks_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_BLKS_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_BLKS_DEC_/$dec/g" $TESTDIR/expect
+hex=`printf "%x" $((orig_ext_fofs_val))`
+sed -i "s/_EXT_FOFS_/$hex/g" $TESTDIR/expect
+hex=`printf "%x" $((orig_ext_blkaddr_val))`
+sed -i "s/_EXT_BLKADDR_/$hex/g" $TESTDIR/expect
+hex=`printf "%x" $((orig_ext_len_val))`
+sed -i "s/_EXT_LEN_/$hex/g" $TESTDIR/expect
+dec=$((orig_extra_isize_val)); hex=`printf "0x%x" $dec`
+sed -i "s/_EXTRA_HEX_/$hex/g" $TESTDIR/expect
+sed -i "s/_EXTRA_DEC_/$dec/g" $TESTDIR/expect
+
+check_result
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions Sheng Yong
@ 2025-06-11 9:22 ` Chao Yu via Linux-f2fs-devel
2025-06-11 9:36 ` Sheng Yong
0 siblings, 1 reply; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-06-11 9:22 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 6/10/25 20:37, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
>
> In some scenario, such as autotest, it is not expected to answer
> question from fsck or dump. To simply answer no to all these questions,
> this patch adds an option `N' to do that.
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> fsck/dump.c | 3 +++
> fsck/fsck.c | 2 +-
> fsck/main.c | 14 +++++++++++---
> include/f2fs_fs.h | 1 +
> 4 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/fsck/dump.c b/fsck/dump.c
> index 66d6c791ae09..10df7e593bfe 100644
> --- a/fsck/dump.c
> +++ b/fsck/dump.c
> @@ -681,6 +681,9 @@ static int dump_filesystem(struct f2fs_sb_info *sbi, struct node_info *ni,
> if (c.show_file_map)
> return dump_inode_blk(sbi, ni->ino, node_blk);
>
> + if (c.answer_no)
> + return 0;
> +
> printf("Do you want to dump this %s into %s/? [Y/N] ",
> S_ISDIR(imode) ? "folder" : "file",
> base_path);
> diff --git a/fsck/fsck.c b/fsck/fsck.c
> index 4d05e1b4a21b..14677128dc2d 100644
> --- a/fsck/fsck.c
> +++ b/fsck/fsck.c
> @@ -3834,7 +3834,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)
> }
>
> #ifndef WITH_ANDROID
> - if (nr_unref_nid && !c.ro) {
> + if (nr_unref_nid && !c.ro && !c.answer_no) {
> char ans[255] = {0};
> int res;
>
> diff --git a/fsck/main.c b/fsck/main.c
> index c5d41597934a..b01a22c8cf53 100644
> --- a/fsck/main.c
> +++ b/fsck/main.c
> @@ -86,6 +86,7 @@ void fsck_usage()
> MSG(0, " -t show directory tree\n");
> MSG(0, " -q preserve quota limits\n");
> MSG(0, " -y fix all the time\n");
> + MSG(0, " -N answer \"No\" for all questions\n");
> MSG(0, " -V print the version number and exit\n");
> MSG(0, " --dry-run do not really fix corruptions\n");
> MSG(0, " --no-kernel-check skips detecting kernel change\n");
> @@ -114,6 +115,7 @@ void dump_usage()
> MSG(0, " -f do not prompt before dumping\n");
> MSG(0, " -H support write hint\n");
> MSG(0, " -y alias for -f\n");
> + MSG(0, " -N answer \"No\" for all questions\n");
> MSG(0, " -o dump inodes to the given path\n");
> MSG(0, " -P preserve mode/owner/group for dumped inode\n");
> MSG(0, " -L Preserves symlinks. Otherwise symlinks are dumped as regular files.\n");
It needs to update manual of fsck.f2fs and dump.f2fs as well?
Thanks,
> @@ -263,7 +265,7 @@ void f2fs_parse_options(int argc, char *argv[])
> }
>
> if (!strcmp("fsck.f2fs", prog)) {
> - const char *option_string = ":aC:c:m:Md:fg:HlO:p:q:StyV";
> + const char *option_string = ":aC:c:m:Md:fg:HlO:p:q:StyNV";
> int opt = 0, val;
> char *token;
> struct option long_opt[] = {
> @@ -396,6 +398,9 @@ void f2fs_parse_options(int argc, char *argv[])
> c.force = 1;
> MSG(0, "Info: Force to fix corruption\n");
> break;
> + case 'N':
> + c.answer_no = true;
> + break;
> case 'q':
> c.preserve_limits = atoi(optarg);
> MSG(0, "Info: Preserve quota limits = %d\n",
> @@ -449,7 +454,7 @@ void f2fs_parse_options(int argc, char *argv[])
> }
> } else if (!strcmp("dump.f2fs", prog)) {
> #ifdef WITH_DUMP
> - const char *option_string = "d:fi:I:n:LMo:Prs:Sa:b:Vy";
> + const char *option_string = "d:fi:I:n:LMo:Prs:Sa:b:VyN";
> static struct dump_option dump_opt = {
> .nid = 0, /* default root ino */
> .start_nat = -1,
> @@ -527,6 +532,9 @@ void f2fs_parse_options(int argc, char *argv[])
> case 'f':
> c.force = 1;
> break;
> + case 'N':
> + c.answer_no = true;
> + break;
> case 'r':
> dump_opt.use_root_nid = 1;
> break;
> @@ -1369,7 +1377,7 @@ fsck_again:
>
> f2fs_do_umount(sbi);
>
> - if (c.func == FSCK && c.bug_on) {
> + if (c.func == FSCK && c.bug_on && !c.answer_no) {
> if (!c.ro && c.fix_on == 0 && c.auto_fix == 0 && !c.dry_run) {
> char ans[255] = {0};
> retry:
> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
> index f7268d1e90ff..5cd4ad666c06 100644
> --- a/include/f2fs_fs.h
> +++ b/include/f2fs_fs.h
> @@ -1593,6 +1593,7 @@ struct f2fs_configuration {
> int whint;
> int aliased_devices;
> uint32_t aliased_segments;
> + bool answer_no;
>
> /* mkfs parameters */
> int fake_seed;
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions
2025-06-11 9:22 ` Chao Yu via Linux-f2fs-devel
@ 2025-06-11 9:36 ` Sheng Yong
0 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-11 9:36 UTC (permalink / raw)
To: Chao Yu, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 6/11/25 17:22, Chao Yu wrote:
> On 6/10/25 20:37, Sheng Yong wrote:
>> From: Sheng Yong <shengyong1@xiaomi.com>
>>
>> In some scenario, such as autotest, it is not expected to answer
>> question from fsck or dump. To simply answer no to all these questions,
>> this patch adds an option `N' to do that.
>>
>> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
>> ---
[...]
>> diff --git a/fsck/main.c b/fsck/main.c
>> index c5d41597934a..b01a22c8cf53 100644
>> --- a/fsck/main.c
>> +++ b/fsck/main.c
>> @@ -86,6 +86,7 @@ void fsck_usage()
>> MSG(0, " -t show directory tree\n");
>> MSG(0, " -q preserve quota limits\n");
>> MSG(0, " -y fix all the time\n");
>> + MSG(0, " -N answer \"No\" for all questions\n");
>> MSG(0, " -V print the version number and exit\n");
>> MSG(0, " --dry-run do not really fix corruptions\n");
>> MSG(0, " --no-kernel-check skips detecting kernel change\n");
>> @@ -114,6 +115,7 @@ void dump_usage()
>> MSG(0, " -f do not prompt before dumping\n");
>> MSG(0, " -H support write hint\n");
>> MSG(0, " -y alias for -f\n");
>> + MSG(0, " -N answer \"No\" for all questions\n");
>> MSG(0, " -o dump inodes to the given path\n");
>> MSG(0, " -P preserve mode/owner/group for dumped inode\n");
>> MSG(0, " -L Preserves symlinks. Otherwise symlinks are dumped as regular files.\n");
>
> It needs to update manual of fsck.f2fs and dump.f2fs as well?
Hi, Chao,
Yes, manual should be updated. I'll add the description in the next version.
Thanks,
shengyong
>
> Thanks,
>
[...]
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 07/32] inject.f2fs: fix injecting sit/nat in journal
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 07/32] inject.f2fs: fix injecting sit/nat in journal Sheng Yong
@ 2025-06-11 11:42 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-06-11 11:42 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 6/10/25 20:37, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
>
> Previously when injecting sit/nat entry, we only inject SIT/NAT pack.
> If the valid target is in journal, the injection has no effect. So we
> have to check whether the valid target is in journal, and inject the
> target at its valid position.
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> fsck/inject.c | 181 ++++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 132 insertions(+), 49 deletions(-)
>
> diff --git a/fsck/inject.c b/fsck/inject.c
> index bd6ab8480972..b3228621de48 100644
> --- a/fsck/inject.c
> +++ b/fsck/inject.c
> @@ -10,6 +10,7 @@
> */
>
> #include <getopt.h>
> +#include "f2fs.h"
> #include "node.h"
> #include "inject.h"
>
> @@ -533,6 +534,31 @@ out:
> return ret;
> }
>
> +static void rewrite_nat_in_journal(struct f2fs_sb_info *sbi, u32 nid,
> + struct f2fs_nat_entry *nat)
> +{
> + struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
> + struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA);
> + struct f2fs_journal *journal = F2FS_SUMMARY_BLOCK_JOURNAL(curseg->sum_blk);
> + block_t blkaddr;
> + int ret, i;
> +
> + for (i = 0; i < nats_in_cursum(journal); i++) {
> + if (nid_in_journal(journal, i) == nid) {
> + memcpy(&nat_in_journal(journal, i), nat, sizeof(*nat));
> + break;
> + }
> + }
> +
> + if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG))
> + blkaddr = sum_blk_addr(sbi, NR_CURSEG_TYPE, CURSEG_HOT_DATA);
> + else
> + blkaddr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, CURSEG_HOT_DATA);
> +
> + ret = dev_write_block(curseg->sum_blk, blkaddr, WRITE_LIFE_NONE);
> + ASSERT(ret >= 0);
> +}
> +
> static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
> {
> struct f2fs_nm_info *nm_i = NM_I(sbi);
> @@ -541,7 +567,7 @@ static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
> struct f2fs_nat_entry *ne;
> block_t blk_addr;
> unsigned int offs;
> - bool is_set;
> + bool is_set, in_journal = false;
> int ret;
>
> if (!IS_VALID_NID(sbi, opt->nid)) {
> @@ -555,38 +581,49 @@ static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
> nat_blk = calloc(F2FS_BLKSIZE, 1);
> ASSERT(nat_blk);
>
> - /* change NAT version bitmap temporarily to select specified pack */
> - is_set = f2fs_test_bit(opt->nid, nm_i->nat_bitmap);
> - if (opt->nat == 0) {
> - opt->nat = is_set ? 2 : 1;
> + if (lookup_nat_in_journal(sbi, opt->nid, &nat_blk->entries[0]) >= 0) {
Yong,
If we found an existed nat entry in journal, what about getting log_type
from return value of lookup_nat_in_journal, and then call
rewrite_nat_in_journal(, log_type) to rewrite nat entry to original position?
> + offs = 0;
> + in_journal = true;
> } else {
> - if (opt->nat == 1)
> - f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
> - else
> - f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
> + /*
> + * read nat entry from NAT area, change NAT version bitmap
> + * temporarily to select specified pack
> + */
> + is_set = f2fs_test_bit(opt->nid, nm_i->nat_bitmap);
> + if (opt->nat == 0) {
> + opt->nat = is_set ? 2 : 1;
> + } else {
> + if (opt->nat == 1)
> + f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
> + else
> + f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
> + }
> + blk_addr = current_nat_addr(sbi, opt->nid, NULL);
> + ret = dev_read_block(nat_blk, blk_addr);
> + ASSERT(ret >= 0);
> + offs = opt->nid % NAT_ENTRY_PER_BLOCK;
> }
> -
> - blk_addr = current_nat_addr(sbi, opt->nid, NULL);
> -
> - ret = dev_read_block(nat_blk, blk_addr);
> - ASSERT(ret >= 0);
> -
> - offs = opt->nid % NAT_ENTRY_PER_BLOCK;
> ne = &nat_blk->entries[offs];
>
> if (!strcmp(opt->mb, "version")) {
> MSG(0, "Info: inject nat entry version of nid %u "
> - "in pack %d: %d -> %d\n", opt->nid, opt->nat,
> + "in %s %d: %d -> %d\n", opt->nid,
> + in_journal ? "journal" : "pack",
> + in_journal ? 0 : opt->nat,
> ne->version, (u8)opt->val);
> ne->version = (u8)opt->val;
> } else if (!strcmp(opt->mb, "ino")) {
> MSG(0, "Info: inject nat entry ino of nid %u "
> - "in pack %d: %d -> %d\n", opt->nid, opt->nat,
> + "in %s %d: %d -> %d\n", opt->nid,
> + in_journal ? "journal" : "pack",
> + in_journal ? 0 : opt->nat,
> le32_to_cpu(ne->ino), (nid_t)opt->val);
> ne->ino = cpu_to_le32((nid_t)opt->val);
> } else if (!strcmp(opt->mb, "block_addr")) {
> MSG(0, "Info: inject nat entry block_addr of nid %u "
> - "in pack %d: 0x%x -> 0x%x\n", opt->nid, opt->nat,
> + "in %s %d: 0x%x -> 0x%x\n", opt->nid,
> + in_journal ? "journal" : "pack",
> + in_journal ? 0 : opt->nat,
> le32_to_cpu(ne->block_addr), (block_t)opt->val);
> ne->block_addr = cpu_to_le32((block_t)opt->val);
> } else {
> @@ -596,16 +633,45 @@ static int inject_nat(struct f2fs_sb_info *sbi, struct inject_option *opt)
> }
> print_raw_nat_entry_info(ne);
>
> - ret = dev_write_block(nat_blk, blk_addr, WRITE_LIFE_NONE);
> - ASSERT(ret >= 0);
> - /* restore NAT version bitmap */
> - if (is_set)
> - f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
> - else
> - f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
> + if (in_journal) {
> + rewrite_nat_in_journal(sbi, opt->nid, ne);
> + } else {
> + ret = dev_write_block(nat_blk, blk_addr, WRITE_LIFE_NONE);
> + ASSERT(ret >= 0);
> + /* restore NAT version bitmap */
> + if (is_set)
> + f2fs_set_bit(opt->nid, nm_i->nat_bitmap);
> + else
> + f2fs_clear_bit(opt->nid, nm_i->nat_bitmap);
> + }
>
> free(nat_blk);
> - return ret;
> + return 0;
> +}
> +
> +static void rewrite_sit_in_journal(struct f2fs_sb_info *sbi, unsigned int segno,
> + struct f2fs_sit_entry *sit)
> +{
> + struct f2fs_checkpoint *cp = F2FS_CKPT(sbi);
> + struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_COLD_DATA);
> + struct f2fs_journal *journal = F2FS_SUMMARY_BLOCK_JOURNAL(curseg->sum_blk);
> + block_t blkaddr;
> + int ret, i;
> +
> + for (i = 0; i < sits_in_cursum(journal); i++) {
> + if (segno_in_journal(journal, i) == segno) {
> + memcpy(&sit_in_journal(journal, i), sit, sizeof(*sit));
> + break;
> + }
> + }
> +
> + if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG))
> + blkaddr = sum_blk_addr(sbi, NR_CURSEG_TYPE, CURSEG_COLD_DATA);
> + else
> + blkaddr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, CURSEG_COLD_DATA);
> +
> + ret = dev_write_block(curseg->sum_blk, blkaddr, WRITE_LIFE_NONE);
> + ASSERT(ret >= 0);
> }
>
> static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
> @@ -614,7 +680,7 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
> struct f2fs_sit_block *sit_blk;
> struct f2fs_sit_entry *sit;
> unsigned int segno, offs;
> - bool is_set;
> + bool is_set, in_journal = false;
>
> if (!f2fs_is_valid_blkaddr(sbi, opt->blk, DATA_GENERIC)) {
> ERR_MSG("Invalid blkaddr 0x%x (valid range [0x%x:0x%lx])\n",
> @@ -627,29 +693,39 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
> ASSERT(sit_blk);
>
> segno = GET_SEGNO(sbi, opt->blk);
> - /* change SIT version bitmap temporarily to select specified pack */
> - is_set = f2fs_test_bit(segno, sit_i->sit_bitmap);
> - if (opt->sit == 0) {
> - opt->sit = is_set ? 2 : 1;
> + if (lookup_sit_in_journal(sbi, segno, &sit_blk->entries[0]) >= 0) {
Ditto,
Thanks,
> + offs = 0;
> + in_journal = true;
> } else {
> - if (opt->sit == 1)
> - f2fs_clear_bit(segno, sit_i->sit_bitmap);
> - else
> - f2fs_set_bit(segno, sit_i->sit_bitmap);
> + /*
> + * read sit entry from SIT area, change SIT version bitmap
> + * temporarily to select specified pack
> + */
> + is_set = f2fs_test_bit(segno, sit_i->sit_bitmap);
> + if (opt->sit == 0) {
> + opt->sit = is_set ? 2 : 1;
> + } else {
> + if (opt->sit == 1)
> + f2fs_clear_bit(segno, sit_i->sit_bitmap);
> + else
> + f2fs_set_bit(segno, sit_i->sit_bitmap);
> + }
> + get_current_sit_page(sbi, segno, sit_blk);
> + offs = SIT_ENTRY_OFFSET(sit_i, segno);
> }
> - get_current_sit_page(sbi, segno, sit_blk);
> - offs = SIT_ENTRY_OFFSET(sit_i, segno);
> sit = &sit_blk->entries[offs];
>
> if (!strcmp(opt->mb, "vblocks")) {
> MSG(0, "Info: inject sit entry vblocks of block 0x%x "
> - "in pack %d: %u -> %u\n", opt->blk, opt->sit,
> + "in %s %d: %u -> %u\n", opt->blk,
> + in_journal ? "journal" : "pack",
> + in_journal ? 0 : opt->sit,
> le16_to_cpu(sit->vblocks), (u16)opt->val);
> sit->vblocks = cpu_to_le16((u16)opt->val);
> } else if (!strcmp(opt->mb, "valid_map")) {
> if (opt->idx == -1) {
> - MSG(0, "Info: auto idx = %u\n", offs);
> - opt->idx = offs;
> + opt->idx = OFFSET_IN_SEG(sbi, opt->blk);
> + MSG(0, "Info: auto idx = %u\n", opt->idx);
> }
> if (opt->idx >= SIT_VBLOCK_MAP_SIZE) {
> ERR_MSG("invalid idx %u of valid_map[]\n", opt->idx);
> @@ -657,8 +733,10 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
> return -ERANGE;
> }
> MSG(0, "Info: inject sit entry valid_map[%d] of block 0x%x "
> - "in pack %d: 0x%02x -> 0x%02x\n", opt->idx, opt->blk,
> - opt->sit, sit->valid_map[opt->idx], (u8)opt->val);
> + "in %s %d: 0x%02x -> 0x%02x\n", opt->idx, opt->blk,
> + in_journal ? "journal" : "pack",
> + in_journal ? 0 : opt->sit,
> + sit->valid_map[opt->idx], (u8)opt->val);
> sit->valid_map[opt->idx] = (u8)opt->val;
> } else if (!strcmp(opt->mb, "mtime")) {
> MSG(0, "Info: inject sit entry mtime of block 0x%x "
> @@ -672,12 +750,17 @@ static int inject_sit(struct f2fs_sb_info *sbi, struct inject_option *opt)
> }
> print_raw_sit_entry_info(sit);
>
> - rewrite_current_sit_page(sbi, segno, sit_blk);
> - /* restore SIT version bitmap */
> - if (is_set)
> - f2fs_set_bit(segno, sit_i->sit_bitmap);
> - else
> - f2fs_clear_bit(segno, sit_i->sit_bitmap);
> + if (in_journal) {
> + rewrite_sit_in_journal(sbi, segno, sit);
> + } else {
> + rewrite_current_sit_page(sbi, segno, sit_blk);
> +
> + /* restore SIT version bitmap */
> + if (is_set)
> + f2fs_set_bit(segno, sit_i->sit_bitmap);
> + else
> + f2fs_clear_bit(segno, sit_i->sit_bitmap);
> + }
>
> free(sit_blk);
> return 0;
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options Sheng Yong
@ 2025-06-13 6:08 ` Chao Yu via Linux-f2fs-devel
2025-06-16 1:49 ` Sheng Yong
0 siblings, 1 reply; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-06-13 6:08 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 2025/6/10 20:37, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
>
> This patch fixes:
> * parsing hex optarg of --idx option
> * converting -1 to 0xff...ff of --val option
> and do a little cleanup of converting string to a long integer.
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> fsck/inject.c | 32 +++++++++++++++++---------------
> 1 file changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/fsck/inject.c b/fsck/inject.c
> index 96817a806f8f..c879ca99c0d8 100644
> --- a/fsck/inject.c
> +++ b/fsck/inject.c
> @@ -236,8 +236,9 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
>
> while ((o = getopt_long(argc, argv, option_string,
> long_opt, NULL)) != EOF) {
> - long nid, blk;
> + long long val;
>
> + errno = 0;
> switch (o) {
> case 1:
> c.dry_run = 1;
> @@ -248,18 +249,19 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> MSG(0, "Info: inject member %s\n", optarg);
> break;
> case 3:
> - if (!is_digits(optarg))
> - return EWRONG_OPT;
> - opt->idx = atoi(optarg);
> - MSG(0, "Info: inject slot index %d\n", opt->idx);
> + val = strtoll(optarg, &endptr, 0);
> + if (errno != 0 || val >= UINT_MAX || val < 0 ||
UINT_MAX is a possible injectable value? if so, it need to use "val > UINT_MAX"?
> + *endptr != '\0')
> + return -ERANGE;
> + opt->idx = (unsigned int)val;
> + MSG(0, "Info: inject slot index %u\n", opt->idx);
> break;
> case 4:
> - opt->val = strtoll(optarg, &endptr, 0);
> - if (opt->val == LLONG_MAX || opt->val == LLONG_MIN ||
> - *endptr != '\0')
> + opt->val = strtoull(optarg, &endptr, 0);
> + if (errno != 0 || *endptr != '\0')
> return -ERANGE;
> MSG(0, "Info: inject value %lld : 0x%llx\n", opt->val,
> - (unsigned long long)opt->val);
> + opt->val);
> break;
> case 5:
> opt->str = strdup(optarg);
> @@ -292,11 +294,11 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> MSG(0, "Info: inject nat pack %s\n", pack[opt->nat]);
> break;
> case 9:
> - nid = strtol(optarg, &endptr, 0);
> - if (nid >= UINT_MAX || nid < 0 ||
> + val = strtoll(optarg, &endptr, 0);
> + if (errno != 0 || val >= UINT_MAX || val < 0 ||
> *endptr != '\0')
> return -ERANGE;
> - opt->nid = nid;
> + opt->nid = (nid_t)val;
> MSG(0, "Info: inject nid %u : 0x%x\n", opt->nid, opt->nid);
> break;
> case 10:
> @@ -308,11 +310,11 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> MSG(0, "Info: inject sit pack %s\n", pack[opt->sit]);
> break;
> case 11:
> - blk = strtol(optarg, &endptr, 0);
> - if (blk >= UINT_MAX || blk < 0 ||
> + val = strtoll(optarg, &endptr, 0);
> + if (errno != 0 || val >= UINT_MAX || val < 0 ||
> *endptr != '\0')
> return -ERANGE;
> - opt->blk = blk;
> + opt->blk = (block_t)val;
> MSG(0, "Info: inject blkaddr %u : 0x%x\n", opt->blk, opt->blk);
> break;
> case 12:
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 10/32] inject.f2fs: add members in inject_cp
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 10/32] inject.f2fs: add members in inject_cp Sheng Yong
@ 2025-06-13 7:30 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-06-13 7:30 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 2025/6/10 20:37, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
>
> The following members are added to inject more fields in cp:
>
> * next_blkaddr: inject fsync dnodes
>
> An error is returned if no fsync dnode is found.
>
> However, the injection is not supported on zoned device. This is because
> fsync dnodes must remains at the end of current warm node segment, any
> dnode change causes all previous dnodes in the chain to be updated
> out-of-place, and there may not have enough space left in the curseg.
> To simplify the injection, it returns an error on zoned device.
>
> * alloc_type: inject curseg's alloc type
> * crc: inject cp's checksum
> * elapsed_time: inject cp's mount elapsed time
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> fsck/fsck.h | 4 ++-
> fsck/inject.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++-
> fsck/mount.c | 18 +++++-----
> man/inject.f2fs.8 | 11 +++++-
> 4 files changed, 107 insertions(+), 11 deletions(-)
>
> diff --git a/fsck/fsck.h b/fsck/fsck.h
> index 40cb6d9a6417..05daa2de9531 100644
> --- a/fsck/fsck.h
> +++ b/fsck/fsck.h
> @@ -223,6 +223,8 @@ extern int f2fs_ra_meta_pages(struct f2fs_sb_info *, block_t, int, int);
> extern int f2fs_do_mount(struct f2fs_sb_info *);
> extern void f2fs_do_umount(struct f2fs_sb_info *);
> extern int f2fs_sparse_initialize_meta(struct f2fs_sb_info *);
> +extern int f2fs_find_fsync_inode(struct f2fs_sb_info *, struct list_head *);
> +extern void f2fs_destroy_fsync_dnodes(struct list_head *);
>
> extern void flush_journal_entries(struct f2fs_sb_info *);
> extern void update_curseg_info(struct f2fs_sb_info *, int);
> @@ -239,7 +241,7 @@ extern void duplicate_checkpoint(struct f2fs_sb_info *);
> extern void write_checkpoint(struct f2fs_sb_info *);
> extern void write_checkpoints(struct f2fs_sb_info *);
> extern void write_raw_cp_blocks(struct f2fs_sb_info *sbi,
> - struct f2fs_checkpoint *cp, int which);
> + struct f2fs_checkpoint *cp, int which, bool update_crc);
> extern void update_superblock(struct f2fs_super_block *, int);
> extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t,
> struct f2fs_node *);
> diff --git a/fsck/inject.c b/fsck/inject.c
> index c879ca99c0d8..53667730775f 100644
> --- a/fsck/inject.c
> +++ b/fsck/inject.c
> @@ -139,6 +139,10 @@ static void inject_cp_usage(void)
> MSG(0, " cur_node_blkoff: inject cur_node_blkoff array selected by --idx <index>\n");
> MSG(0, " cur_data_segno: inject cur_data_segno array selected by --idx <index>\n");
> MSG(0, " cur_data_blkoff: inject cur_data_blkoff array selected by --idx <index>\n");
> + MSG(0, " alloc_type: inject alloc_type array selected by --idx <index>\n");
> + MSG(0, " next_blkaddr: inject next_blkaddr of fsync dnodes selected by --idx <index>\n");
> + MSG(0, " crc: inject crc checksum\n");
> + MSG(0, " elapsed_time: inject elapsed_time\n");
> }
>
> static void inject_nat_usage(void)
> @@ -443,6 +447,7 @@ out:
> static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
> {
> struct f2fs_checkpoint *cp, *cur_cp = F2FS_CKPT(sbi);
> + bool update_crc = true;
> char *buf = NULL;
> int ret = 0;
>
> @@ -521,6 +526,84 @@ static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
> opt->idx, opt->cp, get_cp(cur_data_blkoff[opt->idx]),
> (u16)opt->val);
> set_cp(cur_data_blkoff[opt->idx], (u16)opt->val);
> + } else if (!strcmp(opt->mb, "alloc_type")) {
> + if (opt->idx >= MAX_ACTIVE_LOGS) {
> + ERR_MSG("invalid index %u of cp->alloc_type[]\n",
> + opt->idx);
> + ret = -EINVAL;
> + goto out;
> + }
> + MSG(0, "Info: inject alloc_type[%d] of cp %d: 0x%x -> 0x%x\n",
> + opt->idx, opt->cp, cp->alloc_type[opt->idx],
> + (unsigned char)opt->val);
> + cp->alloc_type[opt->idx] = (unsigned char)opt->val;
> + } else if (!strcmp(opt->mb, "next_blkaddr")) {
> + struct fsync_inode_entry *entry;
> + struct list_head inode_list = LIST_HEAD_INIT(inode_list);
> + struct f2fs_node *node;
> + block_t blkaddr;
> + int i = 0;
> +
> + if (c.zoned_model == F2FS_ZONED_HM) {
> + ERR_MSG("inject fsync dnodes not supported in "
> + "zoned device\n");
> + ret = -EOPNOTSUPP;
> + goto out;
> + }
> +
> + if (!need_fsync_data_record(sbi)) {
> + ERR_MSG("no need to recover fsync dnodes\n");
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + ret = f2fs_find_fsync_inode(sbi, &inode_list);
> + if (ret) {
> + ERR_MSG("failed to find fsync inodes: %d\n", ret);
> + goto out;
> + }
> +
> + list_for_each_entry(entry, &inode_list, list) {
> + if (i == opt->idx)
> + blkaddr = entry->blkaddr;
> + DBG(0, "[%4d] blkaddr:0x%x\n", i++, entry->blkaddr);
> + }
> +
> + f2fs_destroy_fsync_dnodes(&inode_list);
> +
> + if (opt->idx == 0 || opt->idx >= i) {
> + ERR_MSG("invalid index %u of fsync dnodes range [1, %u]\n",
... [0, %u]\n", opt->idx, i - 1);?
> + opt->idx, i);
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + MSG(0, "Info: inject next_blkaddr[%d] of cp %d: 0x%x -> 0x%x\n",
> + opt->idx, opt->cp, blkaddr, (u32)opt->val);
> +
> + node = malloc(F2FS_BLKSIZE);
> + ASSERT(node);
> + ret = dev_read_block(node, blkaddr);
> + ASSERT(ret >= 0);
> + F2FS_NODE_FOOTER(node)->next_blkaddr = cpu_to_le32((u32)opt->val);
> + if (IS_INODE(node))
> + ret = update_inode(sbi, node, &blkaddr);
> + else
> + ret = update_block(sbi, node, &blkaddr, NULL);
free(node);
Thanks,
> + ASSERT(ret >= 0);
> + goto out;
> + } else if (!strcmp(opt->mb, "crc")) {
> + __le32 *crc = (__le32 *)((unsigned char *)cp +
> + get_cp(checksum_offset));
> +
> + MSG(0, "Info: inject crc of cp %d: 0x%x -> 0x%x\n",
> + opt->cp, le32_to_cpu(*crc), (u32)opt->val);
> + *crc = cpu_to_le32((u32)opt->val);
> + update_crc = false;
> + } else if (!strcmp(opt->mb, "elapsed_time")) {
> + MSG(0, "Info: inject elapsed_time of cp %d: %llu -> %"PRIu64"\n",
> + opt->cp, get_cp(elapsed_time), (u64)opt->val);
> + set_cp(elapsed_time, (u64)opt->val);
> } else {
> ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
> ret = -EINVAL;
> @@ -528,7 +611,7 @@ static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
> }
>
> print_ckpt_info(sbi);
> - write_raw_cp_blocks(sbi, cp, opt->cp);
> + write_raw_cp_blocks(sbi, cp, opt->cp, update_crc);
>
> out:
> free(buf);
> diff --git a/fsck/mount.c b/fsck/mount.c
> index 1f2cc960b9c0..eb019ad6826e 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -3503,17 +3503,19 @@ void write_checkpoints(struct f2fs_sb_info *sbi)
> write_checkpoint(sbi);
> }
>
> -void write_raw_cp_blocks(struct f2fs_sb_info *sbi,
> - struct f2fs_checkpoint *cp, int which)
> +void write_raw_cp_blocks(struct f2fs_sb_info *sbi, struct f2fs_checkpoint *cp,
> + int which, bool update_crc)
> {
> struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
> uint32_t crc;
> block_t cp_blkaddr;
> int ret;
>
> - crc = f2fs_checkpoint_chksum(cp);
> - *((__le32 *)((unsigned char *)cp + get_cp(checksum_offset))) =
> + if (update_crc) {
> + crc = f2fs_checkpoint_chksum(cp);
> + *((__le32 *)((unsigned char *)cp + get_cp(checksum_offset))) =
> cpu_to_le32(crc);
> + }
>
> cp_blkaddr = get_sb(cp_blkaddr);
> if (which == 2)
> @@ -3747,7 +3749,7 @@ static void del_fsync_inode(struct fsync_inode_entry *entry)
> free(entry);
> }
>
> -static void destroy_fsync_dnodes(struct list_head *head)
> +void f2fs_destroy_fsync_dnodes(struct list_head *head)
> {
> struct fsync_inode_entry *entry, *tmp;
>
> @@ -3853,7 +3855,7 @@ static int sanity_check_node_chain(struct f2fs_sb_info *sbi,
> return 0;
> }
>
> -static int find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
> +int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
> {
> struct curseg_info *curseg;
> struct f2fs_node *node_blk, *node_blk_fast;
> @@ -4049,7 +4051,7 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
> if (!need_fsync_data_record(sbi))
> return 0;
>
> - ret = find_fsync_inode(sbi, &inode_list);
> + ret = f2fs_find_fsync_inode(sbi, &inode_list);
> if (ret)
> goto out;
>
> @@ -4064,7 +4066,7 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
>
> ret = traverse_dnodes(sbi, &inode_list);
> out:
> - destroy_fsync_dnodes(&inode_list);
> + f2fs_destroy_fsync_dnodes(&inode_list);
> return ret;
> }
>
> diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
> index 01d58effbfe4..975d8c65030a 100644
> --- a/man/inject.f2fs.8
> +++ b/man/inject.f2fs.8
> @@ -45,7 +45,7 @@ The available \fImb\fP of \fIsb\fP are:
> .RS 1.2i
> .TP
> .BI magic
> -magic numbe.
> +magic number.
> .TP
> .BI s_stop_reason
> s_stop_reason array.
> @@ -79,6 +79,15 @@ cur_data_segno array.
> .TP
> .BI cur_data_blkoff
> cur_data_blkoff array.
> +.TP
> +.BI next_blkaddr
> +fsync dnodes.
> +.TP
> +.BI crc
> +crc checksum.
> +.TP
> +.BI elapsed_time
> +elapsed mount time.
> .RE
> .TP
> .BI \-\-nat " 0 or 1 or 2"
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 12/32] inject.f2fs: add members in inject_node
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 12/32] inject.f2fs: add members in inject_node Sheng Yong
@ 2025-06-13 7:38 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-06-13 7:38 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 2025/6/10 20:37, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
>
> This patch adds new members in inject_node to inject inode:
> * i_ext.fofs: extent fofs
> * i_ext.blk_addr: extent blk_addr
> * i_ext.len: extent len
> * i_inline_xattr_size: inline xattr size
> * i_compr_blocks: compression blocks
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> fsck/inject.c | 28 ++++++++++++++++++++++++++++
> man/inject.f2fs.8 | 17 ++++++++++++++++-
> 2 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/fsck/inject.c b/fsck/inject.c
> index 0b5aecbf8061..8c2f8c5dc332 100644
> --- a/fsck/inject.c
> +++ b/fsck/inject.c
> @@ -198,8 +198,13 @@ static void inject_node_usage(void)
> MSG(0, " i_links: inject inode i_links\n");
> MSG(0, " i_size: inject inode i_size\n");
> MSG(0, " i_blocks: inject inode i_blocks\n");
> + MSG(0, " i_ext.fofs: inject inode i_ext.fofs\n");
> + MSG(0, " i_ext.blk_addr: inject inode i_ext.blk_addr\n");
> + MSG(0, " i_ext.len: inject inode i_ext.len\n");
> MSG(0, " i_extra_isize: inject inode i_extra_isize\n");
> + MSG(0, " i_inline_xattr_size: inject inode i_inline_xattr_size\n");
> MSG(0, " i_inode_checksum: inject inode i_inode_checksum\n");
> + MSG(0, " i_compr_blocks: inject inode i_compr_blocks\n");
> MSG(0, " i_addr: inject inode i_addr array selected by --idx <index>\n");
> MSG(0, " i_nid: inject inode i_nid array selected by --idx <index>\n");
> MSG(0, " addr: inject {in}direct node nid/addr array selected by --idx <index>\n");
> @@ -967,16 +972,39 @@ static int inject_inode(struct f2fs_sb_info *sbi, struct f2fs_node *node,
> MSG(0, "Info: inject inode i_blocks of nid %u: %"PRIu64" -> %"PRIu64"\n",
> opt->nid, le64_to_cpu(inode->i_blocks), (u64)opt->val);
> inode->i_blocks = cpu_to_le64((u64)opt->val);
> + } else if (!strcmp(opt->mb, "i_ext.fofs")) {
> + MSG(0, "Info: inject inode i_ext.fofs of nid %u: %u -> %u\n",
> + opt->nid, le32_to_cpu(inode->i_ext.fofs), (u32)opt->val);
> + inode->i_ext.fofs = cpu_to_le32((u32)opt->val);
> + } else if (!strcmp(opt->mb, "i_ext.blk_addr")) {
> + MSG(0, "Info: inject inode i_ext.blk_addr of nid %u: "
> + "0x%x -> 0x%x\n", opt->nid,
> + le32_to_cpu(inode->i_ext.blk_addr), (u32)opt->val);
> + inode->i_ext.blk_addr = cpu_to_le32((u32)opt->val);
> + } else if (!strcmp(opt->mb, "i_ext.len")) {
> + MSG(0, "Info: inject inode i_ext.len of nid %u: %u -> %u\n",
> + opt->nid, le32_to_cpu(inode->i_ext.len), (u32)opt->val);
> + inode->i_ext.len = cpu_to_le32((u32)opt->val);
> } else if (!strcmp(opt->mb, "i_extra_isize")) {
> /* do not care if F2FS_EXTRA_ATTR is enabled */
> MSG(0, "Info: inject inode i_extra_isize of nid %u: %d -> %d\n",
> opt->nid, le16_to_cpu(inode->i_extra_isize), (u16)opt->val);
> inode->i_extra_isize = cpu_to_le16((u16)opt->val);
> + } else if (!strcmp(opt->mb, "i_inline_xattr_size")) {
> + MSG(0, "Info: inject inode i_inline_xattr_size of nid %u: "
> + "%d -> %d\n", opt->nid,
> + le16_to_cpu(inode->i_inline_xattr_size), (u16)opt->val);
> + inode->i_inline_xattr_size = cpu_to_le16((u16)opt->val);
> } else if (!strcmp(opt->mb, "i_inode_checksum")) {
> MSG(0, "Info: inject inode i_inode_checksum of nid %u: "
> "0x%x -> 0x%x\n", opt->nid,
> le32_to_cpu(inode->i_inode_checksum), (u32)opt->val);
> inode->i_inode_checksum = cpu_to_le32((u32)opt->val);
> + } else if (!strcmp(opt->mb, "i_compr_blocks")) {
> + MSG(0, "Info: inject inode i_compr_blocks of nid %u: "
> + "%lu -> %lu\n", opt->nid,
%llu -> %llu
> + le64_to_cpu(inode->i_compr_blocks), (u64)opt->val);
> + inode->i_compr_blocks = cpu_to_le64((u64)opt->val);
> } else if (!strcmp(opt->mb, "i_addr")) {
> /* do not care if it is inline data */
> if (opt->idx >= DEF_ADDRS_PER_INODE) {
> diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
> index 5ae556015a79..72d1c90f7ce4 100644
> --- a/man/inject.f2fs.8
> +++ b/man/inject.f2fs.8
> @@ -145,7 +145,7 @@ summary entry ofs_in_node.
> .RE
> .TP
> .BI \-\-node
> -Inject node block specified by \fInid\P.
> +Inject node block specified by \fInid\fP.
> The available \fImb\fP of \fInode\fP are:
> .RS 1.2i
> .TP
> @@ -182,12 +182,27 @@ inode i_size.
> .BI i_blocks
> inode i_blocks.
> .TP
> +.BI i_ext.fofs
> +inode i_ext.fofs.
> +.TP
> +.BI i_ext.blk_addr
> +inode i_ext.blk_addr.
> +.TP
> +.BI i_ext.len
> +inode i_ext.len.
> +.TP
> .BI i_extra_isize
> inode i_extra_isize.
> .TP
> +.BI i_inline_xattr_size
> +inode i_inline_xattr_size.
> +.TP
> .BI i_inode_checksum
> inode i_inode_checksum.
> .TP
> +.BI i_compr_blocks
> +inode i_compr_blocks.
> +.TP
> .BI i_addr
> inode i_addr array specified by \fIidx\fP.
> .TP
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry Sheng Yong
@ 2025-06-13 7:55 ` Chao Yu via Linux-f2fs-devel
2025-06-16 2:01 ` Sheng Yong
0 siblings, 1 reply; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-06-13 7:55 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 2025/6/10 20:37, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
>
> This patch adds a new member `filename' in inject_dentry to inject
> dentry filename. The dentry is specified by nid option.
>
> Note that '.' and '..' dentries are special, because they are not in the
> parent directory of nid. So this patch also adds a new option `--dots'
> to inject these two dentries.
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> fsck/inject.c | 94 ++++++++++++++++++++++++++++++++++++++++-------
> fsck/inject.h | 1 +
> man/inject.f2fs.8 | 12 +++++-
> 3 files changed, 92 insertions(+), 15 deletions(-)
>
> diff --git a/fsck/inject.c b/fsck/inject.c
> index 8c2f8c5dc332..5eb913fefad7 100644
> --- a/fsck/inject.c
> +++ b/fsck/inject.c
> @@ -105,7 +105,7 @@ void inject_usage(void)
> MSG(0, " --sit <0|1|2> --mb <name> --blk <blk> [--idx <index>] --val <value> inject sit entry\n");
> MSG(0, " --ssa --mb <name> --blk <blk> [--idx <index>] --val <value> inject summary entry\n");
> MSG(0, " --node --mb <name> --nid <nid> [--idx <index>] --val <value> inject node\n");
> - MSG(0, " --dent --mb <name> --nid <ino> [--idx <index>] --val <value> inject ino's dentry\n");
> + MSG(0, " --dent --mb <name> --nid <ino> [--dots <1|2>] --val/str <value/string> inject ino's dentry\n");
> MSG(0, " --dry-run do not really inject\n");
>
> exit(1);
> @@ -212,12 +212,16 @@ static void inject_node_usage(void)
>
> static void inject_dent_usage(void)
> {
> - MSG(0, "inject.f2fs --dent --mb <name> --nid <nid> [--idx <index>] --val <value> inject dentry\n");
> + MSG(0, "inject.f2fs --dent --mb <name> --nid <nid> [--dots <1|2>] --val/str <value/string> inject dentry\n");
> + MSG(0, "[dots]:\n");
> + MSG(0, " 1: inject \".\" in directory which is specified by nid\n");
> + MSG(0, " 2: inject \"..\" in directory which is specified by nid\n");
> MSG(0, "[mb]:\n");
> MSG(0, " d_bitmap: inject dentry block d_bitmap of nid\n");
> MSG(0, " d_hash: inject dentry hash\n");
> MSG(0, " d_ino: inject dentry ino\n");
> MSG(0, " d_ftype: inject dentry ftype\n");
> + MSG(0, " filename: inject dentry filename, its hash and len are updated implicitly\n");
> }
>
> int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> @@ -241,6 +245,7 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> {"ssa", no_argument, 0, 12},
> {"node", no_argument, 0, 13},
> {"dent", no_argument, 0, 14},
> + {"dots", required_argument, 0, 15},
> {0, 0, 0, 0}
> };
>
> @@ -339,6 +344,14 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> opt->dent = true;
> MSG(0, "Info: inject dentry\n");
> break;
> + case 15:
> + opt->dots = atoi(optarg);
> + if (opt->dots != TYPE_DOT &&
> + opt->dots != TYPE_DOTDOT)
> + return -ERANGE;
> + MSG(0, "Info: inject %s dentry\n",
> + opt->dots == TYPE_DOT ? "dot" : "dotdot");
> + break;
> case 'd':
> if (optarg[0] == '-' || !is_digits(optarg))
> return EWRONG_OPT;
> @@ -371,6 +384,9 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
> } else if (opt->dent) {
> inject_dent_usage();
> exit(0);
> + } else {
> + MSG(0, "\tError: Wrong option -%c (%d) %s\n",
> + o, o, optarg);
> }
> return EUNKNOWN_OPT;
> }
> @@ -1146,12 +1162,12 @@ static int find_dir_entry(struct f2fs_dentry_ptr *d, nid_t ino)
> }
>
> de = &d->dentry[slot];
> - if (le32_to_cpu(de->ino) == ino && de->hash_code != 0)
> - return slot;
> if (de->name_len == 0) {
> slot++;
> continue;
> }
> + if (le32_to_cpu(de->ino) == ino)
> + return slot;
> slot += GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
> }
>
> @@ -1164,14 +1180,15 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
> struct f2fs_node *node_blk = NULL;
> struct f2fs_inode *inode;
> struct f2fs_dentry_ptr d;
> - void *inline_dentry;
> + void *buf = NULL, *inline_dentry;
> struct f2fs_dentry_block *dent_blk = NULL;
> block_t addr = 0;
> - void *buf = NULL;
> struct f2fs_dir_entry *dent = NULL;
> struct dnode_of_data dn;
> nid_t pino;
> - int slot = -ENOENT, ret;
> + int slot = -ENOENT, namelen, namecap, ret;
> + unsigned int dentry_hash;
> + char *name;
>
> node_blk = malloc(F2FS_BLKSIZE);
> ASSERT(node_blk != NULL);
> @@ -1180,12 +1197,25 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
> get_node_info(sbi, opt->nid, &ni);
> ret = dev_read_block(node_blk, ni.blk_addr);
> ASSERT(ret >= 0);
> - pino = le32_to_cpu(node_blk->i.i_pino);
>
> - /* get parent inode */
> - get_node_info(sbi, pino, &ni);
> - ret = dev_read_block(node_blk, ni.blk_addr);
> - ASSERT(ret >= 0);
> + if (opt->dots) {
> + if (!LINUX_S_ISDIR(le16_to_cpu(node_blk->i.i_mode))) {
> + ERR_MSG("ino %u is not a directory, cannot inject "
> + "its %s\n", opt->nid,
> + opt->dots == TYPE_DOT ? "." : "..");
> + ret = -EINVAL;
> + goto out;
> + }
> + /* pino is itself */
> + pino = opt->nid;
> + } else {
> + pino = le32_to_cpu(node_blk->i.i_pino);
> +
> + /* get parent inode */
> + get_node_info(sbi, pino, &ni);
> + ret = dev_read_block(node_blk, ni.blk_addr);
> + ASSERT(ret >= 0);
> + }
> inode = &node_blk->i;
>
> /* find child dentry */
> @@ -1195,7 +1225,10 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
> addr = ni.blk_addr;
> buf = node_blk;
>
> - slot = find_dir_entry(&d, opt->nid);
> + if (opt->dots == TYPE_DOTDOT)
> + slot = find_dir_entry(&d, le32_to_cpu(node_blk->i.i_pino));
> + else
> + slot = find_dir_entry(&d, opt->nid);
> if (slot >= 0)
> dent = &d.dentry[slot];
> } else {
> @@ -1231,7 +1264,10 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
> ASSERT(ret >= 0);
>
> make_dentry_ptr(&d, node_blk, dent_blk, 1);
> - slot = find_dir_entry(&d, opt->nid);
> + if (opt->dots == TYPE_DOTDOT)
> + slot = find_dir_entry(&d, le32_to_cpu(node_blk->i.i_pino));
> + else
> + slot = find_dir_entry(&d, opt->nid);
> if (slot >= 0) {
> dent = &d.dentry[slot];
> buf = dent_blk;
> @@ -1265,6 +1301,36 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
> "%d -> %d\n", opt->nid, dent->file_type,
> (u8)opt->val);
> dent->file_type = (u8)opt->val;
> + } else if (!strcmp(opt->mb, "filename")) {
> + if (!opt->str) {
> + ERR_MSG("option str is needed\n");
> + ret = -EINVAL;
> + goto out;
> + }
> + namecap = ALIGN_UP(le16_to_cpu(dent->name_len), F2FS_SLOT_LEN);
> + namelen = strlen(opt->str);
> + if (namelen > namecap || namelen > F2FS_NAME_LEN) {
> + ERR_MSG("option str too long\n");
> + ret = -EINVAL;
> + goto out;
> + }
> + name = (char *)d.filename[slot];
> + MSG(0, "Info: inject dentry filename of nid %u: "
> + "%.*s -> %s\n", opt->nid, le16_to_cpu(dent->name_len),
> + name, opt->str);
> + memcpy(name, opt->str, namelen);
> + MSG(0, "Info: inject dentry namelen of nid %u: "
> + "%d -> %d\n", opt->nid, le16_to_cpu(dent->name_len),
> + namelen);
> + dent->name_len = cpu_to_le16(namelen);
> + dentry_hash = f2fs_dentry_hash(get_encoding(sbi),
> + IS_CASEFOLDED(inode),
> + (unsigned char *)name,
> + namelen);
> + MSG(0, "Info: inject dentry d_hash of nid %u: "
> + "0x%x -> 0x%x\n", opt->nid, le32_to_cpu(dent->hash_code),
> + dentry_hash);
> + dent->hash_code = cpu_to_le32(dentry_hash);
Yong,
Out of curiosity, if we inject filename in target dirent, according new
filename's hash, it may be located in dentry block which belongs to another
bucket, can fsck repair it?
Thanks,
> } else {
> ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
> ret = -EINVAL;
> diff --git a/fsck/inject.h b/fsck/inject.h
> index 43c21b56a7eb..706a211bc645 100644
> --- a/fsck/inject.h
> +++ b/fsck/inject.h
> @@ -30,6 +30,7 @@ struct inject_option {
> int cp; /* which cp */
> int nat; /* which nat pack */
> int sit; /* which sit pack */
> + int dots; /* . or .. dentry */
> bool ssa;
> bool node;
> bool dent;
> diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
> index 72d1c90f7ce4..27b66f59b77d 100644
> --- a/man/inject.f2fs.8
> +++ b/man/inject.f2fs.8
> @@ -214,7 +214,14 @@ inode i_nid array specified by \fIidx\fP.
> .RE
> .TP
> .BI \-\-dent
> -Inject dentry block or dir entry specified \fInid\fP.
> +Inject dentry block or dir entry specified by \fInid\fP.
> +.RS 1.2i
> +.TP
> +.BI \-\-dots " 1 or 2"
> +The option means the "." or ".." directory entry of \fInid\fP is going to be injected.
> +.RE
> +.TP
> +.BI ""
> The available \fImb\fP of \fIdent\fP are:
> .RS 1.2i
> .TP
> @@ -229,6 +236,9 @@ dentry ino.
> .TP
> .BI d_ftype
> dentry ftype.
> +.TP
> +.BI filename
> +dentry filename, and corresponding d_hash and namelen are updated implicitly.
> .RE
> .TP
> .BI \-\-dry\-run
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options
2025-06-13 6:08 ` Chao Yu via Linux-f2fs-devel
@ 2025-06-16 1:49 ` Sheng Yong
0 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-16 1:49 UTC (permalink / raw)
To: Chao Yu, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 6/13/25 14:08, Chao Yu wrote:
> On 2025/6/10 20:37, Sheng Yong wrote:
>> From: Sheng Yong <shengyong1@xiaomi.com>
>>
>> This patch fixes:
>> * parsing hex optarg of --idx option
>> * converting -1 to 0xff...ff of --val option
>> and do a little cleanup of converting string to a long integer.
>>
>> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
>> ---
>> fsck/inject.c | 32 +++++++++++++++++---------------
>> 1 file changed, 17 insertions(+), 15 deletions(-)
>>
>> diff --git a/fsck/inject.c b/fsck/inject.c
>> index 96817a806f8f..c879ca99c0d8 100644
>> --- a/fsck/inject.c
>> +++ b/fsck/inject.c
>> @@ -236,8 +236,9 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
>> while ((o = getopt_long(argc, argv, option_string,
>> long_opt, NULL)) != EOF) {
>> - long nid, blk;
>> + long long val;
>> + errno = 0;
>> switch (o) {
>> case 1:
>> c.dry_run = 1;
>> @@ -248,18 +249,19 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
>> MSG(0, "Info: inject member %s\n", optarg);
>> break;
>> case 3:
>> - if (!is_digits(optarg))
>> - return EWRONG_OPT;
>> - opt->idx = atoi(optarg);
>> - MSG(0, "Info: inject slot index %d\n", opt->idx);
>> + val = strtoll(optarg, &endptr, 0);
>> + if (errno != 0 || val >= UINT_MAX || val < 0 ||
>
> UINT_MAX is a possible injectable value? if so, it need to use "val > UINT_MAX"?
>
Hi, Chao,
For `idx' and sit/nat pack, I think UINT_MAX or -1 will not be used, because these
two values are used to indicate where we do the injection, and UINT_MAX is always
out of boundary of the array.
Thanks,
shengyong
>> + *endptr != '\0')
>> + return -ERANGE;
>> + opt->idx = (unsigned int)val;
>> + MSG(0, "Info: inject slot index %u\n", opt->idx);
>> break;
>> case 4:
>> - opt->val = strtoll(optarg, &endptr, 0);
>> - if (opt->val == LLONG_MAX || opt->val == LLONG_MIN ||
>> - *endptr != '\0')
>> + opt->val = strtoull(optarg, &endptr, 0);
>> + if (errno != 0 || *endptr != '\0')
>> return -ERANGE;
>> MSG(0, "Info: inject value %lld : 0x%llx\n", opt->val,
>> - (unsigned long long)opt->val);
>> + opt->val);
>> break;
>> case 5:
>> opt->str = strdup(optarg);
>> @@ -292,11 +294,11 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
>> MSG(0, "Info: inject nat pack %s\n", pack[opt->nat]);
>> break;
>> case 9:
>> - nid = strtol(optarg, &endptr, 0);
>> - if (nid >= UINT_MAX || nid < 0 ||
>> + val = strtoll(optarg, &endptr, 0);
>> + if (errno != 0 || val >= UINT_MAX || val < 0 ||
>> *endptr != '\0')
>> return -ERANGE;
>> - opt->nid = nid;
>> + opt->nid = (nid_t)val;
>> MSG(0, "Info: inject nid %u : 0x%x\n", opt->nid, opt->nid);
>> break;
>> case 10:
>> @@ -308,11 +310,11 @@ int inject_parse_options(int argc, char *argv[], struct inject_option *opt)
>> MSG(0, "Info: inject sit pack %s\n", pack[opt->sit]);
>> break;
>> case 11:
>> - blk = strtol(optarg, &endptr, 0);
>> - if (blk >= UINT_MAX || blk < 0 ||
>> + val = strtoll(optarg, &endptr, 0);
>> + if (errno != 0 || val >= UINT_MAX || val < 0 ||
>> *endptr != '\0')
>> return -ERANGE;
>> - opt->blk = blk;
>> + opt->blk = (block_t)val;
>> MSG(0, "Info: inject blkaddr %u : 0x%x\n", opt->blk, opt->blk);
>> break;
>> case 12:
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry
2025-06-13 7:55 ` Chao Yu via Linux-f2fs-devel
@ 2025-06-16 2:01 ` Sheng Yong
0 siblings, 0 replies; 45+ messages in thread
From: Sheng Yong @ 2025-06-16 2:01 UTC (permalink / raw)
To: Chao Yu, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 6/13/25 15:55, Chao Yu wrote:
> On 2025/6/10 20:37, Sheng Yong wrote:
>> From: Sheng Yong <shengyong1@xiaomi.com>
>>
>> This patch adds a new member `filename' in inject_dentry to inject
>> dentry filename. The dentry is specified by nid option.
>>
>> Note that '.' and '..' dentries are special, because they are not in the
>> parent directory of nid. So this patch also adds a new option `--dots'
>> to inject these two dentries.
>>
>> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
>> ---
>> fsck/inject.c | 94 ++++++++++++++++++++++++++++++++++++++++-------
>> fsck/inject.h | 1 +
>> man/inject.f2fs.8 | 12 +++++-
>> 3 files changed, 92 insertions(+), 15 deletions(-)
>>
>> diff --git a/fsck/inject.c b/fsck/inject.c
>> index 8c2f8c5dc332..5eb913fefad7 100644
>> --- a/fsck/inject.c
>> +++ b/fsck/inject.c
[...]
>> @@ -1265,6 +1301,36 @@ static int inject_dentry(struct f2fs_sb_info *sbi, struct inject_option *opt)
>> "%d -> %d\n", opt->nid, dent->file_type,
>> (u8)opt->val);
>> dent->file_type = (u8)opt->val;
>> + } else if (!strcmp(opt->mb, "filename")) {
>> + if (!opt->str) {
>> + ERR_MSG("option str is needed\n");
>> + ret = -EINVAL;
>> + goto out;
>> + }
>> + namecap = ALIGN_UP(le16_to_cpu(dent->name_len), F2FS_SLOT_LEN);
>> + namelen = strlen(opt->str);
>> + if (namelen > namecap || namelen > F2FS_NAME_LEN) {
>> + ERR_MSG("option str too long\n");
>> + ret = -EINVAL;
>> + goto out;
>> + }
>> + name = (char *)d.filename[slot];
>> + MSG(0, "Info: inject dentry filename of nid %u: "
>> + "%.*s -> %s\n", opt->nid, le16_to_cpu(dent->name_len),
>> + name, opt->str);
>> + memcpy(name, opt->str, namelen);
>> + MSG(0, "Info: inject dentry namelen of nid %u: "
>> + "%d -> %d\n", opt->nid, le16_to_cpu(dent->name_len),
>> + namelen);
>> + dent->name_len = cpu_to_le16(namelen);
>> + dentry_hash = f2fs_dentry_hash(get_encoding(sbi),
>> + IS_CASEFOLDED(inode),
>> + (unsigned char *)name,
>> + namelen);
>> + MSG(0, "Info: inject dentry d_hash of nid %u: "
>> + "0x%x -> 0x%x\n", opt->nid, le32_to_cpu(dent->hash_code),
>> + dentry_hash);
>> + dent->hash_code = cpu_to_le32(dentry_hash);
>
> Yong,
>
> Out of curiosity, if we inject filename in target dirent, according new
> filename's hash, it may be located in dentry block which belongs to another
> bucket, can fsck repair it?
Hi, Chao,
Yes, I think fsck can repair it, but it removes the entry directly instead of
"reordering" it (`f2fs_check_dirent_position`). I can add a test for this case.
Thanks,
shengyong
>
> Thanks,
>
>> } else {
>> ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
>> ret = -EINVAL;
>> diff --git a/fsck/inject.h b/fsck/inject.h
>> index 43c21b56a7eb..706a211bc645 100644
>> --- a/fsck/inject.h
>> +++ b/fsck/inject.h
>> @@ -30,6 +30,7 @@ struct inject_option {
>> int cp; /* which cp */
>> int nat; /* which nat pack */
>> int sit; /* which sit pack */
>> + int dots; /* . or .. dentry */
>> bool ssa;
>> bool node;
>> bool dent;
>> diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
>> index 72d1c90f7ce4..27b66f59b77d 100644
>> --- a/man/inject.f2fs.8
>> +++ b/man/inject.f2fs.8
>> @@ -214,7 +214,14 @@ inode i_nid array specified by \fIidx\fP.
>> .RE
>> .TP
>> .BI \-\-dent
>> -Inject dentry block or dir entry specified \fInid\fP.
>> +Inject dentry block or dir entry specified by \fInid\fP.
>> +.RS 1.2i
>> +.TP
>> +.BI \-\-dots " 1 or 2"
>> +The option means the "." or ".." directory entry of \fInid\fP is going to be injected.
>> +.RE
>> +.TP
>> +.BI ""
>> The available \fImb\fP of \fIdent\fP are:
>> .RS 1.2i
>> .TP
>> @@ -229,6 +236,9 @@ dentry ino.
>> .TP
>> .BI d_ftype
>> dentry ftype.
>> +.TP
>> +.BI filename
>> +dentry filename, and corresponding d_hash and namelen are updated implicitly.
>> .RE
>> .TP
>> .BI \-\-dry\-run
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
` (31 preceding siblings ...)
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 32/32] tests: add inject testcase of injecting node block Sheng Yong
@ 2025-08-15 10:38 ` Chao Yu via Linux-f2fs-devel
2025-08-15 11:27 ` Sheng Yong
32 siblings, 1 reply; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-08-15 10:38 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
Yong,
Could you please split this patchset to two, 1~13 and 14~32? and update
1~13 first? I guess 1~13 are almost clear to be merged.
On 6/10/25 20:37, Sheng Yong wrote:
> Hi, folks,
>
> This patchset tries to add an auto testsuit for f2fs-tools, including
> fsck.f2fs, inject.f2fs for now.
>
> The patchset can splited into 3 parts:
> PATCH 1~9: is a preparation for testcases. It fixes some errors in
> fsck and inject, and do some cleanup and improvement for
> f2fs-tools.
> PATCH 10~13: add new injection members
> PATCH 14~32: add testcases
>
> thanks,
> shengyong
>
> -8<-
>
> The following is almost quoted from v1:
>
> The basic idea of these testcases are:
> 1. create f2fs image
> 2. corrupt the image by inject specific fields
> 3. fsck fixes the image
> 4. verify fsck output with expected message
>
> Some helper scripts are provided:
> * test_config.in: is used to derive basic configurations of all
> testcases.
> * runtests.in: is used to derive `runtests' which is used to run
> testcases.
> * filter.sed: removes unnecessary messages and cleanup arbitrary
> values.
> * helpers: provides helper functions
>
> The usage of `runtests':
> * run all testcases:
> runtests
> * run one testcase:
> runtests <testcase directory path>
> * cleanup previous results:
> runtests clean
>
> To run the testcases on Android, only have to change settings in
> test_config:
> * set path of $META and $DATA
> * set path of tools
> * push tests directory to an Android phone
> NOTE TAHT: the testcases will format $META!!!
>
> Some testcase requires root permission to mount the image and create
> files.
>
> Each testcase should have a sub-directory, where three files are needed:
> * README: describe information of the testcase
> * script: testcase itself
> * expect.in: is used to derive expected output message
>
> New files are generated in the testcase directory after test:
> * log: output in detail
> * expect: derived from expect.in
> * out: output that will be compared with expect
> * PASS: testcase is passed
> * FAIL: testcase is failed, in which differ of out and expect is saved
>
> The name of testcase directory has some optional prefix:
> * f_: fsck testcase
> * i_: inject testcase
> * m_: mkfs testcase
> But there are only fsck and inject testcases for now.
>
> To run testcases, it's better to compile fsck.f2fs as statically linked
> executable, or `make install' installs tools and libraries. Otherwise,
> libtool compiles f2fs-tools in debug mode and create a wrapper script
> to locate elf executable and libraries. However, dump.f2fs and
> inject.f2fs cannot be used in the wrapper way.
>
> v2: * add some fix and cleanup
> * remove img.tar.gz from testcases
> * add testcases for injection
> * cleanup helpers script and simplify filter.sed and expected.in
> v1: https://lore.kernel.org/linux-f2fs-devel/20241029120956.4186731-1-shengyong@oppo.com/
>
> Sheng Yong (32):
> fsck.f2fs: do not finish/reset zone if dry-run is true
> f2fs-tools: add option N to answer no for all questions
> f2fs-tools: cleanup {nid|segno}_in_journal
> fsck.f2fs: fix invalidate checkpoint
> dump.f2fs: print more info
> f2fs-tools: add and export lookup_sit_in_journal
> inject.f2fs: fix injecting sit/nat in journal
> inject.f2fs: fix injection on zoned device
> inject.f2fs: fix and cleanup parsing numeric options
> inject.f2fs: add members in inject_cp
> inject.f2fs: add member `feature' in inject_sb
> inject.f2fs: add members in inject_node
> inject.f2fs: add member `filename' in inject_dentry
> tests: prepare helper scripts for testcases
> tests: add fsck testcase of fixing bad super magic
> tests: add fsck testcase of fixing errors recorded in sb
> tests: add fsck testcase of fixing cp crc
> tests: add fsck testcase of fixing nat entry with invalid ino
> tests: add fsck testcase of fixing nat entry with invalid blkaddr
> tests: add fsck testcase of fixing sit entry type
> tests: add fsck testcase of fixing sit entry vblocks
> tests: add fsck testcase of fixing sit entry valid_map
> tests: add fsck testcase of fixing sum entry nid
> tests: add fsck testcase of fixing sum footer type
> tests: add fsck testcase of fixing sum entry ofs_in_node
> tests: add fsck testcase of fixing inode invalid i_addr
> tests: add fsck testcase of fixing dentry hash code
> tests: add fsck testcase of fixing lost dots
> tests: add fsck testcase of fixing duplicated dots
> tests: add fsck testcase of fixing loop fsync dnodes
> tests: add inject testcase of injecting META area
> tests: add inject testcase of injecting node block
>
> .gitignore | 14 +
> Makefile.am | 2 +-
> configure.ac | 1 +
> fsck/dump.c | 15 +-
> fsck/f2fs.h | 12 +-
> fsck/fsck.c | 2 +-
> fsck/fsck.h | 4 +-
> fsck/inject.c | 438 +++++++++++++++++++++-----
> fsck/inject.h | 1 +
> fsck/main.c | 14 +-
> fsck/mount.c | 61 ++--
> include/f2fs_fs.h | 1 +
> lib/libf2fs_zoned.c | 6 +-
> man/inject.f2fs.8 | 43 ++-
> tests/Makefile.am | 26 ++
> tests/f_cp_bad_crc/README | 5 +
> tests/f_cp_bad_crc/expect.in | 4 +
> tests/f_cp_bad_crc/script | 38 +++
> tests/f_dentry_bad_hash/README | 8 +
> tests/f_dentry_bad_hash/expect.in | 8 +
> tests/f_dentry_bad_hash/script | 56 ++++
> tests/f_dentry_dup_dots/README | 11 +
> tests/f_dentry_dup_dots/expect.in | 26 ++
> tests/f_dentry_dup_dots/script | 49 +++
> tests/f_dentry_lost_dots/README | 7 +
> tests/f_dentry_lost_dots/expect.in | 16 +
> tests/f_dentry_lost_dots/script | 37 +++
> tests/f_inode_bad_iaddr/README | 6 +
> tests/f_inode_bad_iaddr/expect.in | 13 +
> tests/f_inode_bad_iaddr/script | 50 +++
> tests/f_loop_fsync_dnodes/README | 5 +
> tests/f_loop_fsync_dnodes/expect.in | 6 +
> tests/f_loop_fsync_dnodes/script | 46 +++
> tests/f_nat_bad_blkaddr/README | 4 +
> tests/f_nat_bad_blkaddr/expect.in | 12 +
> tests/f_nat_bad_blkaddr/script | 25 ++
> tests/f_nat_bad_ino/README | 4 +
> tests/f_nat_bad_ino/expect.in | 12 +
> tests/f_nat_bad_ino/script | 31 ++
> tests/f_sb_bad_magic/README | 3 +
> tests/f_sb_bad_magic/expect.in | 5 +
> tests/f_sb_bad_magic/script | 15 +
> tests/f_sb_errors/README | 5 +
> tests/f_sb_errors/expect.in | 7 +
> tests/f_sb_errors/script | 22 ++
> tests/f_sit_bad_type/README | 5 +
> tests/f_sit_bad_type/expect.in | 3 +
> tests/f_sit_bad_type/script | 38 +++
> tests/f_sit_bad_valid_map/README | 5 +
> tests/f_sit_bad_valid_map/expect.in | 4 +
> tests/f_sit_bad_valid_map/script | 43 +++
> tests/f_sit_bad_vblocks/README | 5 +
> tests/f_sit_bad_vblocks/expect.in | 3 +
> tests/f_sit_bad_vblocks/script | 38 +++
> tests/f_ssa_bad_nid/README | 5 +
> tests/f_ssa_bad_nid/expect.in | 3 +
> tests/f_ssa_bad_nid/script | 36 +++
> tests/f_ssa_bad_ofs_in_node/README | 5 +
> tests/f_ssa_bad_ofs_in_node/expect.in | 3 +
> tests/f_ssa_bad_ofs_in_node/script | 36 +++
> tests/f_ssa_bad_type/README | 5 +
> tests/f_ssa_bad_type/expect.in | 3 +
> tests/f_ssa_bad_type/script | 31 ++
> tests/filter.sed | 69 ++++
> tests/helpers | 269 ++++++++++++++++
> tests/i_meta/README | 5 +
> tests/i_meta/expect.in | 60 ++++
> tests/i_meta/script | 212 +++++++++++++
> tests/i_node/README | 5 +
> tests/i_node/expect.in | 66 ++++
> tests/i_node/script | 166 ++++++++++
> tests/runtests.in | 48 +++
> tests/test_config.in | 53 ++++
> 73 files changed, 2284 insertions(+), 116 deletions(-)
> create mode 100644 tests/Makefile.am
> create mode 100644 tests/f_cp_bad_crc/README
> create mode 100644 tests/f_cp_bad_crc/expect.in
> create mode 100644 tests/f_cp_bad_crc/script
> create mode 100644 tests/f_dentry_bad_hash/README
> create mode 100644 tests/f_dentry_bad_hash/expect.in
> create mode 100644 tests/f_dentry_bad_hash/script
> create mode 100644 tests/f_dentry_dup_dots/README
> create mode 100644 tests/f_dentry_dup_dots/expect.in
> create mode 100644 tests/f_dentry_dup_dots/script
> create mode 100644 tests/f_dentry_lost_dots/README
> create mode 100644 tests/f_dentry_lost_dots/expect.in
> create mode 100644 tests/f_dentry_lost_dots/script
> create mode 100644 tests/f_inode_bad_iaddr/README
> create mode 100644 tests/f_inode_bad_iaddr/expect.in
> create mode 100644 tests/f_inode_bad_iaddr/script
> create mode 100644 tests/f_loop_fsync_dnodes/README
> create mode 100644 tests/f_loop_fsync_dnodes/expect.in
> create mode 100644 tests/f_loop_fsync_dnodes/script
> create mode 100644 tests/f_nat_bad_blkaddr/README
> create mode 100644 tests/f_nat_bad_blkaddr/expect.in
> create mode 100644 tests/f_nat_bad_blkaddr/script
> create mode 100644 tests/f_nat_bad_ino/README
> create mode 100644 tests/f_nat_bad_ino/expect.in
> create mode 100644 tests/f_nat_bad_ino/script
> create mode 100644 tests/f_sb_bad_magic/README
> create mode 100644 tests/f_sb_bad_magic/expect.in
> create mode 100644 tests/f_sb_bad_magic/script
> create mode 100644 tests/f_sb_errors/README
> create mode 100644 tests/f_sb_errors/expect.in
> create mode 100644 tests/f_sb_errors/script
> create mode 100644 tests/f_sit_bad_type/README
> create mode 100644 tests/f_sit_bad_type/expect.in
> create mode 100644 tests/f_sit_bad_type/script
> create mode 100644 tests/f_sit_bad_valid_map/README
> create mode 100644 tests/f_sit_bad_valid_map/expect.in
> create mode 100644 tests/f_sit_bad_valid_map/script
> create mode 100644 tests/f_sit_bad_vblocks/README
> create mode 100644 tests/f_sit_bad_vblocks/expect.in
> create mode 100644 tests/f_sit_bad_vblocks/script
> create mode 100644 tests/f_ssa_bad_nid/README
> create mode 100644 tests/f_ssa_bad_nid/expect.in
> create mode 100644 tests/f_ssa_bad_nid/script
> create mode 100644 tests/f_ssa_bad_ofs_in_node/README
> create mode 100644 tests/f_ssa_bad_ofs_in_node/expect.in
> create mode 100644 tests/f_ssa_bad_ofs_in_node/script
> create mode 100644 tests/f_ssa_bad_type/README
> create mode 100644 tests/f_ssa_bad_type/expect.in
> create mode 100644 tests/f_ssa_bad_type/script
> create mode 100644 tests/filter.sed
> create mode 100644 tests/helpers
> create mode 100644 tests/i_meta/README
> create mode 100644 tests/i_meta/expect.in
> create mode 100644 tests/i_meta/script
> create mode 100644 tests/i_node/README
> create mode 100644 tests/i_node/expect.in
> create mode 100644 tests/i_node/script
> create mode 100644 tests/runtests.in
> create mode 100644 tests/test_config.in
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases
2025-08-15 10:38 ` [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Chao Yu via Linux-f2fs-devel
@ 2025-08-15 11:27 ` Sheng Yong
2025-08-16 7:04 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 45+ messages in thread
From: Sheng Yong @ 2025-08-15 11:27 UTC (permalink / raw)
To: Chao Yu, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 8/15/25 18:38, Chao Yu wrote:
> Yong,
>
> Could you please split this patchset to two, 1~13 and 14~32? and update
> 1~13 first? I guess 1~13 are almost clear to be merged.
Hi, Chao,
Sorry for the delay. I will split the patchset and send a new version ASAP.
Thanks,
shengyong
>
> On 6/10/25 20:37, Sheng Yong wrote:
>> Hi, folks,
>>
>> This patchset tries to add an auto testsuit for f2fs-tools, including
>> fsck.f2fs, inject.f2fs for now.
>>
>> The patchset can splited into 3 parts:
>> PATCH 1~9: is a preparation for testcases. It fixes some errors in
>> fsck and inject, and do some cleanup and improvement for
>> f2fs-tools.
>> PATCH 10~13: add new injection members
>> PATCH 14~32: add testcases
>>
>> thanks,
>> shengyong
>>
>> -8<-
>>
>> The following is almost quoted from v1:
>>
>> The basic idea of these testcases are:
>> 1. create f2fs image
>> 2. corrupt the image by inject specific fields
>> 3. fsck fixes the image
>> 4. verify fsck output with expected message
>>
>> Some helper scripts are provided:
>> * test_config.in: is used to derive basic configurations of all
>> testcases.
>> * runtests.in: is used to derive `runtests' which is used to run
>> testcases.
>> * filter.sed: removes unnecessary messages and cleanup arbitrary
>> values.
>> * helpers: provides helper functions
>>
>> The usage of `runtests':
>> * run all testcases:
>> runtests
>> * run one testcase:
>> runtests <testcase directory path>
>> * cleanup previous results:
>> runtests clean
>>
>> To run the testcases on Android, only have to change settings in
>> test_config:
>> * set path of $META and $DATA
>> * set path of tools
>> * push tests directory to an Android phone
>> NOTE TAHT: the testcases will format $META!!!
>>
>> Some testcase requires root permission to mount the image and create
>> files.
>>
>> Each testcase should have a sub-directory, where three files are needed:
>> * README: describe information of the testcase
>> * script: testcase itself
>> * expect.in: is used to derive expected output message
>>
>> New files are generated in the testcase directory after test:
>> * log: output in detail
>> * expect: derived from expect.in
>> * out: output that will be compared with expect
>> * PASS: testcase is passed
>> * FAIL: testcase is failed, in which differ of out and expect is saved
>>
>> The name of testcase directory has some optional prefix:
>> * f_: fsck testcase
>> * i_: inject testcase
>> * m_: mkfs testcase
>> But there are only fsck and inject testcases for now.
>>
>> To run testcases, it's better to compile fsck.f2fs as statically linked
>> executable, or `make install' installs tools and libraries. Otherwise,
>> libtool compiles f2fs-tools in debug mode and create a wrapper script
>> to locate elf executable and libraries. However, dump.f2fs and
>> inject.f2fs cannot be used in the wrapper way.
>>
>> v2: * add some fix and cleanup
>> * remove img.tar.gz from testcases
>> * add testcases for injection
>> * cleanup helpers script and simplify filter.sed and expected.in
>> v1: https://lore.kernel.org/linux-f2fs-devel/20241029120956.4186731-1-shengyong@oppo.com/
>>
>> Sheng Yong (32):
>> fsck.f2fs: do not finish/reset zone if dry-run is true
>> f2fs-tools: add option N to answer no for all questions
>> f2fs-tools: cleanup {nid|segno}_in_journal
>> fsck.f2fs: fix invalidate checkpoint
>> dump.f2fs: print more info
>> f2fs-tools: add and export lookup_sit_in_journal
>> inject.f2fs: fix injecting sit/nat in journal
>> inject.f2fs: fix injection on zoned device
>> inject.f2fs: fix and cleanup parsing numeric options
>> inject.f2fs: add members in inject_cp
>> inject.f2fs: add member `feature' in inject_sb
>> inject.f2fs: add members in inject_node
>> inject.f2fs: add member `filename' in inject_dentry
>> tests: prepare helper scripts for testcases
>> tests: add fsck testcase of fixing bad super magic
>> tests: add fsck testcase of fixing errors recorded in sb
>> tests: add fsck testcase of fixing cp crc
>> tests: add fsck testcase of fixing nat entry with invalid ino
>> tests: add fsck testcase of fixing nat entry with invalid blkaddr
>> tests: add fsck testcase of fixing sit entry type
>> tests: add fsck testcase of fixing sit entry vblocks
>> tests: add fsck testcase of fixing sit entry valid_map
>> tests: add fsck testcase of fixing sum entry nid
>> tests: add fsck testcase of fixing sum footer type
>> tests: add fsck testcase of fixing sum entry ofs_in_node
>> tests: add fsck testcase of fixing inode invalid i_addr
>> tests: add fsck testcase of fixing dentry hash code
>> tests: add fsck testcase of fixing lost dots
>> tests: add fsck testcase of fixing duplicated dots
>> tests: add fsck testcase of fixing loop fsync dnodes
>> tests: add inject testcase of injecting META area
>> tests: add inject testcase of injecting node block
>>
>> .gitignore | 14 +
>> Makefile.am | 2 +-
>> configure.ac | 1 +
>> fsck/dump.c | 15 +-
>> fsck/f2fs.h | 12 +-
>> fsck/fsck.c | 2 +-
>> fsck/fsck.h | 4 +-
>> fsck/inject.c | 438 +++++++++++++++++++++-----
>> fsck/inject.h | 1 +
>> fsck/main.c | 14 +-
>> fsck/mount.c | 61 ++--
>> include/f2fs_fs.h | 1 +
>> lib/libf2fs_zoned.c | 6 +-
>> man/inject.f2fs.8 | 43 ++-
>> tests/Makefile.am | 26 ++
>> tests/f_cp_bad_crc/README | 5 +
>> tests/f_cp_bad_crc/expect.in | 4 +
>> tests/f_cp_bad_crc/script | 38 +++
>> tests/f_dentry_bad_hash/README | 8 +
>> tests/f_dentry_bad_hash/expect.in | 8 +
>> tests/f_dentry_bad_hash/script | 56 ++++
>> tests/f_dentry_dup_dots/README | 11 +
>> tests/f_dentry_dup_dots/expect.in | 26 ++
>> tests/f_dentry_dup_dots/script | 49 +++
>> tests/f_dentry_lost_dots/README | 7 +
>> tests/f_dentry_lost_dots/expect.in | 16 +
>> tests/f_dentry_lost_dots/script | 37 +++
>> tests/f_inode_bad_iaddr/README | 6 +
>> tests/f_inode_bad_iaddr/expect.in | 13 +
>> tests/f_inode_bad_iaddr/script | 50 +++
>> tests/f_loop_fsync_dnodes/README | 5 +
>> tests/f_loop_fsync_dnodes/expect.in | 6 +
>> tests/f_loop_fsync_dnodes/script | 46 +++
>> tests/f_nat_bad_blkaddr/README | 4 +
>> tests/f_nat_bad_blkaddr/expect.in | 12 +
>> tests/f_nat_bad_blkaddr/script | 25 ++
>> tests/f_nat_bad_ino/README | 4 +
>> tests/f_nat_bad_ino/expect.in | 12 +
>> tests/f_nat_bad_ino/script | 31 ++
>> tests/f_sb_bad_magic/README | 3 +
>> tests/f_sb_bad_magic/expect.in | 5 +
>> tests/f_sb_bad_magic/script | 15 +
>> tests/f_sb_errors/README | 5 +
>> tests/f_sb_errors/expect.in | 7 +
>> tests/f_sb_errors/script | 22 ++
>> tests/f_sit_bad_type/README | 5 +
>> tests/f_sit_bad_type/expect.in | 3 +
>> tests/f_sit_bad_type/script | 38 +++
>> tests/f_sit_bad_valid_map/README | 5 +
>> tests/f_sit_bad_valid_map/expect.in | 4 +
>> tests/f_sit_bad_valid_map/script | 43 +++
>> tests/f_sit_bad_vblocks/README | 5 +
>> tests/f_sit_bad_vblocks/expect.in | 3 +
>> tests/f_sit_bad_vblocks/script | 38 +++
>> tests/f_ssa_bad_nid/README | 5 +
>> tests/f_ssa_bad_nid/expect.in | 3 +
>> tests/f_ssa_bad_nid/script | 36 +++
>> tests/f_ssa_bad_ofs_in_node/README | 5 +
>> tests/f_ssa_bad_ofs_in_node/expect.in | 3 +
>> tests/f_ssa_bad_ofs_in_node/script | 36 +++
>> tests/f_ssa_bad_type/README | 5 +
>> tests/f_ssa_bad_type/expect.in | 3 +
>> tests/f_ssa_bad_type/script | 31 ++
>> tests/filter.sed | 69 ++++
>> tests/helpers | 269 ++++++++++++++++
>> tests/i_meta/README | 5 +
>> tests/i_meta/expect.in | 60 ++++
>> tests/i_meta/script | 212 +++++++++++++
>> tests/i_node/README | 5 +
>> tests/i_node/expect.in | 66 ++++
>> tests/i_node/script | 166 ++++++++++
>> tests/runtests.in | 48 +++
>> tests/test_config.in | 53 ++++
>> 73 files changed, 2284 insertions(+), 116 deletions(-)
>> create mode 100644 tests/Makefile.am
>> create mode 100644 tests/f_cp_bad_crc/README
>> create mode 100644 tests/f_cp_bad_crc/expect.in
>> create mode 100644 tests/f_cp_bad_crc/script
>> create mode 100644 tests/f_dentry_bad_hash/README
>> create mode 100644 tests/f_dentry_bad_hash/expect.in
>> create mode 100644 tests/f_dentry_bad_hash/script
>> create mode 100644 tests/f_dentry_dup_dots/README
>> create mode 100644 tests/f_dentry_dup_dots/expect.in
>> create mode 100644 tests/f_dentry_dup_dots/script
>> create mode 100644 tests/f_dentry_lost_dots/README
>> create mode 100644 tests/f_dentry_lost_dots/expect.in
>> create mode 100644 tests/f_dentry_lost_dots/script
>> create mode 100644 tests/f_inode_bad_iaddr/README
>> create mode 100644 tests/f_inode_bad_iaddr/expect.in
>> create mode 100644 tests/f_inode_bad_iaddr/script
>> create mode 100644 tests/f_loop_fsync_dnodes/README
>> create mode 100644 tests/f_loop_fsync_dnodes/expect.in
>> create mode 100644 tests/f_loop_fsync_dnodes/script
>> create mode 100644 tests/f_nat_bad_blkaddr/README
>> create mode 100644 tests/f_nat_bad_blkaddr/expect.in
>> create mode 100644 tests/f_nat_bad_blkaddr/script
>> create mode 100644 tests/f_nat_bad_ino/README
>> create mode 100644 tests/f_nat_bad_ino/expect.in
>> create mode 100644 tests/f_nat_bad_ino/script
>> create mode 100644 tests/f_sb_bad_magic/README
>> create mode 100644 tests/f_sb_bad_magic/expect.in
>> create mode 100644 tests/f_sb_bad_magic/script
>> create mode 100644 tests/f_sb_errors/README
>> create mode 100644 tests/f_sb_errors/expect.in
>> create mode 100644 tests/f_sb_errors/script
>> create mode 100644 tests/f_sit_bad_type/README
>> create mode 100644 tests/f_sit_bad_type/expect.in
>> create mode 100644 tests/f_sit_bad_type/script
>> create mode 100644 tests/f_sit_bad_valid_map/README
>> create mode 100644 tests/f_sit_bad_valid_map/expect.in
>> create mode 100644 tests/f_sit_bad_valid_map/script
>> create mode 100644 tests/f_sit_bad_vblocks/README
>> create mode 100644 tests/f_sit_bad_vblocks/expect.in
>> create mode 100644 tests/f_sit_bad_vblocks/script
>> create mode 100644 tests/f_ssa_bad_nid/README
>> create mode 100644 tests/f_ssa_bad_nid/expect.in
>> create mode 100644 tests/f_ssa_bad_nid/script
>> create mode 100644 tests/f_ssa_bad_ofs_in_node/README
>> create mode 100644 tests/f_ssa_bad_ofs_in_node/expect.in
>> create mode 100644 tests/f_ssa_bad_ofs_in_node/script
>> create mode 100644 tests/f_ssa_bad_type/README
>> create mode 100644 tests/f_ssa_bad_type/expect.in
>> create mode 100644 tests/f_ssa_bad_type/script
>> create mode 100644 tests/filter.sed
>> create mode 100644 tests/helpers
>> create mode 100644 tests/i_meta/README
>> create mode 100644 tests/i_meta/expect.in
>> create mode 100644 tests/i_meta/script
>> create mode 100644 tests/i_node/README
>> create mode 100644 tests/i_node/expect.in
>> create mode 100644 tests/i_node/script
>> create mode 100644 tests/runtests.in
>> create mode 100644 tests/test_config.in
>>
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases
2025-08-15 11:27 ` Sheng Yong
@ 2025-08-16 7:04 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 45+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2025-08-16 7:04 UTC (permalink / raw)
To: Sheng Yong, jaegeuk; +Cc: shengyong1, linux-f2fs-devel
On 2025/8/15 19:27, Sheng Yong wrote:
> On 8/15/25 18:38, Chao Yu wrote:
>> Yong,
>>
>> Could you please split this patchset to two, 1~13 and 14~32? and update
>> 1~13 first? I guess 1~13 are almost clear to be merged.
>
> Hi, Chao,
>
> Sorry for the delay. I will split the patchset and send a new version ASAP.
Thanks a lot, Yong. :)
Thanks,
>
> Thanks,
> shengyong
>>
>> On 6/10/25 20:37, Sheng Yong wrote:
>>> Hi, folks,
>>>
>>> This patchset tries to add an auto testsuit for f2fs-tools, including
>>> fsck.f2fs, inject.f2fs for now.
>>>
>>> The patchset can splited into 3 parts:
>>> PATCH 1~9: is a preparation for testcases. It fixes some errors in
>>> fsck and inject, and do some cleanup and improvement for
>>> f2fs-tools.
>>> PATCH 10~13: add new injection members
>>> PATCH 14~32: add testcases
>>>
>>> thanks,
>>> shengyong
>>>
>>> -8<-
>>>
>>> The following is almost quoted from v1:
>>>
>>> The basic idea of these testcases are:
>>> 1. create f2fs image
>>> 2. corrupt the image by inject specific fields
>>> 3. fsck fixes the image
>>> 4. verify fsck output with expected message
>>>
>>> Some helper scripts are provided:
>>> * test_config.in: is used to derive basic configurations of all
>>> testcases.
>>> * runtests.in: is used to derive `runtests' which is used to run
>>> testcases.
>>> * filter.sed: removes unnecessary messages and cleanup arbitrary
>>> values.
>>> * helpers: provides helper functions
>>>
>>> The usage of `runtests':
>>> * run all testcases:
>>> runtests
>>> * run one testcase:
>>> runtests <testcase directory path>
>>> * cleanup previous results:
>>> runtests clean
>>>
>>> To run the testcases on Android, only have to change settings in
>>> test_config:
>>> * set path of $META and $DATA
>>> * set path of tools
>>> * push tests directory to an Android phone
>>> NOTE TAHT: the testcases will format $META!!!
>>>
>>> Some testcase requires root permission to mount the image and create
>>> files.
>>>
>>> Each testcase should have a sub-directory, where three files are needed:
>>> * README: describe information of the testcase
>>> * script: testcase itself
>>> * expect.in: is used to derive expected output message
>>>
>>> New files are generated in the testcase directory after test:
>>> * log: output in detail
>>> * expect: derived from expect.in
>>> * out: output that will be compared with expect
>>> * PASS: testcase is passed
>>> * FAIL: testcase is failed, in which differ of out and expect is saved
>>>
>>> The name of testcase directory has some optional prefix:
>>> * f_: fsck testcase
>>> * i_: inject testcase
>>> * m_: mkfs testcase
>>> But there are only fsck and inject testcases for now.
>>>
>>> To run testcases, it's better to compile fsck.f2fs as statically linked
>>> executable, or `make install' installs tools and libraries. Otherwise,
>>> libtool compiles f2fs-tools in debug mode and create a wrapper script
>>> to locate elf executable and libraries. However, dump.f2fs and
>>> inject.f2fs cannot be used in the wrapper way.
>>>
>>> v2: * add some fix and cleanup
>>> * remove img.tar.gz from testcases
>>> * add testcases for injection
>>> * cleanup helpers script and simplify filter.sed and expected.in
>>> v1: https://lore.kernel.org/linux-f2fs-devel/20241029120956.4186731-1-shengyong@oppo.com/
>>>
>>> Sheng Yong (32):
>>> fsck.f2fs: do not finish/reset zone if dry-run is true
>>> f2fs-tools: add option N to answer no for all questions
>>> f2fs-tools: cleanup {nid|segno}_in_journal
>>> fsck.f2fs: fix invalidate checkpoint
>>> dump.f2fs: print more info
>>> f2fs-tools: add and export lookup_sit_in_journal
>>> inject.f2fs: fix injecting sit/nat in journal
>>> inject.f2fs: fix injection on zoned device
>>> inject.f2fs: fix and cleanup parsing numeric options
>>> inject.f2fs: add members in inject_cp
>>> inject.f2fs: add member `feature' in inject_sb
>>> inject.f2fs: add members in inject_node
>>> inject.f2fs: add member `filename' in inject_dentry
>>> tests: prepare helper scripts for testcases
>>> tests: add fsck testcase of fixing bad super magic
>>> tests: add fsck testcase of fixing errors recorded in sb
>>> tests: add fsck testcase of fixing cp crc
>>> tests: add fsck testcase of fixing nat entry with invalid ino
>>> tests: add fsck testcase of fixing nat entry with invalid blkaddr
>>> tests: add fsck testcase of fixing sit entry type
>>> tests: add fsck testcase of fixing sit entry vblocks
>>> tests: add fsck testcase of fixing sit entry valid_map
>>> tests: add fsck testcase of fixing sum entry nid
>>> tests: add fsck testcase of fixing sum footer type
>>> tests: add fsck testcase of fixing sum entry ofs_in_node
>>> tests: add fsck testcase of fixing inode invalid i_addr
>>> tests: add fsck testcase of fixing dentry hash code
>>> tests: add fsck testcase of fixing lost dots
>>> tests: add fsck testcase of fixing duplicated dots
>>> tests: add fsck testcase of fixing loop fsync dnodes
>>> tests: add inject testcase of injecting META area
>>> tests: add inject testcase of injecting node block
>>>
>>> .gitignore | 14 +
>>> Makefile.am | 2 +-
>>> configure.ac | 1 +
>>> fsck/dump.c | 15 +-
>>> fsck/f2fs.h | 12 +-
>>> fsck/fsck.c | 2 +-
>>> fsck/fsck.h | 4 +-
>>> fsck/inject.c | 438 +++++++++++++++++++++-----
>>> fsck/inject.h | 1 +
>>> fsck/main.c | 14 +-
>>> fsck/mount.c | 61 ++--
>>> include/f2fs_fs.h | 1 +
>>> lib/libf2fs_zoned.c | 6 +-
>>> man/inject.f2fs.8 | 43 ++-
>>> tests/Makefile.am | 26 ++
>>> tests/f_cp_bad_crc/README | 5 +
>>> tests/f_cp_bad_crc/expect.in | 4 +
>>> tests/f_cp_bad_crc/script | 38 +++
>>> tests/f_dentry_bad_hash/README | 8 +
>>> tests/f_dentry_bad_hash/expect.in | 8 +
>>> tests/f_dentry_bad_hash/script | 56 ++++
>>> tests/f_dentry_dup_dots/README | 11 +
>>> tests/f_dentry_dup_dots/expect.in | 26 ++
>>> tests/f_dentry_dup_dots/script | 49 +++
>>> tests/f_dentry_lost_dots/README | 7 +
>>> tests/f_dentry_lost_dots/expect.in | 16 +
>>> tests/f_dentry_lost_dots/script | 37 +++
>>> tests/f_inode_bad_iaddr/README | 6 +
>>> tests/f_inode_bad_iaddr/expect.in | 13 +
>>> tests/f_inode_bad_iaddr/script | 50 +++
>>> tests/f_loop_fsync_dnodes/README | 5 +
>>> tests/f_loop_fsync_dnodes/expect.in | 6 +
>>> tests/f_loop_fsync_dnodes/script | 46 +++
>>> tests/f_nat_bad_blkaddr/README | 4 +
>>> tests/f_nat_bad_blkaddr/expect.in | 12 +
>>> tests/f_nat_bad_blkaddr/script | 25 ++
>>> tests/f_nat_bad_ino/README | 4 +
>>> tests/f_nat_bad_ino/expect.in | 12 +
>>> tests/f_nat_bad_ino/script | 31 ++
>>> tests/f_sb_bad_magic/README | 3 +
>>> tests/f_sb_bad_magic/expect.in | 5 +
>>> tests/f_sb_bad_magic/script | 15 +
>>> tests/f_sb_errors/README | 5 +
>>> tests/f_sb_errors/expect.in | 7 +
>>> tests/f_sb_errors/script | 22 ++
>>> tests/f_sit_bad_type/README | 5 +
>>> tests/f_sit_bad_type/expect.in | 3 +
>>> tests/f_sit_bad_type/script | 38 +++
>>> tests/f_sit_bad_valid_map/README | 5 +
>>> tests/f_sit_bad_valid_map/expect.in | 4 +
>>> tests/f_sit_bad_valid_map/script | 43 +++
>>> tests/f_sit_bad_vblocks/README | 5 +
>>> tests/f_sit_bad_vblocks/expect.in | 3 +
>>> tests/f_sit_bad_vblocks/script | 38 +++
>>> tests/f_ssa_bad_nid/README | 5 +
>>> tests/f_ssa_bad_nid/expect.in | 3 +
>>> tests/f_ssa_bad_nid/script | 36 +++
>>> tests/f_ssa_bad_ofs_in_node/README | 5 +
>>> tests/f_ssa_bad_ofs_in_node/expect.in | 3 +
>>> tests/f_ssa_bad_ofs_in_node/script | 36 +++
>>> tests/f_ssa_bad_type/README | 5 +
>>> tests/f_ssa_bad_type/expect.in | 3 +
>>> tests/f_ssa_bad_type/script | 31 ++
>>> tests/filter.sed | 69 ++++
>>> tests/helpers | 269 ++++++++++++++++
>>> tests/i_meta/README | 5 +
>>> tests/i_meta/expect.in | 60 ++++
>>> tests/i_meta/script | 212 +++++++++++++
>>> tests/i_node/README | 5 +
>>> tests/i_node/expect.in | 66 ++++
>>> tests/i_node/script | 166 ++++++++++
>>> tests/runtests.in | 48 +++
>>> tests/test_config.in | 53 ++++
>>> 73 files changed, 2284 insertions(+), 116 deletions(-)
>>> create mode 100644 tests/Makefile.am
>>> create mode 100644 tests/f_cp_bad_crc/README
>>> create mode 100644 tests/f_cp_bad_crc/expect.in
>>> create mode 100644 tests/f_cp_bad_crc/script
>>> create mode 100644 tests/f_dentry_bad_hash/README
>>> create mode 100644 tests/f_dentry_bad_hash/expect.in
>>> create mode 100644 tests/f_dentry_bad_hash/script
>>> create mode 100644 tests/f_dentry_dup_dots/README
>>> create mode 100644 tests/f_dentry_dup_dots/expect.in
>>> create mode 100644 tests/f_dentry_dup_dots/script
>>> create mode 100644 tests/f_dentry_lost_dots/README
>>> create mode 100644 tests/f_dentry_lost_dots/expect.in
>>> create mode 100644 tests/f_dentry_lost_dots/script
>>> create mode 100644 tests/f_inode_bad_iaddr/README
>>> create mode 100644 tests/f_inode_bad_iaddr/expect.in
>>> create mode 100644 tests/f_inode_bad_iaddr/script
>>> create mode 100644 tests/f_loop_fsync_dnodes/README
>>> create mode 100644 tests/f_loop_fsync_dnodes/expect.in
>>> create mode 100644 tests/f_loop_fsync_dnodes/script
>>> create mode 100644 tests/f_nat_bad_blkaddr/README
>>> create mode 100644 tests/f_nat_bad_blkaddr/expect.in
>>> create mode 100644 tests/f_nat_bad_blkaddr/script
>>> create mode 100644 tests/f_nat_bad_ino/README
>>> create mode 100644 tests/f_nat_bad_ino/expect.in
>>> create mode 100644 tests/f_nat_bad_ino/script
>>> create mode 100644 tests/f_sb_bad_magic/README
>>> create mode 100644 tests/f_sb_bad_magic/expect.in
>>> create mode 100644 tests/f_sb_bad_magic/script
>>> create mode 100644 tests/f_sb_errors/README
>>> create mode 100644 tests/f_sb_errors/expect.in
>>> create mode 100644 tests/f_sb_errors/script
>>> create mode 100644 tests/f_sit_bad_type/README
>>> create mode 100644 tests/f_sit_bad_type/expect.in
>>> create mode 100644 tests/f_sit_bad_type/script
>>> create mode 100644 tests/f_sit_bad_valid_map/README
>>> create mode 100644 tests/f_sit_bad_valid_map/expect.in
>>> create mode 100644 tests/f_sit_bad_valid_map/script
>>> create mode 100644 tests/f_sit_bad_vblocks/README
>>> create mode 100644 tests/f_sit_bad_vblocks/expect.in
>>> create mode 100644 tests/f_sit_bad_vblocks/script
>>> create mode 100644 tests/f_ssa_bad_nid/README
>>> create mode 100644 tests/f_ssa_bad_nid/expect.in
>>> create mode 100644 tests/f_ssa_bad_nid/script
>>> create mode 100644 tests/f_ssa_bad_ofs_in_node/README
>>> create mode 100644 tests/f_ssa_bad_ofs_in_node/expect.in
>>> create mode 100644 tests/f_ssa_bad_ofs_in_node/script
>>> create mode 100644 tests/f_ssa_bad_type/README
>>> create mode 100644 tests/f_ssa_bad_type/expect.in
>>> create mode 100644 tests/f_ssa_bad_type/script
>>> create mode 100644 tests/filter.sed
>>> create mode 100644 tests/helpers
>>> create mode 100644 tests/i_meta/README
>>> create mode 100644 tests/i_meta/expect.in
>>> create mode 100644 tests/i_meta/script
>>> create mode 100644 tests/i_node/README
>>> create mode 100644 tests/i_node/expect.in
>>> create mode 100644 tests/i_node/script
>>> create mode 100644 tests/runtests.in
>>> create mode 100644 tests/test_config.in
>>>
>>
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 45+ messages in thread
end of thread, other threads:[~2025-08-16 7:05 UTC | newest]
Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-10 12:37 [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 01/32] fsck.f2fs: do not finish/reset zone if dry-run is true Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 02/32] f2fs-tools: add option N to answer no for all questions Sheng Yong
2025-06-11 9:22 ` Chao Yu via Linux-f2fs-devel
2025-06-11 9:36 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 03/32] f2fs-tools: cleanup {nid|segno}_in_journal Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 04/32] fsck.f2fs: fix invalidate checkpoint Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 05/32] dump.f2fs: print more info Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 06/32] f2fs-tools: add and export lookup_sit_in_journal Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 07/32] inject.f2fs: fix injecting sit/nat in journal Sheng Yong
2025-06-11 11:42 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 08/32] inject.f2fs: fix injection on zoned device Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 09/32] inject.f2fs: fix and cleanup parsing numeric options Sheng Yong
2025-06-13 6:08 ` Chao Yu via Linux-f2fs-devel
2025-06-16 1:49 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 10/32] inject.f2fs: add members in inject_cp Sheng Yong
2025-06-13 7:30 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 11/32] inject.f2fs: add member `feature' in inject_sb Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 12/32] inject.f2fs: add members in inject_node Sheng Yong
2025-06-13 7:38 ` Chao Yu via Linux-f2fs-devel
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 13/32] inject.f2fs: add member `filename' in inject_dentry Sheng Yong
2025-06-13 7:55 ` Chao Yu via Linux-f2fs-devel
2025-06-16 2:01 ` Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 14/32] tests: prepare helper scripts for testcases Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 15/32] tests: add fsck testcase of fixing bad super magic Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 16/32] tests: add fsck testcase of fixing errors recorded in sb Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 17/32] tests: add fsck testcase of fixing cp crc Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 18/32] tests: add fsck testcase of fixing nat entry with invalid ino Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 19/32] tests: add fsck testcase of fixing nat entry with invalid blkaddr Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 20/32] tests: add fsck testcase of fixing sit entry type Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 21/32] tests: add fsck testcase of fixing sit entry vblocks Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 22/32] tests: add fsck testcase of fixing sit entry valid_map Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 23/32] tests: add fsck testcase of fixing sum entry nid Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 24/32] tests: add fsck testcase of fixing sum footer type Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 25/32] tests: add fsck testcase of fixing sum entry ofs_in_node Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 26/32] tests: add fsck testcase of fixing inode invalid i_addr Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 27/32] tests: add fsck testcase of fixing dentry hash code Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 28/32] tests: add fsck testcase of fixing lost dots Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 29/32] tests: add fsck testcase of fixing duplicated dots Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 30/32] tests: add fsck testcase of fixing loop fsync dnodes Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 31/32] tests: add inject testcase of injecting META area Sheng Yong
2025-06-10 12:37 ` [f2fs-dev] [RFC PATCH v2 32/32] tests: add inject testcase of injecting node block Sheng Yong
2025-08-15 10:38 ` [f2fs-dev] [RFC PATCH v2 00/32] f2fs-tools: add testcases Chao Yu via Linux-f2fs-devel
2025-08-15 11:27 ` Sheng Yong
2025-08-16 7:04 ` Chao Yu via Linux-f2fs-devel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).