From 06d5085f8ab222c10df1980ca23919c0e34284a1 Mon Sep 17 00:00:00 2001 From: Anuradha Date: Tue, 16 Jun 2015 15:57:30 +0530 Subject: cluster/afr : truncate all sinks files Problem : During data self-heal of sparse files, sparseness of files is lost. Cause : Earlier, only files with larger ia_size in sinks were being truncated to ia_size of source. This caused checksum mismatch of sparse blocks when ia_size of files in sinks were lesser than ia_size of source file. Leading to unnecessary healing of sparse blocks. As a result of which sparseness of files was lost. Solution : truncate files in all the sinks irrespective of their size with respect to the source file. After this change, checksum won't mismatch for sparse blocks and heal won't be triggered. As a result, sparseness of the files will be preserved. Other fixes in this patch : 1) in afr_does_size_mismatch(), check for mismatch only in sources. Previously, the check was being done for all children in a replica. 2) in __afr_selfheal_data_checksums_match(), check checksum mismatch only for children with valid responses. Change-Id: Ifcdb1cdc9b16c4a8a7867aecf9fa94b66e5301c2 BUG: 1232238 Signed-off-by: Anuradha Talur Reviewed-on: http://review.gluster.org/11252 Reviewed-by: Prasanna Kumar Kalever Reviewed-by: Ravishankar N Reviewed-by: Pranith Kumar Karampuri Reviewed-by: Krutika Dhananjay Tested-by: NetBSD Build System --- xlators/cluster/afr/src/afr-self-heal-data.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'xlators') diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index f5664f08a25..6e112d82092 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -97,10 +97,12 @@ __afr_selfheal_data_checksums_match (call_frame_t *frame, xlator_t *this, for (i = 0; i < priv->child_count; i++) { if (i == source) continue; - if (memcmp (local->replies[source].checksum, - local->replies[i].checksum, - MD5_DIGEST_LENGTH)) - return _gf_false; + if (local->replies[i].valid) { + if (memcmp (local->replies[source].checksum, + local->replies[i].checksum, + MD5_DIGEST_LENGTH)) + return _gf_false; + } } return _gf_true; @@ -378,23 +380,16 @@ out: static int __afr_selfheal_truncate_sinks (call_frame_t *frame, xlator_t *this, fd_t *fd, unsigned char *healed_sinks, - struct afr_reply *replies, uint64_t size) + uint64_t size) { afr_local_t *local = NULL; afr_private_t *priv = NULL; - unsigned char *larger_sinks = 0; int i = 0; local = frame->local; priv = this->private; - larger_sinks = alloca0 (priv->child_count); - for (i = 0; i < priv->child_count; i++) { - if (healed_sinks[i] && replies[i].poststat.ia_size > size) - larger_sinks[i] = 1; - } - - AFR_ONLIST (larger_sinks, frame, attr_cbk, ftruncate, fd, size, NULL); + AFR_ONLIST (healed_sinks, frame, attr_cbk, ftruncate, fd, size, NULL); for (i = 0; i < priv->child_count; i++) if (healed_sinks[i] && local->replies[i].op_ret == -1) @@ -439,6 +434,9 @@ afr_does_size_mismatch (xlator_t *this, unsigned char *sources, if (replies[i].op_ret < 0) continue; + if (!sources[i]) + continue; + if (!min) min = &replies[i].poststat; @@ -686,7 +684,6 @@ __afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd, } ret = __afr_selfheal_truncate_sinks (frame, this, fd, healed_sinks, - locked_replies, locked_replies[source].poststat.ia_size); if (ret < 0) goto unlock; -- cgit