From ceac3b4172e7c689941ec3e734eca6c537e69368 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Mon, 27 Jun 2016 15:21:26 +0530 Subject: afr, index: Clean up stale directory and file indices in granular entry sh Specifically when a directory tree is removed (rm -rf) while a brick is down, both the directory index and the name indices of the files and subdirs under it will remain. Self-heal will need to pick up these and remove them. Towards this, afr sh will now also crawl indices/entry-changes and call an rmdir on the dir if the directory index is stale. On the brick side, rmdir fop has been implemented for index xl, which would delete the directory index and its contents if present in a synctask. Change-Id: I8b527331c2547e6c141db6c57c14055ad1198a7e BUG: 1331323 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/14832 Reviewed-by: Ravishankar N Smoke: Gluster Build System NetBSD-regression: NetBSD Build System Reviewed-by: Pranith Kumar Karampuri CentOS-regression: Gluster Build System --- xlators/cluster/afr/src/afr-self-heal-entry.c | 8 +++- xlators/cluster/afr/src/afr-self-heald.c | 55 ++++++++++++++++++++++----- xlators/cluster/afr/src/afr-self-heald.h | 3 +- 3 files changed, 53 insertions(+), 13 deletions(-) (limited to 'xlators/cluster/afr/src') diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index c9a27bf8e20..985cebe76b9 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -567,7 +567,7 @@ afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this, if ((ret == 0) && (priv->esh_granular) && parent_idx_inode) { ret = afr_shd_index_purge (subvol, parent_idx_inode, - name); + name, inode->ia_type); /* Why is ret force-set to 0? We do not care about * index purge failing for full heal as it is quite * possible during replace-brick that not all files @@ -748,7 +748,11 @@ afr_selfheal_entry_granular_dirent (xlator_t *subvol, gf_dirent_t *entry, ret = syncop_lookup (args->xl, &loc, &iatt, NULL, NULL, NULL); if ((ret == -ENOENT) || (ret == -ESTALE)) { - afr_shd_index_purge (subvol, parent->inode, entry->d_name); + /* The name indices under the pgfid index dir are guaranteed + * to be regular files. Hence the hardcoding. + */ + afr_shd_index_purge (subvol, parent->inode, entry->d_name, + IA_IFREG); ret = 0; goto out; } diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index b29a822568d..7ccac919769 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -153,10 +153,13 @@ unlock: inode_t * afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid) { - inode_t *inode = NULL; - int ret = 0; - loc_t loc = {0, }; - struct iatt iatt = {0, }; + int ret = 0; + uint64_t val = IA_INVAL; + loc_t loc = {0, }; + dict_t *xdata = NULL; + dict_t *rsp_dict = NULL; + inode_t *inode = NULL; + struct iatt iatt = {0, }; inode = inode_find (this->itable, gfid); if (inode) @@ -167,12 +170,32 @@ afr_shd_inode_find (xlator_t *this, xlator_t *subvol, uuid_t gfid) goto out; gf_uuid_copy (loc.gfid, gfid); - ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL); + xdata = dict_new (); + if (!xdata) + goto out; + + ret = dict_set_int8 (xdata, GF_INDEX_IA_TYPE_GET_REQ, 1); + if (ret) + goto out; + + ret = syncop_lookup (subvol, &loc, &iatt, NULL, xdata, &rsp_dict); if (ret < 0) goto out; + if (rsp_dict) { + ret = dict_get_uint64 (rsp_dict, GF_INDEX_IA_TYPE_GET_RSP, + &val); + if (ret) + goto out; + } + inode = inode_link (loc.inode, NULL, NULL, &iatt); + ret = inode_ctx_set2 (inode, subvol, 0, &val); out: + if (xdata) + dict_unref (xdata); + if (rsp_dict) + dict_unref (rsp_dict); loc_wipe (&loc); return inode; } @@ -215,15 +238,19 @@ out: } int -afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name) +afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name, + ia_type_t type) { - loc_t loc = {0, }; - int ret = 0; + int ret = 0; + loc_t loc = {0,}; loc.parent = inode_ref (inode); loc.name = name; - ret = syncop_unlink (subvol, &loc, NULL, NULL); + if (IA_ISDIR (type)) + ret = syncop_rmdir (subvol, &loc, 1, NULL, NULL); + else + ret = syncop_unlink (subvol, &loc, NULL, NULL); loc_wipe (&loc); return ret; @@ -395,6 +422,7 @@ afr_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, afr_private_t *priv = NULL; uuid_t gfid = {0}; int ret = 0; + uint64_t val = IA_INVAL; priv = healer->this->private; if (!priv->shd.enabled) @@ -407,10 +435,13 @@ afr_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, if (ret) return 0; + inode_ctx_get2 (parent->inode, subvol, NULL, &val); + ret = afr_shd_selfheal (healer, healer->subvol, gfid); if (ret == -ENOENT || ret == -ESTALE) - afr_shd_index_purge (subvol, parent->inode, entry->d_name); + afr_shd_index_purge (subvol, parent->inode, entry->d_name, val); + if (ret == 2) /* If bricks crashed in pre-op after creating indices/xattrop * link but before setting afr changelogs, we end up with stale @@ -489,6 +520,10 @@ afr_shd_index_sweep_all (struct subvol_healer *healer) goto out; count += ret; + ret = afr_shd_index_sweep (healer, GF_XATTROP_ENTRY_CHANGES_GFID); + if (ret < 0) + goto out; + count += ret; out: if (ret < 0) return ret; diff --git a/xlators/cluster/afr/src/afr-self-heald.h b/xlators/cluster/afr/src/afr-self-heald.h index f591515669c..c6ac5ebfd1b 100644 --- a/xlators/cluster/afr/src/afr-self-heald.h +++ b/xlators/cluster/afr/src/afr-self-heald.h @@ -75,5 +75,6 @@ afr_shd_gfid_to_path (xlator_t *this, xlator_t *subvol, uuid_t gfid, char **path_p); int -afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name); +afr_shd_index_purge (xlator_t *subvol, inode_t *inode, char *name, + ia_type_t type); #endif /* !_AFR_SELF_HEALD_H */ -- cgit