diff options
author | Raghavendra G <rgowdapp@redhat.com> | 2016-01-05 22:16:31 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2016-01-06 21:59:52 -0800 |
commit | ea42ffa13c00263a574226626d30749b6b0f3776 (patch) | |
tree | 57f318acac7a5ec80ba07b44bded5433d73e3a3b /xlators/performance | |
parent | cae9a5b3a1868a8bae25cd1ba9ebb41d698f39e5 (diff) |
performance/write-behind: maintain correct transit size in case of
short writes.
1. Imagine a write when cache is filled with failed syncs.
2. This write won't be unwound since cache size has exceeded
configured limit.
3. With trickling-writes on by default, the last write request wont be
considered for winding when there is non zero in-transit size.
4. There was a bug in accounting of in-transit size when winds
resulted in short writes. Due to this bug, in-transit size used to be
non-zero even when there are no syncs in progress.
5. Due to 3 and 4, current write request won't be wound till there is
another write or fsync or flush from application. But application
can't do any other fop till current write request is unwound. This
resulted in deadlock and hence application would be hung in 'D'
state.
This patch fixes bug in accounting of in-transit size during short
writes.
Change-Id: I04ce8bb510efaaed7623cac38d69b32dbc3730ce
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
BUG: 1279730
Reviewed-on: http://review.gluster.org/13177
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators/performance')
-rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 24 |
1 files changed, 9 insertions, 15 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 3fd419d1c9f..c6bc5ef573e 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -813,9 +813,9 @@ wb_fulfill_err (wb_request_t *head, int op_errno) UNLOCK (&wb_inode->lock); } + void -__wb_modify_write_request (wb_request_t *req, int synced_size, - int head_total_size) +__wb_modify_write_request (wb_request_t *req, int synced_size) { struct iovec *vector = NULL; int count = 0; @@ -825,7 +825,6 @@ __wb_modify_write_request (wb_request_t *req, int synced_size, req->write_size -= synced_size; req->stub->args.offset += synced_size; - req->total_size = head_total_size; vector = req->stub->args.vector; count = req->stub->args.count; @@ -838,7 +837,7 @@ out: } int -__wb_fulfill_short_write (wb_request_t *req, int size, int total_size) +__wb_fulfill_short_write (wb_request_t *req, int size) { int accounted_size = 0; @@ -850,7 +849,7 @@ __wb_fulfill_short_write (wb_request_t *req, int size, int total_size) __wb_fulfill_request (req); } else { accounted_size = size; - __wb_modify_write_request (req, size, total_size); + __wb_modify_write_request (req, size); } out: @@ -860,24 +859,20 @@ out: void wb_fulfill_short_write (wb_request_t *head, int size) { - wb_inode_t *wb_inode = NULL; - wb_request_t *req = NULL, *tmp = NULL; - int total_size = 0, accounted_size = 0; + wb_inode_t *wb_inode = NULL; + wb_request_t *req = NULL, *tmp = NULL; + int accounted_size = 0; if (!head) goto out; wb_inode = head->wb_inode; - total_size = head->total_size - size; - head->total_size = size; - req = head; LOCK (&wb_inode->lock); { - accounted_size = __wb_fulfill_short_write (head, size, - total_size); + accounted_size = __wb_fulfill_short_write (head, size); size -= accounted_size; @@ -885,8 +880,7 @@ wb_fulfill_short_write (wb_request_t *head, int size) goto done; list_for_each_entry_safe (req, tmp, &head->winds, winds) { - accounted_size = __wb_fulfill_short_write (req, size, - total_size); + accounted_size = __wb_fulfill_short_write (req, size); size -= accounted_size; if (size == 0) |