diff options
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-entry.c | 130 |
1 files changed, 72 insertions, 58 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 00af8e9f2e6..c9a27bf8e20 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -565,9 +565,17 @@ afr_selfheal_entry_dirent (call_frame_t *frame, xlator_t *this, source, sources, healed_sinks, locked_on, replies); - if ((ret == 0) && (priv->esh_granular) && (!full_crawl)) + if ((ret == 0) && (priv->esh_granular) && parent_idx_inode) { ret = afr_shd_index_purge (subvol, parent_idx_inode, name); + /* 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 + * and directories have their name indices present in + * entry-changes/. + */ + ret = 0; + } } unlock: @@ -584,6 +592,61 @@ unlock: } +static inode_t * +afr_shd_entry_changes_index_inode (xlator_t *this, xlator_t *subvol, + uuid_t pargfid) +{ + int ret = -1; + void *index_gfid = NULL; + loc_t rootloc = {0,}; + loc_t loc = {0,}; + dict_t *xattr = NULL; + inode_t *inode = NULL; + struct iatt iatt = {0,}; + + rootloc.inode = inode_ref (this->itable->root); + gf_uuid_copy (rootloc.gfid, rootloc.inode->gfid); + + ret = syncop_getxattr (subvol, &rootloc, &xattr, + GF_XATTROP_ENTRY_CHANGES_GFID, NULL, NULL); + if (ret || !xattr) { + errno = -ret; + goto out; + } + + ret = dict_get_ptr (xattr, GF_XATTROP_ENTRY_CHANGES_GFID, &index_gfid); + if (ret) { + errno = EINVAL; + goto out; + } + + loc.inode = inode_new (this->itable); + if (!loc.inode) { + errno = ENOMEM; + goto out; + } + + gf_uuid_copy (loc.pargfid, index_gfid); + loc.name = gf_strdup (uuid_utoa (pargfid)); + + ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL); + if (ret < 0) { + errno = -ret; + goto out; + } + + inode = inode_link (loc.inode, NULL, NULL, &iatt); + +out: + if (xattr) + dict_unref (xattr); + loc_wipe (&rootloc); + GF_FREE ((char *)loc.name); + loc_wipe (&loc); + + return inode; +} + static int afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this, fd_t *fd, int child) @@ -598,6 +661,7 @@ afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this, gf_boolean_t mismatch = _gf_false; afr_local_t *iter_local = NULL; afr_local_t *local = NULL; + loc_t loc = {0,}; priv = this->private; subvol = priv->children[child]; @@ -610,6 +674,9 @@ afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this, if (!iter_frame) return -ENOMEM; + loc.inode = afr_shd_entry_changes_index_inode (this, subvol, + fd->inode->gfid); + while ((ret = syncop_readdir (subvol, fd, 131072, offset, &entries, NULL, NULL))) { if (ret > 0) @@ -626,8 +693,8 @@ afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this, continue; ret = afr_selfheal_entry_dirent (iter_frame, this, fd, - entry->d_name, NULL, - NULL, + entry->d_name, + loc.inode, subvol, local->need_full_crawl); AFR_STACK_RESET (iter_frame); if (iter_frame->local == NULL) { @@ -649,6 +716,8 @@ afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this, break; } + loc_wipe (&loc); + AFR_STACK_DESTROY (iter_frame); if (mismatch == _gf_true) /* undo pending will be skipped */ @@ -656,61 +725,6 @@ afr_selfheal_entry_do_subvol (call_frame_t *frame, xlator_t *this, return ret; } -static inode_t * -afr_shd_entry_changes_index_inode (xlator_t *this, xlator_t *subvol, - uuid_t pargfid) -{ - int ret = -1; - void *index_gfid = NULL; - loc_t rootloc = {0,}; - loc_t loc = {0,}; - dict_t *xattr = NULL; - inode_t *inode = NULL; - struct iatt iatt = {0,}; - - rootloc.inode = inode_ref (this->itable->root); - gf_uuid_copy (rootloc.gfid, rootloc.inode->gfid); - - ret = syncop_getxattr (subvol, &rootloc, &xattr, - GF_XATTROP_ENTRY_CHANGES_GFID, NULL, NULL); - if (ret || !xattr) { - errno = -ret; - goto out; - } - - ret = dict_get_ptr (xattr, GF_XATTROP_ENTRY_CHANGES_GFID, &index_gfid); - if (ret) { - errno = EINVAL; - goto out; - } - - loc.inode = inode_new (this->itable); - if (!loc.inode) { - errno = ENOMEM; - goto out; - } - - gf_uuid_copy (loc.pargfid, index_gfid); - loc.name = gf_strdup (uuid_utoa (pargfid)); - - ret = syncop_lookup (subvol, &loc, &iatt, NULL, NULL, NULL); - if (ret < 0) { - errno = -ret; - goto out; - } - - inode = inode_link (loc.inode, NULL, NULL, &iatt); - -out: - if (xattr) - dict_unref (xattr); - loc_wipe (&rootloc); - GF_FREE ((char *)loc.name); - loc_wipe (&loc); - - return inode; -} - static int afr_selfheal_entry_granular_dirent (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) |