From: Stefan Metzmacher Date: Mon, 27 Aug 2018 11:02:50 +0000 (+0200) Subject: smb2_server: use sendmsg/recvmsg instead of writev/readv X-Git-Tag: ldb-2.1.1~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76e1206717e76dadc212f3363d3faeb66b18c7e7;p=thirdparty%2Fsamba.git smb2_server: use sendmsg/recvmsg instead of writev/readv This avoids a few function calls inside the kernel in order to reach sock_sendmsg() quicker: entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_writev do_writev vfs_writev do_iter_write do_iter_readv_writev sock_write_iter sock_sendmsg entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_sendmsg __sys_sendmsg ___sys_sendmsg sock_sendmsg As a side effect it will be useful for SMB-Direct invalidation messages via msg->msg_control and CMSG_*. Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 8c66d74c8de..a4372bf1145 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -3758,6 +3758,7 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn) while (xconn->smb2.send_queue != NULL) { struct smbd_smb2_send_queue *e = xconn->smb2.send_queue; bool ok; + struct msghdr msg; if (e->sendfile_header != NULL) { size_t size = 0; @@ -3806,7 +3807,12 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn) continue; } - ret = writev(xconn->transport.sock, e->vector, e->count); + msg = (struct msghdr) { + .msg_iov = e->vector, + .msg_iovlen = e->count, + }; + + ret = sendmsg(xconn->transport.sock, &msg, 0); if (ret == 0) { /* propagate end of file */ return NT_STATUS_INTERNAL_ERROR; @@ -3862,6 +3868,7 @@ static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn, bool retry; NTSTATUS status; NTTIME now; + struct msghdr msg; if (!NT_STATUS_IS_OK(xconn->transport.status)) { /* @@ -3896,7 +3903,12 @@ again: state->vector.iov_len = NBT_HDR_SIZE; } - ret = readv(xconn->transport.sock, &state->vector, 1); + msg = (struct msghdr) { + .msg_iov = &state->vector, + .msg_iovlen = 1, + }; + + ret = recvmsg(xconn->transport.sock, &msg, 0); if (ret == 0) { /* propagate end of file */ return NT_STATUS_END_OF_FILE;