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

Reply via email to