smb2_server: split smbd_smb2_advance_incoming() out of smbd_smb2_io_handler()
authorStefan Metzmacher <metze@samba.org>
Thu, 15 Apr 2021 08:23:37 +0000 (10:23 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 6 Sep 2023 19:30:35 +0000 (19:30 +0000)
The logic in smbd_smb2_advance_incoming() will be reused for io_uring.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/smb2_server.c

index 9a3cc8447bad18586a8fbf433e45078ff65fc986..3e47bc4042590cd8c23ad9b97662b0092095bdd7 100644 (file)
@@ -4879,89 +4879,22 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
        return NT_STATUS_OK;
 }
 
-static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
-                                    uint16_t fde_flags)
+static NTSTATUS smbd_smb2_advance_incoming(struct smbXsrv_connection *xconn, int ret)
 {
        struct smbd_server_connection *sconn = xconn->client->sconn;
        struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
        struct smbd_smb2_request *req = NULL;
        size_t min_recvfile_size = UINT32_MAX;
-       unsigned recvmsg_flags = 0;
-       int ret;
-       int err;
-       bool retry;
        NTSTATUS status;
        NTTIME now;
 
-       if (!NT_STATUS_IS_OK(xconn->transport.status)) {
-               /*
-                * we're not supposed to do any io
-                */
-               TEVENT_FD_NOT_READABLE(xconn->transport.fde);
-               TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
-               return NT_STATUS_OK;
-       }
-
-       if (fde_flags & TEVENT_FD_WRITE) {
-               status = smbd_smb2_flush_send_queue(xconn);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-       }
-
-       if (!(fde_flags & TEVENT_FD_READ)) {
-               return NT_STATUS_OK;
-       }
-
-       if (state->req == NULL) {
-               TEVENT_FD_NOT_READABLE(xconn->transport.fde);
-               return NT_STATUS_OK;
-       }
-
-again:
-
-       state->msg = (struct msghdr) {
-               .msg_iov = &state->vector,
-               .msg_iovlen = 1,
-       };
-
-#ifdef MSG_NOSIGNAL
-       recvmsg_flags |= MSG_NOSIGNAL;
-#endif
-#ifdef MSG_DONTWAIT
-       recvmsg_flags |= MSG_DONTWAIT;
-#endif
-
-       ret = recvmsg(xconn->transport.sock, &state->msg, recvmsg_flags);
-       if (ret == 0) {
-               /* propagate end of file */
-               status = NT_STATUS_END_OF_FILE;
-               smbXsrv_connection_disconnect_transport(xconn,
-                                                       status);
-               return status;
-       }
-       err = socket_error_from_errno(ret, errno, &retry);
-       if (retry) {
-               /* retry later */
-               TEVENT_FD_READABLE(xconn->transport.fde);
-               return NT_STATUS_OK;
-       }
-       if (err != 0) {
-               status = map_nt_error_from_unix_common(err);
-               smbXsrv_connection_disconnect_transport(xconn,
-                                                       status);
-               return status;
-       }
-
        if (ret < state->vector.iov_len) {
                uint8_t *base;
                base = (uint8_t *)state->vector.iov_base;
                base += ret;
                state->vector.iov_base = (void *)base;
                state->vector.iov_len -= ret;
-               /* we have more to read */
-               TEVENT_FD_READABLE(xconn->transport.fde);
-               return NT_STATUS_OK;
+               return NT_STATUS_PENDING;
        }
 
        if (state->pktlen > 0) {
@@ -4988,7 +4921,7 @@ again:
                        };
 
                        state->pktlen = state->pktfull;
-                       goto again;
+                       return NT_STATUS_RETRY;
                }
 
                /*
@@ -5039,7 +4972,7 @@ again:
                .iov_len = state->pktlen,
        };
 
-       goto again;
+       return NT_STATUS_RETRY;
 
 got_full:
 
@@ -5056,8 +4989,7 @@ got_full:
                                .iov_len = NBT_HDR_SIZE,
                        },
                };
-               req = NULL;
-               goto again;
+               return NT_STATUS_RETRY;
        }
 
        req = state->req;
@@ -5131,6 +5063,96 @@ got_full:
        return NT_STATUS_OK;
 }
 
+static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
+                                    uint16_t fde_flags)
+{
+       struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
+       unsigned recvmsg_flags = 0;
+       int ret;
+       int err;
+       bool retry;
+       NTSTATUS status;
+
+       if (!NT_STATUS_IS_OK(xconn->transport.status)) {
+               /*
+                * we're not supposed to do any io
+                */
+               TEVENT_FD_NOT_READABLE(xconn->transport.fde);
+               TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
+               return NT_STATUS_OK;
+       }
+
+       if (fde_flags & TEVENT_FD_WRITE) {
+               status = smbd_smb2_flush_send_queue(xconn);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       if (!(fde_flags & TEVENT_FD_READ)) {
+               return NT_STATUS_OK;
+       }
+
+       if (state->req == NULL) {
+               TEVENT_FD_NOT_READABLE(xconn->transport.fde);
+               return NT_STATUS_OK;
+       }
+
+again:
+
+       state->msg = (struct msghdr) {
+               .msg_iov = &state->vector,
+               .msg_iovlen = 1,
+       };
+
+#ifdef MSG_NOSIGNAL
+       recvmsg_flags |= MSG_NOSIGNAL;
+#endif
+#ifdef MSG_DONTWAIT
+       recvmsg_flags |= MSG_DONTWAIT;
+#endif
+
+       ret = recvmsg(xconn->transport.sock, &state->msg, recvmsg_flags);
+       if (ret == 0) {
+               /* propagate end of file */
+               status = NT_STATUS_END_OF_FILE;
+               smbXsrv_connection_disconnect_transport(xconn,
+                                                       status);
+               return status;
+       }
+       err = socket_error_from_errno(ret, errno, &retry);
+       if (retry) {
+               /* retry later */
+               TEVENT_FD_READABLE(xconn->transport.fde);
+               return NT_STATUS_OK;
+       }
+       if (err != 0) {
+               status = map_nt_error_from_unix_common(err);
+               smbXsrv_connection_disconnect_transport(xconn,
+                                                       status);
+               return status;
+       }
+
+       status = smbd_smb2_advance_incoming(xconn, ret);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING)) {
+               /* we have more to read */
+               TEVENT_FD_READABLE(xconn->transport.fde);
+               return NT_STATUS_OK;
+       }
+       if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+               /*
+                * smbd_smb2_advance_incoming setup a new vector
+                * that we should try to read immediately.
+                */
+               goto again;
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
 static void smbd_smb2_connection_handler(struct tevent_context *ev,
                                         struct tevent_fd *fde,
                                         uint16_t flags,