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