summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec
diff options
context:
space:
mode:
authorAshish Pandey <aspandey@redhat.com>2015-10-13 23:25:59 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-10-15 22:24:36 -0700
commit0f31ab1ba9bb7dbc47bfa68cbce81ec104d04ac4 (patch)
treefdd182a313cef55962c1096eaf85b3cebce78104 /xlators/cluster/ec
parent0c02fefaf7d6b54f4d9cae2b1ae1f2b657857625 (diff)
cluster/ec : Remove index entries if file/dir does not exist
Problem: During write and rebalance if a brick is down, index entries will be created. If the same file gets migrated to other subvol by rebalance process, these index entries will remain in index directory. During heal, these indices should be removed when we get ENOENT or ESTALE for a index. Solution: Capture correct errno and take appropriate action to purge these indices. Change-Id: I1aad8b99e4df2e139648e3bf971e4cb1c4b38699 Bug: 1271358 Signed-off-by: Ashish Pandey <aspandey@redhat.com> Reviewed-on: http://review.gluster.org/12353 Reviewed-by: Xavier Hernandez <xhernandez@datalab.es> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/cluster/ec')
-rw-r--r--xlators/cluster/ec/src/ec-heald.c78
1 files changed, 45 insertions, 33 deletions
diff --git a/xlators/cluster/ec/src/ec-heald.c b/xlators/cluster/ec/src/ec-heald.c
index 4498d2e8db2..20724c778bf 100644
--- a/xlators/cluster/ec/src/ec-heald.c
+++ b/xlators/cluster/ec/src/ec-heald.c
@@ -128,54 +128,63 @@ unlock:
}
-inode_t *
-ec_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid)
+int
+ec_shd_inode_find (xlator_t *this, xlator_t *subvol,
+ uuid_t gfid, inode_t **inode)
{
- inode_t *inode = NULL;
int ret = 0;
loc_t loc = {0, };
struct iatt iatt = {0, };
+ *inode = NULL;
- inode = inode_find (this->itable, gfid);
- if (inode) {
- inode_lookup (inode);
+ *inode = inode_find (this->itable, gfid);
+ if (*inode) {
+ inode_lookup (*inode);
goto out;
}
loc.inode = inode_new (this->itable);
- if (!loc.inode)
+ if (!loc.inode) {
+ ret = -ENOMEM;
goto out;
+ }
gf_uuid_copy (loc.gfid, gfid);
ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL);
if (ret < 0)
goto out;
- inode = inode_link (loc.inode, NULL, NULL, &iatt);
- if (inode)
- inode_lookup (inode);
+ *inode = inode_link (loc.inode, NULL, NULL, &iatt);
+ if (!*inode) {
+ ret = -ENOMEM;
+ goto out;
+ } else {
+ inode_lookup (*inode);
+ }
out:
loc_wipe (&loc);
- return inode;
+ return ret;
}
-inode_t*
-ec_shd_index_inode (xlator_t *this, xlator_t *subvol)
+int
+ec_shd_index_inode (xlator_t *this, xlator_t *subvol, inode_t **inode)
{
loc_t rootloc = {0, };
- inode_t *inode = NULL;
int ret = 0;
dict_t *xattr = NULL;
void *index_gfid = NULL;
+ *inode = NULL;
rootloc.inode = inode_ref (this->itable->root);
gf_uuid_copy (rootloc.gfid, rootloc.inode->gfid);
ret = syncop_getxattr (subvol, &rootloc, &xattr,
GF_XATTROP_INDEX_GFID, NULL, NULL);
- if (ret || !xattr) {
- errno = -ret;
+ if (ret < 0)
+ goto out;
+ if (!xattr) {
+ ret = -EINVAL;
goto out;
}
@@ -186,7 +195,7 @@ ec_shd_index_inode (xlator_t *this, xlator_t *subvol)
gf_msg_debug (this->name, 0, "index-dir gfid for %s: %s",
subvol->name, uuid_utoa (index_gfid));
- inode = ec_shd_inode_find (this, subvol, index_gfid);
+ ret = ec_shd_inode_find (this, subvol, index_gfid, inode);
out:
loc_wipe (&rootloc);
@@ -194,7 +203,7 @@ out:
if (xattr)
dict_unref (xattr);
- return inode;
+ return ret;
}
int
@@ -243,18 +252,22 @@ ec_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
/* If this fails with ENOENT/ESTALE index is stale */
ret = syncop_gfid_to_path (healer->this->itable, subvol, loc.gfid,
(char **)&loc.path);
- if (ret == -ENOENT || ret == -ESTALE) {
- ec_shd_index_purge (subvol, parent->inode, entry->d_name);
+ if (ret < 0)
goto out;
- }
- loc.inode = ec_shd_inode_find (healer->this, healer->this, loc.gfid);
- if (!loc.inode)
+ ret = ec_shd_inode_find (healer->this, healer->this, loc.gfid,
+ &loc.inode);
+ if (ret < 0)
goto out;
ec_shd_selfheal (healer, healer->subvol, &loc);
-
out:
+ if (ret == -ENOENT || ret == -ESTALE) {
+ gf_msg (healer->this->name, GF_LOG_DEBUG, 0,
+ EC_MSG_HEAL_FAIL, "Purging index for gfid %s:",
+ uuid_utoa(loc.gfid));
+ ec_shd_index_purge (subvol, parent->inode, entry->d_name);
+ }
if (loc.inode)
inode_forget (loc.inode, 0);
loc_wipe (&loc);
@@ -273,18 +286,19 @@ ec_shd_index_sweep (struct subvol_healer *healer)
ec = healer->this->private;
subvol = ec->xl_list[healer->subvol];
- loc.inode = ec_shd_index_inode (healer->this, subvol);
- if (!loc.inode) {
+ ret = ec_shd_index_inode (healer->this, subvol, &loc.inode);
+ if (ret < 0) {
gf_msg (healer->this->name, GF_LOG_WARNING, errno,
EC_MSG_INDEX_DIR_GET_FAIL,
"unable to get index-dir on %s", subvol->name);
- return -errno;
+ goto out;
}
ret = syncop_dir_scan (subvol, &loc, GF_CLIENT_PID_AFR_SELF_HEALD,
healer, ec_shd_index_heal);
-
- inode_forget (loc.inode, 0);
+out:
+ if (loc.inode)
+ inode_forget (loc.inode, 0);
loc_wipe (&loc);
return ret;
@@ -314,11 +328,9 @@ ec_shd_full_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent,
if (ret < 0)
goto out;
- loc.inode = ec_shd_inode_find (this, this, loc.gfid);
- if (!loc.inode) {
- ret = -EINVAL;
+ ret = ec_shd_inode_find (this, this, loc.gfid, &loc.inode);
+ if (ret < 0)
goto out;
- }
ec_shd_selfheal (healer, healer->subvol, &loc);