From ecc55d15a924e9d9b3f56dd822737f02d8a1f305 Mon Sep 17 00:00:00 2001
From: Bobi Jam <bobijam@whamcloud.com>
Date: Thu, 9 Aug 2018 14:35:49 +0800
Subject: [PATCH] LU-11226 flr: mirror resync regression

There is a glitch in the lfs mirror resync tool in commit
0e5c12ac29a9622e8ca05d5e39cd5e2a721ace93, resync write needs to
restricted to the component's extent.

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: Ifbd3f16b2f621407b31c7fe37ce9745de48fcc99
Reviewed-on: https://review.whamcloud.com/32968
Tested-by: Jenkins
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
---
 lustre/tests/sanity-flr.sh         | 22 ++++++++++++++++++----
 lustre/utils/liblustreapi_layout.c | 22 +++++++++++++++++-----
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/lustre/tests/sanity-flr.sh b/lustre/tests/sanity-flr.sh
index fd5f5c6..b732065 100644
--- a/lustre/tests/sanity-flr.sh
+++ b/lustre/tests/sanity-flr.sh
@@ -1477,9 +1477,11 @@ test_41() {
 	# write data in [0, 2M)
 	dd if=/dev/zero of=$tf bs=1M count=2 conv=notrunc ||
 		error "writing $tf failed"
-	dd if=/dev/zero of=$tf-1 bs=1M count=4 conv=notrunc ||
+	dd if=/dev/urandom of=$tf-1 bs=1M count=4 conv=notrunc ||
 		error "writing $tf-1 failed"
 
+	local sum0=$(cat $tf-1 | md5sum | cut -f 1 -d' ')
+
 	echo " **verify files be WRITE_PENDING"
 	verify_flr_state $tf "wp"
 	verify_flr_state $tf-1 "wp"
@@ -1494,6 +1496,14 @@ test_41() {
 	echo " **full resync"
 	$LFS mirror resync $tf $tf-1 || error "mirror resync $tf $tf-1 failed"
 
+	echo " **verify $tf-1 data consistency in all mirrors"
+	local sum
+	for i in 1 2 3; do
+		sum=$(mirror_io dump -i $i $tf-1 | md5sum | cut -f 1 -d' ')
+		[ "$sum" = "$sum0" ] ||
+			error "$i: mismatch: $sum vs. $sum0"
+	done
+
 	echo " **verify files be RDONLY"
 	verify_flr_state $tf "ro"
 	verify_flr_state $tf-1 "ro"
@@ -1995,9 +2005,13 @@ resync_file_200() {
 
 		echo -n "resync file $tf with '$cmd' .."
 
-		$lock_taken && flock -x 200
-		$cmd $tf &> /dev/null && echo "done" || echo "failed"
-		$lock_taken && flock -u 200
+		if [[ $lock_taken = "true" ]]; then
+			flock -x 200 -c "$cmd $tf &> /dev/null" &&
+				echo "done" || echo "failed"
+			flock -u 200
+		else
+			$cmd $tf &> /dev/null && echo "done" || echo "failed"
+		fi
 
 		sleep 0.$((RANDOM % 8 + 1))
 	done
diff --git a/lustre/utils/liblustreapi_layout.c b/lustre/utils/liblustreapi_layout.c
index a282d7a..a0905d7 100644
--- a/lustre/utils/liblustreapi_layout.c
+++ b/lustre/utils/liblustreapi_layout.c
@@ -2601,15 +2601,27 @@ int llapi_mirror_resync_many(int fd, struct llapi_layout *layout,
 
 		for (i = 0; i < comp_size; i++) {
 			ssize_t written;
+			off_t pos2 = pos;
+			size_t to_write2 = to_write;
 
 			/* skip non-overlapped component */
-			if (pos > comp_array[i].lrc_end ||
-			    pos + to_write < comp_array[i].lrc_start)
+			if (pos >= comp_array[i].lrc_end ||
+			    pos + to_write <= comp_array[i].lrc_start)
 				continue;
 
+			if (pos < comp_array[i].lrc_start)
+				pos2 = comp_array[i].lrc_start;
+
+			to_write2 -= pos2 - pos;
+
+			if ((pos + to_write) > comp_array[i].lrc_end)
+				to_write2 -= pos + to_write -
+					     comp_array[i].lrc_end;
+
 			written = llapi_mirror_write(fd,
-					comp_array[i].lrc_mirror_id, buf,
-					to_write, pos);
+					comp_array[i].lrc_mirror_id,
+					buf + pos2 - pos,
+					to_write2, pos2);
 			if (written < 0) {
 				/**
 				 * this component is not written successfully,
@@ -2624,7 +2636,7 @@ int llapi_mirror_resync_many(int fd, struct llapi_layout *layout,
 				comp_array[i].lrc_synced = true;
 				continue;
 			}
-			assert(written == to_write);
+			assert(written == to_write2);
 		}
 
 		pos += bytes_read;
-- 
1.8.3.1