return NT_STATUS_OK;
}
+static void smbd_smb2_flush_completion_io_uring(struct samba_io_uring_qe *qe,
+ const char *location);
+
static NTSTATUS smbd_smb2_flush_with_io_uring(struct smbXsrv_connection *xconn)
{
int ret;
while (xconn->smb2.send_queue != NULL) {
struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
+ struct samba_io_uring_qe *qe = NULL;
+
+ if (e->io_uring.num_qes != 0) {
+ continue;
+ }
SMB_ASSERT(e->sendfile_header == NULL);
.msg_iovlen = e->count,
};
- ret = sendmsg(xconn->transport.sock, &e->msg, MSG_DONTWAIT);
- if (ret == 0) {
- /* propagate end of file */
- return NT_STATUS_INTERNAL_ERROR;
- }
- err = socket_error_from_errno(ret, errno, &retry);
- if (retry) {
- /* retry later */
- TEVENT_FD_WRITEABLE(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;
- }
+ qe = &e->io_uring.qes[e->io_uring.num_qes++];
+ io_uring_prep_sendmsg(&qe->sqe,
+ xconn->transport.sock,
+ &e->msg,
+ 0);
+ qe->drain = true;
+ qe->private_data = e;
+ qe->completion_fn = smbd_smb2_flush_completion_io_uring;
- status = smbd_smb2_advance_send_queue(xconn, e, ret);
- if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
- /* retry later */
- TEVENT_FD_WRITEABLE(xconn->transport.fde);
- return NT_STATUS_OK;
- }
- if (!NT_STATUS_IS_OK(status)) {
- smbXsrv_connection_disconnect_transport(xconn,
- status);
- return status;
- }
+ samba_io_uring_request_submit(xconn->smb2.send_uring,
+ &e->io_uring);
}
return NT_STATUS_OK;
}
+static void smbd_smb2_flush_completion_io_uring(struct samba_io_uring_qe *qe,
+ const char *location)
+{
+ struct smbd_smb2_send_queue *e =
+ (struct smbd_smb2_send_queue *)qe->private_data;
+ struct smbXsrv_connection *xconn = e->xconn;
+ NTSTATUS status = NT_STATUS_OK;
+ int ret;
+
+ ret = qe->cqe.res;
+ if (ret > 0) {
+ status = NT_STATUS_OK;
+ } else if (ret == 0) {
+ /* propagate end of file */
+ status = NT_STATUS_INTERNAL_ERROR;
+ } else if (ret < 0) {
+ status = map_nt_error_from_unix_common(-ret);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ smbXsrv_connection_disconnect_transport(xconn,
+ status);
+ smbd_server_connection_terminate_ex(xconn,
+ nt_errstr(status),
+ location);
+ return;
+ }
+
+ status = smbd_smb2_advance_send_queue(xconn, e, ret);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+ /* retry later */
+ ZERO_STRUCT(e->io_uring);
+ smbd_smb2_flush_send_queue(xconn);
+ return;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ smbXsrv_connection_disconnect_transport(xconn,
+ status);
+ smbd_server_connection_terminate_ex(xconn,
+ nt_errstr(status),
+ __location__);
+ return;
+ }
+}
+
static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
{
NTSTATUS status;