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 <[email protected]>
---

v2:
- split out the conversion of util_filter_params to make things more
  readable (Dan).
- Not pass in mode as util_filter_params and put back the mode check in
  util_filter_walk() (Dan).

 ndctl/namespace.c |  158 +++++++++++++++++++++++++++++------------------------
 util/filter.c     |    5 +-
 util/filter.h     |    8 +++
 3 files changed, 98 insertions(+), 73 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index e7173ce9..4661771e 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -983,14 +983,86 @@ 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;
@@ -998,74 +1070,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;
+       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;
 
-               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;
-                       }
-
-                       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, &param);
+       if (rc < 0)
+               return rc;
 
-       if (success)
-               return success;
+       rc = nfa.rc;
        return rc;
 }
 
diff --git a/util/filter.c b/util/filter.c
index 6ab391a8..d98c551e 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,7 +395,7 @@ 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) {
+                       ndctl_namespace_foreach_safe(region, ndns, _n) {
                                enum ndctl_namespace_mode mode;
 
                                if (!fctx->filter_namespace)
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;
        };
 };
 

_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to