diff options
Diffstat (limited to 'xlators/cluster')
-rw-r--r-- | xlators/cluster/dht/src/dht-rebalance.c | 130 |
1 files changed, 128 insertions, 2 deletions
diff --git a/xlators/cluster/dht/src/dht-rebalance.c b/xlators/cluster/dht/src/dht-rebalance.c index 7dc89d8a069..a6c14b085fa 100644 --- a/xlators/cluster/dht/src/dht-rebalance.c +++ b/xlators/cluster/dht/src/dht-rebalance.c @@ -2562,6 +2562,118 @@ gf_defrag_settle_hash (xlator_t *this, gf_defrag_info_t *defrag, return 0; } + + +/* Function for doing a named lookup on file inodes during an attach tier + * So that a hardlink lookup heal i.e gfid to parent gfid lookup heal + * happens on pre-existing data. This is required so that the ctr database has + * hardlinks of all the exisitng file in the volume. CTR xlator on the + * brick/server side does db update/insert of the hardlink on a namelookup. + * Currently the namedlookup is done synchronous to the fixlayout that is + * triggered by attach tier. This is not performant, adding more time to + * fixlayout. The performant approach is record the hardlinks on a compressed + * datastore and then do the namelookup asynchronously later, giving the ctr db + * eventual consistency + * */ +int +gf_fix_layout_tier_attach_lookup (xlator_t *this, + loc_t *parent_loc, + gf_dirent_t *file_dentry) +{ + int ret = -1; + dict_t *lookup_xdata = NULL; + dht_conf_t *conf = NULL; + loc_t file_loc = {0,}; + struct iatt iatt = {0,}; + + GF_VALIDATE_OR_GOTO ("tier", this, out); + + GF_VALIDATE_OR_GOTO (this->name, parent_loc, out); + + GF_VALIDATE_OR_GOTO (this->name, file_dentry, out); + + GF_VALIDATE_OR_GOTO (this->name, this->private, out); + + if (!parent_loc->inode) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "%s/%s parent is NULL", parent_loc->path, + file_dentry->d_name); + goto out; + } + + + conf = this->private; + + loc_wipe (&file_loc); + + if (gf_uuid_is_null (file_dentry->d_stat.ia_gfid)) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "%s/%s gfid not present", parent_loc->path, + file_dentry->d_name); + goto out; + } + + gf_uuid_copy (file_loc.gfid, file_dentry->d_stat.ia_gfid); + + if (gf_uuid_is_null (parent_loc->gfid)) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "%s/%s" + " gfid not present", parent_loc->path, + file_dentry->d_name); + goto out; + } + + gf_uuid_copy (file_loc.pargfid, parent_loc->gfid); + + + ret = dht_build_child_loc (this, &file_loc, parent_loc, + file_dentry->d_name); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "Child loc build failed"); + ret = -1; + goto out; + } + + lookup_xdata = dict_new (); + if (!lookup_xdata) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "Failed creating lookup dict for %s", + file_dentry->d_name); + goto out; + } + + ret = dict_set_int32 (lookup_xdata, CTR_ATTACH_TIER_LOOKUP, 1); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "Failed to set lookup flag"); + goto out; + } + + gf_uuid_copy (file_loc.parent->gfid, parent_loc->gfid); + + /* Sending lookup to cold tier only */ + ret = syncop_lookup (conf->subvolumes[0], &file_loc, &iatt, + NULL, lookup_xdata, NULL); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_LOG_TIER_ERROR, + "%s lookup failed", file_loc.path); + goto out; + } + + ret = 0; + +out: + + loc_wipe (&file_loc); + + if (lookup_xdata) + dict_unref (lookup_xdata); + + return ret; +} + + int gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, dict_t *fix_layout, dict_t *migrate_data) @@ -2577,6 +2689,8 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, struct iatt iatt = {0,}; inode_t *linked_inode = NULL, *inode = NULL; + + ret = syncop_lookup (this, loc, &iatt, NULL, NULL, NULL); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Lookup failed on %s", @@ -2638,10 +2752,22 @@ gf_defrag_fix_layout (xlator_t *this, gf_defrag_info_t *defrag, loc_t *loc, if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, "..")) continue; + if (!IA_ISDIR (entry->d_stat.ia_type)) { + + /* If its a fix layout during the attach + * tier operation do lookups on files + * on cold subvolume so that there is a + * CTR DB Lookup Heal triggered on existing + * data. + * */ + if (defrag->cmd == + GF_DEFRAG_CMD_START_TIER) { + gf_fix_layout_tier_attach_lookup + (this, loc, entry); + } - if (!IA_ISDIR (entry->d_stat.ia_type)) continue; - + } loc_wipe (&entry_loc); ret =dht_build_child_loc (this, &entry_loc, loc, |