diff options
Diffstat (limited to 'xlators/cluster/afr')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 105 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-dir-read.c | 10 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 9 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 111 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 9 |
5 files changed, 162 insertions, 82 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 2ac0f078ffa..6c558916477 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -851,6 +851,8 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, afr_local_t *local = NULL; int call_child = (long) cookie; int call_count = 0; + GF_UNUSED int ret = 0; + int8_t need_heal = 1; local = frame->local; @@ -863,10 +865,19 @@ afr_inode_refresh_subvol_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->replies[call_child].xdata = dict_ref (xdata); } + if (xdata) { + ret = dict_get_int8 (xdata, "link-count", &need_heal); + local->replies[call_child].need_heal = need_heal; + } else { + local->replies[call_child].need_heal = need_heal; + } + call_count = afr_frame_return (frame); - if (call_count == 0) + if (call_count == 0) { + afr_set_need_heal (this, local); afr_inode_refresh_done (frame, this); + } return 0; } @@ -898,6 +909,7 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this) afr_private_t *priv = NULL; int call_count = 0; int i = 0; + int ret = 0; dict_t *xdata = NULL; priv = this->private; @@ -917,6 +929,12 @@ afr_inode_refresh_do (call_frame_t *frame, xlator_t *this) return 0; } + ret = dict_set_str (xdata, "link-count", GF_XATTROP_INDEX_COUNT); + if (ret) { + gf_msg_debug (this->name, -ret, + "Unable to set link-count in dict "); + } + local->call_count = AFR_COUNT (local->child_up, priv->child_count); call_count = local->call_count; @@ -1035,6 +1053,12 @@ afr_lookup_xattr_req_prepare (afr_local_t *local, xlator_t *this, loc->path, GLUSTERFS_PARENT_ENTRYLK); } + ret = dict_set_str (xattr_req, "link-count", GF_XATTROP_INDEX_COUNT); + if (ret) { + gf_msg_debug (this->name, -ret, + "Unable to set link-count in dict "); + } + ret = 0; out: return ret; @@ -1231,6 +1255,7 @@ afr_replies_wipe (struct afr_reply *replies, int count) replies[i].xattr = NULL; } } + memset (&replies->need_heal, 0, sizeof (replies->need_heal)); } void @@ -1683,6 +1708,7 @@ afr_lookup_done (call_frame_t *frame, xlator_t *this) afr_handle_quota_size (frame, this); unwind: + afr_set_need_heal (this, local); if (read_subvol == -1) { if (spb_choice >= 0) read_subvol = spb_choice; @@ -1818,6 +1844,8 @@ afr_lookup_sh_metadata_wrap (void *opaque) afr_private_t *priv = NULL; struct afr_reply *replies = NULL; int i= 0, first = -1; + int ret = -1; + dict_t *dict = NULL; local = frame->local; this = frame->this; @@ -1842,14 +1870,27 @@ afr_lookup_sh_metadata_wrap (void *opaque) inode_unref (inode); afr_local_replies_wipe (local, this->private); + + dict = dict_new (); + if (!dict) + goto out; + ret = dict_set_str (dict, "link-count", GF_XATTROP_INDEX_COUNT); + if (ret) { + gf_msg_debug (this->name, -ret, + "Unable to set link-count in dict "); + } + inode = afr_selfheal_unlocked_lookup_on (frame, local->loc.parent, local->loc.name, local->replies, - local->child_up, NULL); + local->child_up, dict); if (inode) inode_unref (inode); out: afr_lookup_done (frame, this); + if (dict) + dict_unref (dict); + return 0; } @@ -2027,6 +2068,8 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, afr_local_t * local = NULL; int call_count = -1; int child_index = -1; + GF_UNUSED int ret = 0; + int8_t need_heal = 1; child_index = (long) cookie; @@ -2043,6 +2086,12 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (xdata && dict_get (xdata, "gfid-changed")) local->cont.lookup.needs_fresh_lookup = _gf_true; + if (xdata) { + ret = dict_get_int8 (xdata, "link-count", &need_heal); + local->replies[child_index].need_heal = need_heal; + } else { + local->replies[child_index].need_heal = need_heal; + } if (op_ret != -1) { local->replies[child_index].poststat = *buf; local->replies[child_index].postparent = *postparent; @@ -2052,6 +2101,7 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, call_count = afr_frame_return (frame); if (call_count == 0) { + afr_set_need_heal (this, local); afr_lookup_entry_heal (frame, this); } @@ -2129,6 +2179,8 @@ afr_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, afr_local_t * local = NULL; int call_count = -1; int child_index = -1; + GF_UNUSED int ret = 0; + int8_t need_heal = 1; child_index = (long) cookie; @@ -2147,8 +2199,16 @@ afr_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (local->do_discovery && (op_ret == 0)) afr_attempt_local_discovery (this, child_index); + if (xdata) { + ret = dict_get_int8 (xdata, "link-count", &need_heal); + local->replies[child_index].need_heal = need_heal; + } else { + local->replies[child_index].need_heal = need_heal; + } + call_count = afr_frame_return (frame); if (call_count == 0) { + afr_set_need_heal (this, local); afr_discover_done (frame, this); } @@ -4872,3 +4932,44 @@ afr_get_child_index_from_name (xlator_t *this, char *name) out: return index; } + +void +afr_priv_need_heal_set (afr_private_t *priv, gf_boolean_t need_heal) +{ + LOCK (&priv->lock); + { + priv->need_heal = need_heal; + } + UNLOCK (&priv->lock); +} + +void +afr_set_need_heal (xlator_t *this, afr_local_t *local) +{ + int i = 0; + afr_private_t *priv = this->private; + gf_boolean_t need_heal = _gf_false; + + for (i = 0; i < priv->child_count; i++) { + if (local->replies[i].valid && local->replies[i].need_heal) { + need_heal = _gf_true; + break; + } + } + afr_priv_need_heal_set (priv, need_heal); + return; +} + +gf_boolean_t +afr_get_need_heal (xlator_t *this) +{ + afr_private_t *priv = this->private; + gf_boolean_t need_heal = _gf_true; + + LOCK (&priv->lock); + { + need_heal = priv->need_heal; + } + UNLOCK (&priv->lock); + return need_heal; +} diff --git a/xlators/cluster/afr/src/afr-dir-read.c b/xlators/cluster/afr/src/afr-dir-read.c index 11f583e42f1..559211eba17 100644 --- a/xlators/cluster/afr/src/afr-dir-read.c +++ b/xlators/cluster/afr/src/afr-dir-read.c @@ -174,8 +174,15 @@ afr_readdir_transform_entries (gf_dirent_t *subvol_entries, int subvol, gf_dirent_t *entry = NULL; gf_dirent_t *tmp = NULL; xlator_t *this = NULL; + afr_private_t *priv = NULL; + gf_boolean_t need_heal = _gf_false; + gf_boolean_t validate_subvol = _gf_false; this = THIS; + priv = this->private; + + need_heal = afr_get_need_heal (this); + validate_subvol = need_heal | priv->consistent_metadata; list_for_each_entry_safe (entry, tmp, &subvol_entries->list, list) { if (__is_root_gfid (fd->inode->gfid) && @@ -186,6 +193,9 @@ afr_readdir_transform_entries (gf_dirent_t *subvol_entries, int subvol, list_del_init (&entry->list); list_add_tail (&entry->list, &entries->list); + if (!validate_subvol) + continue; + if (entry->inode) { ret = afr_validate_read_subvol (entry->inode, this, subvol); diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index c9010dff308..63a52fcae84 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -658,6 +658,8 @@ afr_selfheal_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, { afr_local_t *local = NULL; int i = -1; + GF_UNUSED int ret = -1; + int8_t need_heal = 1; local = frame->local; i = (long) cookie; @@ -669,8 +671,13 @@ afr_selfheal_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->replies[i].poststat = *buf; if (parbuf) local->replies[i].postparent = *parbuf; - if (xdata) + if (xdata) { local->replies[i].xdata = dict_ref (xdata); + ret = dict_get_int8 (xdata, "link-count", &need_heal); + local->replies[i].need_heal = need_heal; + } else { + local->replies[i].need_heal = need_heal; + } syncbarrier_wake (&local->barrier); diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index 7bc39a1036b..61b8b01afb4 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -186,9 +186,8 @@ out: return inode; } - inode_t* -afr_shd_index_inode (xlator_t *this, xlator_t *subvol) +afr_shd_index_inode (xlator_t *this, xlator_t *subvol, char *vgfid) { loc_t rootloc = {0, }; inode_t *inode = NULL; @@ -200,18 +199,18 @@ afr_shd_index_inode (xlator_t *this, xlator_t *subvol) gf_uuid_copy (rootloc.gfid, rootloc.inode->gfid); ret = syncop_getxattr (subvol, &rootloc, &xattr, - GF_XATTROP_INDEX_GFID, NULL, NULL); + vgfid, NULL, NULL); if (ret || !xattr) { errno = -ret; goto out; } - ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID, &index_gfid); + ret = dict_get_ptr (xattr, vgfid, &index_gfid); if (ret) goto out; - gf_msg_debug (this->name, 0, "index-dir gfid for %s: %s", - subvol->name, uuid_utoa (index_gfid)); + gf_msg_debug (this->name, 0, "%s dir gfid for %s: %s", + vgfid, subvol->name, uuid_utoa (index_gfid)); inode = afr_shd_inode_find (this, subvol, index_gfid); @@ -429,7 +428,7 @@ afr_shd_index_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, } int -afr_shd_index_sweep (struct subvol_healer *healer) +afr_shd_index_sweep (struct subvol_healer *healer, char *vgfid) { loc_t loc = {0}; afr_private_t *priv = NULL; @@ -439,7 +438,7 @@ afr_shd_index_sweep (struct subvol_healer *healer) priv = healer->this->private; subvol = priv->children[healer->subvol]; - loc.inode = afr_shd_index_inode (healer->this, subvol); + loc.inode = afr_shd_index_inode (healer->this, subvol, vgfid); if (!loc.inode) { gf_msg (healer->this->name, GF_LOG_WARNING, 0, AFR_MSG_INDEX_DIR_GET_FAILED, @@ -460,6 +459,29 @@ afr_shd_index_sweep (struct subvol_healer *healer) } int +afr_shd_index_sweep_all (struct subvol_healer *healer) +{ + int ret = 0; + int count = 0; + + ret = afr_shd_index_sweep (healer, GF_XATTROP_INDEX_GFID); + if (ret < 0) + goto out; + count = ret; + + ret = afr_shd_index_sweep (healer, GF_XATTROP_DIRTY_GFID); + if (ret < 0) + goto out; + count += ret; + +out: + if (ret < 0) + return ret; + else + return count; +} + +int afr_shd_full_heal (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, void *data) { @@ -515,7 +537,7 @@ afr_shd_index_healer (void *data) afr_shd_sweep_prepare (healer); - ret = afr_shd_index_sweep (healer); + ret = afr_shd_index_sweep_all (healer); afr_shd_sweep_done (healer); /* @@ -847,73 +869,6 @@ out: } int -afr_shd_gather_entry (xlator_t *subvol, gf_dirent_t *entry, loc_t *parent, - void *data) -{ - dict_t *output = data; - xlator_t *this = NULL; - afr_private_t *priv = NULL; - char *path = NULL; - int ret = 0; - int child = 0; - uuid_t gfid = {0}; - - this = THIS; - priv = this->private; - - gf_msg_debug (this->name, 0, "got entry: %s", - entry->d_name); - - ret = gf_uuid_parse (entry->d_name, gfid); - if (ret) - return 0; - - for (child = 0; child < priv->child_count; child++) - if (priv->children[child] == subvol) - break; - - if (child == priv->child_count) - return 0; - - ret = syncop_gfid_to_path (this->itable, subvol, gfid, &path); - - if (ret == -ENOENT || ret == -ESTALE) { - afr_shd_index_purge (subvol, parent->inode, entry->d_name); - } else if (ret == 0) { - ret = afr_shd_dict_add_path (this, output, child, path, NULL); - } - - return 0; -} - -int -afr_shd_gather_index_entries (xlator_t *this, int child, dict_t *output) -{ - loc_t loc = {0}; - afr_private_t *priv = NULL; - xlator_t *subvol = NULL; - int ret = 0; - - priv = this->private; - subvol = priv->children[child]; - - loc.inode = afr_shd_index_inode (this, subvol); - if (!loc.inode) { - gf_msg (this->name, GF_LOG_WARNING, - 0, AFR_MSG_INDEX_DIR_GET_FAILED, - "unable to get index-dir on %s", subvol->name); - return -errno; - } - - ret = syncop_dir_scan (subvol, &loc, GF_CLIENT_PID_AFR_SELF_HEALD, - output, afr_shd_gather_entry); - inode_forget (loc.inode, 1); - loc_wipe (&loc); - return ret; -} - - -int afr_add_shd_event (circular_buffer_t *cb, void *data) { dict_t *output = NULL; @@ -1153,9 +1108,7 @@ afr_xl_op (xlator_t *this, dict_t *input, dict_t *output) } break; case GF_SHD_OP_INDEX_SUMMARY: - for (i = 0; i < priv->child_count; i++) - if (shd->index_healers[i].local) - afr_shd_gather_index_entries (this, i, output); + /* this case has been handled in glfs-heal.c */ break; case GF_SHD_OP_HEALED_FILES: case GF_SHD_OP_HEAL_FAILED_FILES: diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index c2fd1166d96..8e0a1f18816 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -132,6 +132,7 @@ typedef struct _afr_private { gf_boolean_t use_afr_in_pump; gf_boolean_t consistent_metadata; uint64_t spb_choice_timeout; + gf_boolean_t need_heal; } afr_private_t; @@ -273,6 +274,8 @@ struct afr_reply { /* For rchecksum */ uint8_t checksum[MD5_DIGEST_LENGTH]; gf_boolean_t buf_has_zeroes; + /* For lookup */ + int8_t need_heal; }; typedef enum { @@ -1088,4 +1091,10 @@ afr_spb_choice_timeout_cancel (xlator_t *this, inode_t *inode); int afr_set_split_brain_choice (int ret, call_frame_t *frame, void *opaque); + +gf_boolean_t +afr_get_need_heal (xlator_t *this); + +void +afr_set_need_heal (xlator_t *this, afr_local_t *local); #endif /* __AFR_H__ */ |