diff options
author | Raghavendra G <rgowdapp@redhat.com> | 2016-02-12 17:17:30 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2016-05-04 05:01:46 -0700 |
commit | e3b2ed938a5dc8a72d1fe3d7ced341646d241ca4 (patch) | |
tree | 227ea47f2b6efe33d4efe6b0764feda51c945780 /xlators | |
parent | 7d431c14bc458e9451e9c737f5879968a7b6a0b9 (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: 1292020
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
Reviewed-on: http://review.gluster.org/13438
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')
-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 c3c42cd1a4f..c47b537c4fc 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -695,6 +695,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; @@ -734,22 +802,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; } @@ -916,7 +969,7 @@ done: __wb_request_unref (head); - wb_fulfill_err (req, EIO); + wb_add_head_for_retry (req); out: return; } |