Erwin reports:
    The current implementation of ndctl clear-errors takes a very long time,
    because a full scrub happens for every namespace.

    Doing a full system ARS scrub is obviously not necessary, it just needs
    to happen once.

Indeed, it only needs to happen once per bus. Clear the 'scrub' option
after one namespace_clear_bb() invocation, and reset it when looping to
the next bus.

Link: https://github.com/pmem/ndctl/issues/104
Reported-by: Erwin Tsaur <[email protected]>
Fixes: 2ba7b8277075 ("ndctl: add a 'clear-errors' command")
Signed-off-by: Dan Williams <[email protected]>
---
 ndctl/namespace.c |   18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index bbc9107c6baa..c1af7d0db153 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -1295,7 +1295,7 @@ static int raw_clear_badblocks(struct ndctl_namespace 
*ndns)
        return nstype_clear_badblocks(ndns, devname, begin, size);
 }
 
-static int namespace_wait_scrub(struct ndctl_namespace *ndns)
+static int namespace_wait_scrub(struct ndctl_namespace *ndns, bool do_scrub)
 {
        const char *devname = ndctl_namespace_get_devname(ndns);
        struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns);
@@ -1309,7 +1309,7 @@ static int namespace_wait_scrub(struct ndctl_namespace 
*ndns)
        }
 
        /* start a scrub if asked and if one isn't in progress */
-       if (scrub && (!in_progress)) {
+       if (do_scrub && (!in_progress)) {
                rc = ndctl_bus_start_scrub(bus);
                if (rc) {
                        error("%s: Unable to start scrub: %s\n", devname,
@@ -1332,7 +1332,7 @@ static int namespace_wait_scrub(struct ndctl_namespace 
*ndns)
        return 0;
 }
 
-static int namespace_clear_bb(struct ndctl_namespace *ndns)
+static int namespace_clear_bb(struct ndctl_namespace *ndns, bool do_scrub)
 {
        struct ndctl_pfn *pfn = ndctl_namespace_get_pfn(ndns);
        struct ndctl_dax *dax = ndctl_namespace_get_dax(ndns);
@@ -1347,7 +1347,7 @@ static int namespace_clear_bb(struct ndctl_namespace 
*ndns)
                return 1;
        }
 
-       rc = namespace_wait_scrub(ndns);
+       rc = namespace_wait_scrub(ndns, do_scrub);
        if (rc)
                return rc;
 
@@ -1716,9 +1716,14 @@ static int do_xaction_namespace(const char *namespace,
                ndctl_set_log_priority(ctx, LOG_DEBUG);
 
         ndctl_bus_foreach(ctx, bus) {
+               bool do_scrub;
+
                if (!util_bus_filter(bus, param.bus))
                        continue;
 
+               /* only request scrubbing once per bus */
+               do_scrub = scrub;
+
                ndctl_region_foreach(bus, region) {
                        if (!util_region_filter(region, param.region))
                                continue;
@@ -1778,7 +1783,10 @@ static int do_xaction_namespace(const char *namespace,
                                                (*processed)++;
                                        break;
                                case ACTION_CLEAR:
-                                       rc = namespace_clear_bb(ndns);
+                                       rc = namespace_clear_bb(ndns, do_scrub);
+
+                                       /* one scrub per bus is sufficient */
+                                       do_scrub = false;
                                        if (rc == 0)
                                                (*processed)++;
                                        break;

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

Reply via email to