diff options
| author | Ravishankar N <ravishankar@redhat.com> | 2017-08-18 18:05:54 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2017-08-31 09:40:58 +0000 | 
| commit | d594900dbca92c356152be65fce16f77c402117c (patch) | |
| tree | b180273f93d922dd8233e64e82cd7e0aa0b3ba22 /xlators/cluster | |
| parent | 24b95089a18a6a40e7703cb344e92025d67f3086 (diff) | |
afr: check validity of afr_reply
...in various self-heal code paths.
Originally found by Pranith in __afr_selfheal_name_impunge ()
Also change __afr_selfheal_assign_gfid() to send lookup only on those
bricks that don't have a gfid matching that of the source.
Change-Id: I70a2ccd750a2af92c5fc36e0eefb2b6125404b4a
BUG: 1482923
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://review.gluster.org/18065
Smoke: Gluster Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/cluster')
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 23 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 47 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-name.c | 43 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal.h | 2 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 3 | 
5 files changed, 71 insertions, 47 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index a255f9d14ad..c6a110b2288 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -1699,6 +1699,19 @@ afr_local_transaction_cleanup (afr_local_t *local, xlator_t *this)  } +void +afr_reply_wipe (struct afr_reply *reply) +{ +        if (reply->xdata) { +                dict_unref (reply->xdata); +                reply->xdata = NULL; +        } + +        if (reply->xattr) { +                dict_unref (reply->xattr); +                reply->xattr = NULL; +        } +}  void  afr_replies_wipe (struct afr_reply *replies, int count) @@ -1706,15 +1719,7 @@ afr_replies_wipe (struct afr_reply *replies, int count)          int i = 0;          for (i = 0; i < count; i++) { -                if (replies[i].xdata) { -                        dict_unref (replies[i].xdata); -                        replies[i].xdata = NULL; -                } - -                if (replies[i].xattr) { -                        dict_unref (replies[i].xattr); -                        replies[i].xattr = NULL; -                } +                afr_reply_wipe (&replies[i]);          }  } diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 9ecd63ce10c..998289711df 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -549,39 +549,43 @@ afr_selfheal_undo_pending (call_frame_t *frame, xlator_t *this, inode_t *inode,  	return 0;  } +void +afr_reply_copy (struct afr_reply *dst, struct afr_reply *src) +{ +	dict_t *xdata = NULL; + +        dst->valid = src->valid; +	dst->op_ret = src->op_ret; +	dst->op_errno = src->op_errno; +	dst->prestat = src->prestat; +	dst->poststat = src->poststat; +	dst->preparent = src->preparent; +	dst->postparent = src->postparent; +	dst->preparent2 = src->preparent2; +	dst->postparent2 = src->postparent2; +	if (src->xdata) +		xdata = dict_ref (src->xdata); +	else +		xdata = NULL; +	if (dst->xdata) +		dict_unref (dst->xdata); +	dst->xdata = xdata; +	memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH); +}  void  afr_replies_copy (struct afr_reply *dst, struct afr_reply *src, int count)  {  	int i = 0; -	dict_t *xdata = NULL;  	if (dst == src)  		return;  	for (i = 0; i < count; i++) { -		dst[i].valid = src[i].valid; -		dst[i].op_ret = src[i].op_ret; -		dst[i].op_errno = src[i].op_errno; -		dst[i].prestat = src[i].prestat; -		dst[i].poststat = src[i].poststat; -		dst[i].preparent = src[i].preparent; -		dst[i].postparent = src[i].postparent; -		dst[i].preparent2 = src[i].preparent2; -		dst[i].postparent2 = src[i].postparent2; -		if (src[i].xdata) -			xdata = dict_ref (src[i].xdata); -		else -			xdata = NULL; -		if (dst[i].xdata) -			dict_unref (dst[i].xdata); -		dst[i].xdata = xdata; -		memcpy (dst[i].checksum, src[i].checksum, -			MD5_DIGEST_LENGTH); +                afr_reply_copy (&dst[i], &src[i]);  	}  } -  int  afr_selfheal_fill_dirty (xlator_t *this, int *dirty, int subvol,  			 int idx, dict_t *xdata) @@ -650,6 +654,9 @@ afr_selfheal_extract_xattr (xlator_t *this, struct afr_reply *replies,  	priv = this->private;  	for (i = 0; i < priv->child_count; i++) { +                if (!replies[i].valid || replies[i].op_ret != 0) +                        continue; +  		if (!replies[i].xdata)  			continue; diff --git a/xlators/cluster/afr/src/afr-self-heal-name.c b/xlators/cluster/afr/src/afr-self-heal-name.c index 1d198a8883e..2aad4c75bee 100644 --- a/xlators/cluster/afr/src/afr-self-heal-name.c +++ b/xlators/cluster/afr/src/afr-self-heal-name.c @@ -24,13 +24,16 @@ __afr_selfheal_assign_gfid (xlator_t *this, inode_t *parent, uuid_t pargfid,  	int             ret          = 0;          int             up_count     = 0;          int             locked_count = 0; +        int             i            = 0;  	afr_private_t  *priv         = NULL;  	dict_t         *xdata        = NULL;  	loc_t           loc          = {0, };          call_frame_t   *new_frame    = NULL;          afr_local_t    *new_local    = NULL; +        unsigned char  *wind_on      = NULL;  	priv = this->private; +        wind_on = alloca0 (priv->child_count);          new_frame = afr_frame_create (this);          if (!new_frame) { @@ -76,20 +79,26 @@ __afr_selfheal_assign_gfid (xlator_t *this, inode_t *parent, uuid_t pargfid,                  }          } -        /* Clear out old replies here and wind lookup on all locked -         * subvolumes to achieve two things: -         *   a. gfid heal on those subvolumes that do not have gfid associated -         *      with the inode, and -         *   b. refresh replies, which can be consumed by -         *      __afr_selfheal_name_impunge(). +        /* gfid heal on those subvolumes that do not have gfid associated +         * with the inode and update those replies.           */ +        for (i = 0; i < priv->child_count; i++) { +                if (replies[i].valid && replies[i].op_ret == 0 && +                    !gf_uuid_is_null (replies[i].poststat.ia_gfid) && +                    !gf_uuid_compare (replies[i].poststat.ia_gfid, gfid)) +                        continue; +                wind_on[i] = 1; +        } -        AFR_ONLIST (locked_on, new_frame, afr_selfheal_discover_cbk, lookup, +        AFR_ONLIST (wind_on, new_frame, afr_selfheal_discover_cbk, lookup,                      &loc, xdata); -        afr_replies_wipe (replies, priv->child_count); - -        afr_replies_copy (replies, new_local->replies, priv->child_count); +        for (i = 0; i < priv->child_count; i++) { +                if (!wind_on[i]) +                        continue; +                afr_reply_wipe (&replies[i]); +                afr_reply_copy (&replies[i], &new_local->replies[i]); +        }  out:  	loc_wipe (&loc); @@ -119,7 +128,7 @@ __afr_selfheal_name_impunge (call_frame_t *frame, xlator_t *this,  	gf_uuid_copy (parent->gfid, pargfid);  	for (i = 0; i < priv->child_count; i++) { -		if (!replies[i].valid) +                if (!replies[i].valid || replies[i].op_ret != 0)  			continue;  		if (gf_uuid_compare (replies[i].poststat.ia_gfid, @@ -213,7 +222,7 @@ afr_selfheal_gfid_idx_get (xlator_t *this, struct afr_reply *replies,          priv = this->private;          for (i = 0; i < priv->child_count; i++) { -                if (!replies[i].valid) +                if (!replies[i].valid || replies[i].op_ret != 0)                          continue;                  if (!sources[i]) @@ -281,7 +290,7 @@ afr_selfheal_name_type_mismatch_check (xlator_t *this, struct afr_reply *replies          priv = this->private;          for (i = 0; i < priv->child_count; i++) { -                if (!replies[i].valid) +                if (!replies[i].valid || replies[i].op_ret != 0)                          continue;                  if (replies[i].poststat.ia_type == IA_INVAL) @@ -343,8 +352,8 @@ afr_selfheal_name_gfid_mismatch_check (xlator_t *this, struct afr_reply *replies          priv = this->private;  	for (i = 0; i < priv->child_count; i++) { -		if (!replies[i].valid) -			continue; +                if (!replies[i].valid || replies[i].op_ret != 0) +                        continue;  		if (gf_uuid_is_null (replies[i].poststat.ia_gfid))  			continue; @@ -496,7 +505,6 @@ int  __afr_selfheal_name_finalize_source (xlator_t *this, unsigned char *sources,  				     unsigned char *healed_sinks,  				     unsigned char *locked_on, -				     struct afr_reply *replies,                                       uint64_t *witness)  {  	int i = 0; @@ -565,8 +573,7 @@ __afr_selfheal_name_prepare (call_frame_t *frame, xlator_t *this, inode_t *paren  	source = __afr_selfheal_name_finalize_source (this, sources,                                                        healed_sinks, -						      locked_on, replies, -                                                      witness); +						      locked_on, witness);  	if (source < 0) {  		/* If source is < 0 (typically split-brain), we perform a  		   conservative merge of entries rather than erroring out */ diff --git a/xlators/cluster/afr/src/afr-self-heal.h b/xlators/cluster/afr/src/afr-self-heal.h index 82608d261d5..15b47f66b4c 100644 --- a/xlators/cluster/afr/src/afr-self-heal.h +++ b/xlators/cluster/afr/src/afr-self-heal.h @@ -215,6 +215,8 @@ afr_selfheal_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  			   int op_ret, int op_errno, inode_t *inode,  			   struct iatt *buf, dict_t *xdata,                             struct iatt *parbuf); +void +afr_reply_copy (struct afr_reply *dst, struct afr_reply *src);  void  afr_replies_copy (struct afr_reply *dst, struct afr_reply *src, int count); diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index cf736ed3d2e..c4ceb66914f 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -1159,6 +1159,9 @@ void  afr_remove_eager_lock_stub (afr_local_t *local);  void +afr_reply_wipe (struct afr_reply *reply); + +void  afr_replies_wipe (struct afr_reply *replies, int count);  gf_boolean_t  | 
