summaryrefslogtreecommitdiffstats
path: root/xlators/performance/write-behind
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2016-01-05 22:16:31 +0530
committerRaghavendra G <rgowdapp@redhat.com>2016-01-06 21:59:52 -0800
commitea42ffa13c00263a574226626d30749b6b0f3776 (patch)
tree57f318acac7a5ec80ba07b44bded5433d73e3a3b /xlators/performance/write-behind
parentcae9a5b3a1868a8bae25cd1ba9ebb41d698f39e5 (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/write-behind')
-rw-r--r--xlators/performance/write-behind/src/write-behind.c24
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)