diff options
| author | Raghavendra G <rgowdapp@redhat.com> | 2019-05-07 10:35:06 +0530 | 
|---|---|---|
| committer | Raghavendra G <rgowdapp@redhat.com> | 2019-05-07 11:35:40 +0530 | 
| commit | dc7f464d019ebe980232263cad8528456253e9dd (patch) | |
| tree | 12a11c0b167fd7247caaaff739384ede47a384bf /api/src/glfs-fops.c | |
| parent | e26fc565990091ac18acd2859296029d3b7609b4 (diff) | |
performance/write-behind: remove request from wip list in wb_writev_cbk
There is a race in the way O_DIRECT writes are handled. Assume two
overlapping write requests w1 and w2.
* w1 is issued and is in wb_inode->wip queue as the response is still
  pending from bricks. Also wb_request_unref in wb_do_winds is not yet
  invoked.
       list_for_each_entry_safe (req, tmp, tasks, winds) {
		list_del_init (&req->winds);
                if (req->op_ret == -1) {
			call_unwind_error_keep_stub (req->stub, req->op_ret,
		                                     req->op_errno);
                } else {
                        call_resume_keep_stub (req->stub);
		}
                wb_request_unref (req);
        }
* w2 is issued and wb_process_queue is invoked. w2 is not picked up
  for winding as w1 is still in wb_inode->wip. w1 is added to todo
  list and wb_writev for w2 returns.
* response to w1 is received and invokes wb_request_unref. Assume
  wb_request_unref in wb_do_winds (see point 1) is not invoked
  yet. Since there is one more refcount, wb_request_unref in
  wb_writev_cbk of w1 doesn't remove w1 from wip.
* wb_process_queue is invoked as part of wb_writev_cbk of w1. But, it
  fails to wind w2 as w1 is still in wip.
* wb_requet_unref is invoked on w1 as part of wb_do_winds. w1 is
  removed from all queues including w1.
* After this point there is no invocation of wb_process_queue unless
  new request is issued from application causing w2 to be hung till
  the next request.
This bug is similar to bz 1626780 and bz 1379655.
Change-Id: Iab47437613591699d4c8ad18bc0b32de6affcc31
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Fixes: bz#1707200
Diffstat (limited to 'api/src/glfs-fops.c')
0 files changed, 0 insertions, 0 deletions
