hack avoid tevent_req_create on read
authorStefan Metzmacher <metze@samba.org>
Thu, 5 Dec 2013 12:37:50 +0000 (13:37 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 12 Mar 2014 23:04:55 +0000 (00:04 +0100)
source3/smbd/globals.h
source3/smbd/smb2_read.c
source3/smbd/smb2_server.c

index cd99fe72ca154423aa53f330ab46a58ef9eeb1a9..65b18199a7aa0296b5a68691f2a5de04d97c617b 100644 (file)
@@ -474,6 +474,8 @@ struct smbd_smb2_send_queue {
        struct smbd_smb2_send_queue *prev, *next;
 
        DATA_BLOB *sendfile_header;
+       void (*sendfile_fn)(void *sendfile_private);
+       void *sendfile_private;
        struct iovec *vector;
        int count;
 
index 7413b00995fe52320213269fd4aaf155fcf5c27c..6f9a954e75099d368dabc5626f3145b85f3e098d 100644 (file)
@@ -94,15 +94,18 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
        if (subreq == NULL) {
                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
        }
-       tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
+       //tevent_req_set_callback(subreq, smbd_smb2_request_read_done, req);
 
+       smbd_smb2_request_read_done(req);
+       return NT_STATUS_OK;
        return smbd_smb2_request_pending_queue(req, subreq, 500);
 }
 
 static void smbd_smb2_request_read_done(struct tevent_req *subreq)
 {
-       struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
-                                       struct smbd_smb2_request);
+       struct smbd_smb2_request *req = subreq;//tevent_req_callback_data(subreq,
+                                       //struct smbd_smb2_request);
+                                       subreq = NULL;
        DATA_BLOB outbody;
        DATA_BLOB outdyn;
        uint8_t out_data_offset;
@@ -172,6 +175,8 @@ struct smbd_smb2_read_state {
        uint32_t out_remaining;
 };
 
+static struct smbd_smb2_read_state _state;
+
 static int smb2_smb2_read_state_deny_destructor(struct smbd_smb2_read_state *state)
 {
        return -1;
@@ -261,6 +266,12 @@ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state)
        return 0;
 }
 
+static void smb2_sendfile_fn(struct smbd_smb2_read_state *state)
+{
+       smb2_sendfile_send_data(state);
+       ZERO_STRUCTP(state);
+}
+
 static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
                                        struct smbd_smb2_read_state *state)
 {
@@ -312,8 +323,8 @@ static void smbd_smb2_read_pipe_done(struct tevent_req *subreq);
 
 NTSTATUS smb2_read_complete(struct tevent_req *req, ssize_t nread, int err)
 {
-       struct smbd_smb2_read_state *state = tevent_req_data(req,
-                                       struct smbd_smb2_read_state);
+       struct smbd_smb2_read_state *state = &_state;//tevent_req_data(req,
+                                       //struct smbd_smb2_read_state);
        files_struct *fsp = state->fsp;
 
        if (nread < 0) {
@@ -358,9 +369,9 @@ NTSTATUS smb2_read_complete(struct tevent_req *req, ssize_t nread, int err)
 
 static bool smbd_smb2_read_cancel(struct tevent_req *req)
 {
-       struct smbd_smb2_read_state *state =
-               tevent_req_data(req,
-               struct smbd_smb2_read_state);
+       struct smbd_smb2_read_state *state = &_state;
+               //tevent_req_data(req,
+               //struct smbd_smb2_read_state);
 
        return cancel_smb2_aio(state->smbreq);
 }
@@ -375,7 +386,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
                                              uint32_t in_remaining)
 {
        NTSTATUS status;
-       struct tevent_req *req = NULL;
+       //struct tevent_req *req = NULL;
        struct smbd_smb2_read_state *state = NULL;
        struct smb_request *smbreq = NULL;
        connection_struct *conn = smb2req->tcon->compat;
@@ -383,11 +394,13 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
        struct lock_struct lock;
        int saved_errno;
 
-       req = tevent_req_create(mem_ctx, &state,
-                               struct smbd_smb2_read_state);
-       if (req == NULL) {
-               return NULL;
-       }
+       //req = tevent_req_create(mem_ctx, &state,
+       //                      struct smbd_smb2_read_state);
+       //if (req == NULL) {
+       //      return NULL;
+       //}
+       state = &_state;
+       ZERO_STRUCTP(state);
        state->smb2req = smb2req;
        state->in_length = in_length;
        state->in_offset = in_offset;
@@ -399,48 +412,48 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
                  fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
 
        smbreq = smbd_smb2_fake_smb_request(smb2req);
-       if (tevent_req_nomem(smbreq, req)) {
-               return tevent_req_post(req, ev);
-       }
+       //if (tevent_req_nomem(smbreq, req)) {
+       //      return tevent_req_post(req, ev);
+       //}
        state->smbreq = smbreq;
 
-       if (fsp->is_directory) {
-               tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
-               return tevent_req_post(req, ev);
-       }
+       //if (fsp->is_directory) {
+       //      tevent_req_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
+       //      return tevent_req_post(req, ev);
+       //}
 
        state->fsp = fsp;
 
-       if (IS_IPC(smbreq->conn)) {
-               struct tevent_req *subreq = NULL;
-
-               state->out_data = data_blob_talloc(state, NULL, in_length);
-               if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
-                       return tevent_req_post(req, ev);
-               }
-
-               if (!fsp_is_np(fsp)) {
-                       tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
-                       return tevent_req_post(req, ev);
-               }
-
-               subreq = np_read_send(state, ev,
-                                     fsp->fake_file_handle,
-                                     state->out_data.data,
-                                     state->out_data.length);
-               if (tevent_req_nomem(subreq, req)) {
-                       return tevent_req_post(req, ev);
-               }
-               tevent_req_set_callback(subreq,
-                                       smbd_smb2_read_pipe_done,
-                                       req);
-               return req;
-       }
-
-       if (!CHECK_READ(fsp, smbreq)) {
-               tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-               return tevent_req_post(req, ev);
-       }
+       //if (IS_IPC(smbreq->conn)) {
+       //      struct tevent_req *subreq = NULL;
+
+       //      state->out_data = data_blob_talloc(state, NULL, in_length);
+       //      if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
+       //              return tevent_req_post(req, ev);
+       //      }
+
+       //      if (!fsp_is_np(fsp)) {
+       //              tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+       //              return tevent_req_post(req, ev);
+       //      }
+
+       //      subreq = np_read_send(state, ev,
+       //                            fsp->fake_file_handle,
+       //                            state->out_data.data,
+       //                            state->out_data.length);
+       //      if (tevent_req_nomem(subreq, req)) {
+       //              return tevent_req_post(req, ev);
+       //      }
+       //      tevent_req_set_callback(subreq,
+       //                              smbd_smb2_read_pipe_done,
+       //                              req);
+       //      return req;
+       //}
+
+       //if (!CHECK_READ(fsp, smbreq)) {
+       //      tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+       //      return tevent_req_post(req, ev);
+       //}
 
        status = schedule_smb2_aio_read(fsp->conn,
                                smbreq,
@@ -455,15 +468,16 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
                 * Doing an async read, allow this
                 * request to be canceled
                 */
-               tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
-               return req;
+               //tevent_req_set_cancel_fn(req, smbd_smb2_read_cancel);
+               return state;
+               //return req;
        }
 
-       if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
-               /* Real error in setting up aio. Fail. */
-               tevent_req_nterror(req, status);
-               return tevent_req_post(req, ev);
-       }
+       //if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+       //      /* Real error in setting up aio. Fail. */
+       //      tevent_req_nterror(req, status);
+       //      return tevent_req_post(req, ev);
+       //}
 
        /* Fallback to synchronous. */
 
@@ -475,29 +489,29 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
                                &lock);
 
        if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) {
-               tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-               return tevent_req_post(req, ev);
+       //      tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+       //      return tevent_req_post(req, ev);
        }
 
        /* Try sendfile in preference. */
        status = schedule_smb2_sendfile_read(smb2req, state);
        if (NT_STATUS_IS_OK(status)) {
-               tevent_req_done(req);
-               return req;//tevent_req_post(req, ev);
+               //tevent_req_done(req);
+               return state;//req;//tevent_req_post(req, ev);
        } else {
-               if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
-                       SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-                       tevent_req_nterror(req, status);
-                       return tevent_req_post(req, ev);
-               }
+//             if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+//                     SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+//                     tevent_req_nterror(req, status);
+//                     return tevent_req_post(req, ev);
+//             }
        }
 
        /* Ok, read into memory. Allocate the out buffer. */
        state->out_data = data_blob_talloc(state, NULL, in_length);
-       if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
-               SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
-               return tevent_req_post(req, ev);
-       }
+//     if (in_length > 0 && tevent_req_nomem(state->out_data.data, req)) {
+//             SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
+//             return tevent_req_post(req, ev);
+//     }
 
        nread = read_file(fsp,
                          (char *)state->out_data.data,
@@ -516,22 +530,22 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
                (unsigned long long)in_length,
                (long long)nread));
 
-       status = smb2_read_complete(req, nread, saved_errno);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-       } else {
-               /* Success. */
-               tevent_req_done(req);
-       }
-       return req;//tevent_req_post(req, ev);
+       status = smb2_read_complete(NULL, nread, saved_errno);
+//     if (!NT_STATUS_IS_OK(status)) {
+//             tevent_req_nterror(req, status);
+//     } else {
+//             /* Success. */
+//             tevent_req_done(req);
+//     }
+       return state;//req;//tevent_req_post(req, ev);
 }
 
 static void smbd_smb2_read_pipe_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(subreq,
                                 struct tevent_req);
-       struct smbd_smb2_read_state *state = tevent_req_data(req,
-                                            struct smbd_smb2_read_state);
+       struct smbd_smb2_read_state *state = &_state;//tevent_req_data(req,
+                                            //struct smbd_smb2_read_state);
        NTSTATUS status;
        ssize_t nread = -1;
        bool is_data_outstanding;
@@ -567,26 +581,28 @@ static NTSTATUS smbd_smb2_read_recv(struct tevent_req *req,
                                    uint32_t *out_remaining)
 {
        NTSTATUS status;
-       struct smbd_smb2_read_state *state = tevent_req_data(req,
-                                            struct smbd_smb2_read_state);
+       struct smbd_smb2_read_state *state = &_state;//tevent_req_data(req,
+                                            //struct smbd_smb2_read_state);
 
-       if (tevent_req_is_nterror(req, &status)) {
-               tevent_req_received(req);
-               return status;
-       }
+       //if (tevent_req_is_nterror(req, &status)) {
+       //      tevent_req_received(req);
+       //      return status;
+       //}
 
        *out_data = state->out_data;
        talloc_steal(mem_ctx, out_data->data);
        *out_remaining = state->out_remaining;
 
        if (state->out_headers.length > 0) {
-               talloc_steal(mem_ctx, state);
-               talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor);
-               tevent_req_received(req);
+               //talloc_steal(mem_ctx, state);
+               //talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor);
+               //tevent_req_received(req);
                state->smb2req->queue_entry.sendfile_header = &state->out_headers;
-               talloc_set_destructor(state, smb2_sendfile_send_data);
+               state->smb2req->queue_entry.sendfile_private = state;
+               state->smb2req->queue_entry.sendfile_fn = smb2_sendfile_fn;
+               //talloc_set_destructor(state, smb2_sendfile_send_data);
        } else {
-               tevent_req_received(req);
+               //tevent_req_received(req);
        }
 
        return NT_STATUS_OK;
index ad375ce278d61fffc7046b75bab2af9cf6ad9710..9bd20370d6c6bf097e9494d51862f68df76248b0 100644 (file)
@@ -3090,6 +3090,7 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbd_server_connection *sconn)
                         * This triggers the sendfile path via
                         * the destructor.
                         */
+                       e->sendfile_fn(e->sendfile_private);
                        talloc_free(e->mem_ctx);
                        continue;
                }