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