From e3b2ed938a5dc8a72d1fe3d7ced341646d241ca4 Mon Sep 17 00:00:00 2001 From: Raghavendra G Date: Fri, 12 Feb 2016 17:17:30 +0530 Subject: 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" for the test script. Change-Id: I73a18b39b661a7424db1a7855a980469a51da8f9 BUG: 1292020 Signed-off-by: Raghavendra G Reviewed-on: http://review.gluster.org/13438 Smoke: Gluster Build System NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- .../performance/write-behind/src/write-behind.c | 87 +++++++++++++++++----- 1 file changed, 70 insertions(+), 17 deletions(-) (limited to 'xlators/performance/write-behind') 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 @@ -694,6 +694,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) { @@ -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; } -- cgit