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