[Ocfs2-tools-devel] [PATCH 1/5] Move feature string parsing out of
mkfs.ocfs2, take 2
Tao Ma
tao.ma at oracle.com
Thu Oct 25 00:35:50 PDT 2007
tunfs.ocfs2 now also have to parse the feature-strings,
so move the feature string parsing out of mkfs.ocfs2 and create
a new file named feature_string.c in libocfs2 to handle this work.
Now tunefs.ocfs2 can also use it.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
Signed-off-by: Mark Fasheh <mark.fasheh at oracle.com>
---
libocfs2/Makefile | 6 +-
libocfs2/feature_string.c | 234 +++++++++++++++++++++++++++++++++++
libocfs2/include/feature_string.h | 67 ++++++++++
mkfs.ocfs2/mkfs.c | 247 +++----------------------------------
mkfs.ocfs2/mkfs.h | 10 +--
5 files changed, 322 insertions(+), 242 deletions(-)
create mode 100644 libocfs2/feature_string.c
create mode 100644 libocfs2/include/feature_string.h
diff --git a/libocfs2/Makefile b/libocfs2/Makefile
index cfbce83..18d255b 100644
--- a/libocfs2/Makefile
+++ b/libocfs2/Makefile
@@ -81,7 +81,8 @@ CFILES = \
unix_io.c \
unlink.c \
lockid.c \
- backup_super.c
+ backup_super.c \
+ feature_string.c
HFILES = \
include/bitmap.h \
@@ -96,7 +97,8 @@ HFILES = \
include/ocfs1_fs_compat.h \
include/ocfs2_lockid.h \
include/ocfs2_fs.h \
- include/ocfs2.h
+ include/ocfs2.h \
+ include/feature_string.h
HFILES_GEN = \
include/ocfs2_err.h
diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
new file mode 100644
index 0000000..40720b8
--- /dev/null
+++ b/libocfs2/feature_string.c
@@ -0,0 +1,234 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * feature_strings.c
+ *
+ * Routines for analyzing a feature string.
+ *
+ * Copyright (C) 2007 Oracle. All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+#include <feature_string.h>
+
+struct feature_level_translation {
+ const char *fl_str;
+ enum feature_level_indexes fl_type;
+};
+
+static struct feature_level_translation ocfs2_feature_levels_table[] = {
+ {"default", FEATURE_LEVEL_DEFAULT},
+ {"max-compat", FEATURE_LEVEL_MAX_COMPAT},
+ {"max-features", FEATURE_LEVEL_MAX_FEATURES},
+ {NULL, FEATURE_LEVEL_DEFAULT},
+};
+
+static fs_options feature_level_defaults[] = {
+ {OCFS2_FEATURE_COMPAT_BACKUP_SB,
+ OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC,
+ 0}, /* FEATURE_LEVEL_DEFAULT */
+
+ {OCFS2_FEATURE_COMPAT_BACKUP_SB,
+ 0,
+ 0}, /* FEATURE_LEVEL_MAX_COMPAT */
+
+ {OCFS2_FEATURE_COMPAT_BACKUP_SB,
+ OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC,
+ OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* FEATURE_LEVEL_MAX_FEATURES */
+};
+
+static struct fs_feature_flags ocfs2_supported_features[] = {
+ {
+ "local",
+ {0, OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT, 0},
+ {0, OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT, 0},
+ },
+ {
+ "sparse",
+ {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC, 0},
+ {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC, 0},
+ },
+ {
+ "backup-super",
+ {OCFS2_FEATURE_COMPAT_BACKUP_SB, 0, 0},
+ {OCFS2_FEATURE_COMPAT_BACKUP_SB, 0, 0},
+ },
+ {
+ "unwritten",
+ {0, 0, OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},
+ {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC,
+ OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},
+ },
+ {
+ NULL,
+ {0, 0, 0},
+ {0, 0, 0}
+ },
+};
+
+static inline void merge_features(fs_options *features,
+ fs_options new_features)
+{
+ features->compat |= new_features.compat;
+ features->incompat |= new_features.incompat;
+ features->ro_compat |= new_features.ro_compat;
+}
+
+/* Get the feature level according to the value set by "--fs-feature-level". */
+int parse_feature_level(const char *typestr,
+ enum feature_level_indexes *index)
+{
+ int i;
+
+ for(i = 0; ocfs2_feature_levels_table[i].fl_str; i++) {
+ if (strcmp(typestr,
+ ocfs2_feature_levels_table[i].fl_str) == 0) {
+ *index = ocfs2_feature_levels_table[i].fl_type;
+ break;
+ }
+ }
+
+ if (!ocfs2_feature_levels_table[i].fl_str) {
+ return OCFS2_ET_UNSUPP_FEATURE;
+ }
+
+ return 0;
+}
+
+static int check_feature_flags(fs_options *fs_flags,
+ fs_options *fs_r_flags)
+{
+ int ret = 1;
+
+ if (fs_r_flags->compat &&
+ fs_flags->compat & fs_r_flags->compat)
+ ret = 0;
+ else if (fs_r_flags->incompat &&
+ fs_flags->incompat & fs_r_flags->incompat)
+ ret = 0;
+ else if (fs_r_flags->ro_compat &&
+ fs_flags->ro_compat & fs_r_flags->ro_compat)
+ ret = 0;
+
+ return ret;
+}
+
+/*
+ * Check and Merge all the diffent features set by the user.
+ *
+ * index: the feature level.
+ * feature_set: all the features a user set by "--fs-features".
+ * reverse_set: all the features a user want to clear by "--fs-features".
+ */
+int merge_feature_flags_with_level(fs_options *dest,
+ int index,
+ fs_options *feature_set,
+ fs_options *reverse_set)
+{
+ int i;
+ fs_options level_set = feature_level_defaults[index];
+ /*
+ * "Check whether the user asked for a flag to be set and cleared,
+ * which is illegal. The feature_set and reverse_set are both set
+ * by "--fs-features", so they shouldn't collide with each other.
+ */
+ if (!check_feature_flags(feature_set, reverse_set))
+ return 0;
+
+ /* Now combine all the features the user has set. */
+ *dest = level_set;
+ merge_features(dest, *feature_set);
+
+ /*
+ * We have to remove all the features in the reverse set
+ * and other features which depend on them.
+ */
+ for(i = 0; ocfs2_supported_features[i].ff_str; i++) {
+ if ((reverse_set->compat &
+ ocfs2_supported_features[i].ff_flags.compat) ||
+ (reverse_set->incompat &
+ ocfs2_supported_features[i].ff_flags.incompat) ||
+ (reverse_set->ro_compat &
+ ocfs2_supported_features[i].ff_flags.ro_compat)) {
+ dest->compat &=
+ ~ocfs2_supported_features[i].ff_own_flags.compat;
+
+ dest->incompat &=
+ ~ocfs2_supported_features[i].ff_own_flags.incompat;
+
+ dest->ro_compat &=
+ ~ocfs2_supported_features[i].ff_own_flags.ro_compat;
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * Parse the feature string.
+ *
+ * For those the user want to clear(with "no" in the beginning),
+ * they are stored in "reverse_flags".
+ *
+ * For those the user want to set, they are stored in "feature_flags".
+ */
+errcode_t parse_feature(const char *opts,
+ fs_options *feature_flags,
+ fs_options *reverse_flags)
+{
+ char *options, *token, *next, *p, *arg;
+ int i, reverse = 0;
+
+ memset(feature_flags, 0, sizeof(fs_options));
+ memset(reverse_flags, 0, sizeof(fs_options));
+
+ options = strdup(opts);
+ for (token = options; token && *token; token = next) {
+ reverse = 0;
+ p = strchr(token, ',');
+ next = NULL;
+
+ if (p) {
+ *p = '\0';
+ next = p + 1;
+ }
+
+ arg = strstr(token, "no");
+ if (arg && arg == token) {
+ reverse = 1;
+ token += 2;
+ }
+
+ for(i = 0; ocfs2_supported_features[i].ff_str; i++) {
+ if (strcmp(token,
+ ocfs2_supported_features[i].ff_str) == 0) {
+ if (!reverse)
+ merge_features(feature_flags,
+ ocfs2_supported_features[i].ff_flags);
+ else
+ merge_features(reverse_flags,
+ ocfs2_supported_features[i].ff_own_flags);
+ break;
+ }
+ }
+ if (!ocfs2_supported_features[i].ff_str)
+ return OCFS2_ET_UNSUPP_FEATURE;
+ }
+
+ free(options);
+
+ return 0;
+}
diff --git a/libocfs2/include/feature_string.h b/libocfs2/include/feature_string.h
new file mode 100644
index 0000000..b8e860d
--- /dev/null
+++ b/libocfs2/include/feature_string.h
@@ -0,0 +1,67 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * feature_strings.h
+ *
+ * Routines for analyzing a feature string.
+ *
+ * Copyright (C) 2007 Oracle. All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ */
+
+#ifndef __FEATURE_STRING_H
+#define __FEATURE_STRING_H
+
+#include <ocfs2.h>
+
+typedef struct _fs_options fs_options;
+
+struct _fs_options {
+ uint32_t compat;
+ uint32_t incompat;
+ uint32_t ro_compat;
+};
+
+struct fs_feature_flags {
+ const char *ff_str;
+ /* this flag is the feature's own flag. */
+ fs_options ff_own_flags;
+ /*
+ * this flag includes the feature's own flag and
+ * all the other features' flag it depends on.
+ */
+ fs_options ff_flags;
+};
+
+enum feature_level_indexes {
+ FEATURE_LEVEL_DEFAULT = 0,
+ FEATURE_LEVEL_MAX_COMPAT,
+ FEATURE_LEVEL_MAX_FEATURES,
+};
+
+errcode_t parse_feature(const char *opts,
+ fs_options *feature_flags,
+ fs_options *reverse_flags);
+
+int parse_feature_level(const char *typestr,
+ enum feature_level_indexes *index);
+
+int merge_feature_flags_with_level(fs_options *dest,
+ int index,
+ fs_options *feature_set,
+ fs_options *reverse_set);
+#endif /* __FEATURE_STIRNG_H */
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 77bc6b7..0ade0ab 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -120,78 +120,6 @@ enum {
FEATURES_OPTION,
};
-struct fs_feature_flags {
- const char *ff_str;
- /* this flag is the feature's own flag. */
- fs_options ff_own_flags;
- /*
- * this flag includes the feature's own flag and
- * all the other features' flag it depends on.
- */
- fs_options ff_flags;
-};
-
-static struct fs_feature_flags ocfs2_supported_features[] = {
- {
- "local",
- {0, OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT, 0},
- {0, OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT, 0},
- },
- {
- "sparse",
- {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC, 0},
- {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC, 0},
- },
- {
- "backup-super",
- {OCFS2_FEATURE_COMPAT_BACKUP_SB, 0, 0},
- {OCFS2_FEATURE_COMPAT_BACKUP_SB, 0, 0},
- },
- {
- "unwritten",
- {0, 0, OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},
- {0, OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC,
- OCFS2_FEATURE_RO_COMPAT_UNWRITTEN},
- },
- {
- NULL,
- {0, 0, 0},
- {0, 0, 0}
- },
-};
-
-enum feature_level_indexes {
- FEATURE_LEVEL_DEFAULT = 0,
- FEATURE_LEVEL_MAX_COMPAT,
- FEATURE_LEVEL_MAX_FEATURES,
-};
-
-struct feature_level_translation {
- const char *fl_str;
- enum feature_level_indexes fl_type;
-};
-
-static struct feature_level_translation ocfs2_feature_levels_table[] = {
- {"default", FEATURE_LEVEL_DEFAULT},
- {"max-compat", FEATURE_LEVEL_MAX_COMPAT},
- {"max-features", FEATURE_LEVEL_MAX_FEATURES},
- {NULL, FEATURE_LEVEL_DEFAULT},
-};
-
-static fs_options feature_level_defaults[] = {
- {OCFS2_FEATURE_COMPAT_BACKUP_SB,
- OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC,
- 0}, /* FEATURE_LEVEL_DEFAULT */
-
- {OCFS2_FEATURE_COMPAT_BACKUP_SB,
- 0,
- 0}, /* FEATURE_LEVEL_MAX_COMPAT */
-
- {OCFS2_FEATURE_COMPAT_BACKUP_SB,
- OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC,
- OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* FEATURE_LEVEL_MAX_FEATURES */
-};
-
static uint64_t align_bytes_to_clusters_ceil(State *s,
uint64_t bytes)
{
@@ -579,159 +507,6 @@ parse_fs_type_opts(char *progname, const char *typestr,
}
}
-/* Get the feature level according to the value set by "--fs-feature-level". */
-static void parse_feature_level_opts(char *progname, const char *typestr,
- enum feature_level_indexes *index)
-{
- int i;
-
- for(i = 0; ocfs2_feature_levels_table[i].fl_str; i++) {
- if (strcmp(typestr,
- ocfs2_feature_levels_table[i].fl_str) == 0) {
- *index = ocfs2_feature_levels_table[i].fl_type;
- break;
- }
- }
-
- if (!ocfs2_feature_levels_table[i].fl_str) {
- com_err(progname, 0,
- "unrecognized fs-feature-level:%s", typestr);
- exit(1);
- }
-}
-
-static void inline merge_features(fs_options *features,
- fs_options new_features)
-{
- features->compat |= new_features.compat;
- features->incompat |= new_features.incompat;
- features->ro_compat |= new_features.ro_compat;
-}
-
-/*
- * Parse the feature string set by the user in "--fs-features".
- * for all the features the user want to set, they are added into
- * the "feature_flags". For those the user want to clear(with "no"
- * in the beginning), they are stored in the "reverse_flags".
- */
-static void parse_feature_opts(char *progname, const char *opts,
- fs_options *feature_flags,
- fs_options *reverse_flags)
-{
- char *options, *token, *next, *p, *arg;
- int i, reverse = 0;
-
- memset(feature_flags, 0, sizeof(fs_options));
- memset(reverse_flags, 0, sizeof(fs_options));
-
- options = strdup(opts);
- for (token = options; token && *token; token = next) {
- reverse = 0;
- p = strchr(token, ',');
- next = NULL;
-
- if (p) {
- *p = '\0';
- next = p + 1;
- }
-
- arg = strstr(token, "no");
- if (arg && arg == token) {
- reverse = 1;
- token += 2;
- }
-
- for(i = 0; ocfs2_supported_features[i].ff_str; i++) {
- if (strcmp(token,
- ocfs2_supported_features[i].ff_str) == 0) {
- if (!reverse)
- merge_features(feature_flags,
- ocfs2_supported_features[i].ff_flags);
- else
- merge_features(reverse_flags,
- ocfs2_supported_features[i].ff_own_flags);
- break;
- }
- }
- if (!ocfs2_supported_features[i].ff_str) {
- com_err(progname, 0,
- "unrecognized fs-feature-string:%s", token);
- exit(1);
- }
- }
-
- free(options);
-}
-
-static int check_feature_flags(fs_options *fs_flags,
- fs_options *fs_r_flags)
-{
- int ret = 1;
-
- if (fs_r_flags->compat &&
- fs_flags->compat & fs_r_flags->compat)
- ret = 0;
- else if (fs_r_flags->incompat &&
- fs_flags->incompat & fs_r_flags->incompat)
- ret = 0;
- else if (fs_r_flags->ro_compat &&
- fs_flags->ro_compat & fs_r_flags->ro_compat)
- ret = 0;
-
- return ret;
-}
-
-/*
- * Check and Merge all the diffent features set by the user.
- *
- * level_set: all the features a user set by choose a feature level.
- * feature_set: all the features a user set by "--fs-features".
- * reverse_set: all the features a user want to clear by "--fs-features".
- */
-static int merge_feature_flags_with_level(State *s,
- fs_options *level_set,
- fs_options *feature_set,
- fs_options *reverse_set)
-{
- int i;
-
- /*
- * "Check whether the user asked for a flag to be set and cleared,
- * which is illegal. The feature_set and reverse_set are both set
- * by "--fs-features", so they shouldn't collide with each other.
- */
- if (!check_feature_flags(feature_set, reverse_set))
- return 0;
-
- /* Now combine all the features the user has set. */
- s->feature_flags = *level_set;
- merge_features(&s->feature_flags, *feature_set);
-
- /*
- * We have to remove all the features in the reverse set
- * and other features which depend on them.
- */
- for(i = 0; ocfs2_supported_features[i].ff_str; i++) {
- if ((reverse_set->compat &
- ocfs2_supported_features[i].ff_flags.compat) ||
- (reverse_set->incompat &
- ocfs2_supported_features[i].ff_flags.incompat) ||
- (reverse_set->ro_compat &
- ocfs2_supported_features[i].ff_flags.ro_compat)) {
- s->feature_flags.compat &=
- ~ocfs2_supported_features[i].ff_own_flags.compat;
-
- s->feature_flags.incompat &=
- ~ocfs2_supported_features[i].ff_own_flags.incompat;
-
- s->feature_flags.ro_compat &=
- ~ocfs2_supported_features[i].ff_own_flags.ro_compat;
- }
- }
-
- return 1;
-}
-
static State *
get_state(int argc, char **argv)
{
@@ -905,14 +680,23 @@ get_state(int argc, char **argv)
break;
case FEATURE_LEVEL:
- parse_feature_level_opts(progname, optarg,
- &index);
+ ret = parse_feature_level(optarg, &index);
+ if (ret) {
+ com_err(progname, ret,
+ "when parsing fs-feature-level string");
+ exit(1);
+ }
break;
case FEATURES_OPTION:
- parse_feature_opts(progname, optarg,
- &feature_flags,
- &reverse_flags);
+ ret = parse_feature(optarg,
+ &feature_flags,
+ &reverse_flags);
+ if (ret) {
+ com_err(progname, ret,
+ "when parsing fs-features string");
+ exit(1);
+ }
break;
default:
@@ -977,7 +761,8 @@ get_state(int argc, char **argv)
s->fs_type = fs_type;
- if(!merge_feature_flags_with_level(s, &feature_level_defaults[index],
+ if(!merge_feature_flags_with_level(&s->feature_flags,
+ index,
&feature_flags, &reverse_flags)) {
com_err(s->progname, 0,
"Incompatible feature flags"
diff --git a/mkfs.ocfs2/mkfs.h b/mkfs.ocfs2/mkfs.h
index cd1b5f3..5cef74a 100644
--- a/mkfs.ocfs2/mkfs.h
+++ b/mkfs.ocfs2/mkfs.h
@@ -56,7 +56,7 @@
#include <libgen.h>
#include "jbd.h"
-
+#include <feature_string.h>
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
@@ -193,14 +193,6 @@ struct _DirData {
SystemFileDiskRecord *record;
};
-typedef struct _fs_options fs_options;
-
-struct _fs_options {
- uint32_t compat;
- uint32_t incompat;
- uint32_t ro_compat;
-};
-
typedef struct _State State;
struct _State {
--
1.5.3.2.g4f337
More information about the Ocfs2-tools-devel
mailing list