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