From eeefe5346d6e45fd65d9c30a03e354e710f3c052 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Jul 2017 14:51:33 +0200 Subject: [PATCH] smbd: Fix a connection run-down race condition When we do a server exit with active aio jobs, we need to keep the aio state active for the helper thread. Right now I don't see another chance than to leak memory in this case. And, I don't really oversee how cancelling requests works in this case, but this does fix crashes seen at a customer site. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12925 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison (cherry picked from commit 0181fcc4aaa730e3a88ff5d397145332f4013950) --- source3/modules/vfs_default.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 111a0c3aa71..350b5af5b67 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -750,6 +750,7 @@ struct vfswrap_pread_state { static void vfs_pread_do(void *private_data); static void vfs_pread_done(struct tevent_req *subreq); +static int vfs_pread_state_destructor(struct vfswrap_pread_state *state); static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, @@ -790,6 +791,8 @@ static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle, } tevent_req_set_callback(subreq, vfs_pread_done, req); + talloc_set_destructor(state, vfs_pread_state_destructor); + return req; } @@ -818,19 +821,23 @@ static void vfs_pread_do(void *private_data) SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); } +static int vfs_pread_state_destructor(struct vfswrap_pread_state *state) +{ + return -1; +} + static void vfs_pread_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); -#ifdef WITH_PROFILE struct vfswrap_pread_state *state = tevent_req_data( req, struct vfswrap_pread_state); -#endif int ret; ret = pthreadpool_tevent_job_recv(subreq); TALLOC_FREE(subreq); SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); + talloc_set_destructor(state, NULL); if (tevent_req_error(req, ret)) { return; } @@ -866,6 +873,7 @@ struct vfswrap_pwrite_state { static void vfs_pwrite_do(void *private_data); static void vfs_pwrite_done(struct tevent_req *subreq); +static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state); static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, @@ -906,6 +914,8 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle, } tevent_req_set_callback(subreq, vfs_pwrite_done, req); + talloc_set_destructor(state, vfs_pwrite_state_destructor); + return req; } @@ -934,19 +944,23 @@ static void vfs_pwrite_do(void *private_data) SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); } +static int vfs_pwrite_state_destructor(struct vfswrap_pwrite_state *state) +{ + return -1; +} + 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); + talloc_set_destructor(state, NULL); if (tevent_req_error(req, ret)) { return; } @@ -979,6 +993,7 @@ struct vfswrap_fsync_state { static void vfs_fsync_do(void *private_data); static void vfs_fsync_done(struct tevent_req *subreq); +static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state); static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, @@ -1012,6 +1027,8 @@ static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle, } tevent_req_set_callback(subreq, vfs_fsync_done, req); + talloc_set_destructor(state, vfs_fsync_state_destructor); + return req; } @@ -1035,19 +1052,23 @@ static void vfs_fsync_do(void *private_data) state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time); } +static int vfs_fsync_state_destructor(struct vfswrap_fsync_state *state) +{ + return -1; +} + static void vfs_fsync_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); -#ifdef WITH_PROFILE struct vfswrap_fsync_state *state = tevent_req_data( req, struct vfswrap_fsync_state); -#endif int ret; ret = pthreadpool_tevent_job_recv(subreq); TALLOC_FREE(subreq); SMBPROFILE_BASIC_ASYNC_END(state->profile_basic); + talloc_set_destructor(state, NULL); if (tevent_req_error(req, ret)) { return; } -- 2.14.0.rc0.284.gd933b75aa4-goog