[PATCH v2 1/2] ndctl: convert namespace actions to use util_filter_params
by Dave Jiang
In preparation of moving to using util_filter_walk, moving parts of namespace
params to util_filter_params.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
---
ndctl/namespace.c | 165 ++++++++++++++++++++++++++---------------------------
1 file changed, 82 insertions(+), 83 deletions(-)
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index fe86d826..e7173ce9 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -40,21 +40,20 @@ static struct parameters {
bool mode_default;
bool align_default;
bool autolabel;
- const char *bus;
const char *map;
- const char *type;
const char *uuid;
const char *name;
const char *size;
const char *mode;
- const char *region;
const char *reconfig;
const char *sector_size;
const char *align;
-} param = {
+} ndns_action = {
.autolabel = true,
};
+struct util_filter_params param;
+
void builtin_xaction_namespace_reset(void)
{
/*
@@ -94,26 +93,26 @@ OPT_STRING('r', "region", ¶m.region, "region-id", \
OPT_BOOLEAN('v', "verbose", &verbose, "emit extra debug messages to stderr")
#define CREATE_OPTIONS() \
-OPT_STRING('e', "reconfig", ¶m.reconfig, "reconfig namespace", \
+OPT_STRING('e', "reconfig", &ndns_action.reconfig, "reconfig namespace", \
"reconfigure existing namespace"), \
-OPT_STRING('u', "uuid", ¶m.uuid, "uuid", \
+OPT_STRING('u', "uuid", &ndns_action.uuid, "uuid", \
"specify the uuid for the namespace (default: autogenerate)"), \
-OPT_STRING('n', "name", ¶m.name, "name", \
+OPT_STRING('n', "name", &ndns_action.name, "name", \
"specify an optional free form name for the namespace"), \
-OPT_STRING('s', "size", ¶m.size, "size", \
+OPT_STRING('s', "size", &ndns_action.size, "size", \
"specify the namespace size in bytes (default: available capacity)"), \
-OPT_STRING('m', "mode", ¶m.mode, "operation-mode", \
+OPT_STRING('m', "mode", &ndns_action.mode, "operation-mode", \
"specify a mode for the namespace, 'sector', 'fsdax', 'devdax' or 'raw'"), \
-OPT_STRING('M', "map", ¶m.map, "memmap-location", \
+OPT_STRING('M', "map", &ndns_action.map, "memmap-location", \
"specify 'mem' or 'dev' for the location of the memmap"), \
-OPT_STRING('l', "sector-size", ¶m.sector_size, "lba-size", \
+OPT_STRING('l', "sector-size", &ndns_action.sector_size, "lba-size", \
"specify the logical sector size in bytes"), \
OPT_STRING('t', "type", ¶m.type, "type", \
"specify the type of namespace to create 'pmem' or 'blk'"), \
-OPT_STRING('a', "align", ¶m.align, "align", \
+OPT_STRING('a', "align", &ndns_action.align, "align", \
"specify the namespace alignment in bytes (default: 2M)"), \
OPT_BOOLEAN('f', "force", &force, "reconfigure namespace even if currently active"), \
-OPT_BOOLEAN('L', "autolabel", ¶m.autolabel, "automatically initialize labels")
+OPT_BOOLEAN('L', "autolabel", &ndns_action.autolabel, "automatically initialize labels")
#define CHECK_OPTIONS() \
OPT_BOOLEAN('R', "repair", &repair, "perform metadata repairs"), \
@@ -158,96 +157,96 @@ static int set_defaults(enum device_action mode)
param.type);
rc = -EINVAL;
}
- } else if (!param.reconfig && mode == ACTION_CREATE)
+ } else if (!ndns_action.reconfig && mode == ACTION_CREATE)
param.type = "pmem";
- if (param.mode) {
- if (strcmp(param.mode, "safe") == 0)
+ if (ndns_action.mode) {
+ if (strcmp(ndns_action.mode, "safe") == 0)
/* pass */;
- else if (strcmp(param.mode, "sector") == 0)
- param.mode = "safe"; /* pass */
- else if (strcmp(param.mode, "memory") == 0)
+ else if (strcmp(ndns_action.mode, "sector") == 0)
+ ndns_action.mode = "safe"; /* pass */
+ else if (strcmp(ndns_action.mode, "memory") == 0)
/* pass */;
- else if (strcmp(param.mode, "fsdax") == 0)
- param.mode = "memory"; /* pass */
- else if (strcmp(param.mode, "raw") == 0)
+ else if (strcmp(ndns_action.mode, "fsdax") == 0)
+ ndns_action.mode = "memory"; /* pass */
+ else if (strcmp(ndns_action.mode, "raw") == 0)
/* pass */;
- else if (strcmp(param.mode, "dax") == 0)
+ else if (strcmp(ndns_action.mode, "dax") == 0)
/* pass */;
- else if (strcmp(param.mode, "devdax") == 0)
- param.mode = "dax"; /* pass */
+ else if (strcmp(ndns_action.mode, "devdax") == 0)
+ ndns_action.mode = "dax"; /* pass */
else {
- error("invalid mode '%s'\n", param.mode);
+ error("invalid mode '%s'\n", ndns_action.mode);
rc = -EINVAL;
}
- } else if (!param.reconfig && param.type) {
+ } else if (!ndns_action.reconfig && param.type) {
if (strcmp(param.type, "pmem") == 0)
- param.mode = "memory";
+ ndns_action.mode = "memory";
else
- param.mode = "safe";
- param.mode_default = true;
+ ndns_action.mode = "safe";
+ ndns_action.mode_default = true;
}
- if (param.map) {
- if (strcmp(param.map, "mem") == 0)
+ if (ndns_action.map) {
+ if (strcmp(ndns_action.map, "mem") == 0)
/* pass */;
- else if (strcmp(param.map, "dev") == 0)
+ else if (strcmp(ndns_action.map, "dev") == 0)
/* pass */;
else {
- error("invalid map location '%s'\n", param.map);
+ error("invalid map location '%s'\n", ndns_action.map);
rc = -EINVAL;
}
- if (!param.reconfig && param.mode
- && strcmp(param.mode, "memory") != 0
- && strcmp(param.mode, "dax") != 0) {
+ if (!ndns_action.reconfig && ndns_action.mode
+ && strcmp(ndns_action.mode, "memory") != 0
+ && strcmp(ndns_action.mode, "dax") != 0) {
error("--map only valid for an dax mode pmem namespace\n");
rc = -EINVAL;
}
- } else if (!param.reconfig)
- param.map = "dev";
+ } else if (!ndns_action.reconfig)
+ ndns_action.map = "dev";
/* check for incompatible mode and type combinations */
- if (param.type && param.mode && strcmp(param.type, "blk") == 0
- && (strcmp(param.mode, "memory") == 0
- || strcmp(param.mode, "dax") == 0)) {
+ if (param.type && ndns_action.mode && strcmp(param.type, "blk") == 0
+ && (strcmp(ndns_action.mode, "memory") == 0
+ || strcmp(ndns_action.mode, "dax") == 0)) {
error("only 'pmem' namespaces support dax operation\n");
rc = -ENXIO;
}
- if (param.size && parse_size64(param.size) == ULLONG_MAX) {
+ if (ndns_action.size && parse_size64(ndns_action.size) == ULLONG_MAX) {
error("failed to parse namespace size '%s'\n",
- param.size);
+ ndns_action.size);
rc = -EINVAL;
}
- if (param.align && parse_size64(param.align) == ULLONG_MAX) {
+ if (ndns_action.align && parse_size64(ndns_action.align) == ULLONG_MAX) {
error("failed to parse namespace alignment '%s'\n",
- param.align);
+ ndns_action.align);
rc = -EINVAL;
- } else if (!param.align) {
- param.align = "2M";
- param.align_default = true;
+ } else if (!ndns_action.align) {
+ ndns_action.align = "2M";
+ ndns_action.align_default = true;
}
- if (param.uuid) {
+ if (ndns_action.uuid) {
uuid_t uuid;
- if (uuid_parse(param.uuid, uuid)) {
- error("failed to parse uuid: '%s'\n", param.uuid);
+ if (uuid_parse(ndns_action.uuid, uuid)) {
+ error("failed to parse uuid: '%s'\n", ndns_action.uuid);
rc = -EINVAL;
}
}
- if (param.sector_size) {
- if (parse_size64(param.sector_size) == ULLONG_MAX) {
- error("invalid sector size: %s\n", param.sector_size);
+ if (ndns_action.sector_size) {
+ if (parse_size64(ndns_action.sector_size) == ULLONG_MAX) {
+ error("invalid sector size: %s\n", ndns_action.sector_size);
rc = -EINVAL;
}
} else if (((param.type && strcmp(param.type, "blk") == 0)
- || (param.mode && strcmp(param.mode, "safe") == 0))) {
+ || (ndns_action.mode && strcmp(ndns_action.mode, "safe") == 0))) {
/* default sector size for blk-type or safe-mode */
- param.sector_size = "4096";
+ ndns_action.sector_size = "4096";
}
return rc;
@@ -267,7 +266,7 @@ static const char *parse_namespace_options(int argc, const char **argv,
};
int i, rc = 0;
- param.do_scan = argc == 1;
+ ndns_action.do_scan = argc == 1;
argc = parse_options(argc, argv, options, u, 0);
rc = set_defaults(mode);
@@ -305,7 +304,7 @@ static const char *parse_namespace_options(int argc, const char **argv,
return NULL; /* we won't return from usage_with_options() */
}
- return mode == ACTION_CREATE ? param.reconfig : argv[0];
+ return mode == ACTION_CREATE ? ndns_action.reconfig : argv[0];
}
#define try(prefix, op, dev, p) \
@@ -474,21 +473,21 @@ static int validate_namespace_options(struct ndctl_region *region,
return -EAGAIN;
}
- if (param.size)
- p->size = __parse_size64(param.size, &units);
+ if (ndns_action.size)
+ p->size = __parse_size64(ndns_action.size, &units);
else if (ndns)
p->size = ndctl_namespace_get_size(ndns);
- if (param.uuid) {
- if (uuid_parse(param.uuid, p->uuid) != 0) {
+ if (ndns_action.uuid) {
+ if (uuid_parse(ndns_action.uuid, p->uuid) != 0) {
debug("%s: invalid uuid\n", __func__);
return -EINVAL;
}
} else
uuid_generate(p->uuid);
- if (param.name)
- rc = snprintf(p->name, sizeof(p->name), "%s", param.name);
+ if (ndns_action.name)
+ rc = snprintf(p->name, sizeof(p->name), "%s", ndns_action.name);
else if (ndns)
rc = snprintf(p->name, sizeof(p->name), "%s",
ndctl_namespace_get_alt_name(ndns));
@@ -497,14 +496,14 @@ static int validate_namespace_options(struct ndctl_region *region,
return -EINVAL;
}
- if (param.mode) {
- if (strcmp(param.mode, "memory") == 0)
+ if (ndns_action.mode) {
+ if (strcmp(ndns_action.mode, "memory") == 0)
p->mode = NDCTL_NS_MODE_MEMORY;
- else if (strcmp(param.mode, "sector") == 0)
+ else if (strcmp(ndns_action.mode, "sector") == 0)
p->mode = NDCTL_NS_MODE_SAFE;
- else if (strcmp(param.mode, "safe") == 0)
+ else if (strcmp(ndns_action.mode, "safe") == 0)
p->mode = NDCTL_NS_MODE_SAFE;
- else if (strcmp(param.mode, "dax") == 0)
+ else if (strcmp(ndns_action.mode, "dax") == 0)
p->mode = NDCTL_NS_MODE_DAX;
else
p->mode = NDCTL_NS_MODE_RAW;
@@ -520,11 +519,11 @@ static int validate_namespace_options(struct ndctl_region *region,
} else if (ndns)
p->mode = ndctl_namespace_get_mode(ndns);
- if (param.align) {
+ if (ndns_action.align) {
struct ndctl_pfn *pfn = ndctl_region_get_pfn_seed(region);
struct ndctl_dax *dax = ndctl_region_get_dax_seed(region);
- p->align = parse_size64(param.align);
+ p->align = parse_size64(ndns_action.align);
if (p->mode == NDCTL_NS_MODE_MEMORY && p->align != SZ_2M
&& (!pfn || !ndctl_pfn_has_align(pfn))) {
@@ -545,7 +544,7 @@ static int validate_namespace_options(struct ndctl_region *region,
debug("%s not support 'align' for devdax mode\n",
region_name);
return -EAGAIN;
- } else if (!param.align_default
+ } else if (!ndns_action.align_default
&& (p->mode == NDCTL_NS_MODE_SAFE
|| p->mode == NDCTL_NS_MODE_RAW)) {
/*
@@ -565,7 +564,7 @@ static int validate_namespace_options(struct ndctl_region *region,
* memory.
*/
resource = ndctl_region_get_resource(region);
- if (param.align_default && resource < ULLONG_MAX
+ if (ndns_action.align_default && resource < ULLONG_MAX
&& (resource & (SZ_2M - 1))) {
debug("%s: falling back to a 4K alignment\n",
region_name);
@@ -578,7 +577,7 @@ static int validate_namespace_options(struct ndctl_region *region,
case SZ_1G:
break;
default:
- error("unsupported align: %s\n", param.align);
+ error("unsupported align: %s\n", ndns_action.align);
return -ENXIO;
}
@@ -616,16 +615,16 @@ static int validate_namespace_options(struct ndctl_region *region,
p->size *= size_align;
p->size /= units;
error("'--size=' must align to interleave-width: %d and alignment: %ld\n"
- " did you intend --size=%lld%s?\n", ways, param.align
+ " did you intend --size=%lld%s?\n", ways, ndns_action.align
? p->align : SZ_4K, p->size, suffix);
return -EINVAL;
}
- if (param.sector_size) {
+ if (ndns_action.sector_size) {
struct ndctl_btt *btt;
int num, i;
- p->sector_size = parse_size64(param.sector_size);
+ p->sector_size = parse_size64(ndns_action.sector_size);
btt = ndctl_region_get_btt_seed(region);
if (p->mode == NDCTL_NS_MODE_SAFE) {
if (!btt) {
@@ -688,8 +687,8 @@ static int validate_namespace_options(struct ndctl_region *region,
p->sector_size = 512;
}
- if (param.map) {
- if (!strcmp(param.map, "mem"))
+ if (ndns_action.map) {
+ if (!strcmp(ndns_action.map, "mem"))
p->loc = NDCTL_PFN_LOC_RAM;
else
p->loc = NDCTL_PFN_LOC_PMEM;
@@ -708,7 +707,7 @@ static int validate_namespace_options(struct ndctl_region *region,
if (do_setup_pfn(ndns, p)) {
struct ndctl_pfn *pfn = ndctl_region_get_pfn_seed(region);
- if (!pfn && param.mode_default) {
+ if (!pfn && ndns_action.mode_default) {
debug("%s fsdax mode not available\n", region_name);
p->mode = NDCTL_NS_MODE_RAW;
} else if (!pfn) {
@@ -729,7 +728,7 @@ static int validate_namespace_options(struct ndctl_region *region,
}
}
- p->autolabel = param.autolabel;
+ p->autolabel = ndns_action.autolabel;
return 0;
}
@@ -1119,7 +1118,7 @@ int cmd_create_namespace(int argc, const char **argv, void *ctx)
ACTION_CREATE, create_options, xable_usage);
int created = do_xaction_namespace(namespace, ACTION_CREATE, ctx);
- if (created < 1 && param.do_scan) {
+ if (created < 1 && ndns_action.do_scan) {
/*
* In the default scan case we try pmem first and then
* fallback to blk before giving up.
2 years, 9 months
[PATCH] ndctl: convert namespace ops to use util_filter_walk()
by Dave Jiang
util_filter_walk() does the looping through of busses and regions. Removing
duplicate code in namespace ops and provide filter functions so we can
utilize util_filter_walk() and share common code.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
---
ndctl/namespace.c | 281 ++++++++++++++++++++++++++++-------------------------
util/filter.c | 11 +-
util/filter.h | 8 ++
3 files changed, 162 insertions(+), 138 deletions(-)
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index fe86d826..9c504e7f 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -35,26 +35,24 @@ static bool verbose;
static bool force;
static bool repair;
static bool logfix;
-static struct parameters {
+static struct {
bool do_scan;
bool mode_default;
bool align_default;
bool autolabel;
- const char *bus;
const char *map;
- const char *type;
const char *uuid;
const char *name;
const char *size;
- const char *mode;
- const char *region;
const char *reconfig;
const char *sector_size;
const char *align;
-} param = {
+} ndns_action = {
.autolabel = true,
};
+struct util_filter_params param;
+
void builtin_xaction_namespace_reset(void)
{
/*
@@ -94,26 +92,26 @@ OPT_STRING('r', "region", ¶m.region, "region-id", \
OPT_BOOLEAN('v', "verbose", &verbose, "emit extra debug messages to stderr")
#define CREATE_OPTIONS() \
-OPT_STRING('e', "reconfig", ¶m.reconfig, "reconfig namespace", \
+OPT_STRING('e', "reconfig", &ndns_action.reconfig, "reconfig namespace", \
"reconfigure existing namespace"), \
-OPT_STRING('u', "uuid", ¶m.uuid, "uuid", \
+OPT_STRING('u', "uuid", &ndns_action.uuid, "uuid", \
"specify the uuid for the namespace (default: autogenerate)"), \
-OPT_STRING('n', "name", ¶m.name, "name", \
+OPT_STRING('n', "name", &ndns_action.name, "name", \
"specify an optional free form name for the namespace"), \
-OPT_STRING('s', "size", ¶m.size, "size", \
+OPT_STRING('s', "size", &ndns_action.size, "size", \
"specify the namespace size in bytes (default: available capacity)"), \
OPT_STRING('m', "mode", ¶m.mode, "operation-mode", \
"specify a mode for the namespace, 'sector', 'fsdax', 'devdax' or 'raw'"), \
-OPT_STRING('M', "map", ¶m.map, "memmap-location", \
+OPT_STRING('M', "map", &ndns_action.map, "memmap-location", \
"specify 'mem' or 'dev' for the location of the memmap"), \
-OPT_STRING('l', "sector-size", ¶m.sector_size, "lba-size", \
+OPT_STRING('l', "sector-size", &ndns_action.sector_size, "lba-size", \
"specify the logical sector size in bytes"), \
OPT_STRING('t', "type", ¶m.type, "type", \
"specify the type of namespace to create 'pmem' or 'blk'"), \
-OPT_STRING('a', "align", ¶m.align, "align", \
+OPT_STRING('a', "align", &ndns_action.align, "align", \
"specify the namespace alignment in bytes (default: 2M)"), \
OPT_BOOLEAN('f', "force", &force, "reconfigure namespace even if currently active"), \
-OPT_BOOLEAN('L', "autolabel", ¶m.autolabel, "automatically initialize labels")
+OPT_BOOLEAN('L', "autolabel", &ndns_action.autolabel, "automatically initialize labels")
#define CHECK_OPTIONS() \
OPT_BOOLEAN('R', "repair", &repair, "perform metadata repairs"), \
@@ -158,7 +156,7 @@ static int set_defaults(enum device_action mode)
param.type);
rc = -EINVAL;
}
- } else if (!param.reconfig && mode == ACTION_CREATE)
+ } else if (!ndns_action.reconfig && mode == ACTION_CREATE)
param.type = "pmem";
if (param.mode) {
@@ -180,32 +178,32 @@ static int set_defaults(enum device_action mode)
error("invalid mode '%s'\n", param.mode);
rc = -EINVAL;
}
- } else if (!param.reconfig && param.type) {
+ } else if (!ndns_action.reconfig && param.type) {
if (strcmp(param.type, "pmem") == 0)
param.mode = "memory";
else
param.mode = "safe";
- param.mode_default = true;
+ ndns_action.mode_default = true;
}
- if (param.map) {
- if (strcmp(param.map, "mem") == 0)
+ if (ndns_action.map) {
+ if (strcmp(ndns_action.map, "mem") == 0)
/* pass */;
- else if (strcmp(param.map, "dev") == 0)
+ else if (strcmp(ndns_action.map, "dev") == 0)
/* pass */;
else {
- error("invalid map location '%s'\n", param.map);
+ error("invalid map location '%s'\n", ndns_action.map);
rc = -EINVAL;
}
- if (!param.reconfig && param.mode
+ if (!ndns_action.reconfig && param.mode
&& strcmp(param.mode, "memory") != 0
&& strcmp(param.mode, "dax") != 0) {
error("--map only valid for an dax mode pmem namespace\n");
rc = -EINVAL;
}
- } else if (!param.reconfig)
- param.map = "dev";
+ } else if (!ndns_action.reconfig)
+ ndns_action.map = "dev";
/* check for incompatible mode and type combinations */
if (param.type && param.mode && strcmp(param.type, "blk") == 0
@@ -215,39 +213,43 @@ static int set_defaults(enum device_action mode)
rc = -ENXIO;
}
- if (param.size && parse_size64(param.size) == ULLONG_MAX) {
+ if (ndns_action.size &&
+ parse_size64(ndns_action.size) == ULLONG_MAX) {
error("failed to parse namespace size '%s'\n",
- param.size);
+ ndns_action.size);
rc = -EINVAL;
}
- if (param.align && parse_size64(param.align) == ULLONG_MAX) {
+ if (ndns_action.align &&
+ parse_size64(ndns_action.align) == ULLONG_MAX) {
error("failed to parse namespace alignment '%s'\n",
- param.align);
+ ndns_action.align);
rc = -EINVAL;
- } else if (!param.align) {
- param.align = "2M";
- param.align_default = true;
+ } else if (!ndns_action.align) {
+ ndns_action.align = "2M";
+ ndns_action.align_default = true;
}
- if (param.uuid) {
+ if (ndns_action.uuid) {
uuid_t uuid;
- if (uuid_parse(param.uuid, uuid)) {
- error("failed to parse uuid: '%s'\n", param.uuid);
+ if (uuid_parse(ndns_action.uuid, uuid)) {
+ error("failed to parse uuid: '%s'\n",
+ ndns_action.uuid);
rc = -EINVAL;
}
}
- if (param.sector_size) {
- if (parse_size64(param.sector_size) == ULLONG_MAX) {
- error("invalid sector size: %s\n", param.sector_size);
+ if (ndns_action.sector_size) {
+ if (parse_size64(ndns_action.sector_size) == ULLONG_MAX) {
+ error("invalid sector size: %s\n",
+ ndns_action.sector_size);
rc = -EINVAL;
}
} else if (((param.type && strcmp(param.type, "blk") == 0)
|| (param.mode && strcmp(param.mode, "safe") == 0))) {
/* default sector size for blk-type or safe-mode */
- param.sector_size = "4096";
+ ndns_action.sector_size = "4096";
}
return rc;
@@ -267,7 +269,7 @@ static const char *parse_namespace_options(int argc, const char **argv,
};
int i, rc = 0;
- param.do_scan = argc == 1;
+ ndns_action.do_scan = argc == 1;
argc = parse_options(argc, argv, options, u, 0);
rc = set_defaults(mode);
@@ -305,7 +307,7 @@ static const char *parse_namespace_options(int argc, const char **argv,
return NULL; /* we won't return from usage_with_options() */
}
- return mode == ACTION_CREATE ? param.reconfig : argv[0];
+ return mode == ACTION_CREATE ? ndns_action.reconfig : argv[0];
}
#define try(prefix, op, dev, p) \
@@ -474,21 +476,22 @@ static int validate_namespace_options(struct ndctl_region *region,
return -EAGAIN;
}
- if (param.size)
- p->size = __parse_size64(param.size, &units);
+ if (ndns_action.size)
+ p->size = __parse_size64(ndns_action.size, &units);
else if (ndns)
p->size = ndctl_namespace_get_size(ndns);
- if (param.uuid) {
- if (uuid_parse(param.uuid, p->uuid) != 0) {
+ if (ndns_action.uuid) {
+ if (uuid_parse(ndns_action.uuid, p->uuid) != 0) {
debug("%s: invalid uuid\n", __func__);
return -EINVAL;
}
} else
uuid_generate(p->uuid);
- if (param.name)
- rc = snprintf(p->name, sizeof(p->name), "%s", param.name);
+ if (ndns_action.name)
+ rc = snprintf(p->name, sizeof(p->name), "%s",
+ ndns_action.name);
else if (ndns)
rc = snprintf(p->name, sizeof(p->name), "%s",
ndctl_namespace_get_alt_name(ndns));
@@ -520,11 +523,11 @@ static int validate_namespace_options(struct ndctl_region *region,
} else if (ndns)
p->mode = ndctl_namespace_get_mode(ndns);
- if (param.align) {
+ if (ndns_action.align) {
struct ndctl_pfn *pfn = ndctl_region_get_pfn_seed(region);
struct ndctl_dax *dax = ndctl_region_get_dax_seed(region);
- p->align = parse_size64(param.align);
+ p->align = parse_size64(ndns_action.align);
if (p->mode == NDCTL_NS_MODE_MEMORY && p->align != SZ_2M
&& (!pfn || !ndctl_pfn_has_align(pfn))) {
@@ -545,7 +548,7 @@ static int validate_namespace_options(struct ndctl_region *region,
debug("%s not support 'align' for devdax mode\n",
region_name);
return -EAGAIN;
- } else if (!param.align_default
+ } else if (!ndns_action.align_default
&& (p->mode == NDCTL_NS_MODE_SAFE
|| p->mode == NDCTL_NS_MODE_RAW)) {
/*
@@ -565,7 +568,7 @@ static int validate_namespace_options(struct ndctl_region *region,
* memory.
*/
resource = ndctl_region_get_resource(region);
- if (param.align_default && resource < ULLONG_MAX
+ if (ndns_action.align_default && resource < ULLONG_MAX
&& (resource & (SZ_2M - 1))) {
debug("%s: falling back to a 4K alignment\n",
region_name);
@@ -578,7 +581,7 @@ static int validate_namespace_options(struct ndctl_region *region,
case SZ_1G:
break;
default:
- error("unsupported align: %s\n", param.align);
+ error("unsupported align: %s\n", ndns_action.align);
return -ENXIO;
}
@@ -616,16 +619,17 @@ static int validate_namespace_options(struct ndctl_region *region,
p->size *= size_align;
p->size /= units;
error("'--size=' must align to interleave-width: %d and alignment: %ld\n"
- " did you intend --size=%lld%s?\n", ways, param.align
+ " did you intend --size=%lld%s?\n",
+ ways, ndns_action.align
? p->align : SZ_4K, p->size, suffix);
return -EINVAL;
}
- if (param.sector_size) {
+ if (ndns_action.sector_size) {
struct ndctl_btt *btt;
int num, i;
- p->sector_size = parse_size64(param.sector_size);
+ p->sector_size = parse_size64(ndns_action.sector_size);
btt = ndctl_region_get_btt_seed(region);
if (p->mode == NDCTL_NS_MODE_SAFE) {
if (!btt) {
@@ -688,8 +692,8 @@ static int validate_namespace_options(struct ndctl_region *region,
p->sector_size = 512;
}
- if (param.map) {
- if (!strcmp(param.map, "mem"))
+ if (ndns_action.map) {
+ if (!strcmp(ndns_action.map, "mem"))
p->loc = NDCTL_PFN_LOC_RAM;
else
p->loc = NDCTL_PFN_LOC_PMEM;
@@ -708,7 +712,7 @@ static int validate_namespace_options(struct ndctl_region *region,
if (do_setup_pfn(ndns, p)) {
struct ndctl_pfn *pfn = ndctl_region_get_pfn_seed(region);
- if (!pfn && param.mode_default) {
+ if (!pfn && ndns_action.mode_default) {
debug("%s fsdax mode not available\n", region_name);
p->mode = NDCTL_NS_MODE_RAW;
} else if (!pfn) {
@@ -729,7 +733,7 @@ static int validate_namespace_options(struct ndctl_region *region,
}
}
- p->autolabel = param.autolabel;
+ p->autolabel = ndns_action.autolabel;
return 0;
}
@@ -984,14 +988,87 @@ static int namespace_reconfig(struct ndctl_region *region,
int namespace_check(struct ndctl_namespace *ndns, bool verbose, bool force,
bool repair, bool logfix);
+static bool filter_bus(struct ndctl_bus *bus, struct util_filter_ctx *ctx)
+{
+ return true;
+}
+
+static bool filter_region(struct ndctl_region *region,
+ struct util_filter_ctx *ctx)
+{
+ struct ndns_filter_arg *nfa = ctx->ndns;
+ int rc = 0;
+ bool out = true;
+
+ if (nfa->action == ACTION_CREATE && !nfa->namespace) {
+ rc = namespace_create(region);
+ if (rc != -EAGAIN) {
+ if (rc == 0)
+ rc = 1;
+ /* don't proceed in the filter loop */
+ out = false;
+ }
+ }
+
+ nfa->rc = rc;
+ return out;
+}
+
+static void filter_namespace(struct ndctl_namespace *ndns,
+ struct util_filter_ctx *ctx)
+{
+ struct ndctl_region *region = ndctl_namespace_get_region(ndns);
+ struct ndns_filter_arg *nfa = ctx->ndns;
+ const char *ndns_name;
+ int rc;
+
+ /* we have an error, don't do anything else */
+ if (nfa->rc < 0)
+ return;
+
+ ndns_name = ndctl_namespace_get_devname(ndns);
+ if (strcmp(nfa->namespace, "all") != 0
+ && strcmp(nfa->namespace, ndns_name) != 0)
+ return;
+
+ switch (nfa->action) {
+ case ACTION_DISABLE:
+ rc = ndctl_namespace_disable_safe(ndns);
+ break;
+ case ACTION_ENABLE:
+ rc = ndctl_namespace_enable(ndns);
+ break;
+ case ACTION_DESTROY:
+ rc = namespace_destroy(region, ndns);
+ break;
+ case ACTION_CHECK:
+ rc = namespace_check(ndns, verbose, force, repair, logfix);
+ if (rc < 0) {
+ nfa->rc = rc;
+ return;
+ }
+ case ACTION_CREATE:
+ rc = namespace_reconfig(region, ndns);
+ if (rc < 0) {
+ nfa->rc = rc;
+ return;
+ }
+ default:
+ rc = -EINVAL;
+ break;
+ }
+
+ if (rc >= 0)
+ nfa->rc++;
+}
+
static int do_xaction_namespace(const char *namespace,
enum device_action action, struct ndctl_ctx *ctx)
{
- struct ndctl_namespace *ndns, *_n;
- int rc = -ENXIO, success = 0;
- struct ndctl_region *region;
- const char *ndns_name;
- struct ndctl_bus *bus;
+ int rc = -ENXIO;
+
+ struct util_filter_ctx fctx = { 0 };
+ struct ndns_filter_arg nfa = { 0 };
if (!namespace && action != ACTION_CREATE)
return rc;
@@ -999,74 +1076,18 @@ static int do_xaction_namespace(const char *namespace,
if (verbose)
ndctl_set_log_priority(ctx, LOG_DEBUG);
- ndctl_bus_foreach(ctx, bus) {
- if (!util_bus_filter(bus, param.bus))
- continue;
-
- ndctl_region_foreach(bus, region) {
- if (!util_region_filter(region, param.region))
- continue;
-
- if (param.type) {
- if (strcmp(param.type, "pmem") == 0
- && ndctl_region_get_type(region)
- == ND_DEVICE_REGION_PMEM)
- /* pass */;
- else if (strcmp(param.type, "blk") == 0
- && ndctl_region_get_type(region)
- == ND_DEVICE_REGION_BLK)
- /* pass */;
- else
- continue;
- }
+ fctx.filter_bus = filter_bus;
+ fctx.filter_region = filter_region;
+ fctx.filter_namespace = filter_namespace;
+ fctx.ndns = &nfa;
+ fctx.ndns->action = action;
+ fctx.ndns->namespace = namespace;
- if (action == ACTION_CREATE && !namespace) {
- rc = namespace_create(region);
- if (rc == -EAGAIN)
- continue;
- if (rc == 0)
- rc = 1;
- return rc;
- }
- ndctl_namespace_foreach_safe(region, ndns, _n) {
- ndns_name = ndctl_namespace_get_devname(ndns);
-
- if (strcmp(namespace, "all") != 0
- && strcmp(namespace, ndns_name) != 0)
- continue;
- switch (action) {
- case ACTION_DISABLE:
- rc = ndctl_namespace_disable_safe(ndns);
- break;
- case ACTION_ENABLE:
- rc = ndctl_namespace_enable(ndns);
- break;
- case ACTION_DESTROY:
- rc = namespace_destroy(region, ndns);
- break;
- case ACTION_CHECK:
- rc = namespace_check(ndns, verbose,
- force, repair, logfix);
- if (rc < 0)
- return rc;
- break;
- case ACTION_CREATE:
- rc = namespace_reconfig(region, ndns);
- if (rc < 0)
- return rc;
- return 1;
- default:
- rc = -EINVAL;
- break;
- }
- if (rc >= 0)
- success++;
- }
- }
- }
+ rc = util_filter_walk(ctx, &fctx, ¶m);
+ if (rc < 0)
+ return rc;
- if (success)
- return success;
+ rc = nfa.rc;
return rc;
}
@@ -1119,7 +1140,7 @@ int cmd_create_namespace(int argc, const char **argv, void *ctx)
ACTION_CREATE, create_options, xable_usage);
int created = do_xaction_namespace(namespace, ACTION_CREATE, ctx);
- if (created < 1 && param.do_scan) {
+ if (created < 1 && ndns_action.do_scan) {
/*
* In the default scan case we try pmem first and then
* fallback to blk before giving up.
diff --git a/util/filter.c b/util/filter.c
index 6ab391a8..98e68ebe 100644
--- a/util/filter.c
+++ b/util/filter.c
@@ -18,6 +18,7 @@
#include <sys/stat.h>
#include <util/util.h>
#include <sys/types.h>
+#include <ndctl/action.h>
#include <ndctl/ndctl.h>
#include <util/filter.h>
#include <ndctl/libndctl.h>
@@ -375,7 +376,7 @@ int util_filter_walk(struct ndctl_ctx *ctx, struct util_filter_ctx *fctx,
}
ndctl_region_foreach(bus, region) {
- struct ndctl_namespace *ndns;
+ struct ndctl_namespace *ndns, *_n;
if (!util_region_filter(region, param->region)
|| !util_region_filter_by_dimm(region,
@@ -394,18 +395,12 @@ int util_filter_walk(struct ndctl_ctx *ctx, struct util_filter_ctx *fctx,
if (!fctx->filter_region(region, fctx))
continue;
- ndctl_namespace_foreach(region, ndns) {
- enum ndctl_namespace_mode mode;
-
+ ndctl_namespace_foreach_safe(region, ndns, _n) {
if (!fctx->filter_namespace)
break;
if (!util_namespace_filter(ndns, param->namespace))
continue;
- mode = ndctl_namespace_get_mode(ndns);
- if (param->mode && mode_to_type(param->mode) != mode)
- continue;
-
fctx->filter_namespace(ndns, fctx);
}
}
diff --git a/util/filter.h b/util/filter.h
index effda24b..ce3336a5 100644
--- a/util/filter.h
+++ b/util/filter.h
@@ -13,6 +13,7 @@
#ifndef _UTIL_FILTER_H_
#define _UTIL_FILTER_H_
#include <stdbool.h>
+#include <ndctl/action.h>
struct ndctl_bus *util_bus_filter(struct ndctl_bus *bus, const char *ident);
struct ndctl_region *util_region_filter(struct ndctl_region *region,
@@ -50,6 +51,12 @@ struct list_filter_arg {
unsigned long flags;
};
+struct ndns_filter_arg {
+ enum device_action action;
+ const char *namespace;
+ int rc;
+};
+
/*
* struct util_filter_ctx - control and callbacks for util_filter_walk()
* ->filter_bus() and ->filter_region() return bool because the
@@ -67,6 +74,7 @@ struct util_filter_ctx {
union {
void *arg;
struct list_filter_arg *list;
+ struct ndns_filter_arg *ndns;
};
};
2 years, 9 months
[PATCH ndctl v3 0/3] Documentation: add asciidoctor support
by Takashi Iwai
Hi,
this is a revised patchset to add the support for asciidoctor to
generate documents. The reason for adding this feature is that the
future of asciidoc isn't clear as it's written in python2, which is
now hated by all people out of sudden :)
The asciidoctor support is enabled via configure option, the default
is still asciidoc for now.
thanks,
Takashi
v1->v2:
* more marker fixes to ndctl man pages
* skip superfluous xmlto processing for asciidoctor
* add .gitignore entries
* rebased to v60
v2->v3:
* fix the link processing regression in v2
===
Takashi Iwai (3):
Documentation: fix title and section markers
Documentation: Add the support for asciidoctor
Documentation: add asciidoctor-extensions.rb to .gitignore
.gitignore | 2 ++
Documentation/asciidoctor-extensions.rb.in | 30 +++++++++++++++++++++++++++++
Documentation/daxctl/Makefile.am | 29 ++++++++++++++++++++++++++--
Documentation/daxctl/daxctl-list.txt | 13 +++++++------
Documentation/ndctl/Makefile.am | 29 ++++++++++++++++++++++++++--
Documentation/ndctl/ndctl-disable-dimm.txt | 2 +-
Documentation/ndctl/ndctl-enable-region.txt | 2 +-
Documentation/ndctl/ndctl-init-labels.txt | 15 ++++++++++-----
Documentation/ndctl/ndctl-list.txt | 13 ++++++++-----
Documentation/ndctl/ndctl-start-scrub.txt | 6 ++++--
Documentation/ndctl/ndctl-wait-scrub.txt | 6 ++++--
configure.ac | 17 ++++++++++++++--
12 files changed, 136 insertions(+), 28 deletions(-)
create mode 100644 Documentation/asciidoctor-extensions.rb.in
--
2.16.3
2 years, 9 months
[PATCH ndctl v2 0/3] Documentation: add asciidoctor support
by Takashi Iwai
Hi,
this is a revised patchset to add the support for asciidoctor to
generate documents. The reason for adding this feature is that the
future of asciidoc isn't clear as it's written in python2, which is
now hated by all people out of sudden :)
The asciidoctor support is enabled via configure option, the default
is still asciidoc for now.
thanks,
Takashi
v1->v2:
* more marker fixes to ndctl man pages
* skip superfluous xmlto processing for asciidoctor
* add .gitignore entries
===
Takashi Iwai (3):
Documentation: fix title and section markers
Documentation: Add the support for asciidoctor
Documentation: add asciidoctor-extensions.rb to .gitignore
.gitignore | 2 ++
Documentation/asciidoctor-extensions.rb.in | 28 ++++++++++++++++++++++++++++
Documentation/daxctl/Makefile.am | 28 ++++++++++++++++++++++++++--
Documentation/daxctl/daxctl-list.txt | 13 +++++++------
Documentation/ndctl/Makefile.am | 28 ++++++++++++++++++++++++++--
Documentation/ndctl/ndctl-disable-dimm.txt | 2 +-
Documentation/ndctl/ndctl-enable-region.txt | 2 +-
Documentation/ndctl/ndctl-init-labels.txt | 15 ++++++++++-----
Documentation/ndctl/ndctl-list.txt | 13 ++++++++-----
Documentation/ndctl/ndctl-start-scrub.txt | 6 ++++--
Documentation/ndctl/ndctl-wait-scrub.txt | 6 ++++--
configure.ac | 17 +++++++++++++++--
12 files changed, 132 insertions(+), 28 deletions(-)
create mode 100644 Documentation/asciidoctor-extensions.rb.in
--
2.16.3
2 years, 9 months
[ndctl PATCH] ndctl: fix ABI breakage due to rename of fw_info_get_updated_version
by Vishal Verma
Commit 47ad9f830f42 ("ndctl: add option to list firmware information for a DIMM")
renamed ndctl_cmd_fw_info_get_updated_version to ...get_next_version,
which causes an ABI breakage, since the former has appeared in a
released ndctl. Fix by renaming it back to the original.
Fixes: commit 47ad9f830f42 ("ndctl: add option to list firmware information for a DIMM")
Cc: Dave Jiang <dave.jiang(a)intel.com>
Cc: Dan Williams <dan.j.williams(a)intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma(a)intel.com>
---
ndctl/lib/firmware.c | 2 +-
ndctl/lib/intel.c | 4 ++--
ndctl/lib/libndctl.sym | 2 +-
ndctl/lib/private.h | 2 +-
ndctl/libndctl.h | 2 +-
ndctl/util/json-firmware.c | 2 +-
6 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/ndctl/lib/firmware.c b/ndctl/lib/firmware.c
index 277b539..a5dd006 100644
--- a/ndctl/lib/firmware.c
+++ b/ndctl/lib/firmware.c
@@ -93,7 +93,7 @@ firmware_cmd_op(fw_info_get_max_send_len, unsigned int, 0)
firmware_cmd_op(fw_info_get_query_interval, unsigned int, 0)
firmware_cmd_op(fw_info_get_max_query_time, unsigned int, 0)
firmware_cmd_op(fw_info_get_run_version, unsigned long long, 0)
-firmware_cmd_op(fw_info_get_next_version, unsigned long long, 0)
+firmware_cmd_op(fw_info_get_updated_version, unsigned long long, 0)
firmware_cmd_op(fw_start_get_context, unsigned int, 0)
firmware_cmd_op(fw_fquery_get_fw_rev, unsigned long long, 0)
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index ba210e1..49a4360 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -434,7 +434,7 @@ intel_fw_info_get_field32(cmd, query_interval)
intel_fw_info_get_field32(cmd, max_query_time);
intel_fw_info_get_field64(cmd, run_version);
-static unsigned long long intel_cmd_fw_info_get_next_version(
+static unsigned long long intel_cmd_fw_info_get_updated_version(
struct ndctl_cmd *cmd)
{
if (intel_fw_get_info_valid(cmd) < 0)
@@ -720,7 +720,7 @@ struct ndctl_dimm_ops * const intel_dimm_ops = &(struct ndctl_dimm_ops) {
.fw_info_get_query_interval = intel_cmd_fw_info_get_query_interval,
.fw_info_get_max_query_time = intel_cmd_fw_info_get_max_query_time,
.fw_info_get_run_version = intel_cmd_fw_info_get_run_version,
- .fw_info_get_next_version = intel_cmd_fw_info_get_next_version,
+ .fw_info_get_updated_version = intel_cmd_fw_info_get_updated_version,
.new_fw_start_update = intel_dimm_cmd_new_fw_start,
.fw_start_get_context = intel_cmd_fw_start_get_context,
.new_fw_send = intel_dimm_cmd_new_fw_send,
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index df17c3e..65e735f 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -339,6 +339,7 @@ global:
ndctl_cmd_fw_info_get_query_interval;
ndctl_cmd_fw_info_get_max_query_time;
ndctl_cmd_fw_info_get_run_version;
+ ndctl_cmd_fw_info_get_updated_version;
ndctl_cmd_fw_start_get_context;
ndctl_cmd_fw_fquery_get_fw_rev;
ndctl_cmd_fw_xlat_firmware_status;
@@ -346,7 +347,6 @@ global:
LIBNDCTL_15 {
global:
- ndctl_cmd_fw_info_get_next_version;
ndctl_dimm_cmd_new_ack_shutdown_count;
ndctl_region_get_numa_node;
ndctl_dimm_fw_update_supported;
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 1cad06b..73bbeed 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -314,7 +314,7 @@ struct ndctl_dimm_ops {
unsigned int (*fw_info_get_query_interval)(struct ndctl_cmd *);
unsigned int (*fw_info_get_max_query_time)(struct ndctl_cmd *);
unsigned long long (*fw_info_get_run_version)(struct ndctl_cmd *);
- unsigned long long (*fw_info_get_next_version)(struct ndctl_cmd *);
+ unsigned long long (*fw_info_get_updated_version)(struct ndctl_cmd *);
struct ndctl_cmd *(*new_fw_start_update)(struct ndctl_dimm *);
unsigned int (*fw_start_get_context)(struct ndctl_cmd *);
struct ndctl_cmd *(*new_fw_send)(struct ndctl_cmd *,
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 10b423f..498ae19 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -640,7 +640,7 @@ unsigned int ndctl_cmd_fw_info_get_max_send_len(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_fw_info_get_query_interval(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_fw_info_get_max_query_time(struct ndctl_cmd *cmd);
unsigned long long ndctl_cmd_fw_info_get_run_version(struct ndctl_cmd *cmd);
-unsigned long long ndctl_cmd_fw_info_get_next_version(struct ndctl_cmd *cmd);
+unsigned long long ndctl_cmd_fw_info_get_updated_version(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_fw_start_get_context(struct ndctl_cmd *cmd);
unsigned long long ndctl_cmd_fw_fquery_get_fw_rev(struct ndctl_cmd *cmd);
enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct ndctl_cmd *cmd);
diff --git a/ndctl/util/json-firmware.c b/ndctl/util/json-firmware.c
index e595e2f..118424f 100644
--- a/ndctl/util/json-firmware.c
+++ b/ndctl/util/json-firmware.c
@@ -46,7 +46,7 @@ struct json_object *util_dimm_firmware_to_json(struct ndctl_dimm *dimm,
if (jobj)
json_object_object_add(jfirmware, "current_version", jobj);
- next = ndctl_cmd_fw_info_get_next_version(cmd);
+ next = ndctl_cmd_fw_info_get_updated_version(cmd);
if (next == ULLONG_MAX) {
jobj = util_json_object_hex(-1, flags);
if (jobj)
--
2.14.3
2 years, 9 months
[RFC v2 00/83] NOVA: a new file system for persistent memory
by Andiry Xu
From: Andiry Xu <jix024(a)cs.ucsd.edu>
This is the second version of RFC patch series that impements
NOVA (NOn-Volatile memory Accelerated file system), a new file system built for PMEM.
NOVA's goal is to provide a high performance, production-ready
file system tailored for byte-addressable non-volatile memories (e.g., NVDIMMs
and Intel's soon-to-be-released 3DXpoint DIMMs).
NOVA was developed at the Non-Volatile Systems Laboratory in the Computer
Science and Engineering Department at the University of California, San Diego.
Its primary authors are Andiry Xu <jix024(a)cs.ucsd.edu>, Lu Zhang
<luzh(a)eng.ucsd.edu>, and Steven Swanson <swanson(a)eng.ucsd.edu>.
NOVA is stable enough to run complex applications, but there is substantial
work left to do. This RFC is intended to gather feedback to guide its
development toward eventual inclusion upstream.
The patches are based on Linux 4.16-rc4.
Changes from v1:
* Remove snapshot, metadata replication and data parity for future submission.
This significantly reduces complexity and LOC: 22129 -> 13834.
* Breakdown the code in a more reviewer-friendly way:
The patchset starts with a simple skeleton and adds more features gradually.
Each patch leaves the tree in a compilable and working state,
and is self-contained and small, so easier to review.
* Fix bugs so that NOVA passes xfstests: https://github.com/NVSL/xfstests
Overview
========
NOVA is primarily a log-structured file system, but rather than maintain a
single global log for the entire file system, it maintains separate logs for
each inode. NOVA breaks the logs into 4KB pages, they need not be
contiguous in memory. The logs only contain metadata.
File data pages reside outside the log, and log entries for write operations
point to data pages they modify. File modification can be done in
either inplace update or copy-on-write (COW) way to provide atomic file updates.
For file operations that involve multiple inodes, NOVA use small, fixed-sized
redo logs to atomically append log entries to the logs of the inodes involved.
This structure keeps logs small and makes garbage collection very fast. It also
enables enormous parallelism during recovery from an unclean unmount, since
threads can scan logs in parallel.
Documentation/filesystems/NOVA.txt contains some lower-level implementation and
usage information. A more thorough discussion of NOVA's goals and design is
avaialable in two papers:
NOVA: A Log-structured File system for Hybrid Volatile/Non-volatile Main Memories
http://cseweb.ucsd.edu/~swanson/papers/FAST2016NOVA.pdf
Jian Xu and Steven Swanson
Published in FAST 2016
NOVA-Fortis: A Fault-Tolerant Non-Volatile Main Memory File System
http://cseweb.ucsd.edu/~swanson/papers/SOSP2017-NOVAFortis.pdf
Jian Xu, Lu Zhang, Amirsaman Memaripour, Akshatha Gangadharaiah,
Amit Borase, Tamires Brito Da Silva, Andy Rudoff, Steven Swanson
Published in SOSP 2017
This version contains features from the FAST paper. We leave NOVA-Fortis
features for future.
Build and Run
=============
To build NOVA, build the kernel with PMEM (`CONFIG_BLK_DEV_PMEM`),
DAX (`CONFIG_FS_DAX`) and NOVA (`CONFIG_NOVA_FS`) support. Install as usual.
NOVA runs on a pmem non-volatile memory region created by memmap kernel option.
For instance, adding 'memmap=16G!8G' to the kernel boot parameters will reserve
16GB memory starting from address 8GB, and the kernel will create a pmem0
block device under the /dev directory.
After the OS has booted, initialize a NOVA instance with the following commands:
# modprobe nova
# mount -t NOVA -o init /dev/pmem0 /mnt/nova
The above commands create a NOVA instance on /dev/pmem0 and mounts it on
/mnt/nova. Currently NOVA does not have mkfs or fsck support.
Performance
===========
Comparing to other DAX file systems such as ext4-DAX and xfs-DAX,
NOVA provides fine-grained, byte granularity metadata operation,
and it performs better in metadata-intensive and write-intensive applications.
NOVA also excel in append-fsync access pattern, i.e. write-ahead logging,
which is very common in DBMS and key-value stores.
The following test is performed on Intel i7-3770K with 16GB DRAM
and 8GB PMEM emulated with DRAM. The kernel is 4.16-rc4 64bit on Ubuntu 16.04.
Performance may vary on different platforms.
Filebench throughout (ops/s):
xfs-DAX ext4-DAX NOVA
Fileserver 86971 177826 334166
Varmail 148032 288033 999794
Webserver 370245 370144 374130
Webproxy 315084 737544 927216
Webserver is read-intensive and all the file systems have similar performance.
SQLite test:
SQLite has four journaling modes:
Delete: delete the undo log file after transaction commit
Truncate: truncate the undo log file to zero after transaction commit
Persist: write a flag at the beginning of the log file after transaction commit
WAL: write-ahead logging
SQLite insert (transactions/s):
xfs-DAX ext4-DAX NOVA
Delete 18525 23615 45289
Truncate 21930 26391 52046
Persist 58053 56106 50554
WAL 38622 62703 85395
NOVA performs bad in Persist mode because it does copy-on-write for writes,
and writes 4KB for sub-page writes.
Redis: fsync the WAL file after every set.
Redis set throughout (trans/s):
xfs-DAX ext4-DAX NOVA
49771 88308 102560
RocksDB fillunique test (ops/s):
xfs-DAX ext4-DAX NOVA
WAL sync 33563 62066 295655
WAL nosync 254533 288106 393713
Both ext4-DAX and xfs-DAX suffer from high fsync overhead.
More test results are available in the two NOVA papers.
NOVA uses per-inode logging, per-CPU inode table and journal to avoid lock contention.
We use the FxMark test suite (https://github.com/sslab-gatech/fxmark)
to test the filesystem scalability. The result is at
http://cseweb.ucsd.edu/~jix024/sc.pdf
Thanks,
Andiry
---
Andiry Xu (83):
Introduction and documentation of NOVA filesystem.
Add nova_def.h.
Add super.h.
NOVA inode definition.
Add NOVA filesystem definitions and useful helper routines.
Add inode get/read methods.
Initialize inode_info and rebuild inode information in nova_iget().
NOVA superblock operations.
Add Kconfig and Makefile
Add superblock integrity check.
Add timing and I/O statistics for performance analysis and profiling.
Add timing for mount and init.
Add remount_fs and show_options methods.
Add range node kmem cache.
Add free list data structure.
Initialize block map and free lists in nova_init().
Add statfs support.
Add freelist statistics printing.
Add pmem block free routines.
Pmem block allocation routines.
Add log structure.
Inode log pages allocation and reclaimation.
Save allocator to pmem in put_super.
Initialize and allocate inode table.
Support get normal inode address and inode table extentsion.
Add inode_map to track inuse inodes.
Save the inode inuse list to pmem upon umount
Add NOVA address space operations
Add write_inode and dirty_inode routines.
New NOVA inode allocation.
Add new vfs inode allocation.
Add log entry definitions.
Inode log and entry printing for debug purpose.
Journal: NOVA light weight journal definitions.
Journal: Lite journal helper routines.
Journal: Lite journal recovery.
Journal: Lite journal create and commit.
Journal: NOVA lite journal initialization.
Log operation: dentry append.
Log operation: file write entry append.
Log operation: setattr entry append
Log operation: link change append.
Log operation: in-place update log entry
Log operation: invalidate log entries
Log operation: file inode log lookup and assign
Dir: Add Directory radix tree insert/remove methods.
Dir: Add initial dentries when initializing a directory inode log.
Dir: Readdir operation.
Dir: Append create/remove dentry.
Inode: Add nova_evict_inode.
Rebuild: directory inode.
Rebuild: file inode.
Namei: lookup.
Namei: create and mknod.
Namei: mkdir
Namei: link and unlink.
Namei: rmdir
Namei: rename
Namei: setattr
Add special inode operations.
Super: Add nova_export_ops.
File: getattr and file inode operations
File operation: llseek.
File operation: open, fsync, flush.
File operation: read.
Super: Add file write item cache.
Dax: commit list of file write items to log.
File operation: copy-on-write write.
Super: Add module param inplace_data_updates.
File operation: Inplace write.
Symlink support.
File operation: fallocate.
Dax: Add iomap operations.
File operation: Mmap.
File operation: read/write iter.
Ioctl support.
GC: Fast garbage collection.
GC: Thorough garbage collection.
Normal recovery.
Failure recovery: bitmap operations.
Failure recovery: Inode pages recovery routines.
Failure recovery: Per-CPU recovery.
Sysfs support.
Documentation/filesystems/00-INDEX | 2 +
Documentation/filesystems/nova.txt | 498 +++++++++++++
MAINTAINERS | 8 +
fs/Kconfig | 2 +
fs/Makefile | 1 +
fs/nova/Kconfig | 15 +
fs/nova/Makefile | 8 +
fs/nova/balloc.c | 730 ++++++++++++++++++
fs/nova/balloc.h | 96 +++
fs/nova/bbuild.c | 1437 ++++++++++++++++++++++++++++++++++++
fs/nova/bbuild.h | 28 +
fs/nova/dax.c | 970 ++++++++++++++++++++++++
fs/nova/dir.c | 520 +++++++++++++
fs/nova/file.c | 728 ++++++++++++++++++
fs/nova/gc.c | 459 ++++++++++++
fs/nova/inode.c | 1310 ++++++++++++++++++++++++++++++++
fs/nova/inode.h | 277 +++++++
fs/nova/ioctl.c | 184 +++++
fs/nova/journal.c | 412 +++++++++++
fs/nova/journal.h | 56 ++
fs/nova/log.c | 1111 ++++++++++++++++++++++++++++
fs/nova/log.h | 417 +++++++++++
fs/nova/namei.c | 848 +++++++++++++++++++++
fs/nova/nova.h | 566 ++++++++++++++
fs/nova/nova_def.h | 128 ++++
fs/nova/rebuild.c | 499 +++++++++++++
fs/nova/stats.c | 600 +++++++++++++++
fs/nova/stats.h | 178 +++++
fs/nova/super.c | 1063 ++++++++++++++++++++++++++
fs/nova/super.h | 171 +++++
fs/nova/symlink.c | 133 ++++
fs/nova/sysfs.c | 379 ++++++++++
32 files changed, 13834 insertions(+)
create mode 100644 Documentation/filesystems/nova.txt
create mode 100644 fs/nova/Kconfig
create mode 100644 fs/nova/Makefile
create mode 100644 fs/nova/balloc.c
create mode 100644 fs/nova/balloc.h
create mode 100644 fs/nova/bbuild.c
create mode 100644 fs/nova/bbuild.h
create mode 100644 fs/nova/dax.c
create mode 100644 fs/nova/dir.c
create mode 100644 fs/nova/file.c
create mode 100644 fs/nova/gc.c
create mode 100644 fs/nova/inode.c
create mode 100644 fs/nova/inode.h
create mode 100644 fs/nova/ioctl.c
create mode 100644 fs/nova/journal.c
create mode 100644 fs/nova/journal.h
create mode 100644 fs/nova/log.c
create mode 100644 fs/nova/log.h
create mode 100644 fs/nova/namei.c
create mode 100644 fs/nova/nova.h
create mode 100644 fs/nova/nova_def.h
create mode 100644 fs/nova/rebuild.c
create mode 100644 fs/nova/stats.c
create mode 100644 fs/nova/stats.h
create mode 100644 fs/nova/super.c
create mode 100644 fs/nova/super.h
create mode 100644 fs/nova/symlink.c
create mode 100644 fs/nova/sysfs.c
--
2.7.4
2 years, 9 months
采购礼品印刷品办公用品价格会比你现在下浮10-20%。一站式服务更省心。
by 力圣传播
到力圣采购礼品印刷品办公用品,价格会比你现在采购价下浮10-20%。
参考网址www.l6660.com.www.66600619。关注我们的微信号,天天新品不断。
上海力圣文化传播有限公司 陆洋 13361869996021-66600619 66600619a(a)163.com
2 years, 9 months