233933
From 76127f4f8f3c2bf415f66a335e7b37670cb9bd84 Mon Sep 17 00:00:00 2001
233933
From: Raghavendra G <rgowdapp@redhat.com>
233933
Date: Fri, 3 May 2019 10:14:48 +0530
233933
Subject: [PATCH 134/141] performance/write-behind: remove request from wip
233933
 list in wb_writev_cbk
233933
233933
There is a race in the way O_DIRECT writes are handled. Assume two
233933
overlapping write requests w1 and w2.
233933
233933
* w1 is issued and is in wb_inode->wip queue as the response is still
233933
  pending from bricks. Also wb_request_unref in wb_do_winds is not yet
233933
  invoked.
233933
233933
       list_for_each_entry_safe (req, tmp, tasks, winds) {
233933
		list_del_init (&req->winds);
233933
233933
                if (req->op_ret == -1) {
233933
			call_unwind_error_keep_stub (req->stub, req->op_ret,
233933
		                                     req->op_errno);
233933
                } else {
233933
                        call_resume_keep_stub (req->stub);
233933
		}
233933
233933
                wb_request_unref (req);
233933
        }
233933
233933
* w2 is issued and wb_process_queue is invoked. w2 is not picked up
233933
  for winding as w1 is still in wb_inode->wip. w1 is added to todo
233933
  list and wb_writev for w2 returns.
233933
233933
* response to w1 is received and invokes wb_request_unref. Assume
233933
  wb_request_unref in wb_do_winds (see point 1) is not invoked
233933
  yet. Since there is one more refcount, wb_request_unref in
233933
  wb_writev_cbk of w1 doesn't remove w1 from wip.
233933
233933
* wb_process_queue is invoked as part of wb_writev_cbk of w1. But, it
233933
  fails to wind w2 as w1 is still in wip.
233933
233933
* wb_requet_unref is invoked on w1 as part of wb_do_winds. w1 is
233933
  removed from all queues including w1.
233933
233933
* After this point there is no invocation of wb_process_queue unless
233933
  new request is issued from application causing w2 to be hung till
233933
  the next request.
233933
233933
This bug is similar to bz 1626780 and bz 1379655.
233933
233933
upstream patch: https://review.gluster.org/#/c/glusterfs/+/22654/
233933
BUG: 1702686
233933
Change-Id: Iaa47437613591699d4c8ad18bc0b32de6affcc31
233933
fixes: bz#1702686
233933
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
233933
Reviewed-on: https://code.engineering.redhat.com/gerrit/169552
233933
Tested-by: RHGS Build Bot <nigelb@redhat.com>
233933
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
233933
---
233933
 xlators/performance/write-behind/src/write-behind.c | 6 ++++++
233933
 1 file changed, 6 insertions(+)
233933
233933
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
233933
index cf302bd..70e281a 100644
233933
--- a/xlators/performance/write-behind/src/write-behind.c
233933
+++ b/xlators/performance/write-behind/src/write-behind.c
233933
@@ -1813,6 +1813,12 @@ wb_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
233933
     frame->local = NULL;
233933
     wb_inode = req->wb_inode;
233933
 
233933
+    LOCK(&req->wb_inode->lock);
233933
+    {
233933
+        list_del_init(&req->wip);
233933
+    }
233933
+    UNLOCK(&req->wb_inode->lock);
233933
+
233933
     wb_request_unref(req);
233933
 
233933
     /* requests could be pending while this was in progress */
233933
-- 
233933
1.8.3.1
233933