This patch introduces a new tool inject.f2fs to modify metadata or data (directory entry) of f2fs image offline flexibly.
With inject.f2fs, it is easier to generate a corrupted f2fs image, which can help verify fsck or reproduce userspace behaviors of some a fault. If option `--dry-run' is used, nothing really gets changed, and that could be used to get the value of a specified field. The following patches enable injecting each part of f2fs. Signed-off-by: Sheng Yong <shengy...@oppo.com> --- fsck/Makefile.am | 5 ++-- fsck/inject.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ fsck/inject.h | 28 +++++++++++++++++++++ fsck/main.c | 29 +++++++++++++++++++++ include/f2fs_fs.h | 2 ++ 5 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 fsck/inject.c create mode 100644 fsck/inject.h diff --git a/fsck/Makefile.am b/fsck/Makefile.am index 40d31b8..48402ab 100644 --- a/fsck/Makefile.am +++ b/fsck/Makefile.am @@ -4,11 +4,12 @@ AM_CPPFLAGS = ${libuuid_CFLAGS} -I$(top_srcdir)/include AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 sbin_PROGRAMS = fsck.f2fs noinst_HEADERS = common.h dict.h dqblk_v2.h f2fs.h fsck.h node.h quotaio.h \ - quotaio_tree.h quotaio_v2.h xattr.h compress.h + quotaio_tree.h quotaio_v2.h xattr.h compress.h inject.h include_HEADERS = $(top_srcdir)/include/quota.h fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c resize.c \ node.c segment.c dir.c sload.c xattr.c compress.c \ - dict.c mkquota.c quotaio.c quotaio_tree.c quotaio_v2.c + dict.c mkquota.c quotaio.c quotaio_tree.c quotaio_v2.c \ + inject.c fsck_f2fs_LDADD = ${libselinux_LIBS} ${libuuid_LIBS} \ ${liblzo2_LIBS} ${liblz4_LIBS} ${libwinpthread_LIBS} \ $(top_builddir)/lib/libf2fs.la diff --git a/fsck/inject.c b/fsck/inject.c new file mode 100644 index 0000000..f6fd346 --- /dev/null +++ b/fsck/inject.c @@ -0,0 +1,64 @@ +/** + * inject.c + * + * Copyright (c) 2024 OPPO Mobile Comm Corp., Ltd. + * http://www.oppo.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <getopt.h> +#include "inject.h" + +void inject_usage(void) +{ + MSG(0, "\nUsage: inject.f2fs [options] device\n"); + MSG(0, "[options]:\n"); + MSG(0, " -d debug level [default:0]\n"); + MSG(0, " -V print the version number and exit\n"); + MSG(0, " --dry-run do not really inject\n"); + + exit(1); +} + +int inject_parse_options(int argc, char *argv[], struct inject_option *opt) +{ + int o = 0; + const char *option_string = "d:V"; + struct option long_opt[] = { + {"dry-run", no_argument, 0, 1}, + {0, 0, 0, 0} + }; + + while ((o = getopt_long(argc, argv, option_string, + long_opt, NULL)) != EOF) { + switch (o) { + case 1: + c.dry_run = 1; + MSG(0, "Info: Dry run\n"); + break; + case 'd': + if (optarg[0] == '-' || !is_digits(optarg)) + return EWRONG_OPT; + c.dbg_lv = atoi(optarg); + MSG(0, "Info: Debug level = %d\n", c.dbg_lv); + break; + case 'V': + show_version("inject.f2fs"); + exit(0); + default: + return EUNKNOWN_OPT; + } + } + + return 0; +} + +int do_inject(struct f2fs_sb_info *sbi) +{ + int ret = -EINVAL; + + return ret; +} diff --git a/fsck/inject.h b/fsck/inject.h new file mode 100644 index 0000000..62543c1 --- /dev/null +++ b/fsck/inject.h @@ -0,0 +1,28 @@ +/** + * inject.h + * + * Copyright (c) 2024 OPPO Mobile Comm Corp., Ltd. + * http://www.oppo.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _INJECT_H_ +#define _INJECT_H_ + +#include <stdio.h> +#include <stdint.h> +#include <limits.h> + +#include "f2fs_fs.h" +#include "fsck.h" + +struct inject_option { +}; + +void inject_usage(void); +int inject_parse_options(int argc, char *argv[], struct inject_option *inject_opt); +int do_inject(struct f2fs_sb_info *sbi); +#endif diff --git a/fsck/main.c b/fsck/main.c index 9bda412..f093ca7 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -29,6 +29,15 @@ #include <stdbool.h> #include "quotaio.h" #include "compress.h" +#ifdef WITH_INJECT +#include "inject.h" +#else +static void inject_usage(void) +{ + MSG(0, "\ninject.f2fs not supported\n"); + exit(1); +} +#endif struct f2fs_fsck gfsck; @@ -190,6 +199,8 @@ static void error_out(char *prog) sload_usage(); else if (!strcmp("f2fslabel", prog)) label_usage(); + else if (!strcmp("inject.f2fs", prog)) + inject_usage(); else MSG(0, "\nWrong program.\n"); } @@ -804,6 +815,18 @@ void f2fs_parse_options(int argc, char *argv[]) c.vol_label = NULL; } #endif /* WITH_LABEL */ + } else if (!strcmp("inject.f2fs", prog)) { +#ifdef WITH_INJECT + static struct inject_option inject_opt; + + err = inject_parse_options(argc, argv, &inject_opt); + if (err < 0) { + err = EWRONG_OPT; + } + + c.func = INJECT; + c.private = &inject_opt; +#endif /* WITH_INJECT */ } if (err == NOERROR) { @@ -1224,6 +1247,12 @@ fsck_again: if (do_label(sbi)) goto out_err; break; +#endif +#ifdef WITH_INJECT + case INJECT: + if (do_inject(sbi)) + goto out_err; + break; #endif default: ERR_MSG("Wrong program name\n"); diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index 870a6e4..3a5d146 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -45,6 +45,7 @@ #define WITH_RESIZE #define WITH_SLOAD #define WITH_LABEL +#define WITH_INJECT #endif #include <inttypes.h> @@ -427,6 +428,7 @@ enum f2fs_config_func { RESIZE, SLOAD, LABEL, + INJECT, }; enum default_set { -- 2.40.1 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel