Introduce tune.f2fs tool to change the f2fs parameters.
Currently this tool only supports adding or removing encrypt
feature bit in superblock.

Signed-off-by: Junling Zheng <zhengjunl...@huawei.com>
---
 fsck/Makefile.am  |  3 ++-
 fsck/fsck.h       |  5 +++++
 fsck/main.c       | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fsck/tune.c       | 46 +++++++++++++++++++++++++++++++++++++++++
 include/f2fs_fs.h | 61 +++++++++++++++++++++++++++++++++++++++----------------
 man/Makefile.am   |  2 +-
 man/tune.f2fs.8   | 50 +++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 207 insertions(+), 20 deletions(-)
 create mode 100644 fsck/tune.c
 create mode 100644 man/tune.f2fs.8

diff --git a/fsck/Makefile.am b/fsck/Makefile.am
index 1fc7310..3efacfd 100644
--- a/fsck/Makefile.am
+++ b/fsck/Makefile.am
@@ -5,7 +5,7 @@ AM_CFLAGS = -Wall
 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
 include_HEADERS = $(top_srcdir)/include/quota.h
-fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c resize.c \
+fsck_f2fs_SOURCES = main.c fsck.c dump.c mount.c defrag.c resize.c tune.c \
                node.c segment.c dir.c sload.c xattr.c \
                dict.c mkquota.c quotaio.c quotaio_tree.c quotaio_v2.c
 fsck_f2fs_LDADD = ${libselinux_LIBS} ${libuuid_LIBS} 
$(top_builddir)/lib/libf2fs.la
@@ -15,3 +15,4 @@ install-data-hook:
        ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/defrag.f2fs
        ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/resize.f2fs
        ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/sload.f2fs
+       ln -sf fsck.f2fs $(DESTDIR)/$(sbindir)/tune.f2fs
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 3e13fc6..39d6ed4 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -180,6 +180,8 @@ extern void write_superblock(struct f2fs_super_block *);
 extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t);
 extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, block_t);
 
+extern int validate_super_block(struct f2fs_sb_info *, int);
+extern void print_sb_state(struct f2fs_super_block *);
 extern void print_raw_sb_info(struct f2fs_super_block *);
 
 extern u32 get_free_segments(struct f2fs_sb_info *);
@@ -220,6 +222,9 @@ int f2fs_resize(struct f2fs_sb_info *);
 /* sload.c */
 int f2fs_sload(struct f2fs_sb_info *);
 
+/* tune.c */
+int f2fs_tune(struct f2fs_sb_info *);
+
 /* segment.c */
 void reserve_new_block(struct f2fs_sb_info *, block_t *,
                                        struct f2fs_summary *, int);
diff --git a/fsck/main.c b/fsck/main.c
index c4dd8b1..b8e1aee 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -29,6 +29,7 @@ extern struct sparse_file *f2fs_sparse_file;
 #endif
 
 INIT_FEATURE_TABLE;
+INIT_TUNE_FEATURE_TABLE;
 
 static char *absolute_path(const char *file)
 {
@@ -123,6 +124,15 @@ void sload_usage()
        exit(1);
 }
 
+void tune_usage()
+{
+       MSG(0, "\nUsage: tune.f2fs [options] device\n");
+       MSG(0, "[options]:\n");
+       MSG(0, "  -d debug level [default:0]\n");
+       MSG(0, "  -O [^]feature[,...]\n");
+       exit(1);
+}
+
 static int is_digits(char *optarg)
 {
        unsigned int i;
@@ -145,6 +155,8 @@ static void error_out(char *prog)
                resize_usage();
        else if (!strcmp("sload.f2fs", prog))
                sload_usage();
+       else if (!strcmp("tune.f2fs", prog))
+               tune_usage();
        else
                MSG(0, "\nWrong program.\n");
 }
@@ -528,6 +540,32 @@ void f2fs_parse_options(int argc, char *argv[])
                        if (err != NOERROR)
                                break;
                }
+       } else if (!strcmp("tune.f2fs", prog)) {
+               const char *option_string = "d:O:";
+
+               c.func = TUNE;
+               while ((option = getopt(argc, argv, option_string)) != EOF) {
+                       switch (option) {
+                       case 'd':
+                               if (!is_digits(optarg)) {
+                                       err = EWRONG_OPT;
+                                       break;
+                               }
+                               c.dbg_lv = atoi(optarg);
+                               MSG(0, "Info: Debug level = %d\n",
+                                                       c.dbg_lv);
+                               break;
+                       case 'O':
+                               if (parse_feature(tune_feature_table, optarg))
+                                       tune_usage();
+                               break;
+                       default:
+                               err = EUNKNOWN_OPT;
+                               break;
+                       }
+                       if (err != NOERROR)
+                               break;
+               }
        }
 
        add_default_options();
@@ -736,6 +774,13 @@ static int do_sload(struct f2fs_sb_info *sbi)
        return f2fs_sload(sbi);
 }
 
+static int do_tune(struct f2fs_sb_info *sbi)
+{
+       // TODO: check global configuration
+
+       return f2fs_tune(sbi);
+}
+
 int main(int argc, char **argv)
 {
        struct f2fs_sb_info *sbi;
@@ -768,6 +813,18 @@ fsck_again:
        gfsck.sbi.fsck = &gfsck;
        sbi = &gfsck.sbi;
 
+#ifdef WITH_TUNE
+       if (c.func == TUNE) {
+               ret = do_tune(sbi);
+               if (ret)
+                       goto out_err;
+               /* If tune successfully, then call
+                * f2fs_finalize_device to fsync.
+                */
+               goto out;
+       }
+#endif
+
        ret = f2fs_do_mount(sbi);
        if (ret != 0) {
                if (ret == 1) {
@@ -836,6 +893,9 @@ retry:
                                goto fsck_again;
                }
        }
+#ifdef WITH_TUNE
+out:
+#endif
        ret = f2fs_finalize_device();
        if (ret < 0)
                return ret;
diff --git a/fsck/tune.c b/fsck/tune.c
new file mode 100644
index 0000000..1322639
--- /dev/null
+++ b/fsck/tune.c
@@ -0,0 +1,46 @@
+/**
+ * tune.c
+ *
+ * Copyright (C) 2018 Huawei Ltd.
+ * Witten by:
+ *   Junling Zheng <zhengjunl...@huawei.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 "fsck.h"
+
+int f2fs_tune(struct f2fs_sb_info *sbi)
+{
+       int ret;
+
+       /* Get and validate sbi->raw_super */
+       ret = validate_super_block(sbi, 0);
+       if (ret) {
+               ret = validate_super_block(sbi, 1);
+               if (ret)
+                       return -1;
+       }
+
+       /* Tune features in sb */
+       if (c.feature)
+               sbi->raw_super->feature |= c.feature;
+       if (c.nofeature)
+               sbi->raw_super->feature &= ~c.nofeature;
+
+       MSG(0, "Info: Tune feature successfully!\n");
+       /* Print features in sb */
+       print_sb_state(sbi->raw_super);
+
+       /* Write raw_super back to both 1st and 2nd sb on disk */
+       ret = dev_write(sbi->raw_super, F2FS_SUPER_OFFSET,
+                               sizeof(struct f2fs_super_block));
+       ASSERT(ret >= 0);
+       ret = dev_write(sbi->raw_super, F2FS_SUPER_OFFSET + F2FS_BLKSIZE,
+                                               sizeof(struct 
f2fs_super_block));
+       ASSERT(ret >= 0);
+       MSG(0, "Info: Writeback successfully!\n");
+
+       return ret;
+}
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index a1274fd..87d2fe9 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -13,6 +13,7 @@
 #define __F2FS_FS_H__
 
 #include <stdio.h>
+#include <ctype.h>
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -28,6 +29,7 @@
 #define WITH_DEFRAG
 #define WITH_RESIZE
 #define WITH_SLOAD
+#define WITH_TUNE
 #endif
 
 #include <inttypes.h>
@@ -309,6 +311,7 @@ enum f2fs_config_func {
        DEFRAG,
        RESIZE,
        SLOAD,
+       TUNE,
 };
 
 enum default_set {
@@ -381,7 +384,8 @@ struct f2fs_configuration {
        int ro;
        int preserve_limits;            /* preserve quota limits */
        int large_nat_bitmap;
-       __le32 feature;                 /* defined features */
+       __le32 feature;                 /* defined features to enable */
+       __le32 nofeature;               /* defined features to disable */
 
        /* mkfs parameters */
        u_int32_t next_free_nid;
@@ -1334,6 +1338,12 @@ struct feature feature_table[] = {                       
                \
        { NULL,                         0x0},                           \
 };
 
+#define INIT_TUNE_FEATURE_TABLE                                                
\
+struct feature tune_feature_table[] = {                                        
\
+       { "encrypt",                    F2FS_FEATURE_ENCRYPT },         \
+       { NULL,                         0x0},                           \
+};
+
 static inline u32 feature_map(struct feature *table, char *feature)
 {
        struct feature *p;
@@ -1342,21 +1352,11 @@ static inline u32 feature_map(struct feature *table, 
char *feature)
        return p->mask;
 }
 
-static inline int set_feature_bits(struct feature *table, char *features)
-{
-       u32 mask = feature_map(table, features);
-       if (mask) {
-               c.feature |= cpu_to_le32(mask);
-       } else {
-               MSG(0, "Error: Wrong features %s\n", features);
-               return -1;
-       }
-       return 0;
-}
-
 static inline int parse_feature(struct feature *table, const char *features)
 {
-       char *buf, *sub, *next;
+       char op, *buf, *sub, *next;
+       u32 feature_bit = 0;
+       int ret = 0;
 
        buf = calloc(strlen(features) + 1, sizeof(char));
        ASSERT(buf);
@@ -1376,12 +1376,37 @@ static inline int parse_feature(struct feature *table, 
const char *features)
                else
                        *next = 0;
 
-               if (set_feature_bits(table, sub)) {
-                       free(buf);
-                       return -1;
+               if (!isalnum(*sub)) {
+                       op = *sub;
+                       sub++;
+               } else {
+                       op = '+';
+               }
+
+               feature_bit = feature_map(table, sub);
+               if (!feature_bit) {
+                       ERR_MSG("\tError: Not support feature %s\n", sub);
+                       ret = -1;
+                       goto out;
+               }
+
+               switch (op) {
+               case '+':
+                       c.feature |= cpu_to_le32(feature_bit);
+                       break;
+               case '-':
+               case '^':
+                       c.nofeature |= cpu_to_le32(feature_bit);
+                       break;
+               default:
+                       ERR_MSG("\tError: Wrong operation %c\n", op);
+                       ret = -1;
+                       goto out;
                }
        }
+
+out:
        free(buf);
-       return 0;
+       return ret;
 }
 #endif /*__F2FS_FS_H */
diff --git a/man/Makefile.am b/man/Makefile.am
index 7856586..bfc4d19 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,3 +1,3 @@
 ## Makefile.am
 
-dist_man_MANS = mkfs.f2fs.8 fsck.f2fs.8 dump.f2fs.8 defrag.f2fs.8 
resize.f2fs.8 sload.f2fs.8
+dist_man_MANS = mkfs.f2fs.8 fsck.f2fs.8 dump.f2fs.8 defrag.f2fs.8 
resize.f2fs.8 sload.f2fs.8 tune.f2fs.8
diff --git a/man/tune.f2fs.8 b/man/tune.f2fs.8
new file mode 100644
index 0000000..5ee6790
--- /dev/null
+++ b/man/tune.f2fs.8
@@ -0,0 +1,50 @@
+.\" Copyright (C) 2015 Huawei Ltd.
+.\"
+.TH TUNE.F2FS 8
+.SH NAME
+tune.f2fs \- change the parameters of f2fs
+.SH SYNOPSIS
+.B tune.f2fs
+[
+.B \-d
+.I debugging-level
+]
+[
+.B \-O
+.I features to change
+]
+.I device
+.SH DESCRIPTION
+.B tune.f2fs
+is used to change the parameters of an f2fs file system (usually in a disk 
partition).
+\fIdevice\fP is the special file corresponding to the device (e.g.
+\fI/dev/sdXX\fP).
+
+Current version only supports enabling and disabling 'encrypt' feature.
+
+.PP
+The exit code returned by
+.B tune.f2fs
+is 0 on success and -1 on failure.
+.SH OPTIONS
+.TP
+.BI \-d " debug-level"
+Specify the level of debugging options.
+The default number is 0, which shows basic debugging messages.
+.TP
+.BI \-O " features"
+Specify the features to enable or disable. Currently only support 'encrypt' 
feature.
+.TP
+.SH AUTHOR
+This version of
+.B tune.f2fs
+has been written by Junling Zheng <zhengjunl...@huawei.com>.
+.SH AVAILABILITY
+.B tune.f2fs
+is available from 
git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs-tools.git.
+.SH SEE ALSO
+.BR mkfs.f2fs(8),
+.BR fsck.f2fs(8),
+.BR dump.f2fs(8),
+.BR defrag.f2fs(8),
+.BR sload.f2fs(8).
-- 
2.16.2


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to