diff options
-rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 247 |
1 files changed, 122 insertions, 125 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 064e0b717c7..883d25e9666 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -55,7 +55,6 @@ typedef struct wb_file { int32_t refcount; int32_t op_ret; int32_t op_errno; - int32_t flags; list_head_t request; list_head_t passive_requests; fd_t *fd; @@ -266,7 +265,7 @@ out: wb_file_t * -wb_file_create (xlator_t *this, fd_t *fd, int32_t flags) +wb_file_create (xlator_t *this, fd_t *fd) { wb_file_t *file = NULL; wb_conf_t *conf = this->private; @@ -288,7 +287,6 @@ wb_file_create (xlator_t *this, fd_t *fd, int32_t flags) file->this = this; file->refcount = 1; file->window_conf = conf->window_size; - file->flags = flags; fd_ctx_set (fd, this, (uint64_t)(long)file); @@ -1230,7 +1228,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, flags); + file = wb_file_create (this, fd); if (file == NULL) { op_ret = -1; op_errno = ENOMEM; @@ -1309,7 +1307,7 @@ 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, flags); + file = wb_file_create (this, fd); if (file == NULL) { op_ret = -1; op_errno = ENOMEM; @@ -1340,8 +1338,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; } @@ -1360,22 +1358,14 @@ 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) { @@ -1394,18 +1384,9 @@ __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) - > conf->aggregate_size))) { - 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); @@ -1480,14 +1461,15 @@ __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; - __wb_can_wind (list, &other_fop_in_queue, - &non_contiguous_writes, &incomplete_writes); + if (!wind_all && (file->aggregate_current < aggregate_conf)) { + __wb_can_wind (list, &other_fop_in_queue, + &non_contiguous_writes, &incomplete_writes); + } - if (!incomplete_writes && ((enable_trickling_writes) - || (wind_all) || (non_contiguous_writes) - || (other_fop_in_queue) - || (file->aggregate_current - >= aggregate_conf))) { + if ((enable_trickling_writes && !incomplete_writes) + || (wind_all) || (non_contiguous_writes) + || (other_fop_in_queue) + || (file->aggregate_current >= aggregate_conf)) { size = __wb_mark_wind_all (file, list, winds); } @@ -2105,66 +2087,64 @@ 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; - int32_t ret = -1; + 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; conf = this->private; local = frame->local; - file = local->file; - if (file != NULL) { + if ((local != NULL) && (local->file != NULL)) { + file = local->file; + LOCK (&file->lock); { - if (file->op_ret == -1) { - op_ret = file->op_ret; - op_errno = file->op_errno; - - file->op_ret = 0; - } + disabled = file->disabled; + disable_till = file->disable_till; } UNLOCK (&file->lock); - ret = wb_process_queue (frame, file, 0); - if ((ret == -1) && (errno == ENOMEM)) { - op_ret = -1; - op_errno = ENOMEM; + 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; + } } + } else { + unwind = 1; } - - STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno); - - 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; - conf = this->private; + if (unwind) { + if (file != NULL) { + LOCK (&file->lock); + { + if (file->op_ret == -1) { + op_ret = file->op_ret; + op_errno = file->op_errno; - local = frame->local; + file->op_ret = 0; + } + } + UNLOCK (&file->lock); - if (local && local->request) { - local->request->stub = NULL; - wb_request_unref (local->request); - } + ret = wb_process_queue (frame, file, 0); + if ((ret == -1) && (errno == ENOMEM)) { + op_ret = -1; + op_errno = ENOMEM; + } + } - if (conf->flush_behind) { - STACK_WIND (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); + STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno); } return 0; @@ -2179,9 +2159,12 @@ 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 *flush_frame = NULL; + call_frame_t *process_frame = NULL; + wb_local_t *tmp_local = NULL; wb_request_t *request = NULL; int32_t ret = 0; + int disabled = 0; + int64_t disable_till = 0; conf = this->private; @@ -2200,79 +2183,93 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd) if (file != NULL) { local = CALLOC (1, sizeof (*local)); if (local == NULL) { - STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM); + STACK_UNWIND (frame, -1, ENOMEM, NULL); return 0; } local->file = file; - if (conf->flush_behind) { - flush_frame = copy_frame (frame); - if (flush_frame == NULL) { - STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM); - return 0; - } - } else { - flush_frame = frame; + 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; } - flush_frame->local = local; + process_frame = copy_frame (frame); + if (process_frame == NULL) { + STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM); + call_stub_destroy (stub); + return 0; + } - stub = fop_flush_stub (flush_frame, wb_flush_helper, fd); - if (stub == NULL) { - if (flush_frame != frame) { - STACK_DESTROY (flush_frame->root); + LOCK (&file->lock); + { + disabled = file->disabled; + disable_till = file->disable_till; + } + UNLOCK (&file->lock); + + if (conf->flush_behind + && (!disabled) && (disable_till == 0)) { + tmp_local = CALLOC (1, sizeof (*local)); + 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; - STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM); - return 0; + process_frame->local = tmp_local; } + fd_ref (fd); + request = wb_enqueue (file, stub); if (request == NULL) { - if (flush_frame != frame) { - STACK_DESTROY (flush_frame->root); - } - 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 (flush_frame, file, 1); + ret = wb_process_queue (process_frame, file, 1); if ((ret == -1) && (errno == ENOMEM)) { - if (flush_frame != frame) { - STACK_DESTROY (flush_frame->root); - } - 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 { - if (conf->flush_behind) { - flush_frame = copy_frame (frame); - if (flush_frame == NULL) { - STACK_UNWIND_STRICT (flush, frame, -1, ENOMEM); - return 0; - } + STACK_WIND (frame, + wb_ffr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->flush, + 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); + if (process_frame != NULL) { + STACK_DESTROY (process_frame->root); } } - if (conf->flush_behind) { - STACK_UNWIND_STRICT (flush, frame, 0, 0); + + if (file != NULL) { + fd_unref (fd); } return 0; |