diff options
author | Ashish Pandey <aspandey@redhat.com> | 2015-10-13 23:25:59 +0530 |
---|---|---|
committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2015-10-18 23:22:47 -0700 |
commit | 9a14852e95880b08f9209384032e7e5413b493b2 (patch) | |
tree | f6a6e09abc3d28315439badc2e73b422954dffb0 /xlators | |
parent | 66992a18e06105dfe6f7a14b1f30227f985a94bc (diff) |
cluster/ec : Remove index entries if file/dir does not exist
Backport of http://review.gluster.org/12353
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: 1271967
Signed-off-by: Ashish Pandey <aspandey@redhat.com>
Reviewed-on: http://review.gluster.org/12361
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')
-rw-r--r-- | xlators/cluster/ec/src/ec-heald.c | 78 |
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); |