|
|
3604df |
From d1c4817b7c63a7fd94aa11dae5899d6d50e75897 Mon Sep 17 00:00:00 2001
|
|
|
3604df |
From: Ashish Pandey <aspandey@redhat.com>
|
|
|
3604df |
Date: Tue, 20 Sep 2016 12:32:28 +0530
|
|
|
3604df |
Subject: [PATCH 099/141] cluster/ec: Implement heal info with lock
|
|
|
3604df |
|
|
|
3604df |
Problem: Currently heal info command prints all
|
|
|
3604df |
the files/directories if the index for the
|
|
|
3604df |
file/directory is present in .glusterfs/indices folder.
|
|
|
3604df |
After implementing patch http://review.gluster.org/#/c/13733/
|
|
|
3604df |
indices of the file which is going through update fop
|
|
|
3604df |
will also be present in .glusterfs/indices even
|
|
|
3604df |
if the fop is successful on all the brick. At this time
|
|
|
3604df |
if heal info command is being used, it will also display this
|
|
|
3604df |
file which is actually healthy and does not require any heal.
|
|
|
3604df |
|
|
|
3604df |
Solution: Take lock on a file corresponding to the indices
|
|
|
3604df |
and inspect xattrs to decide if the file needs heal or not.
|
|
|
3604df |
|
|
|
3604df |
>Reviewed-on: http://review.gluster.org/15543
|
|
|
3604df |
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
3604df |
>Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
3604df |
>Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
|
|
|
3604df |
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
|
|
|
3604df |
>Smoke: Gluster Build System <jenkins@build.gluster.org>
|
|
|
3604df |
|
|
|
3604df |
Change-Id: I6361e2813ece369be12d02e74816df4eddb81cfa
|
|
|
3604df |
BUG: 1347257
|
|
|
3604df |
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
|
|
|
3604df |
Reviewed-on: https://code.engineering.redhat.com/gerrit/87015
|
|
|
3604df |
Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
3604df |
Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
|
|
|
3604df |
---
|
|
|
3604df |
libglusterfs/src/syncop-utils.c | 35 ++++
|
|
|
3604df |
libglusterfs/src/syncop-utils.h | 4 +
|
|
|
3604df |
tests/afr.rc | 5 -
|
|
|
3604df |
tests/basic/ec/ec-background-heals.t | 5 +-
|
|
|
3604df |
tests/volume.rc | 5 +
|
|
|
3604df |
xlators/cluster/afr/src/afr-self-heald.c | 27 +--
|
|
|
3604df |
xlators/cluster/ec/src/ec-common.h | 3 +
|
|
|
3604df |
xlators/cluster/ec/src/ec-heal.c | 254 ++++++++++++++++++++++++++++--
|
|
|
3604df |
xlators/cluster/ec/src/ec-heald.c | 46 +-----
|
|
|
3604df |
xlators/cluster/ec/src/ec.c | 10 +-
|
|
|
3604df |
10 files changed, 308 insertions(+), 86 deletions(-)
|
|
|
3604df |
|
|
|
3604df |
diff --git a/libglusterfs/src/syncop-utils.c b/libglusterfs/src/syncop-utils.c
|
|
|
3604df |
index 8f25db2..8c25dd1 100644
|
|
|
3604df |
--- a/libglusterfs/src/syncop-utils.c
|
|
|
3604df |
+++ b/libglusterfs/src/syncop-utils.c
|
|
|
3604df |
@@ -591,3 +591,38 @@ out:
|
|
|
3604df |
|
|
|
3604df |
return ret;
|
|
|
3604df |
}
|
|
|
3604df |
+
|
|
|
3604df |
+int
|
|
|
3604df |
+syncop_inode_find (xlator_t *this, xlator_t *subvol,
|
|
|
3604df |
+ uuid_t gfid, inode_t **inode,
|
|
|
3604df |
+ dict_t *xdata, dict_t **rsp_dict)
|
|
|
3604df |
+{
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+ loc_t loc = {0, };
|
|
|
3604df |
+ struct iatt iatt = {0, };
|
|
|
3604df |
+ *inode = NULL;
|
|
|
3604df |
+
|
|
|
3604df |
+ *inode = inode_find (this->itable, gfid);
|
|
|
3604df |
+ if (*inode)
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+
|
|
|
3604df |
+ loc.inode = inode_new (this->itable);
|
|
|
3604df |
+ if (!loc.inode) {
|
|
|
3604df |
+ ret = -ENOMEM;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ gf_uuid_copy (loc.gfid, gfid);
|
|
|
3604df |
+
|
|
|
3604df |
+ ret = syncop_lookup (subvol, &loc, &iatt, NULL, xdata, rsp_dict);
|
|
|
3604df |
+ if (ret < 0)
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+
|
|
|
3604df |
+ *inode = inode_link (loc.inode, NULL, NULL, &iatt);
|
|
|
3604df |
+ if (!*inode) {
|
|
|
3604df |
+ ret = -ENOMEM;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+out:
|
|
|
3604df |
+ loc_wipe (&loc;;
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
diff --git a/libglusterfs/src/syncop-utils.h b/libglusterfs/src/syncop-utils.h
|
|
|
3604df |
index 3968d75..4761371 100644
|
|
|
3604df |
--- a/libglusterfs/src/syncop-utils.h
|
|
|
3604df |
+++ b/libglusterfs/src/syncop-utils.h
|
|
|
3604df |
@@ -43,4 +43,8 @@ syncop_ftw_throttle (xlator_t *subvol, loc_t *loc, int pid, void *data,
|
|
|
3604df |
int (*fn) (xlator_t *subvol, gf_dirent_t *entry,
|
|
|
3604df |
loc_t *parent, void *data),
|
|
|
3604df |
int count, int sleep_time);
|
|
|
3604df |
+int
|
|
|
3604df |
+syncop_inode_find (xlator_t *this, xlator_t *subvol,
|
|
|
3604df |
+ uuid_t gfid, inode_t **inode,
|
|
|
3604df |
+ dict_t *xdata, dict_t **rsp_dict);
|
|
|
3604df |
#endif /* _SYNCOP_H */
|
|
|
3604df |
diff --git a/tests/afr.rc b/tests/afr.rc
|
|
|
3604df |
index ed376f0..bdf4075 100644
|
|
|
3604df |
--- a/tests/afr.rc
|
|
|
3604df |
+++ b/tests/afr.rc
|
|
|
3604df |
@@ -85,11 +85,6 @@ function is_file_heal_done {
|
|
|
3604df |
#count the number of entries marked for self-heal
|
|
|
3604df |
#in brick $1's index
|
|
|
3604df |
|
|
|
3604df |
-function count_sh_entries()
|
|
|
3604df |
-{
|
|
|
3604df |
- ls $1/.glusterfs/indices/xattrop | grep -v "xattrop-" | wc -l
|
|
|
3604df |
-}
|
|
|
3604df |
-
|
|
|
3604df |
function count_index_entries()
|
|
|
3604df |
{
|
|
|
3604df |
ls $1/.glusterfs/indices/xattrop | wc -l
|
|
|
3604df |
diff --git a/tests/basic/ec/ec-background-heals.t b/tests/basic/ec/ec-background-heals.t
|
|
|
3604df |
index 7ac6c0e..28efc83 100644
|
|
|
3604df |
--- a/tests/basic/ec/ec-background-heals.t
|
|
|
3604df |
+++ b/tests/basic/ec/ec-background-heals.t
|
|
|
3604df |
@@ -23,7 +23,9 @@ EXPECT_WITHIN $CHILD_UP_TIMEOUT "3" ec_child_up_count $V0 0
|
|
|
3604df |
EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "0" mount_get_option_value $M0 $V0-disperse-0 background-heals
|
|
|
3604df |
EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "0" mount_get_option_value $M0 $V0-disperse-0 heal-wait-qlength
|
|
|
3604df |
TEST touch $M0/a
|
|
|
3604df |
-EXPECT_WITHIN $CHILD_UP_TIMEOUT "0" get_pending_heal_count $V0 #One for each active brick
|
|
|
3604df |
+EXPECT_WITHIN $HEAL_TIMEOUT "^0$" count_sh_entries $B0/${V0}0
|
|
|
3604df |
+EXPECT_WITHIN $HEAL_TIMEOUT "^0$" count_sh_entries $B0/${V0}1
|
|
|
3604df |
+EXPECT_WITHIN $HEAL_TIMEOUT "^0$" count_sh_entries $B0/${V0}2
|
|
|
3604df |
TEST kill_brick $V0 $H0 $B0/${V0}2
|
|
|
3604df |
echo abc > $M0/a
|
|
|
3604df |
EXPECT 2 get_pending_heal_count $V0 #One for each active brick
|
|
|
3604df |
@@ -31,7 +33,6 @@ $CLI volume start $V0 force
|
|
|
3604df |
EXPECT_WITHIN $CHILD_UP_TIMEOUT "3" ec_child_up_count $V0 0
|
|
|
3604df |
#Accessing file shouldn't heal the file
|
|
|
3604df |
EXPECT "abc" cat $M0/a
|
|
|
3604df |
-sleep 3
|
|
|
3604df |
EXPECT 2 get_pending_heal_count $V0 #One for each active brick
|
|
|
3604df |
TEST $CLI volume set $V0 disperse.background-heals 1
|
|
|
3604df |
EXPECT_WITHIN $CONFIG_UPDATE_TIMEOUT "1" mount_get_option_value $M0 $V0-disperse-0 background-heals
|
|
|
3604df |
diff --git a/tests/volume.rc b/tests/volume.rc
|
|
|
3604df |
index 989538d..b7fd20a 100644
|
|
|
3604df |
--- a/tests/volume.rc
|
|
|
3604df |
+++ b/tests/volume.rc
|
|
|
3604df |
@@ -686,3 +686,8 @@ function get_hard_link_count {
|
|
|
3604df |
local path=$1;
|
|
|
3604df |
stat -c %h $path
|
|
|
3604df |
}
|
|
|
3604df |
+
|
|
|
3604df |
+function count_sh_entries()
|
|
|
3604df |
+{
|
|
|
3604df |
+ ls $1/.glusterfs/indices/xattrop | grep -v "xattrop-" | wc -l
|
|
|
3604df |
+}
|
|
|
3604df |
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
|
|
|
3604df |
index 26f4a80..f54a1c4 100644
|
|
|
3604df |
--- a/xlators/cluster/afr/src/afr-self-heald.c
|
|
|
3604df |
+++ b/xlators/cluster/afr/src/afr-self-heald.c
|
|
|
3604df |
@@ -153,22 +153,11 @@ unlock:
|
|
|
3604df |
inode_t *
|
|
|
3604df |
afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)
|
|
|
3604df |
{
|
|
|
3604df |
- int ret = 0;
|
|
|
3604df |
- uint64_t val = IA_INVAL;
|
|
|
3604df |
- loc_t loc = {0, };
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+ uint64_t val = IA_INVAL;
|
|
|
3604df |
dict_t *xdata = NULL;
|
|
|
3604df |
dict_t *rsp_dict = NULL;
|
|
|
3604df |
- inode_t *inode = NULL;
|
|
|
3604df |
- struct iatt iatt = {0, };
|
|
|
3604df |
-
|
|
|
3604df |
- inode = inode_find (this->itable, gfid);
|
|
|
3604df |
- if (inode)
|
|
|
3604df |
- goto out;
|
|
|
3604df |
-
|
|
|
3604df |
- loc.inode = inode_new (this->itable);
|
|
|
3604df |
- if (!loc.inode)
|
|
|
3604df |
- goto out;
|
|
|
3604df |
- gf_uuid_copy (loc.gfid, gfid);
|
|
|
3604df |
+ inode_t *inode = NULL;
|
|
|
3604df |
|
|
|
3604df |
xdata = dict_new ();
|
|
|
3604df |
if (!xdata)
|
|
|
3604df |
@@ -178,7 +167,8 @@ afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)
|
|
|
3604df |
if (ret)
|
|
|
3604df |
goto out;
|
|
|
3604df |
|
|
|
3604df |
- ret = syncop_lookup (subvol, &loc, &iatt, NULL, xdata, &rsp_dict);
|
|
|
3604df |
+ ret = syncop_inode_find (this, subvol, gfid, &inode,
|
|
|
3604df |
+ xdata, &rsp_dict);
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
goto out;
|
|
|
3604df |
|
|
|
3604df |
@@ -188,15 +178,16 @@ afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)
|
|
|
3604df |
if (ret)
|
|
|
3604df |
goto out;
|
|
|
3604df |
}
|
|
|
3604df |
-
|
|
|
3604df |
- inode = inode_link (loc.inode, NULL, NULL, &iatt);
|
|
|
3604df |
ret = inode_ctx_set2 (inode, subvol, 0, &val;;
|
|
|
3604df |
out:
|
|
|
3604df |
+ if (ret && inode) {
|
|
|
3604df |
+ inode_unref (inode);
|
|
|
3604df |
+ inode = NULL;
|
|
|
3604df |
+ }
|
|
|
3604df |
if (xdata)
|
|
|
3604df |
dict_unref (xdata);
|
|
|
3604df |
if (rsp_dict)
|
|
|
3604df |
dict_unref (rsp_dict);
|
|
|
3604df |
- loc_wipe (&loc;;
|
|
|
3604df |
return inode;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
diff --git a/xlators/cluster/ec/src/ec-common.h b/xlators/cluster/ec/src/ec-common.h
|
|
|
3604df |
index d720d24..5851b5d 100644
|
|
|
3604df |
--- a/xlators/cluster/ec/src/ec-common.h
|
|
|
3604df |
+++ b/xlators/cluster/ec/src/ec-common.h
|
|
|
3604df |
@@ -118,4 +118,7 @@ void ec_manager(ec_fop_data_t * fop, int32_t error);
|
|
|
3604df |
gf_boolean_t ec_is_recoverable_error (int32_t op_errno);
|
|
|
3604df |
void ec_handle_healers_done (ec_fop_data_t *fop);
|
|
|
3604df |
|
|
|
3604df |
+int32_t
|
|
|
3604df |
+ec_get_heal_info (xlator_t *this, loc_t *loc, dict_t **dict);
|
|
|
3604df |
+
|
|
|
3604df |
#endif /* __EC_COMMON_H__ */
|
|
|
3604df |
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
|
|
|
3604df |
index 94ff475..39cce19 100644
|
|
|
3604df |
--- a/xlators/cluster/ec/src/ec-heal.c
|
|
|
3604df |
+++ b/xlators/cluster/ec/src/ec-heal.c
|
|
|
3604df |
@@ -1489,22 +1489,29 @@ unlock:
|
|
|
3604df |
return ret;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
-/*Data heal*/
|
|
|
3604df |
+/*Find direction for data heal and heal info*/
|
|
|
3604df |
int
|
|
|
3604df |
ec_heal_data_find_direction (ec_t *ec, default_args_cbk_t *replies,
|
|
|
3604df |
- uint64_t *versions, uint64_t *dirty,
|
|
|
3604df |
- uint64_t *size, unsigned char *sources,
|
|
|
3604df |
- unsigned char *healed_sinks)
|
|
|
3604df |
+ uint64_t *data_versions, uint64_t *meta_versions,
|
|
|
3604df |
+ uint64_t *dirty, uint64_t *size, unsigned char *sources,
|
|
|
3604df |
+ unsigned char *healed_sinks, int which)
|
|
|
3604df |
{
|
|
|
3604df |
uint64_t xattr[EC_VERSION_SIZE] = {0};
|
|
|
3604df |
- char version_size[64] = {0};
|
|
|
3604df |
+ char version_size[128] = {0};
|
|
|
3604df |
dict_t *version_size_db = NULL;
|
|
|
3604df |
+ uint64_t *m_versions = NULL;
|
|
|
3604df |
unsigned char *same = NULL;
|
|
|
3604df |
int max_same_count = 0;
|
|
|
3604df |
int source = 0;
|
|
|
3604df |
int i = 0;
|
|
|
3604df |
int ret = 0;
|
|
|
3604df |
+ dict_t *dict = NULL;
|
|
|
3604df |
|
|
|
3604df |
+ if (!meta_versions) {
|
|
|
3604df |
+ m_versions = alloca0 (ec->nodes * sizeof (*m_versions));
|
|
|
3604df |
+ } else {
|
|
|
3604df |
+ m_versions = meta_versions;
|
|
|
3604df |
+ }
|
|
|
3604df |
version_size_db = dict_new ();
|
|
|
3604df |
if (!version_size_db) {
|
|
|
3604df |
ret = -ENOMEM;
|
|
|
3604df |
@@ -1516,23 +1523,31 @@ ec_heal_data_find_direction (ec_t *ec, default_args_cbk_t *replies,
|
|
|
3604df |
continue;
|
|
|
3604df |
if (replies[i].op_ret < 0)
|
|
|
3604df |
continue;
|
|
|
3604df |
- ret = ec_dict_del_array (replies[i].xattr, EC_XATTR_VERSION,
|
|
|
3604df |
+ dict = (which == EC_COMBINE_XDATA) ? replies[i].xdata :
|
|
|
3604df |
+ replies[i].xattr;
|
|
|
3604df |
+
|
|
|
3604df |
+ ret = ec_dict_del_array (dict, EC_XATTR_VERSION,
|
|
|
3604df |
xattr, EC_VERSION_SIZE);
|
|
|
3604df |
if (ret == 0) {
|
|
|
3604df |
- versions[i] = xattr[EC_DATA_TXN];
|
|
|
3604df |
+ data_versions[i] = xattr[EC_DATA_TXN];
|
|
|
3604df |
+ if (meta_versions) {
|
|
|
3604df |
+ m_versions[i] = xattr[EC_METADATA_TXN];
|
|
|
3604df |
+ }
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
memset (xattr, 0, sizeof (xattr));
|
|
|
3604df |
- ret = ec_dict_del_array (replies[i].xattr, EC_XATTR_DIRTY,
|
|
|
3604df |
+ ret = ec_dict_del_array (dict, EC_XATTR_DIRTY,
|
|
|
3604df |
xattr, EC_VERSION_SIZE);
|
|
|
3604df |
if (ret == 0) {
|
|
|
3604df |
dirty[i] = xattr[EC_DATA_TXN];
|
|
|
3604df |
}
|
|
|
3604df |
- ret = ec_dict_del_number (replies[i].xattr, EC_XATTR_SIZE,
|
|
|
3604df |
+ ret = ec_dict_del_number (dict, EC_XATTR_SIZE,
|
|
|
3604df |
&size[i]);
|
|
|
3604df |
- /*Build a db of same version, size*/
|
|
|
3604df |
+ /*Build a db of same metadata and data version and size*/
|
|
|
3604df |
snprintf (version_size, sizeof (version_size),
|
|
|
3604df |
- "%"PRIu64"-%"PRIu64, versions[i], size[i]);
|
|
|
3604df |
+ "%"PRIu64"-%"PRIu64"-%"PRIu64, data_versions[i],
|
|
|
3604df |
+ m_versions[i], size[i]);
|
|
|
3604df |
+
|
|
|
3604df |
ret = dict_get_bin (version_size_db, version_size,
|
|
|
3604df |
(void **)&same);
|
|
|
3604df |
if (ret < 0) {
|
|
|
3604df |
@@ -1562,7 +1577,11 @@ ec_heal_data_find_direction (ec_t *ec, default_args_cbk_t *replies,
|
|
|
3604df |
goto out;
|
|
|
3604df |
} else {
|
|
|
3604df |
snprintf (version_size, sizeof (version_size),
|
|
|
3604df |
- "%"PRIu64"-%"PRIu64, versions[source], size[source]);
|
|
|
3604df |
+ "%"PRIu64"-%"PRIu64"-%"PRIu64,
|
|
|
3604df |
+ data_versions[source],
|
|
|
3604df |
+ m_versions[source],
|
|
|
3604df |
+ size[source]);
|
|
|
3604df |
+
|
|
|
3604df |
ret = dict_get_bin (version_size_db, version_size,
|
|
|
3604df |
(void **)&same);
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
@@ -1621,8 +1640,9 @@ __ec_heal_data_prepare (call_frame_t *frame, ec_t *ec, fd_t *fd,
|
|
|
3604df |
goto out;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
- source = ec_heal_data_find_direction (ec, replies, versions, dirty,
|
|
|
3604df |
- size, sources, healed_sinks);
|
|
|
3604df |
+ source = ec_heal_data_find_direction (ec, replies, versions, NULL,
|
|
|
3604df |
+ dirty, size, sources,
|
|
|
3604df |
+ healed_sinks, EC_COMBINE_DICT);
|
|
|
3604df |
ret = source;
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
goto out;
|
|
|
3604df |
@@ -2602,7 +2622,7 @@ out:
|
|
|
3604df |
int32_t
|
|
|
3604df |
ec_launch_replace_heal (ec_t *ec)
|
|
|
3604df |
{
|
|
|
3604df |
- int ret = -1;
|
|
|
3604df |
+ int ret = -1;
|
|
|
3604df |
|
|
|
3604df |
if (!ec)
|
|
|
3604df |
return ret;
|
|
|
3604df |
@@ -2614,3 +2634,207 @@ ec_launch_replace_heal (ec_t *ec)
|
|
|
3604df |
}
|
|
|
3604df |
return ret;
|
|
|
3604df |
}
|
|
|
3604df |
+
|
|
|
3604df |
+int32_t
|
|
|
3604df |
+ec_set_heal_info(dict_t **dict_rsp, char *status)
|
|
|
3604df |
+{
|
|
|
3604df |
+ dict_t *dict = NULL;
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+
|
|
|
3604df |
+ dict = dict_new ();
|
|
|
3604df |
+ if (!dict) {
|
|
|
3604df |
+ ret = -ENOMEM;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ ret = dict_set_str (dict, "heal-info", status);
|
|
|
3604df |
+ if (ret) {
|
|
|
3604df |
+ gf_msg (THIS->name, GF_LOG_WARNING, -ret,
|
|
|
3604df |
+ EC_MSG_HEAL_FAIL,
|
|
|
3604df |
+ "Failed to set heal-info key to "
|
|
|
3604df |
+ "%s", status);
|
|
|
3604df |
+ dict_unref(dict);
|
|
|
3604df |
+ dict = NULL;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ *dict_rsp = dict;
|
|
|
3604df |
+out:
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+int32_t
|
|
|
3604df |
+ec_need_heal (ec_t *ec, default_args_cbk_t *replies, gf_boolean_t *need_heal)
|
|
|
3604df |
+{
|
|
|
3604df |
+ uint64_t *dirty = NULL;
|
|
|
3604df |
+ unsigned char *sources = NULL;
|
|
|
3604df |
+ unsigned char *healed_sinks = NULL;
|
|
|
3604df |
+ uint64_t *data_versions = NULL;
|
|
|
3604df |
+ uint64_t *meta_versions = NULL;
|
|
|
3604df |
+ uint64_t *size = NULL;
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+ int source_count = 0;
|
|
|
3604df |
+
|
|
|
3604df |
+ sources = alloca0(ec->nodes);
|
|
|
3604df |
+ healed_sinks = alloca0(ec->nodes);
|
|
|
3604df |
+ dirty = alloca0 (ec->nodes * sizeof (*dirty));
|
|
|
3604df |
+ size = alloca0 (ec->nodes * sizeof (*size));
|
|
|
3604df |
+ data_versions = alloca0 (ec->nodes * sizeof (*data_versions));
|
|
|
3604df |
+ meta_versions = alloca0 (ec->nodes * sizeof (*meta_versions));
|
|
|
3604df |
+
|
|
|
3604df |
+ ret = ec_heal_data_find_direction (ec, replies, data_versions,
|
|
|
3604df |
+ meta_versions, dirty, size,
|
|
|
3604df |
+ sources, healed_sinks,
|
|
|
3604df |
+ EC_COMBINE_XDATA);
|
|
|
3604df |
+ if (ret < 0 && ret != -EIO) {
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ source_count = EC_COUNT (sources, ec->nodes);
|
|
|
3604df |
+ if (source_count != ec->nodes) {
|
|
|
3604df |
+ *need_heal = _gf_true;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ ret = source_count;
|
|
|
3604df |
+out:
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+int32_t
|
|
|
3604df |
+ec_heal_inspect (call_frame_t *frame, ec_t *ec,
|
|
|
3604df |
+ inode_t *inode, unsigned char *locked_on,
|
|
|
3604df |
+ gf_boolean_t *need_heal)
|
|
|
3604df |
+{
|
|
|
3604df |
+ loc_t loc = {0};
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+ dict_t *xdata = NULL;
|
|
|
3604df |
+ uint64_t zero_array[2] = {0};
|
|
|
3604df |
+ uint64_t zero_value = 0;
|
|
|
3604df |
+ unsigned char *output = NULL;
|
|
|
3604df |
+ default_args_cbk_t *replies = NULL;
|
|
|
3604df |
+
|
|
|
3604df |
+ EC_REPLIES_ALLOC (replies, ec->nodes);
|
|
|
3604df |
+ output = alloca0 (ec->nodes);
|
|
|
3604df |
+
|
|
|
3604df |
+ loc.inode = inode_ref (inode);
|
|
|
3604df |
+ gf_uuid_copy (loc.gfid, inode->gfid);
|
|
|
3604df |
+
|
|
|
3604df |
+ xdata = dict_new ();
|
|
|
3604df |
+ if (!xdata ||
|
|
|
3604df |
+ dict_set_static_bin (xdata, EC_XATTR_VERSION, zero_array,
|
|
|
3604df |
+ sizeof (zero_array)) ||
|
|
|
3604df |
+ dict_set_static_bin (xdata, EC_XATTR_DIRTY, zero_array,
|
|
|
3604df |
+ sizeof (zero_array)) ||
|
|
|
3604df |
+ dict_set_static_bin (xdata, EC_XATTR_SIZE, &zero_value,
|
|
|
3604df |
+ sizeof (zero_value))) {
|
|
|
3604df |
+ ret = -ENOMEM;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ ret = cluster_lookup (ec->xl_list, locked_on, ec->nodes, replies,
|
|
|
3604df |
+ output, frame, ec->xl, &loc, xdata);
|
|
|
3604df |
+ if (ret != ec->nodes) {
|
|
|
3604df |
+ ret = ec->nodes;
|
|
|
3604df |
+ *need_heal = _gf_true;
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ ret = ec_need_heal (ec, replies, need_heal);
|
|
|
3604df |
+
|
|
|
3604df |
+out:
|
|
|
3604df |
+ cluster_replies_wipe (replies, ec->nodes);
|
|
|
3604df |
+ loc_wipe (&loc;;
|
|
|
3604df |
+ if (xdata) {
|
|
|
3604df |
+ dict_unref(xdata);
|
|
|
3604df |
+ }
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+int32_t
|
|
|
3604df |
+ec_heal_locked_inspect (call_frame_t *frame, ec_t *ec, inode_t *inode,
|
|
|
3604df |
+ gf_boolean_t *need_heal)
|
|
|
3604df |
+{
|
|
|
3604df |
+ unsigned char *locked_on = NULL;
|
|
|
3604df |
+ unsigned char *up_subvols = NULL;
|
|
|
3604df |
+ unsigned char *output = NULL;
|
|
|
3604df |
+ default_args_cbk_t *replies = NULL;
|
|
|
3604df |
+ int ret = 0;
|
|
|
3604df |
+
|
|
|
3604df |
+ EC_REPLIES_ALLOC (replies, ec->nodes);
|
|
|
3604df |
+ locked_on = alloca0(ec->nodes);
|
|
|
3604df |
+ output = alloca0(ec->nodes);
|
|
|
3604df |
+ up_subvols = alloca0(ec->nodes);
|
|
|
3604df |
+ ec_mask_to_char_array (ec->xl_up, up_subvols, ec->nodes);
|
|
|
3604df |
+
|
|
|
3604df |
+ ret = cluster_inodelk (ec->xl_list, up_subvols, ec->nodes,
|
|
|
3604df |
+ replies, locked_on, frame, ec->xl,
|
|
|
3604df |
+ ec->xl->name, inode, 0, 0);
|
|
|
3604df |
+ if (ret != ec->nodes) {
|
|
|
3604df |
+ *need_heal = _gf_true;
|
|
|
3604df |
+ goto unlock;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ ret = ec_heal_inspect (frame, ec, inode,
|
|
|
3604df |
+ locked_on, need_heal);
|
|
|
3604df |
+unlock:
|
|
|
3604df |
+ cluster_uninodelk (ec->xl_list, locked_on, ec->nodes,
|
|
|
3604df |
+ replies, output, frame, ec->xl,
|
|
|
3604df |
+ ec->xl->name, inode, 0, 0);
|
|
|
3604df |
+ cluster_replies_wipe (replies, ec->nodes);
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
+
|
|
|
3604df |
+int32_t
|
|
|
3604df |
+ec_get_heal_info (xlator_t *this, loc_t *entry_loc, dict_t **dict_rsp)
|
|
|
3604df |
+{
|
|
|
3604df |
+ int ret = -ENOMEM;
|
|
|
3604df |
+ gf_boolean_t need_heal = _gf_false;
|
|
|
3604df |
+ call_frame_t *frame = NULL;
|
|
|
3604df |
+ ec_t *ec = NULL;
|
|
|
3604df |
+ unsigned char *up_subvols = NULL;
|
|
|
3604df |
+ loc_t loc = {0, };
|
|
|
3604df |
+
|
|
|
3604df |
+ VALIDATE_OR_GOTO(this, out);
|
|
|
3604df |
+ GF_VALIDATE_OR_GOTO(this->name, entry_loc, out);
|
|
|
3604df |
+
|
|
|
3604df |
+ ec = this->private;
|
|
|
3604df |
+ up_subvols = alloca0(ec->nodes);
|
|
|
3604df |
+ ec_mask_to_char_array (ec->xl_up, up_subvols, ec->nodes);
|
|
|
3604df |
+
|
|
|
3604df |
+ frame = create_frame (this, this->ctx->pool);
|
|
|
3604df |
+ if (!frame) {
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ ec_owner_set(frame, frame->root);
|
|
|
3604df |
+ frame->root->uid = 0;
|
|
|
3604df |
+ frame->root->gid = 0;
|
|
|
3604df |
+ frame->root->pid = GF_CLIENT_PID_SELF_HEALD;
|
|
|
3604df |
+
|
|
|
3604df |
+ if (loc_copy(&loc, entry_loc) != 0) {
|
|
|
3604df |
+ gf_msg (this->name, GF_LOG_ERROR,
|
|
|
3604df |
+ ENOMEM, EC_MSG_LOC_COPY_FAIL,
|
|
|
3604df |
+ "Failed to copy a location.");
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ if (!loc.inode) {
|
|
|
3604df |
+ ret = syncop_inode_find (this, this, loc.gfid,
|
|
|
3604df |
+ &loc.inode, NULL, NULL);
|
|
|
3604df |
+ if (ret < 0)
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+ }
|
|
|
3604df |
+
|
|
|
3604df |
+ ret = ec_heal_inspect (frame, ec, loc.inode, up_subvols,
|
|
|
3604df |
+ &need_heal);
|
|
|
3604df |
+ if (ret == ec->nodes) {
|
|
|
3604df |
+ goto set_heal;
|
|
|
3604df |
+ }
|
|
|
3604df |
+ need_heal = _gf_false;
|
|
|
3604df |
+ ret = ec_heal_locked_inspect (frame, ec, loc.inode,
|
|
|
3604df |
+ &need_heal);
|
|
|
3604df |
+ if (ret < 0)
|
|
|
3604df |
+ goto out;
|
|
|
3604df |
+set_heal:
|
|
|
3604df |
+ if (need_heal) {
|
|
|
3604df |
+ ret = ec_set_heal_info (dict_rsp, "heal");
|
|
|
3604df |
+ } else {
|
|
|
3604df |
+ ret = ec_set_heal_info (dict_rsp, "no-heal");
|
|
|
3604df |
+ }
|
|
|
3604df |
+out:
|
|
|
3604df |
+ if (frame) {
|
|
|
3604df |
+ STACK_DESTROY (frame->root);
|
|
|
3604df |
+ }
|
|
|
3604df |
+ loc_wipe (&loc;;
|
|
|
3604df |
+ return ret;
|
|
|
3604df |
+}
|
|
|
3604df |
diff --git a/xlators/cluster/ec/src/ec-heald.c b/xlators/cluster/ec/src/ec-heald.c
|
|
|
3604df |
index 0e80768..0f63ab1 100644
|
|
|
3604df |
--- a/xlators/cluster/ec/src/ec-heald.c
|
|
|
3604df |
+++ b/xlators/cluster/ec/src/ec-heald.c
|
|
|
3604df |
@@ -126,42 +126,6 @@ unlock:
|
|
|
3604df |
return ret;
|
|
|
3604df |
}
|
|
|
3604df |
|
|
|
3604df |
-
|
|
|
3604df |
-int
|
|
|
3604df |
-ec_shd_inode_find (xlator_t *this, xlator_t *subvol,
|
|
|
3604df |
- uuid_t gfid, inode_t **inode)
|
|
|
3604df |
-{
|
|
|
3604df |
- int ret = 0;
|
|
|
3604df |
- loc_t loc = {0, };
|
|
|
3604df |
- struct iatt iatt = {0, };
|
|
|
3604df |
- *inode = NULL;
|
|
|
3604df |
-
|
|
|
3604df |
- *inode = inode_find (this->itable, gfid);
|
|
|
3604df |
- if (*inode)
|
|
|
3604df |
- goto out;
|
|
|
3604df |
-
|
|
|
3604df |
- loc.inode = inode_new (this->itable);
|
|
|
3604df |
- if (!loc.inode) {
|
|
|
3604df |
- ret = -ENOMEM;
|
|
|
3604df |
- goto out;
|
|
|
3604df |
- }
|
|
|
3604df |
- gf_uuid_copy (loc.gfid, gfid);
|
|
|
3604df |
-
|
|
|
3604df |
- ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL);
|
|
|
3604df |
- if (ret < 0)
|
|
|
3604df |
- goto out;
|
|
|
3604df |
-
|
|
|
3604df |
- *inode = inode_link (loc.inode, NULL, NULL, &iatt);
|
|
|
3604df |
- if (!*inode) {
|
|
|
3604df |
- ret = -ENOMEM;
|
|
|
3604df |
- goto out;
|
|
|
3604df |
- }
|
|
|
3604df |
-out:
|
|
|
3604df |
- loc_wipe (&loc;;
|
|
|
3604df |
- return ret;
|
|
|
3604df |
-}
|
|
|
3604df |
-
|
|
|
3604df |
-
|
|
|
3604df |
int
|
|
|
3604df |
ec_shd_index_inode (xlator_t *this, xlator_t *subvol, inode_t **inode)
|
|
|
3604df |
{
|
|
|
3604df |
@@ -190,7 +154,8 @@ ec_shd_index_inode (xlator_t *this, xlator_t *subvol, inode_t **inode)
|
|
|
3604df |
gf_msg_debug (this->name, 0, "index-dir gfid for %s: %s",
|
|
|
3604df |
subvol->name, uuid_utoa (index_gfid));
|
|
|
3604df |
|
|
|
3604df |
- ret = ec_shd_inode_find (this, subvol, index_gfid, inode);
|
|
|
3604df |
+ ret = syncop_inode_find (this, subvol, index_gfid,
|
|
|
3604df |
+ inode, NULL, NULL);
|
|
|
3604df |
|
|
|
3604df |
out:
|
|
|
3604df |
loc_wipe (&rootloc);
|
|
|
3604df |
@@ -250,8 +215,8 @@ ec_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
goto out;
|
|
|
3604df |
|
|
|
3604df |
- ret = ec_shd_inode_find (healer->this, healer->this, loc.gfid,
|
|
|
3604df |
- &loc.inode);
|
|
|
3604df |
+ ret = syncop_inode_find (healer->this, healer->this, loc.gfid,
|
|
|
3604df |
+ &loc.inode, NULL, NULL);
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
goto out;
|
|
|
3604df |
|
|
|
3604df |
@@ -319,7 +284,8 @@ ec_shd_full_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
goto out;
|
|
|
3604df |
|
|
|
3604df |
- ret = ec_shd_inode_find (this, this, loc.gfid, &loc.inode);
|
|
|
3604df |
+ ret = syncop_inode_find (this, this, loc.gfid,
|
|
|
3604df |
+ &loc.inode, NULL, NULL);
|
|
|
3604df |
if (ret < 0)
|
|
|
3604df |
goto out;
|
|
|
3604df |
|
|
|
3604df |
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
|
|
|
3604df |
index 591ab25..7e295ca 100644
|
|
|
3604df |
--- a/xlators/cluster/ec/src/ec.c
|
|
|
3604df |
+++ b/xlators/cluster/ec/src/ec.c
|
|
|
3604df |
@@ -772,13 +772,11 @@ ec_handle_heal_commands (call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
3604df |
if (!name || strcmp (name, GF_HEAL_INFO))
|
|
|
3604df |
return -1;
|
|
|
3604df |
|
|
|
3604df |
- dict_rsp = dict_new ();
|
|
|
3604df |
- if (dict_rsp == NULL)
|
|
|
3604df |
- goto out;
|
|
|
3604df |
+ op_errno = -ec_get_heal_info (this, loc, &dict_rsp);
|
|
|
3604df |
+ if (op_errno <= 0) {
|
|
|
3604df |
+ op_errno = op_ret = 0;
|
|
|
3604df |
+ }
|
|
|
3604df |
|
|
|
3604df |
- if (dict_set_str (dict_rsp, "heal-info", "heal") == 0)
|
|
|
3604df |
- op_ret = 0;
|
|
|
3604df |
-out:
|
|
|
3604df |
STACK_UNWIND_STRICT (getxattr, frame, op_ret, op_errno, dict_rsp, NULL);
|
|
|
3604df |
if (dict_rsp)
|
|
|
3604df |
dict_unref (dict_rsp);
|
|
|
3604df |
--
|
|
|
3604df |
1.7.1
|
|
|
3604df |
|