s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[garming/samba-autobuild/.git] / source3 / smbd / aio.c
index a5a0e44738d4f54ee1217bfdaddf674c36d41e93..db2926b4a4f3a41ff579d2152820d276a2f7aaff 100644 (file)
@@ -19,7 +19,9 @@
 */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "smbd/globals.h"
+#include "../lib/util/tevent_ntstatus.h"
 
 #if defined(WITH_AIO)
 
@@ -67,23 +69,31 @@ static void smbd_aio_signal_handler(struct tevent_context *ev_ctx,
 }
 
 
-static void initialize_async_io_handler(void)
+static bool initialize_async_io_handler(void)
 {
+       static bool tried_signal_setup = false;
+
        if (aio_signal_event) {
-               return;
+               return true;
+       }
+       if (tried_signal_setup) {
+               return false;
        }
+       tried_signal_setup = true;
 
-       aio_signal_event = tevent_add_signal(smbd_event_context(),
-                                            smbd_event_context(),
+       aio_signal_event = tevent_add_signal(server_event_context(),
+                                            server_event_context(),
                                             RT_SIGNAL_AIO, SA_SIGINFO,
                                             smbd_aio_signal_handler,
                                             NULL);
        if (!aio_signal_event) {
-               exit_server("Failed to setup RT_SIGNAL_AIO handler");
+               DEBUG(10, ("Failed to setup RT_SIGNAL_AIO handler\n"));
+               return false;
        }
 
        /* tevent supports 100 signal with SA_SIGINFO */
        aio_pending_size = 100;
+       return true;
 }
 
 static int handle_aio_read_complete(struct aio_extra *aio_ex, int errcode);
@@ -106,7 +116,7 @@ static struct aio_extra *create_aio_extra(TALLOC_CTX *mem_ctx,
                                        files_struct *fsp,
                                        size_t buflen)
 {
-       struct aio_extra *aio_ex = TALLOC_ZERO_P(mem_ctx, struct aio_extra);
+       struct aio_extra *aio_ex = talloc_zero(mem_ctx, struct aio_extra);
 
        if (!aio_ex) {
                return NULL;
@@ -145,7 +155,9 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
        int ret;
 
        /* Ensure aio is initialized. */
-       initialize_async_io_handler();
+       if (!initialize_async_io_handler()) {
+               return NT_STATUS_RETRY;
+       }
 
        if (fsp->base_fsp != NULL) {
                /* No AIO on streams yet */
@@ -239,7 +251,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
 
 NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
                              struct smb_request *smbreq,
-                             files_struct *fsp, char *data,
+                             files_struct *fsp, const char *data,
                              SMB_OFF_T startpos,
                              size_t numtowrite)
 {
@@ -250,7 +262,9 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
        int ret;
 
        /* Ensure aio is initialized. */
-       initialize_async_io_handler();
+       if (!initialize_async_io_handler()) {
+               return NT_STATUS_RETRY;
+       }
 
        if (fsp->base_fsp != NULL) {
                /* No AIO on streams yet */
@@ -315,7 +329,7 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
        /* Now set up the aio record for the write call. */
 
        a->aio_fildes = fsp->fh->fd;
-       a->aio_buf = data;
+       a->aio_buf = discard_const_p(char, data);
        a->aio_nbytes = numtowrite;
        a->aio_offset = startpos;
        a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
@@ -345,12 +359,13 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
                SSVAL(aio_ex->outbuf.data,smb_vwv2,numtowrite);
                 SSVAL(aio_ex->outbuf.data,smb_vwv4,(numtowrite>>16)&1);
                show_msg((char *)aio_ex->outbuf.data);
-               if (!srv_send_smb(smbd_server_fd(),(char *)aio_ex->outbuf.data,
+               if (!srv_send_smb(aio_ex->smbreq->sconn,
+                               (char *)aio_ex->outbuf.data,
                                true, aio_ex->smbreq->seqnum+1,
                                IS_CONN_ENCRYPTED(fsp->conn),
                                &aio_ex->smbreq->pcd)) {
-                       exit_server_cleanly("handle_aio_write: srv_send_smb "
-                                           "failed.");
+                       exit_server_cleanly("schedule_aio_write_and_X: "
+                                           "srv_send_smb failed.");
                }
                DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
                          "behind for file %s\n", fsp_str_dbg(fsp)));
@@ -372,7 +387,8 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
 NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
                                struct smb_request *smbreq,
                                files_struct *fsp,
-                               char *inbuf,
+                               TALLOC_CTX *ctx,
+                               DATA_BLOB *preadbuf,
                                SMB_OFF_T startpos,
                                size_t smb_maxcnt)
 {
@@ -382,7 +398,9 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
        int ret;
 
        /* Ensure aio is initialized. */
-       initialize_async_io_handler();
+       if (!initialize_async_io_handler()) {
+               return NT_STATUS_RETRY;
+       }
 
        if (fsp->base_fsp != NULL) {
                /* No AIO on streams yet */
@@ -412,6 +430,12 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
                return NT_STATUS_RETRY;
        }
 
+       /* Create the out buffer. */
+       *preadbuf = data_blob_talloc(ctx, NULL, smb_maxcnt);
+       if (preadbuf->data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        if (!(aio_ex = create_aio_extra(smbreq->smb2req, fsp, 0))) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -432,7 +456,7 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
        /* Now set up the aio record for the read call. */
 
        a->aio_fildes = fsp->fh->fd;
-       a->aio_buf = inbuf;
+       a->aio_buf = preadbuf->data;
        a->aio_nbytes = smb_maxcnt;
        a->aio_offset = startpos;
        a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
@@ -478,7 +502,9 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
        int ret;
 
        /* Ensure aio is initialized. */
-       initialize_async_io_handler();
+       if (!initialize_async_io_handler()) {
+               return NT_STATUS_RETRY;
+       }
 
        if (fsp->base_fsp != NULL) {
                /* No AIO on streams yet */
@@ -616,7 +642,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex, int errcode)
        }
        smb_setlen(outbuf,outsize - 4);
        show_msg(outbuf);
-       if (!srv_send_smb(smbd_server_fd(),outbuf,
+       if (!srv_send_smb(aio_ex->smbreq->sconn, outbuf,
                        true, aio_ex->smbreq->seqnum+1,
                        IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) {
                exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
@@ -705,11 +731,12 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex, int errcode)
        }
 
        show_msg(outbuf);
-       if (!srv_send_smb(smbd_server_fd(),outbuf,
+       if (!srv_send_smb(aio_ex->smbreq->sconn, outbuf,
                          true, aio_ex->smbreq->seqnum+1,
                          IS_CONN_ENCRYPTED(fsp->conn),
                          NULL)) {
-               exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
+               exit_server_cleanly("handle_aio_write_complete: "
+                                   "srv_send_smb failed.");
        }
 
        DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
@@ -882,7 +909,7 @@ int wait_for_aio_completion(files_struct *fsp)
        struct aio_extra *aio_ex;
        const SMB_STRUCT_AIOCB **aiocb_list;
        int aio_completion_count = 0;
-       time_t start_time = time(NULL);
+       time_t start_time = time_mono(NULL);
        int seconds_left;
 
        for (seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT;
@@ -957,7 +984,7 @@ int wait_for_aio_completion(files_struct *fsp)
 
                SAFE_FREE(aiocb_list);
                seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT
-                       - (time(NULL) - start_time);
+                       - (time_mono(NULL) - start_time);
        }
 
        /* We timed out - we don't know why. Return ret if already an error,
@@ -1003,7 +1030,7 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
 
 NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
                              struct smb_request *smbreq,
-                             files_struct *fsp, char *data,
+                             files_struct *fsp, const char *data,
                              SMB_OFF_T startpos,
                              size_t numtowrite)
 {
@@ -1013,7 +1040,8 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
 NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
                                 struct smb_request *smbreq,
                                 files_struct *fsp,
-                                char *inbuf,
+                               TALLOC_CTX *ctx,
+                               DATA_BLOB *preadbuf,
                                 SMB_OFF_T startpos,
                                 size_t smb_maxcnt)
 {