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