9ae3f9
From 3e8b3a2c2c6f83635486035fc8040c87d89813d2 Mon Sep 17 00:00:00 2001
9ae3f9
From: Xavi Hernandez <xhernandez@redhat.com>
9ae3f9
Date: Thu, 2 Jul 2020 18:08:52 +0200
9ae3f9
Subject: [PATCH 457/465] cluster/ec: Improve detection of new heals
9ae3f9
9ae3f9
When EC successfully healed a directory it assumed that maybe other
9ae3f9
entries inside that directory could have been created, which could
9ae3f9
require additional heal cycles. For this reason, when the heal happened
9ae3f9
as part of one index heal iteration, it triggered a new iteration.
9ae3f9
9ae3f9
The problem happened when the directory was healthy, so no new entries
9ae3f9
were added, but its index entry was not removed for some reason. In
9ae3f9
this case self-heal started and endless loop healing the same directory
9ae3f9
continuously, cause high CPU utilization.
9ae3f9
9ae3f9
This patch improves detection of new files added to the heal index so
9ae3f9
that a new index heal iteration is only triggered if there is new work
9ae3f9
to do.
9ae3f9
9ae3f9
>Upstream patch: https://review.gluster.org/#/c/glusterfs/+/24665/
9ae3f9
>Fixes: #1354
9ae3f9
9ae3f9
Change-Id: I2355742b85fbfa6de758bccc5d2e1a283c82b53f
9ae3f9
BUG: 1852736
9ae3f9
Signed-off-by: Xavi Hernandez <xhernandez@redhat.com>
9ae3f9
Reviewed-on: https://code.engineering.redhat.com/gerrit/208041
9ae3f9
Tested-by: Ashish Pandey <aspandey@redhat.com>
9ae3f9
Tested-by: RHGS Build Bot <nigelb@redhat.com>
9ae3f9
Reviewed-by: Ashish Pandey <aspandey@redhat.com>
9ae3f9
---
9ae3f9
 xlators/cluster/ec/src/ec-common.c     |  2 +-
9ae3f9
 xlators/cluster/ec/src/ec-heal.c       | 58 +++++++++++++++++++++++-----------
9ae3f9
 xlators/cluster/ec/src/ec-heald.c      | 24 ++++++++++----
9ae3f9
 xlators/cluster/ec/src/ec-inode-read.c | 27 ++++++++++++++--
9ae3f9
 xlators/cluster/ec/src/ec-types.h      |  4 +--
9ae3f9
 xlators/cluster/ec/src/ec.h            |  1 +
9ae3f9
 6 files changed, 86 insertions(+), 30 deletions(-)
9ae3f9
9ae3f9
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
9ae3f9
index e580bfb..e3f8769 100644
9ae3f9
--- a/xlators/cluster/ec/src/ec-common.c
9ae3f9
+++ b/xlators/cluster/ec/src/ec-common.c
9ae3f9
@@ -230,7 +230,7 @@ ec_child_next(ec_t *ec, ec_fop_data_t *fop, uint32_t idx)
9ae3f9
 int32_t
9ae3f9
 ec_heal_report(call_frame_t *frame, void *cookie, xlator_t *this,
9ae3f9
                int32_t op_ret, int32_t op_errno, uintptr_t mask, uintptr_t good,
9ae3f9
-               uintptr_t bad, dict_t *xdata)
9ae3f9
+               uintptr_t bad, uint32_t pending, dict_t *xdata)
9ae3f9
 {
9ae3f9
     if (op_ret < 0) {
9ae3f9
         gf_msg(this->name, GF_LOG_DEBUG, op_errno, EC_MSG_HEAL_FAIL,
9ae3f9
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
9ae3f9
index 06a7016..e2de879 100644
9ae3f9
--- a/xlators/cluster/ec/src/ec-heal.c
9ae3f9
+++ b/xlators/cluster/ec/src/ec-heal.c
9ae3f9
@@ -72,6 +72,7 @@ struct ec_name_data {
9ae3f9
     char *name;
9ae3f9
     inode_t *parent;
9ae3f9
     default_args_cbk_t *replies;
9ae3f9
+    uint32_t heal_pending;
9ae3f9
 };
9ae3f9
 
9ae3f9
 static char *ec_ignore_xattrs[] = {GF_SELINUX_XATTR_KEY, QUOTA_SIZE_KEY, NULL};
9ae3f9
@@ -996,6 +997,7 @@ ec_set_new_entry_dirty(ec_t *ec, loc_t *loc, struct iatt *ia,
9ae3f9
         ret = -ENOTCONN;
9ae3f9
         goto out;
9ae3f9
     }
9ae3f9
+
9ae3f9
 out:
9ae3f9
     if (xattr)
9ae3f9
         dict_unref(xattr);
9ae3f9
@@ -1164,6 +1166,7 @@ ec_create_name(call_frame_t *frame, ec_t *ec, inode_t *parent, char *name,
9ae3f9
     dict_t *xdata = NULL;
9ae3f9
     char *linkname = NULL;
9ae3f9
     ec_config_t config;
9ae3f9
+
9ae3f9
     /* There should be just one gfid key */
9ae3f9
     EC_REPLIES_ALLOC(replies, ec->nodes);
9ae3f9
     if (gfid_db->count != 1) {
9ae3f9
@@ -1408,6 +1411,11 @@ __ec_heal_name(call_frame_t *frame, ec_t *ec, inode_t *parent, char *name,
9ae3f9
 
9ae3f9
     ret = ec_create_name(frame, ec, parent, name, replies, gfid_db, enoent,
9ae3f9
                          participants);
9ae3f9
+    if (ret >= 0) {
9ae3f9
+        /* If ec_create_name() succeeded we return 1 to indicate that a new
9ae3f9
+         * file has been created and it will need to be healed. */
9ae3f9
+        ret = 1;
9ae3f9
+    }
9ae3f9
 out:
9ae3f9
     cluster_replies_wipe(replies, ec->nodes);
9ae3f9
     loc_wipe(&loc;;
9ae3f9
@@ -1485,18 +1493,22 @@ ec_name_heal_handler(xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
9ae3f9
     ret = ec_heal_name(name_data->frame, ec, parent->inode, entry->d_name,
9ae3f9
                        name_on);
9ae3f9
 
9ae3f9
-    if (ret < 0)
9ae3f9
+    if (ret < 0) {
9ae3f9
         memset(name_on, 0, ec->nodes);
9ae3f9
+    } else {
9ae3f9
+        name_data->heal_pending += ret;
9ae3f9
+    }
9ae3f9
 
9ae3f9
     for (i = 0; i < ec->nodes; i++)
9ae3f9
         if (name_data->participants[i] && !name_on[i])
9ae3f9
             name_data->failed_on[i] = 1;
9ae3f9
+
9ae3f9
     return 0;
9ae3f9
 }
9ae3f9
 
9ae3f9
 int
9ae3f9
 ec_heal_names(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
-              unsigned char *participants)
9ae3f9
+              unsigned char *participants, uint32_t *pending)
9ae3f9
 {
9ae3f9
     int i = 0;
9ae3f9
     int j = 0;
9ae3f9
@@ -1509,7 +1521,7 @@ ec_heal_names(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
     name_data.frame = frame;
9ae3f9
     name_data.participants = participants;
9ae3f9
     name_data.failed_on = alloca0(ec->nodes);
9ae3f9
-    ;
9ae3f9
+    name_data.heal_pending = 0;
9ae3f9
 
9ae3f9
     for (i = 0; i < ec->nodes; i++) {
9ae3f9
         if (!participants[i])
9ae3f9
@@ -1528,6 +1540,8 @@ ec_heal_names(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
             break;
9ae3f9
         }
9ae3f9
     }
9ae3f9
+    *pending += name_data.heal_pending;
9ae3f9
+
9ae3f9
     loc_wipe(&loc;;
9ae3f9
     return ret;
9ae3f9
 }
9ae3f9
@@ -1535,7 +1549,7 @@ ec_heal_names(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
 int
9ae3f9
 __ec_heal_entry(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
                 unsigned char *heal_on, unsigned char *sources,
9ae3f9
-                unsigned char *healed_sinks)
9ae3f9
+                unsigned char *healed_sinks, uint32_t *pending)
9ae3f9
 {
9ae3f9
     unsigned char *locked_on = NULL;
9ae3f9
     unsigned char *output = NULL;
9ae3f9
@@ -1580,7 +1594,7 @@ unlock:
9ae3f9
         if (sources[i] || healed_sinks[i])
9ae3f9
             participants[i] = 1;
9ae3f9
     }
9ae3f9
-    ret = ec_heal_names(frame, ec, inode, participants);
9ae3f9
+    ret = ec_heal_names(frame, ec, inode, participants, pending);
9ae3f9
 
9ae3f9
     if (EC_COUNT(participants, ec->nodes) <= ec->fragments)
9ae3f9
         goto out;
9ae3f9
@@ -1601,7 +1615,8 @@ out:
9ae3f9
 
9ae3f9
 int
9ae3f9
 ec_heal_entry(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
-              unsigned char *sources, unsigned char *healed_sinks)
9ae3f9
+              unsigned char *sources, unsigned char *healed_sinks,
9ae3f9
+              uint32_t *pending)
9ae3f9
 {
9ae3f9
     unsigned char *locked_on = NULL;
9ae3f9
     unsigned char *up_subvols = NULL;
9ae3f9
@@ -1632,7 +1647,7 @@ ec_heal_entry(call_frame_t *frame, ec_t *ec, inode_t *inode,
9ae3f9
             goto unlock;
9ae3f9
         }
9ae3f9
         ret = __ec_heal_entry(frame, ec, inode, locked_on, sources,
9ae3f9
-                              healed_sinks);
9ae3f9
+                              healed_sinks, pending);
9ae3f9
     }
9ae3f9
 unlock:
9ae3f9
     cluster_uninodelk(ec->xl_list, locked_on, ec->nodes, replies, output, frame,
9ae3f9
@@ -1953,14 +1968,14 @@ ec_manager_heal_block(ec_fop_data_t *fop, int32_t state)
9ae3f9
             if (fop->cbks.heal) {
9ae3f9
                 fop->cbks.heal(fop->req_frame, fop, fop->xl, 0, 0,
9ae3f9
                                (heal->good | heal->bad), heal->good, heal->bad,
9ae3f9
-                               NULL);
9ae3f9
+                               0, NULL);
9ae3f9
             }
9ae3f9
 
9ae3f9
             return EC_STATE_END;
9ae3f9
         case -EC_STATE_REPORT:
9ae3f9
             if (fop->cbks.heal) {
9ae3f9
-                fop->cbks.heal(fop->req_frame, fop, fop->xl, -1, fop->error, 0,
9ae3f9
-                               0, 0, NULL);
9ae3f9
+                fop->cbks.heal(fop->req_frame, fop->data, fop->xl, -1,
9ae3f9
+                               fop->error, 0, 0, 0, 0, NULL);
9ae3f9
             }
9ae3f9
 
9ae3f9
             return EC_STATE_END;
9ae3f9
@@ -1997,14 +2012,15 @@ out:
9ae3f9
     if (fop != NULL) {
9ae3f9
         ec_manager(fop, error);
9ae3f9
     } else {
9ae3f9
-        func(frame, NULL, this, -1, error, 0, 0, 0, NULL);
9ae3f9
+        func(frame, heal, this, -1, error, 0, 0, 0, 0, NULL);
9ae3f9
     }
9ae3f9
 }
9ae3f9
 
9ae3f9
 int32_t
9ae3f9
 ec_heal_block_done(call_frame_t *frame, void *cookie, xlator_t *this,
9ae3f9
                    int32_t op_ret, int32_t op_errno, uintptr_t mask,
9ae3f9
-                   uintptr_t good, uintptr_t bad, dict_t *xdata)
9ae3f9
+                   uintptr_t good, uintptr_t bad, uint32_t pending,
9ae3f9
+                   dict_t *xdata)
9ae3f9
 {
9ae3f9
     ec_fop_data_t *fop = cookie;
9ae3f9
     ec_heal_t *heal = fop->data;
9ae3f9
@@ -2489,6 +2505,7 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
9ae3f9
     intptr_t mbad = 0;
9ae3f9
     intptr_t good = 0;
9ae3f9
     intptr_t bad = 0;
9ae3f9
+    uint32_t pending = 0;
9ae3f9
     ec_fop_data_t *fop = data;
9ae3f9
     gf_boolean_t blocking = _gf_false;
9ae3f9
     ec_heal_need_t need_heal = EC_HEAL_NONEED;
9ae3f9
@@ -2524,7 +2541,7 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
9ae3f9
     if (loc->name && strlen(loc->name)) {
9ae3f9
         ret = ec_heal_name(frame, ec, loc->parent, (char *)loc->name,
9ae3f9
                            participants);
9ae3f9
-        if (ret == 0) {
9ae3f9
+        if (ret >= 0) {
9ae3f9
             gf_msg_debug(this->name, 0,
9ae3f9
                          "%s: name heal "
9ae3f9
                          "successful on %" PRIXPTR,
9ae3f9
@@ -2542,7 +2559,7 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
9ae3f9
 
9ae3f9
     /* Mount triggers heal only when it detects that it must need heal, shd
9ae3f9
      * triggers heals periodically which need not be thorough*/
9ae3f9
-    if (ec->shd.iamshd) {
9ae3f9
+    if (ec->shd.iamshd && (ret <= 0)) {
9ae3f9
         ec_heal_inspect(frame, ec, loc->inode, up_subvols, _gf_false, _gf_false,
9ae3f9
                         &need_heal);
9ae3f9
 
9ae3f9
@@ -2552,13 +2569,15 @@ ec_heal_do(xlator_t *this, void *data, loc_t *loc, int32_t partial)
9ae3f9
             goto out;
9ae3f9
         }
9ae3f9
     }
9ae3f9
+
9ae3f9
     sources = alloca0(ec->nodes);
9ae3f9
     healed_sinks = alloca0(ec->nodes);
9ae3f9
     if (IA_ISREG(loc->inode->ia_type)) {
9ae3f9
         ret = ec_heal_data(frame, ec, blocking, loc->inode, sources,
9ae3f9
                            healed_sinks);
9ae3f9
     } else if (IA_ISDIR(loc->inode->ia_type) && !partial) {
9ae3f9
-        ret = ec_heal_entry(frame, ec, loc->inode, sources, healed_sinks);
9ae3f9
+        ret = ec_heal_entry(frame, ec, loc->inode, sources, healed_sinks,
9ae3f9
+                            &pending);
9ae3f9
     } else {
9ae3f9
         ret = 0;
9ae3f9
         memcpy(sources, participants, ec->nodes);
9ae3f9
@@ -2588,10 +2607,11 @@ out:
9ae3f9
     if (fop->cbks.heal) {
9ae3f9
         fop->cbks.heal(fop->req_frame, fop, fop->xl, op_ret, op_errno,
9ae3f9
                        ec_char_array_to_mask(participants, ec->nodes),
9ae3f9
-                       mgood & good, mbad & bad, NULL);
9ae3f9
+                       mgood & good, mbad & bad, pending, NULL);
9ae3f9
     }
9ae3f9
     if (frame)
9ae3f9
         STACK_DESTROY(frame->root);
9ae3f9
+
9ae3f9
     return;
9ae3f9
 }
9ae3f9
 
9ae3f9
@@ -2638,8 +2658,8 @@ void
9ae3f9
 ec_heal_fail(ec_t *ec, ec_fop_data_t *fop)
9ae3f9
 {
9ae3f9
     if (fop->cbks.heal) {
9ae3f9
-        fop->cbks.heal(fop->req_frame, NULL, ec->xl, -1, fop->error, 0, 0, 0,
9ae3f9
-                       NULL);
9ae3f9
+        fop->cbks.heal(fop->req_frame, fop->data, ec->xl, -1, fop->error, 0, 0,
9ae3f9
+                       0, 0, NULL);
9ae3f9
     }
9ae3f9
     ec_fop_data_release(fop);
9ae3f9
 }
9ae3f9
@@ -2826,7 +2846,7 @@ fail:
9ae3f9
     if (fop)
9ae3f9
         ec_fop_data_release(fop);
9ae3f9
     if (func)
9ae3f9
-        func(frame, NULL, this, -1, err, 0, 0, 0, NULL);
9ae3f9
+        func(frame, data, this, -1, err, 0, 0, 0, 0, NULL);
9ae3f9
 }
9ae3f9
 
9ae3f9
 int
9ae3f9
diff --git a/xlators/cluster/ec/src/ec-heald.c b/xlators/cluster/ec/src/ec-heald.c
9ae3f9
index cba111a..4f4b6aa 100644
9ae3f9
--- a/xlators/cluster/ec/src/ec-heald.c
9ae3f9
+++ b/xlators/cluster/ec/src/ec-heald.c
9ae3f9
@@ -156,15 +156,27 @@ int
9ae3f9
 ec_shd_selfheal(struct subvol_healer *healer, int child, loc_t *loc,
9ae3f9
                 gf_boolean_t full)
9ae3f9
 {
9ae3f9
+    dict_t *xdata = NULL;
9ae3f9
+    uint32_t count;
9ae3f9
     int32_t ret;
9ae3f9
 
9ae3f9
-    ret = syncop_getxattr(healer->this, loc, NULL, EC_XATTR_HEAL, NULL, NULL);
9ae3f9
-    if (!full && (ret >= 0) && (loc->inode->ia_type == IA_IFDIR)) {
9ae3f9
+    ret = syncop_getxattr(healer->this, loc, NULL, EC_XATTR_HEAL, NULL, &xdata);
9ae3f9
+    if (!full && (loc->inode->ia_type == IA_IFDIR)) {
9ae3f9
         /* If we have just healed a directory, it's possible that
9ae3f9
-         * other index entries have appeared to be healed. We put a
9ae3f9
-         * mark so that we can check it later and restart a scan
9ae3f9
-         * without delay. */
9ae3f9
-        healer->rerun = _gf_true;
9ae3f9
+         * other index entries have appeared to be healed. */
9ae3f9
+        if ((xdata != NULL) &&
9ae3f9
+            (dict_get_uint32(xdata, EC_XATTR_HEAL_NEW, &count) == 0) &&
9ae3f9
+            (count > 0)) {
9ae3f9
+            /* Force a rerun of the index healer. */
9ae3f9
+            gf_msg_debug(healer->this->name, 0, "%d more entries to heal",
9ae3f9
+                         count);
9ae3f9
+
9ae3f9
+            healer->rerun = _gf_true;
9ae3f9
+        }
9ae3f9
+    }
9ae3f9
+
9ae3f9
+    if (xdata != NULL) {
9ae3f9
+        dict_unref(xdata);
9ae3f9
     }
9ae3f9
 
9ae3f9
     return ret;
9ae3f9
diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c
9ae3f9
index f87a94a..e82e8f6 100644
9ae3f9
--- a/xlators/cluster/ec/src/ec-inode-read.c
9ae3f9
+++ b/xlators/cluster/ec/src/ec-inode-read.c
9ae3f9
@@ -393,7 +393,8 @@ ec_manager_getxattr(ec_fop_data_t *fop, int32_t state)
9ae3f9
 int32_t
9ae3f9
 ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl,
9ae3f9
                      int32_t op_ret, int32_t op_errno, uintptr_t mask,
9ae3f9
-                     uintptr_t good, uintptr_t bad, dict_t *xdata)
9ae3f9
+                     uintptr_t good, uintptr_t bad, uint32_t pending,
9ae3f9
+                     dict_t *xdata)
9ae3f9
 {
9ae3f9
     ec_fop_data_t *fop = cookie;
9ae3f9
     fop_getxattr_cbk_t func = fop->data;
9ae3f9
@@ -402,6 +403,25 @@ ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl,
9ae3f9
     char *str;
9ae3f9
     char bin1[65], bin2[65];
9ae3f9
 
9ae3f9
+    /* We try to return the 'pending' information in xdata, but if this cannot
9ae3f9
+     * be set, we will ignore it silently. We prefer to report the success or
9ae3f9
+     * failure of the heal itself. */
9ae3f9
+    if (xdata == NULL) {
9ae3f9
+        xdata = dict_new();
9ae3f9
+    } else {
9ae3f9
+        dict_ref(xdata);
9ae3f9
+    }
9ae3f9
+    if (xdata != NULL) {
9ae3f9
+        if (dict_set_uint32(xdata, EC_XATTR_HEAL_NEW, pending) != 0) {
9ae3f9
+            /* dict_set_uint32() is marked as 'warn_unused_result' and gcc
9ae3f9
+             * enforces to check the result in this case. However we don't
9ae3f9
+             * really care if it succeeded or not. We'll just do the same.
9ae3f9
+             *
9ae3f9
+             * This empty 'if' avoids the warning, and it will be removed by
9ae3f9
+             * the optimizer. */
9ae3f9
+        }
9ae3f9
+    }
9ae3f9
+
9ae3f9
     if (op_ret >= 0) {
9ae3f9
         dict = dict_new();
9ae3f9
         if (dict == NULL) {
9ae3f9
@@ -435,11 +455,14 @@ ec_getxattr_heal_cbk(call_frame_t *frame, void *cookie, xlator_t *xl,
9ae3f9
     }
9ae3f9
 
9ae3f9
 out:
9ae3f9
-    func(frame, NULL, xl, op_ret, op_errno, dict, NULL);
9ae3f9
+    func(frame, NULL, xl, op_ret, op_errno, dict, xdata);
9ae3f9
 
9ae3f9
     if (dict != NULL) {
9ae3f9
         dict_unref(dict);
9ae3f9
     }
9ae3f9
+    if (xdata != NULL) {
9ae3f9
+        dict_unref(xdata);
9ae3f9
+    }
9ae3f9
 
9ae3f9
     return 0;
9ae3f9
 }
9ae3f9
diff --git a/xlators/cluster/ec/src/ec-types.h b/xlators/cluster/ec/src/ec-types.h
9ae3f9
index 34a9768..f15429d 100644
9ae3f9
--- a/xlators/cluster/ec/src/ec-types.h
9ae3f9
+++ b/xlators/cluster/ec/src/ec-types.h
9ae3f9
@@ -186,10 +186,10 @@ struct _ec_inode {
9ae3f9
 
9ae3f9
 typedef int32_t (*fop_heal_cbk_t)(call_frame_t *, void *, xlator_t *, int32_t,
9ae3f9
                                   int32_t, uintptr_t, uintptr_t, uintptr_t,
9ae3f9
-                                  dict_t *);
9ae3f9
+                                  uint32_t, dict_t *);
9ae3f9
 typedef int32_t (*fop_fheal_cbk_t)(call_frame_t *, void *, xlator_t *, int32_t,
9ae3f9
                                    int32_t, uintptr_t, uintptr_t, uintptr_t,
9ae3f9
-                                   dict_t *);
9ae3f9
+                                   uint32_t, dict_t *);
9ae3f9
 
9ae3f9
 union _ec_cbk {
9ae3f9
     fop_access_cbk_t access;
9ae3f9
diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h
9ae3f9
index 1b210d9..6f6de6d 100644
9ae3f9
--- a/xlators/cluster/ec/src/ec.h
9ae3f9
+++ b/xlators/cluster/ec/src/ec.h
9ae3f9
@@ -18,6 +18,7 @@
9ae3f9
 #define EC_XATTR_SIZE EC_XATTR_PREFIX "size"
9ae3f9
 #define EC_XATTR_VERSION EC_XATTR_PREFIX "version"
9ae3f9
 #define EC_XATTR_HEAL EC_XATTR_PREFIX "heal"
9ae3f9
+#define EC_XATTR_HEAL_NEW EC_XATTR_PREFIX "heal-new"
9ae3f9
 #define EC_XATTR_DIRTY EC_XATTR_PREFIX "dirty"
9ae3f9
 #define EC_STRIPE_CACHE_MAX_SIZE 10
9ae3f9
 #define EC_VERSION_SIZE 2
9ae3f9
-- 
9ae3f9
1.8.3.1
9ae3f9