diff options
| author | Raghavendra G <rgowdapp@redhat.com> | 2016-02-12 17:17:30 +0530 | 
|---|---|---|
| committer | Raghavendra G <rgowdapp@redhat.com> | 2016-05-04 20:27:33 -0700 | 
| commit | fee46d447321689ba059d548f62d7c3c06c24e08 (patch) | |
| tree | 523737a13895fc71824da1743872f3b6ec7b5a67 /xlators/performance/write-behind | |
| parent | 0b7631b44b829f44c2ebb3a2f2d01d97987e1fd7 (diff) | |
performance/write-behind: guaranteed retry after a short write
* Don't mark the request with a fake EIO after a short write.
* retry the remaining buffer at least once before unwinding reply to
  application. This way we capture correct error from backend (ENOSPC,
  EDQUOT etc).
Thanks to "Vijaikumar Mallikarjuna"<vmallika@redhat.com> for the test
script.
Change-Id: I73a18b39b661a7424db1a7855a980469a51da8f9
BUG: 1332790
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: http://review.gluster.org/14196
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators/performance/write-behind')
| -rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 87 | 
1 files changed, 70 insertions, 17 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 9d5570ac96d..5089f056b77 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -700,6 +700,74 @@ __wb_request_waiting_on (wb_request_t *req)  void +__wb_add_request_for_retry (wb_request_t *req) +{ +        wb_inode_t *wb_inode = NULL; + +        if (!req) +                goto out; + +        wb_inode = req->wb_inode; + +        /* response was unwound and no waiter waiting on this request, retry +           till a flush or fsync (subject to conf->resync_after_fsync). +        */ +	wb_inode->transit -= req->total_size; + +        req->total_size = 0; + +        list_del_init (&req->winds); +        list_del_init (&req->todo); +        list_del_init (&req->wip); + +        /* sanitize ordering flags to retry */ +        req->ordering.go = 0; + +        /* Add back to todo list to retry */ +        list_add (&req->todo, &wb_inode->todo); + +out: +        return; +} + +void +__wb_add_head_for_retry (wb_request_t *head) +{ +	wb_request_t *req      = NULL, *tmp = NULL; + +        if (!head) +                goto out; + +        list_for_each_entry_safe_reverse (req, tmp, &head->winds, +                                          winds) { +                __wb_add_request_for_retry (req); +        } + +        __wb_add_request_for_retry (head); + +out: +        return; +} + + +void +wb_add_head_for_retry (wb_request_t *head) +{ +        if (!head) +                goto out; + +        LOCK (&head->wb_inode->lock); +        { +                __wb_add_head_for_retry (head); +        } +        UNLOCK (&head->wb_inode->lock); + +out: +        return; +} + + +void  __wb_fulfill_request_err (wb_request_t *req, int32_t op_errno)  {  	wb_inode_t   *wb_inode = NULL; @@ -739,22 +807,7 @@ __wb_fulfill_request_err (wb_request_t *req, int32_t op_errno)                  }          } -        /* response was unwound and no waiter waiting on this request, retry -           till a flush or fsync (subject to conf->resync_after_fsync). -        */ -	wb_inode->transit -= req->total_size; - -        req->total_size = 0; - -        list_del_init (&req->winds); -        list_del_init (&req->todo); -        list_del_init (&req->wip); - -        /* sanitize ordering flags to retry */ -        req->ordering.go = 0; - -        /* Add back to todo list to retry */ -        list_add (&req->todo, &wb_inode->todo); +        __wb_add_request_for_retry (req);          return;  } @@ -921,7 +974,7 @@ done:          __wb_request_unref (head); -        wb_fulfill_err (req, EIO); +        wb_add_head_for_retry (req);  out:          return;  }  | 
