From c780adb365fb44f1bd011244fcfa657acc18a5d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 7 Aug 2016 15:44:52 +0200 Subject: [PATCH] vfs: Convert vfs_write_send to pthreadpool_tevent Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- source3/modules/vfs_default.c | 106 ++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 12 deletions(-) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 4007395c230..8825e7bf8b1 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -896,6 +896,21 @@ static ssize_t vfswrap_pread_recv(struct tevent_req *req, return state->ret; } +struct vfswrap_pwrite_state { + ssize_t ret; + int err; + int fd; + const void *buf; + size_t count; + off_t offset; + + struct vfs_aio_state vfs_aio_state; + SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes); +}; + +static void vfs_pwrite_do(void *private_data); +static void vfs_pwrite_done(struct tevent_req *subreq); + static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -903,33 +918,100 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle, const void *data, size_t n, off_t offset) { - struct tevent_req *req; - struct vfswrap_asys_state *state; + struct tevent_req *req, *subreq; + struct vfswrap_pwrite_state *state; int ret; - req = tevent_req_create(mem_ctx, &state, struct vfswrap_asys_state); + req = tevent_req_create(mem_ctx, &state, struct vfswrap_pwrite_state); if (req == NULL) { return NULL; } - if (!vfswrap_init_asys_ctx(handle->conn->sconn)) { - tevent_req_oom(req); + + ret = vfswrap_init_pool(handle->conn->sconn); + if (tevent_req_error(req, ret)) { return tevent_req_post(req, ev); } - state->asys_ctx = handle->conn->sconn->asys_ctx; - state->req = req; + + state->ret = -1; + state->fd = fsp->fh->fd; + state->buf = data; + state->count = n; + state->offset = offset; SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite, profile_p, state->profile_bytes, n); - ret = asys_pwrite(state->asys_ctx, fsp->fh->fd, data, n, offset, req); - if (ret != 0) { - tevent_req_error(req, ret); + SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); + + subreq = pthreadpool_tevent_job_send( + state, ev, handle->conn->sconn->pool, + vfs_pwrite_do, state); + if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - talloc_set_destructor(state, vfswrap_asys_state_destructor); + tevent_req_set_callback(subreq, vfs_pwrite_done, req); return req; } +static void vfs_pwrite_do(void *private_data) +{ + struct vfswrap_pwrite_state *state = talloc_get_type_abort( + private_data, struct vfswrap_pwrite_state); + struct timespec start_time; + struct timespec end_time; + + SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes); + + PROFILE_TIMESTAMP(&start_time); + + do { + state->ret = pwrite(state->fd, state->buf, state->count, + state->offset); + } while ((state->ret == -1) && (errno == EINTR)); + + state->err = errno; + + PROFILE_TIMESTAMP(&end_time); + + state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time); + + SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); +} + +static void vfs_pwrite_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); +#ifdef WITH_PROFILE + struct vfswrap_pwrite_state *state = tevent_req_data( + req, struct vfswrap_pwrite_state); +#endif + int ret; + + ret = pthreadpool_tevent_job_recv(subreq); + TALLOC_FREE(subreq); + SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); + if (tevent_req_error(req, ret)) { + return; + } + + tevent_req_done(req); +} + +static ssize_t vfswrap_pwrite_recv(struct tevent_req *req, + struct vfs_aio_state *vfs_aio_state) +{ + struct vfswrap_pwrite_state *state = tevent_req_data( + req, struct vfswrap_pwrite_state); + + if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { + return -1; + } + + *vfs_aio_state = state->vfs_aio_state; + return state->ret; +} + static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -2746,7 +2828,7 @@ static struct vfs_fn_pointers vfs_default_fns = { .write_fn = vfswrap_write, .pwrite_fn = vfswrap_pwrite, .pwrite_send_fn = vfswrap_pwrite_send, - .pwrite_recv_fn = vfswrap_asys_ssize_t_recv, + .pwrite_recv_fn = vfswrap_pwrite_recv, .lseek_fn = vfswrap_lseek, .sendfile_fn = vfswrap_sendfile, .recvfile_fn = vfswrap_recvfile,