|
|
a3470f |
From 430ff66f69074063dd824b0cde8808ee3d2c7ca8 Mon Sep 17 00:00:00 2001
|
|
|
a3470f |
From: Raghavendra G <rgowdapp@redhat.com>
|
|
|
a3470f |
Date: Fri, 22 Dec 2017 12:02:09 +0530
|
|
|
a3470f |
Subject: [PATCH 156/180] performance/write-behind: fix bug while handling
|
|
|
a3470f |
short writes
|
|
|
a3470f |
|
|
|
a3470f |
The variabled "fulfilled" in wb_fulfill_short_write is not reset to 0
|
|
|
a3470f |
while handling every member of the list.
|
|
|
a3470f |
|
|
|
a3470f |
This has some interesting consequences:
|
|
|
a3470f |
|
|
|
a3470f |
* If we break from the loop while processing last member of the list
|
|
|
a3470f |
head->winds, req is reset to head as the list is a circular
|
|
|
a3470f |
one. However, head is already fulfilled and can potentially be
|
|
|
a3470f |
freed. So, we end up adding a freed request to wb_inode->todo
|
|
|
a3470f |
list. This is the RCA for the crash tracked by the bug associated
|
|
|
a3470f |
with this patch (Note that we saw "holder" which is freed in todo
|
|
|
a3470f |
list).
|
|
|
a3470f |
|
|
|
a3470f |
* If we break from the loop while processing any of the last but one
|
|
|
a3470f |
member of the list head->winds, req is set to next member in the
|
|
|
a3470f |
list, skipping the current request, even though it is not entirely
|
|
|
a3470f |
synced. This can lead to data corruption.
|
|
|
a3470f |
|
|
|
a3470f |
The fix is very simple and we've to change the code to make sure
|
|
|
a3470f |
"fulfilled" reflects whether the current request is fulfilled or not
|
|
|
a3470f |
and it doesn't carry history of previous requests in the list.
|
|
|
a3470f |
|
|
|
a3470f |
Change-Id: Ia3d6988175a51c9e08efdb521a7b7938b01f93c8
|
|
|
a3470f |
BUG: 1516638
|
|
|
a3470f |
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
|
|
|
a3470f |
upstream patch: https://review.gluster.org/19064
|
|
|
a3470f |
Reviewed-on: https://code.engineering.redhat.com/gerrit/126512
|
|
|
a3470f |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
a3470f |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
a3470f |
---
|
|
|
a3470f |
xlators/performance/write-behind/src/write-behind.c | 5 +++--
|
|
|
a3470f |
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
|
|
|
a3470f |
index d1a95c9..7104eb9 100644
|
|
|
a3470f |
--- a/xlators/performance/write-behind/src/write-behind.c
|
|
|
a3470f |
+++ b/xlators/performance/write-behind/src/write-behind.c
|
|
|
a3470f |
@@ -964,6 +964,7 @@ __wb_fulfill_short_write (wb_request_t *req, int size, gf_boolean_t *fulfilled)
|
|
|
a3470f |
} else {
|
|
|
a3470f |
accounted_size = size;
|
|
|
a3470f |
__wb_modify_write_request (req, size);
|
|
|
a3470f |
+ *fulfilled = 0;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
out:
|
|
|
a3470f |
@@ -1005,7 +1006,7 @@ wb_fulfill_short_write (wb_request_t *head, int size)
|
|
|
a3470f |
size -= accounted_size;
|
|
|
a3470f |
|
|
|
a3470f |
if (size == 0) {
|
|
|
a3470f |
- if (fulfilled)
|
|
|
a3470f |
+ if (fulfilled && (next != head))
|
|
|
a3470f |
req = next;
|
|
|
a3470f |
|
|
|
a3470f |
goto done;
|
|
|
a3470f |
@@ -1017,7 +1018,7 @@ wb_fulfill_short_write (wb_request_t *head, int size)
|
|
|
a3470f |
size -= accounted_size;
|
|
|
a3470f |
|
|
|
a3470f |
if (size == 0) {
|
|
|
a3470f |
- if (fulfilled)
|
|
|
a3470f |
+ if (fulfilled && (next != head))
|
|
|
a3470f |
req = next;
|
|
|
a3470f |
break;
|
|
|
a3470f |
}
|
|
|
a3470f |
--
|
|
|
a3470f |
1.8.3.1
|
|
|
a3470f |
|