cb8e9e
From 212caab4f8db39845c4c391e97103be82c0e8d88 Mon Sep 17 00:00:00 2001
cb8e9e
From: Anuradha <atalur@redhat.com>
cb8e9e
Date: Tue, 16 Jun 2015 15:57:30 +0530
cb8e9e
Subject: [PATCH 169/190] cluster/afr : truncate all sinks files
cb8e9e
cb8e9e
        Backport of: http://review.gluster.org/11252/
cb8e9e
cb8e9e
Problem : During data self-heal of sparse files,
cb8e9e
sparseness of files is lost.
cb8e9e
cb8e9e
Cause : Earlier, only files with larger ia_size in sinks
cb8e9e
were being truncated to ia_size of source. This caused
cb8e9e
checksum mismatch of sparse blocks when ia_size of files
cb8e9e
in sinks were lesser than ia_size of source file.
cb8e9e
Leading to unnecessary healing of sparse blocks.
cb8e9e
As a result of which sparseness of files was lost.
cb8e9e
cb8e9e
Solution : truncate files in all the sinks irrespective of
cb8e9e
their size with respect to the source file. After this change,
cb8e9e
checksum won't mismatch for sparse blocks and heal won't
cb8e9e
be triggered. As a result, sparseness of the files will
cb8e9e
be preserved.
cb8e9e
cb8e9e
Other fixes in this patch :
cb8e9e
1) in afr_does_size_mismatch(), check for mismatch only
cb8e9e
in sources. Previously, the check was being done for all
cb8e9e
children in a replica.
cb8e9e
cb8e9e
2) in __afr_selfheal_data_checksums_match(), check checksum
cb8e9e
mismatch only for children with valid responses.
cb8e9e
cb8e9e
Upstream URLs:
cb8e9e
1) master : http://review.gluster.org/11252/
cb8e9e
2) 3.7    : http://review.gluster.org/11423/
cb8e9e
cb8e9e
Change-Id: Ifcdb1cdc9b16c4a8a7867aecf9fa94b66e5301c2
cb8e9e
BUG: 1223677
cb8e9e
Signed-off-by: Anuradha Talur <atalur@redhat.com>
cb8e9e
Reviewed-on: https://code.engineering.redhat.com/gerrit/51673
cb8e9e
Reviewed-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
cb8e9e
Tested-by: Ravishankar Narayanankutty <ravishankar@redhat.com>
cb8e9e
---
cb8e9e
 tests/bugs/glusterfs/bug-853690.t            |    2 +-
cb8e9e
 xlators/cluster/afr/src/afr-self-heal-data.c |   25 +++++++++++--------------
cb8e9e
 2 files changed, 12 insertions(+), 15 deletions(-)
cb8e9e
cb8e9e
diff --git a/tests/bugs/glusterfs/bug-853690.t b/tests/bugs/glusterfs/bug-853690.t
cb8e9e
index d81be01..59facfc 100755
cb8e9e
--- a/tests/bugs/glusterfs/bug-853690.t
cb8e9e
+++ b/tests/bugs/glusterfs/bug-853690.t
cb8e9e
@@ -65,7 +65,7 @@ TEST glusterfs --volfile=$B0/test.vol --attribute-timeout=0 --entry-timeout=0 $M
cb8e9e
 # Send a single write, guaranteed to be short on one replica, and attempt to
cb8e9e
 # read the data back. Failure to detect the short write results in different
cb8e9e
 # file sizes and immediate split-brain (EIO).
cb8e9e
-TEST dd if=/dev/zero of=$M0/file bs=128k count=1
cb8e9e
+TEST dd if=/dev/urandom of=$M0/file bs=128k count=1
cb8e9e
 TEST dd if=$M0/file of=/dev/null bs=128k count=1
cb8e9e
 ########
cb8e9e
 #
cb8e9e
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
cb8e9e
index 7567fe9..4ab6f00 100644
cb8e9e
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
cb8e9e
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
cb8e9e
@@ -102,10 +102,12 @@ __afr_selfheal_data_checksums_match (call_frame_t *frame, xlator_t *this,
cb8e9e
 	for (i = 0; i < priv->child_count; i++) {
cb8e9e
 		if (i == source)
cb8e9e
 			continue;
cb8e9e
-		if (memcmp (local->replies[source].checksum,
cb8e9e
-			    local->replies[i].checksum,
cb8e9e
-			    MD5_DIGEST_LENGTH))
cb8e9e
-			return _gf_false;
cb8e9e
+                if (local->replies[i].valid) {
cb8e9e
+                        if (memcmp (local->replies[source].checksum,
cb8e9e
+                                    local->replies[i].checksum,
cb8e9e
+                                    MD5_DIGEST_LENGTH))
cb8e9e
+                                return _gf_false;
cb8e9e
+                }
cb8e9e
 	}
cb8e9e
 
cb8e9e
 	return _gf_true;
cb8e9e
@@ -383,23 +385,16 @@ out:
cb8e9e
 static int
cb8e9e
 __afr_selfheal_truncate_sinks (call_frame_t *frame, xlator_t *this,
cb8e9e
 			       fd_t *fd, unsigned char *healed_sinks,
cb8e9e
-			       struct afr_reply *replies, uint64_t size)
cb8e9e
+			       uint64_t size)
cb8e9e
 {
cb8e9e
 	afr_local_t *local = NULL;
cb8e9e
 	afr_private_t *priv = NULL;
cb8e9e
-	unsigned char *larger_sinks = 0;
cb8e9e
 	int i = 0;
cb8e9e
 
cb8e9e
 	local = frame->local;
cb8e9e
 	priv = this->private;
cb8e9e
 
cb8e9e
-	larger_sinks = alloca0 (priv->child_count);
cb8e9e
-	for (i = 0; i < priv->child_count; i++) {
cb8e9e
-		if (healed_sinks[i] && replies[i].poststat.ia_size > size)
cb8e9e
-			larger_sinks[i] = 1;
cb8e9e
-	}
cb8e9e
-
cb8e9e
-	AFR_ONLIST (larger_sinks, frame, attr_cbk, ftruncate, fd, size, NULL);
cb8e9e
+	AFR_ONLIST (healed_sinks, frame, attr_cbk, ftruncate, fd, size, NULL);
cb8e9e
 
cb8e9e
 	for (i = 0; i < priv->child_count; i++)
cb8e9e
 		if (healed_sinks[i] && local->replies[i].op_ret == -1)
cb8e9e
@@ -444,6 +439,9 @@ afr_does_size_mismatch (xlator_t *this, unsigned char *sources,
cb8e9e
                 if (replies[i].op_ret < 0)
cb8e9e
                         continue;
cb8e9e
 
cb8e9e
+                if (!sources[i])
cb8e9e
+                        continue;
cb8e9e
+
cb8e9e
                 if (!min)
cb8e9e
                         min = &replies[i].poststat;
cb8e9e
 
cb8e9e
@@ -691,7 +689,6 @@ __afr_selfheal_data (call_frame_t *frame, xlator_t *this, fd_t *fd,
cb8e9e
                 }
cb8e9e
 
cb8e9e
 		ret = __afr_selfheal_truncate_sinks (frame, this, fd, healed_sinks,
cb8e9e
-						     locked_replies,
cb8e9e
 						     locked_replies[source].poststat.ia_size);
cb8e9e
 		if (ret < 0)
cb8e9e
 			goto unlock;
cb8e9e
-- 
cb8e9e
1.7.1
cb8e9e