Add a new -r option to change sb_fs_format.  Only increasing the number
is supported. New tests added.

Signed-off-by: Andrew Price <[email protected]>
---
 gfs2/libgfs2/libgfs2.h |  1 +
 gfs2/man/tunegfs2.8    |  5 +++++
 gfs2/tune/Makefile.am  |  3 ++-
 gfs2/tune/main.c       | 18 +++++++++++++-----
 gfs2/tune/super.c      | 20 ++++++++++++++++++++
 gfs2/tune/tunegfs2.h   |  5 +++--
 tests/Makefile.am      |  3 ++-
 tests/testsuite.at     |  1 +
 tests/tune.at          | 17 +++++++++++++++++
 9 files changed, 64 insertions(+), 9 deletions(-)
 create mode 100644 tests/tune.at

diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 6973c6f3..1f64b59e 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -327,6 +327,7 @@ struct metapath {
 
 #define LGFS2_FS_FORMAT_MIN (1801)
 #define LGFS2_FS_FORMAT_MAX (1802)
+#define LGFS2_FS_FORMAT_VALID(n) ((n) >= LGFS2_FS_FORMAT_MIN && (n) <= 
LGFS2_FS_FORMAT_MAX)
 
 /* meta.c */
 extern const struct lgfs2_metadata lgfs2_metadata[];
diff --git a/gfs2/man/tunegfs2.8 b/gfs2/man/tunegfs2.8
index c4446f44..660bf962 100644
--- a/gfs2/man/tunegfs2.8
+++ b/gfs2/man/tunegfs2.8
@@ -53,6 +53,11 @@ Set the filesystem UUID
 
 Print out the information on the version of the tool.
 
+.TP
+\fB-r\fP \fI<version>\fR
+
+Set the filesystem format version.
+
 .SH SEE ALSO
 
 \fBgfs2\fP(5)
diff --git a/gfs2/tune/Makefile.am b/gfs2/tune/Makefile.am
index b03f609a..6c4bbe1f 100644
--- a/gfs2/tune/Makefile.am
+++ b/gfs2/tune/Makefile.am
@@ -10,10 +10,11 @@ tunegfs2_SOURCES = \
 tunegfs2_CPPFLAGS = \
        -D_FILE_OFFSET_BITS=64 \
        -I$(top_srcdir)/gfs2/include \
-       -I$(top_srcdir)/group/include
+       -I$(top_srcdir)/gfs2/libgfs2
 tunegfs2_CFLAGS = \
        $(uuid_CFLAGS)
 tunegfs2_LDADD = \
+       $(top_builddir)/gfs2/libgfs2/libgfs2.la \
        $(uuid_LIBS)
 
 if HAVE_CHECK
diff --git a/gfs2/tune/main.c b/gfs2/tune/main.c
index 93f0f60c..d5998071 100644
--- a/gfs2/tune/main.c
+++ b/gfs2/tune/main.c
@@ -52,9 +52,9 @@ static void parse_mount_options(char *arg)
 
 static void usage(char *name)
 {
-       printf("%s %s [-hlV] [-L <%s>] [-U <%s>] [-o <%s>] <%s>\n",
+       printf("%s %s [-hlV] [-L <%s>] [-U <%s>] [-o <%s>] [-r <%s>] <%s>\n",
               _("Usage:"), basename(name), _("label"), _("UUID"),
-              _("mount options"), _("device"));
+              _("mount options"), _("version"), _("device"));
 }
 
 static void version(void)
@@ -68,7 +68,7 @@ int main(int argc, char **argv)
        int c, status;
 
        memset(tfs, 0, sizeof(struct tunegfs2));
-       while((c = getopt(argc, argv, "hL:U:lo:V")) != -1) {
+       while((c = getopt(argc, argv, "hL:U:lo:Vr:")) != -1) {
                switch(c) {
                case 'h':
                        usage(argv[0]);
@@ -90,6 +90,10 @@ int main(int argc, char **argv)
                case 'V':
                        version();
                        return 0;
+               case 'r':
+                       tfs->opt_format = 1;
+                       tfs->format = optarg;
+                       break;
                default:
                        fprintf(stderr, _("Invalid option: %c\n"), c);
                        usage(argv[0]);
@@ -145,9 +149,13 @@ int main(int argc, char **argv)
                if (status)
                        goto out;
        }
-
+       if (tfs->opt_format) {
+               status = change_format(tfs, tfs->format);
+               if (status)
+                       goto out;
+       }
        if (tfs->opt_label || tfs->opt_uuid || tfs->opt_table ||
-           tfs->opt_proto) {
+           tfs->opt_proto || tfs->opt_format) {
                status = write_super(tfs);
                if (status)
                        goto out;
diff --git a/gfs2/tune/super.c b/gfs2/tune/super.c
index f4b7d85b..c3029fd1 100644
--- a/gfs2/tune/super.c
+++ b/gfs2/tune/super.c
@@ -12,6 +12,7 @@
 #define _(String) gettext(String)
 #include <linux_endian.h>
 #include <linux/gfs2_ondisk.h>
+#include <libgfs2.h>
 #include "tunegfs2.h"
 
 #ifdef GFS2_HAS_UUID
@@ -64,6 +65,7 @@ int print_super(const struct tunegfs2 *tfs)
        }
 #endif
        printf( _("File system magic number: 0x%X\n"), 
be32_to_cpu(tfs->sb->sb_header.mh_magic));
+       printf(_("File system format version: %"PRIu32"\n"), 
be32_to_cpu(tfs->sb->sb_fs_format));
        printf(_("Block size: %d\n"), be32_to_cpu(tfs->sb->sb_bsize));
        printf(_("Block shift: %d\n"), be32_to_cpu(tfs->sb->sb_bsize_shift));
        printf(_("Root inode: %llu\n"), (unsigned long 
long)be64_to_cpu(tfs->sb->sb_root_dir.no_addr));
@@ -150,3 +152,21 @@ int change_locktable(struct tunegfs2 *tfs, const char 
*locktable)
        return 0;
 }
 
+int change_format(struct tunegfs2 *tfs, const char *format)
+{
+       char *end;
+       long ln;
+
+       errno = 0;
+       ln = strtol(format, &end, 10);
+       if (errno || end == format || !LGFS2_FS_FORMAT_VALID(ln)) {
+               fprintf(stderr, _("Invalid format option '%s'\n"), format);
+               return EX_DATAERR;
+       }
+       if (ln < be32_to_cpu(tfs->sb->sb_fs_format)) {
+               fprintf(stderr, _("Regressing the filesystem format is not 
supported\n"));
+               return EX_DATAERR;
+       }
+       tfs->sb->sb_fs_format = cpu_to_be32(ln);
+       return 0;
+}
diff --git a/gfs2/tune/tunegfs2.h b/gfs2/tune/tunegfs2.h
index 3b28c58e..98c99696 100644
--- a/gfs2/tune/tunegfs2.h
+++ b/gfs2/tune/tunegfs2.h
@@ -1,8 +1,6 @@
 #ifndef __GFS2_TUNE_DOT_H__
 #define __GFS2_TUNE_DOT_H__
 
-#define GFS2_DEFAULT_BSIZE     4096
-
 struct tunegfs2 {
        char *devicename;
        int fd;
@@ -13,11 +11,13 @@ struct tunegfs2 {
        char *table;
        char *proto;
        char *mount_options;
+       char *format;
        int opt_list;
        int opt_label;
        int opt_uuid;
        int opt_proto;
        int opt_table;
+       int opt_format;
 };
 
 extern int print_super(const struct tunegfs2 *);
@@ -26,6 +26,7 @@ extern int write_super(const struct tunegfs2 *);
 extern int change_uuid(struct tunegfs2 *, const char *uuid);
 extern int change_lockproto(struct tunegfs2 *, const char *label);
 extern int change_locktable(struct tunegfs2 *, const char *label);
+extern int change_format(struct tunegfs2 *, const char *format);
 
 #endif
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 11d848cd..9109cf39 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -52,7 +52,8 @@ TESTSUITE_AT = \
        testsuite.at \
        mkfs.at \
        fsck.at \
-       edit.at
+       edit.at \
+       tune.at
 
 TESTSUITE = testsuite
 
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 98102183..1c1dc9e5 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -51,3 +51,4 @@ AT_COLOR_TESTS
 m4_include([mkfs.at])
 m4_include([fsck.at])
 m4_include([edit.at])
+m4_include([tune.at])
diff --git a/tests/tune.at b/tests/tune.at
new file mode 100644
index 00000000..b0158034
--- /dev/null
+++ b/tests/tune.at
@@ -0,0 +1,17 @@
+AT_TESTED([tunegfs2])
+AT_BANNER([tunegfs2 tests])
+
+AT_SETUP([Format version])
+AT_KEYWORDS(tunegfs2 tune)
+AT_CHECK([$GFS_MKFS -p lock_nolock -o format=1802 $GFS_TGT], 0, [ignore], 
[ignore])
+# Exit code 65 == EX_DATAERR (sysexits.h)
+AT_CHECK([tunegfs2 -r 0 $GFS_TGT], 65, [ignore], [ignore])
+# Regress not supported
+AT_CHECK([tunegfs2 -r 1801 $GFS_TGT], 65, [ignore], [ignore])
+# Format 1803 does not exist
+AT_CHECK([tunegfs2 -r 1803 $GFS_TGT], 65, [ignore], [ignore])
+# Normal version bump
+AT_CHECK([$GFS_MKFS -p lock_nolock -o format=1801 $GFS_TGT], 0, [ignore], 
[ignore])
+AT_CHECK([tunegfs2 -r 1802 $GFS_TGT], 0, [ignore], [ignore])
+AT_CHECK([fsck.gfs2 -n $GFS_TGT], 0, [ignore], [ignore])
+AT_CLEANUP
-- 
2.29.2

Reply via email to