diff options
-rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 452 |
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 bd66a7ad5..a71d3a378 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); |