smbd: Fix a connection run-down race condition
authorVolker Lendecke <vl@samba.org>
Wed, 19 Jul 2017 12:51:33 +0000 (14:51 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 19 Jul 2017 19:22:12 +0000 (21:22 +0200)
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.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/vfs_default.c

index bf857b6b1ca3fc1929aa67d83899ca38a4cd9245..fbfe654f1fd3fadad0ed00f5f2695f6d39eee55e 100644 (file)
@@ -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;
        }