summaryrefslogtreecommitdiffstats
path: root/xlators/performance/write-behind/src/write-behind.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/performance/write-behind/src/write-behind.c')
-rw-r--r--xlators/performance/write-behind/src/write-behind.c452
1 files changed, 279 insertions, 173 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index bd66a7ad5f3..a71d3a37855 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -52,6 +52,7 @@ typedef struct wb_file {
uint64_t disable_till;
size_t window_conf;
size_t window_current;
+ int32_t flags;
size_t aggregate_current;
int32_t refcount;
int32_t op_ret;
@@ -79,6 +80,14 @@ typedef struct wb_request {
char stack_wound;
char got_reply;
char virgin;
+ char flush_all; /* while trying to sync to back-end,
+ * don't wait till a data of size
+ * equal to configured aggregate-size
+ * is accumulated, instead sync
+ * whatever data currently present in
+ * request queue.
+ */
+
}write_request;
struct {
@@ -116,26 +125,28 @@ typedef struct wb_page wb_page_t;
int32_t
-wb_process_queue (call_frame_t *frame, wb_file_t *file, char flush_all);
+wb_process_queue (call_frame_t *frame, wb_file_t *file);
ssize_t
wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds);
ssize_t
__wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_size,
- char wind_all, char enable_trickling_writes);
+ char enable_trickling_writes);
-static void
+static int
__wb_request_unref (wb_request_t *this)
{
+ int ret = -1;
+
if (this->refcount <= 0) {
gf_log ("wb-request", GF_LOG_DEBUG,
"refcount(%d) is <= 0", this->refcount);
- return;
+ goto out;
}
- this->refcount--;
+ ret = --this->refcount;
if (this->refcount == 0) {
list_del_init (&this->list);
if (this->stub && this->stub->fop == GF_FOP_WRITE) {
@@ -144,25 +155,33 @@ __wb_request_unref (wb_request_t *this)
GF_FREE (this);
}
+
+out:
+ return ret;
}
-static void
+static int
wb_request_unref (wb_request_t *this)
{
wb_file_t *file = NULL;
+ int ret = 0;
+
if (this == NULL) {
gf_log ("wb-request", GF_LOG_DEBUG,
"request is NULL");
- return;
+ goto out;
}
file = this->file;
LOCK (&file->lock);
{
- __wb_request_unref (this);
+ ret = __wb_request_unref (this);
}
UNLOCK (&file->lock);
+
+out:
+ return ret;
}
@@ -204,11 +223,11 @@ wb_request_ref (wb_request_t *this)
wb_request_t *
wb_enqueue (wb_file_t *file, call_stub_t *stub)
{
- wb_request_t *request = NULL;
- call_frame_t *frame = NULL;
- wb_local_t *local = NULL;
- struct iovec *vector = NULL;
- int32_t count = 0;
+ wb_request_t *request = NULL, *tmp = NULL;
+ call_frame_t *frame = NULL;
+ wb_local_t *local = NULL;
+ struct iovec *vector = NULL;
+ int32_t count = 0;
request = GF_CALLOC (1, sizeof (*request), gf_wb_mt_wb_request_t);
if (request == NULL) {
@@ -254,6 +273,13 @@ wb_enqueue (wb_file_t *file, call_stub_t *stub)
file->aggregate_current += request->write_size;
} else {
+ list_for_each_entry (tmp, &file->request, list) {
+ if (tmp->stub && tmp->stub->fop
+ == GF_FOP_WRITE) {
+ tmp->flags.write_request.flush_all = 1;
+ }
+ }
+
/*reference for resuming */
__wb_request_ref (request);
}
@@ -266,7 +292,7 @@ out:
wb_file_t *
-wb_file_create (xlator_t *this, fd_t *fd)
+wb_file_create (xlator_t *this, fd_t *fd, int32_t flags)
{
wb_file_t *file = NULL;
wb_conf_t *conf = this->private;
@@ -288,6 +314,7 @@ wb_file_create (xlator_t *this, fd_t *fd)
file->this = this;
file->refcount = 1;
file->window_conf = conf->window_size;
+ file->flags = flags;
fd_ctx_set (fd, this, (uint64_t)(long)file);
@@ -359,7 +386,7 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
UNLOCK (&file->lock);
- ret = wb_process_queue (frame, file, 0);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
LOCK (&file->lock);
{
@@ -393,6 +420,12 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
size_t bytecount = 0;
wb_conf_t *conf = NULL;
fd_t *fd = NULL;
+ int32_t op_errno = -1;
+
+ if (frame == NULL) {
+ op_errno = EINVAL;
+ goto out;
+ }
conf = file->this->private;
list_for_each_entry (request, winds, winds) {
@@ -403,6 +436,8 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
}
if (total_count == 0) {
+ gf_log (file->this->name, GF_LOG_DEBUG, "no vectors are to be"
+ "synced");
goto out;
}
@@ -412,12 +447,18 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
gf_wb_mt_iovec);
if (vector == NULL) {
bytes = -1;
+ op_errno = ENOMEM;
+ gf_log (file->this->name, GF_LOG_ERROR,
+ "out of memory");
goto out;
}
iobref = iobref_new ();
if (iobref == NULL) {
bytes = -1;
+ op_errno = ENOMEM;
+ gf_log (file->this->name, GF_LOG_ERROR,
+ "out of memory");
goto out;
}
@@ -425,6 +466,9 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
gf_wb_mt_wb_local_t);
if (local == NULL) {
bytes = -1;
+ op_errno = ENOMEM;
+ gf_log (file->this->name, GF_LOG_ERROR,
+ "out of memory");
goto out;
}
@@ -466,6 +510,9 @@ wb_sync (call_frame_t *frame, wb_file_t *file, list_head_t *winds)
sync_frame = copy_frame (frame);
if (sync_frame == NULL) {
bytes = -1;
+ op_errno = ENOMEM;
+ gf_log (file->this->name, GF_LOG_ERROR,
+ "out of memory");
goto out;
}
@@ -508,6 +555,14 @@ out:
}
if (local != NULL) {
+ /* had we winded these requests, we would have unrefed
+ * in wb_sync_cbk.
+ */
+ list_for_each_entry_safe (request, dummy, &local->winds,
+ winds) {
+ wb_request_unref (request);
+ }
+
GF_FREE (local);
}
@@ -519,6 +574,27 @@ out:
GF_FREE (vector);
}
+ if (bytes == -1) {
+ /*
+ * had we winded these requests, we would have unrefed
+ * in wb_sync_cbk.
+ */
+
+ list_for_each_entry_safe (request, dummy, &local->winds,
+ winds) {
+ wb_request_unref (request);
+ }
+
+ if (file != NULL) {
+ LOCK (&file->lock);
+ {
+ file->op_ret = -1;
+ file->op_errno = op_errno;
+ }
+ UNLOCK (&file->lock);
+ }
+ }
+
return bytes;
}
@@ -553,7 +629,7 @@ wb_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
if (process_frame != NULL) {
- ret = wb_process_queue (process_frame, file, 0);
+ ret = wb_process_queue (process_frame, file);
if ((ret == -1) && (errno == ENOMEM) && (file != NULL)) {
LOCK (&file->lock);
{
@@ -639,7 +715,7 @@ wb_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
goto unwind;
}
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
goto unwind;
@@ -683,7 +759,7 @@ wb_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
request = local->request;
if ((file != NULL) && (request != NULL)) {
wb_request_unref (request);
- ret = wb_process_queue (frame, file, 0);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_ret = -1;
op_errno = ENOMEM;
@@ -757,7 +833,7 @@ wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
/*
FIXME:should the request queue be emptied in case of error?
*/
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
goto unwind;
@@ -813,7 +889,7 @@ wb_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
if (process_frame != NULL) {
- ret = wb_process_queue (process_frame, file, 0);
+ ret = wb_process_queue (process_frame, file);
if ((ret == -1) && (errno == ENOMEM) && (file != NULL)) {
LOCK (&file->lock);
{
@@ -906,7 +982,7 @@ wb_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
goto unwind;
}
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
goto unwind;
@@ -949,7 +1025,7 @@ wb_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if ((request != NULL) && (file != NULL)) {
wb_request_unref (request);
- ret = wb_process_queue (frame, file, 0);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1026,7 +1102,7 @@ wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
goto unwind;
}
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
goto unwind;
@@ -1055,7 +1131,8 @@ unwind:
int32_t
wb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, struct iatt *statpre, struct iatt *statpost)
+ int32_t op_ret, int32_t op_errno, struct iatt *statpre,
+ struct iatt *statpost)
{
wb_local_t *local = NULL;
wb_request_t *request = NULL;
@@ -1076,14 +1153,15 @@ wb_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
}
- STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre, statpost);
+ STACK_UNWIND_STRICT (setattr, frame, op_ret, op_errno, statpre,
+ statpost);
if (request) {
wb_request_unref (request);
}
if (request && (process_frame != NULL)) {
- ret = wb_process_queue (process_frame, file, 0);
+ ret = wb_process_queue (process_frame, file);
if ((ret == -1) && (errno == ENOMEM) && (file != NULL)) {
LOCK (&file->lock);
{
@@ -1188,7 +1266,7 @@ wb_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
goto unwind;
}
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
goto unwind;
@@ -1236,7 +1314,7 @@ wb_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
wbflags = local->wbflags;
if (op_ret != -1) {
- file = wb_file_create (this, fd);
+ file = wb_file_create (this, fd, flags);
if (file == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1307,7 +1385,11 @@ wb_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
wb_conf_t *conf = this->private;
if (op_ret != -1) {
- file = wb_file_create (this, fd);
+ if (frame->local) {
+ flags = (long) frame->local;
+ }
+
+ file = wb_file_create (this, fd, flags);
if (file == NULL) {
op_ret = -1;
op_errno = ENOMEM;
@@ -1316,7 +1398,6 @@ wb_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* If O_DIRECT then, we disable chaching */
if (frame->local) {
- flags = (long)frame->local;
if (((flags & O_DIRECT) == O_DIRECT)
|| ((flags & O_ACCMODE) == O_RDONLY)
|| (((flags & O_SYNC) == O_SYNC)
@@ -1331,8 +1412,8 @@ wb_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
frame->local = NULL;
out:
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, preparent,
- postparent);
+ STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf,
+ preparent, postparent);
return 0;
}
@@ -1351,14 +1432,22 @@ wb_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
return 0;
}
-
+/* Mark all the contiguous write requests for winding starting from head of
+ * request list. Stops marking at the first non-write request found. If
+ * file is opened with O_APPEND, make sure all the writes marked for winding
+ * will fit into a single write call to server.
+ */
size_t
__wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
{
- wb_request_t *request = NULL;
- size_t size = 0;
- char first_request = 1;
+ wb_request_t *request = NULL;
+ size_t size = 0;
+ char first_request = 1;
off_t offset_expected = 0;
+ wb_conf_t *conf = NULL;
+ int count = 0;
+
+ conf = file->this->private;
list_for_each_entry (request, list, list)
{
@@ -1377,9 +1466,18 @@ __wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
break;
}
+ if ((file->flags & O_APPEND)
+ && (((size + request->write_size)
+ > conf->aggregate_size)
+ || ((count + request->stub->args.writev.count)
+ > MAX_VECTOR_COUNT))) {
+ break;
+ }
+
size += request->write_size;
offset_expected += request->write_size;
file->aggregate_current -= request->write_size;
+ count += request->stub->args.writev.count;
request->flags.write_request.stack_wound = 1;
list_add_tail (&request->winds, winds);
@@ -1392,7 +1490,8 @@ __wb_mark_wind_all (wb_file_t *file, list_head_t *list, list_head_t *winds)
void
__wb_can_wind (list_head_t *list, char *other_fop_in_queue,
- char *non_contiguous_writes, char *incomplete_writes)
+ char *non_contiguous_writes, char *incomplete_writes,
+ char *wind_all)
{
wb_request_t *request = NULL;
char first_request = 1;
@@ -1418,7 +1517,11 @@ __wb_can_wind (list_head_t *list, char *other_fop_in_queue,
if (!request->flags.write_request.stack_wound) {
if (first_request) {
first_request = 0;
- offset_expected = request->stub->args.writev.off;
+ offset_expected
+ = request->stub->args.writev.off;
+ if (wind_all != NULL) {
+ *wind_all = request->flags.write_request.flush_all;
+ }
}
if (offset_expected != request->stub->args.writev.off) {
@@ -1438,7 +1541,7 @@ __wb_can_wind (list_head_t *list, char *other_fop_in_queue,
ssize_t
__wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
- char wind_all, char enable_trickling_writes)
+ char enable_trickling_writes)
{
size_t size = 0;
char other_fop_in_queue = 0;
@@ -1446,6 +1549,7 @@ __wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
char non_contiguous_writes = 0;
wb_request_t *request = NULL;
wb_file_t *file = NULL;
+ char wind_all = 0;
if (list_empty (list)) {
goto out;
@@ -1454,17 +1558,16 @@ __wb_mark_winds (list_head_t *list, list_head_t *winds, size_t aggregate_conf,
request = list_entry (list->next, typeof (*request), list);
file = request->file;
- if (!wind_all && (file->aggregate_current < aggregate_conf)) {
- __wb_can_wind (list, &other_fop_in_queue,
- &non_contiguous_writes, &incomplete_writes);
- }
+ __wb_can_wind (list, &other_fop_in_queue,
+ &non_contiguous_writes, &incomplete_writes, &wind_all);
- if ((enable_trickling_writes && !incomplete_writes)
- || (wind_all) || (non_contiguous_writes)
- || (other_fop_in_queue)
- || (file->aggregate_current >= aggregate_conf)) {
+ if (!incomplete_writes && ((enable_trickling_writes)
+ || (wind_all) || (non_contiguous_writes)
+ || (other_fop_in_queue)
+ || (file->aggregate_current
+ >= aggregate_conf))) {
size = __wb_mark_wind_all (file, list, winds);
- }
+ }
out:
return size;
@@ -1565,6 +1668,7 @@ wb_stack_unwind (list_head_t *unwinds)
wb_request_t *request = NULL, *dummy = NULL;
call_frame_t *frame = NULL;
wb_local_t *local = NULL;
+ int ret = 0, write_requests_removed = 0;
list_for_each_entry_safe (request, dummy, unwinds, unwinds)
{
@@ -1574,10 +1678,13 @@ wb_stack_unwind (list_head_t *unwinds)
STACK_UNWIND (frame, local->op_ret, local->op_errno, &buf,
&buf);
- wb_request_unref (request);
+ ret = wb_request_unref (request);
+ if (ret == 0) {
+ write_requests_removed++;
+ }
}
- return 0;
+ return write_requests_removed;
}
@@ -1615,7 +1722,7 @@ wb_resume_other_requests (call_frame_t *frame, wb_file_t *file,
}
if (fops_removed > 0) {
- ret = wb_process_queue (frame, file, 0);
+ ret = wb_process_queue (frame, file);
}
out:
@@ -1627,19 +1734,27 @@ int32_t
wb_do_ops (call_frame_t *frame, wb_file_t *file, list_head_t *winds,
list_head_t *unwinds, list_head_t *other_requests)
{
- int32_t ret = -1;
+ int32_t ret = -1, write_requests_removed = 0;
ret = wb_stack_unwind (unwinds);
- if (ret == -1) {
- goto out;
- }
+
+ write_requests_removed = ret;
ret = wb_sync (frame, file, winds);
if (ret == -1) {
goto out;
}
- ret = wb_resume_other_requests (frame, file, other_requests);
+ wb_resume_other_requests (frame, file, other_requests);
+
+ /* wb_stack_unwind does wb_request_unref after unwinding a write
+ * request. Hence if a write-request was just freed in wb_stack_unwind,
+ * we have to process request queue once again to unblock requests
+ * blocked on the writes just unwound.
+ */
+ if (write_requests_removed > 0) {
+ ret = wb_process_queue (frame, file);
+ }
out:
return ret;
@@ -1763,7 +1878,7 @@ __wb_collapse_write_bufs (list_head_t *requests, size_t page_size)
int32_t
-wb_process_queue (call_frame_t *frame, wb_file_t *file, char flush_all)
+wb_process_queue (call_frame_t *frame, wb_file_t *file)
{
list_head_t winds, unwinds, other_requests;
size_t size = 0;
@@ -1800,7 +1915,6 @@ wb_process_queue (call_frame_t *frame, wb_file_t *file, char flush_all)
if (count == 0) {
__wb_mark_winds (&file->request, &winds, size,
- flush_all,
conf->enable_trickling_writes);
}
@@ -1927,7 +2041,7 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
goto unwind;
}
- ret = wb_process_queue (process_frame, file, 0);
+ ret = wb_process_queue (process_frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_errno = ENOMEM;
goto unwind;
@@ -1969,7 +2083,7 @@ wb_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if ((request != NULL) && (file != NULL)) {
wb_request_unref (request);
- ret = wb_process_queue (frame, file, 0);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2048,7 +2162,7 @@ wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
return 0;
}
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
STACK_UNWIND_STRICT (readv, frame, -1, ENOMEM,
NULL, 0, NULL, NULL);
@@ -2082,67 +2196,102 @@ wb_ffr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
int32_t op_errno)
{
wb_local_t *local = NULL;
- wb_file_t *file = NULL;
- wb_conf_t *conf = NULL;
- char unwind = 0;
- int32_t ret = -1;
- int disabled = 0;
- int64_t disable_till = 0;
+ wb_file_t *file = NULL;
+ wb_conf_t *conf = NULL;
conf = this->private;
local = frame->local;
+ file = local->file;
- if ((local != NULL) && (local->file != NULL)) {
- file = local->file;
-
+ if (file != NULL) {
LOCK (&file->lock);
{
- disabled = file->disabled;
- disable_till = file->disable_till;
+ if (file->op_ret == -1) {
+ op_ret = file->op_ret;
+ op_errno = file->op_errno;
+
+ file->op_ret = 0;
+ }
}
UNLOCK (&file->lock);
+ }
+
+ STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
- if (conf->flush_behind
- && (!disabled) && (disable_till == 0)) {
- unwind = 1;
- } else {
- local->reply_count++;
- /*
- * without flush-behind, unwind should wait for replies
- * of writes queued before and the flush
- */
- if (local->reply_count == 2) {
- unwind = 1;
- }
+ return 0;
+}
+
+
+int32_t
+wb_flush_helper (call_frame_t *frame, xlator_t *this, fd_t *fd)
+{
+ wb_conf_t *conf = NULL;
+ wb_local_t *local = NULL;
+ wb_file_t *file = NULL;
+ call_frame_t *flush_frame = NULL, *process_frame = NULL;
+ int32_t op_ret = -1, op_errno = -1, ret = -1;
+
+ conf = this->private;
+
+ local = frame->local;
+ file = local->file;
+
+ LOCK (&file->lock);
+ {
+ op_ret = file->op_ret;
+ op_errno = file->op_errno;
+ }
+ UNLOCK (&file->lock);
+
+ if (local && local->request) {
+ process_frame = copy_frame (frame);
+ if (process_frame == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
+ }
+
+ wb_request_unref (local->request);
+ }
+
+ if (conf->flush_behind) {
+ flush_frame = copy_frame (frame);
+ if (flush_frame == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "out of memory");
+ goto unwind;
}
+
+ STACK_WIND (flush_frame,
+ wb_ffr_bg_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
} else {
- unwind = 1;
+ STACK_WIND (frame,
+ wb_ffr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
}
- if (unwind) {
- if (file != NULL) {
- LOCK (&file->lock);
- {
- if (file->op_ret == -1) {
- op_ret = file->op_ret;
- op_errno = file->op_errno;
+ if (process_frame != NULL) {
+ ret = wb_process_queue (process_frame, file);
+ if ((ret == -1) && (errno == ENOMEM)) {
+ STACK_DESTROY (process_frame->root);
+ goto unwind;
+ }
- file->op_ret = 0;
- }
- }
- UNLOCK (&file->lock);
+ STACK_DESTROY (process_frame->root);
+ }
- ret = wb_process_queue (frame, file, 0);
- if ((ret == -1) && (errno == ENOMEM)) {
- op_ret = -1;
- op_errno = ENOMEM;
- }
- }
-
+ if (conf->flush_behind) {
STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno);
}
return 0;
+
+unwind:
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
+ return 0;
}
@@ -2154,12 +2303,9 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
wb_local_t *local = NULL;
uint64_t tmp_file = 0;
call_stub_t *stub = NULL;
- call_frame_t *process_frame = NULL;
- wb_local_t *tmp_local = NULL;
+ call_frame_t *flush_frame = NULL;
wb_request_t *request = NULL;
int32_t ret = 0;
- int disabled = 0;
- int64_t disable_till = 0;
conf = this->private;
@@ -2176,97 +2322,57 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
file = (wb_file_t *)(long)tmp_file;
if (file != NULL) {
- local = GF_CALLOC (1, sizeof (*local),
- gf_wb_mt_wb_local_t);
+ local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
- STACK_UNWIND (frame, -1, ENOMEM, NULL);
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
return 0;
}
local->file = file;
frame->local = local;
- stub = fop_flush_cbk_stub (frame, wb_ffr_cbk, 0, 0);
- if (stub == NULL) {
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
- return 0;
- }
- process_frame = copy_frame (frame);
- if (process_frame == NULL) {
+ stub = fop_flush_stub (frame, wb_flush_helper, fd);
+ if (stub == NULL) {
STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
- call_stub_destroy (stub);
return 0;
}
- LOCK (&file->lock);
- {
- disabled = file->disabled;
- disable_till = file->disable_till;
- }
- UNLOCK (&file->lock);
-
- if (conf->flush_behind
- && (!disabled) && (disable_till == 0)) {
- tmp_local = GF_CALLOC (1, sizeof (*local),
- gf_wb_mt_wb_local_t);
- if (tmp_local == NULL) {
- STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
-
- STACK_DESTROY (process_frame->root);
- call_stub_destroy (stub);
- return 0;
- }
- tmp_local->file = file;
-
- process_frame->local = tmp_local;
- }
-
- fd_ref (fd);
-
request = wb_enqueue (file, stub);
if (request == NULL) {
STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
-
- fd_unref (fd);
call_stub_destroy (stub);
- STACK_DESTROY (process_frame->root);
return 0;
}
- ret = wb_process_queue (process_frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
-
- fd_unref (fd);
call_stub_destroy (stub);
- STACK_DESTROY (process_frame->root);
return 0;
}
- }
-
- if ((file != NULL) && conf->flush_behind
- && (!disabled) && (disable_till == 0)) {
- STACK_WIND (process_frame,
- wb_ffr_bg_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- fd);
} else {
- STACK_WIND (frame,
- wb_ffr_cbk,
- FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->flush,
- fd);
+ if (conf->flush_behind) {
+ flush_frame = copy_frame (frame);
+ if (flush_frame == NULL) {
+ STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM);
+ return 0;
+ }
- if (process_frame != NULL) {
- STACK_DESTROY (process_frame->root);
- }
- }
+ STACK_UNWIND_STRICT (flush, frame, 0, 0);
-
- if (file != NULL) {
- fd_unref (fd);
+ STACK_WIND (flush_frame,
+ wb_ffr_bg_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ } else {
+ STACK_WIND (frame,
+ wb_ffr_cbk,
+ FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->flush,
+ fd);
+ }
}
return 0;
@@ -2300,7 +2406,7 @@ wb_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if (request) {
wb_request_unref (request);
- ret = wb_process_queue (frame, file, 0);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
op_ret = -1;
op_errno = ENOMEM;
@@ -2377,7 +2483,7 @@ wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync)
return 0;
}
- ret = wb_process_queue (frame, file, 1);
+ ret = wb_process_queue (frame, file);
if ((ret == -1) && (errno == ENOMEM)) {
STACK_UNWIND_STRICT (fsync, frame, -1, ENOMEM,
NULL, NULL);