diff options
| -rw-r--r-- | tests/bugs/bug-1139230.t | 58 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-self-heal-common.c | 25 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 46 | 
3 files changed, 88 insertions, 41 deletions
diff --git a/tests/bugs/bug-1139230.t b/tests/bugs/bug-1139230.t new file mode 100644 index 00000000000..24317dd5f27 --- /dev/null +++ b/tests/bugs/bug-1139230.t @@ -0,0 +1,58 @@ +#!/bin/bash +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc +. $(dirname $0)/../afr.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +# Create a 1X2 replica +TEST $CLI volume create $V0 replica 2 $H0:$B0/${V0}-{0,1} +EXPECT 'Created' volinfo_field $V0 'Status'; + +# Volume start +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +# FUSE Mount +TEST glusterfs -s $H0 --volfile-id $V0 $M0 + +TEST mkdir -p $M0/one + +# Kill a brick +TEST kill_brick $V0 $H0 $B0/${V0}-1 + +TEST `echo "A long" > $M0/one/two` + +# Start force +TEST $CLI volume start $V0 force + +EXPECT_WITHIN $CHILD_UP_TIMEOUT "1" afr_child_up_status $V0 1 + +EXPECT_WITHIN $HEAL_TIMEOUT "Y" is_dir_heal_done $B0/${V0}-0 $B0/${V0}-1 one +EXPECT_WITHIN $HEAL_TIMEOUT "Y" is_file_heal_done $B0/${V0}-0 $B0/${V0}-1 one/two + +# Pending xattrs should be set for all the bricks once self-heal is done +# Check pending xattrs +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-0/one trusted.afr.$V0-client-0 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-0/one trusted.afr.$V0-client-1 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-1/one trusted.afr.$V0-client-0 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-1/one trusted.afr.$V0-client-1 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-0/one trusted.afr.dirty +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-1/one trusted.afr.dirty + +TEST `echo "time ago" > $M0/one/three` + +# Pending xattrs should be set for all the bricks once transaction is done +# Check pending xattrs +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-0/one/three trusted.afr.$V0-client-0 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-0/one/three trusted.afr.$V0-client-1 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-1/one/three trusted.afr.$V0-client-0 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-1/one/three trusted.afr.$V0-client-1 +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-0/one/three trusted.afr.dirty +EXPECT "0x000000000000000000000000" afr_get_changelog_xattr $B0/${V0}-1/one/three trusted.afr.dirty + +cleanup; diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index ab1552a0224..0158948d728 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -75,24 +75,19 @@ afr_selfheal_output_xattr (xlator_t *this, afr_transaction_type type,  	if (!xattr)  		return NULL; -	if (output_dirty[subvol]) { -		/* clear dirty */ -		raw = GF_CALLOC (sizeof(int), AFR_NUM_CHANGE_LOGS, gf_afr_mt_int32_t); -		if (!raw) -			goto err; - -		raw[idx] = hton32 (output_dirty[subvol]); -		ret = dict_set_bin (xattr, AFR_DIRTY, raw, -				    sizeof(int) * AFR_NUM_CHANGE_LOGS); -		if (ret) -			goto err; -	} +	/* clear dirty */ +	raw = GF_CALLOC (sizeof(int), AFR_NUM_CHANGE_LOGS, gf_afr_mt_int32_t); +	if (!raw) +		goto err; + +	raw[idx] = hton32 (output_dirty[subvol]); +	ret = dict_set_bin (xattr, AFR_DIRTY, raw, +			    sizeof(int) * AFR_NUM_CHANGE_LOGS); +	if (ret) +		goto err;  	/* clear/set pending */  	for (j = 0; j < priv->child_count; j++) { -		if (!output_matrix[subvol][j]) -			continue; -  		raw = GF_CALLOC (sizeof(int), AFR_NUM_CHANGE_LOGS,  				 gf_afr_mt_int32_t);  		if (!raw) diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index a2eab3494e3..d287e6ab66c 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -239,12 +239,8 @@ afr_set_pending_dict (afr_private_t *priv, dict_t *xattr, int **pending)  {          int i = 0;          int ret = 0; -	int pending_zero[AFR_NUM_CHANGE_LOGS] = {0, };          for (i = 0; i < priv->child_count; i++) { -		if (!memcmp (pending_zero, pending[i], sizeof (pending_zero))) -			/* don't set xattrs for non-pending servers */ -			continue;                  ret = dict_set_static_bin (xattr, priv->pending_key[i],  					   pending[i], @@ -605,33 +601,31 @@ afr_changelog_post_op_now (call_frame_t *frame, xlator_t *this)  		goto out;  	} -	if (need_undirty) { +	if (need_undirty)  		local->dirty[idx] = hton32(-1); +	else +		local->dirty[idx] = hton32(0); -		ret = dict_set_static_bin (xattr, AFR_DIRTY, local->dirty, -					   sizeof(int) * AFR_NUM_CHANGE_LOGS); -		if (ret) { -			local->op_ret = -1; -			local->op_errno = ENOMEM; -			afr_changelog_post_op_done (frame, this); -			goto out; -		} - +	ret = dict_set_static_bin (xattr, AFR_DIRTY, local->dirty, +				   sizeof(int) * AFR_NUM_CHANGE_LOGS); +	if (ret) { +		local->op_ret = -1; +		local->op_errno = ENOMEM; +		afr_changelog_post_op_done (frame, this); +		goto out;  	} -	if (!nothing_failed) { -		for (i = 0; i < priv->child_count; i++) { -			if (local->transaction.failed_subvols[i]) -				local->pending[i][idx] = hton32(1); -		} -		ret = afr_set_pending_dict (priv, xattr, local->pending); -		if (ret < 0) { -			local->op_ret = -1; -			local->op_errno = ENOMEM; -			afr_changelog_post_op_done (frame, this); -			goto out; -		} +	for (i = 0; i < priv->child_count; i++) { +		if (local->transaction.failed_subvols[i]) +			local->pending[i][idx] = hton32(1); +	} +	ret = afr_set_pending_dict (priv, xattr, local->pending); +	if (ret < 0) { +		local->op_ret = -1; +		local->op_errno = ENOMEM; +		afr_changelog_post_op_done (frame, this); +		goto out;  	}  	afr_changelog_do (frame, this, xattr, afr_changelog_post_op_done);  | 
