summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2017-12-22 12:02:09 +0530
committerjiffin tony Thottan <jthottan@redhat.com>2018-01-02 09:51:52 +0000
commitcc9e239ce4909cbe8880ef083ae6be0b5bfa705c (patch)
tree0bd2daf019adffc6dc05fc1aad3cf362305b166a
parent18e2ce7e63cb786856a24847a6baa1d560123d77 (diff)
performance/write-behind: fix bug while handling short writes
The variabled "fulfilled" in wb_fulfill_short_write is not reset to 0 while handling every member of the list. This has some interesting consequences: * If we break from the loop while processing last member of the list head->winds, req is reset to head as the list is a circular one. However, head is already fulfilled and can potentially be freed. So, we end up adding a freed request to wb_inode->todo list. This is the RCA for the crash tracked by the bug associated with this patch (Note that we saw "holder" which is freed in todo list). * If we break from the loop while processing any of the last but one member of the list head->winds, req is set to next member in the list, skipping the current request, even though it is not entirely synced. This can lead to data corruption. The fix is very simple and we've to change the code to make sure "fulfilled" reflects whether the current request is fulfilled or not and it doesn't carry history of previous requests in the list. >Change-Id: Ia3d6988175a51c9e08efdb521a7b7938b01f93c8 >BUG: 1528558 >Signed-off-by: Raghavendra G <rgowdapp@redhat.com> (cherry picked from commit 0bc22bef7f3c24663aadfb3548b348aa121e3047) Change-Id: Ia3d6988175a51c9e08efdb521a7b7938b01f93c8 BUG: 1529095 Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r--xlators/performance/write-behind/src/write-behind.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index d1a95c97d7a..7104eb908b5 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -964,6 +964,7 @@ __wb_fulfill_short_write (wb_request_t *req, int size, gf_boolean_t *fulfilled)
} else {
accounted_size = size;
__wb_modify_write_request (req, size);
+ *fulfilled = 0;
}
out:
@@ -1005,7 +1006,7 @@ wb_fulfill_short_write (wb_request_t *head, int size)
size -= accounted_size;
if (size == 0) {
- if (fulfilled)
+ if (fulfilled && (next != head))
req = next;
goto done;
@@ -1017,7 +1018,7 @@ wb_fulfill_short_write (wb_request_t *head, int size)
size -= accounted_size;
if (size == 0) {
- if (fulfilled)
+ if (fulfilled && (next != head))
req = next;
break;
}