mirror of
https://github.com/samba-team/samba.git
synced 2025-02-04 17:47:26 +03:00
s3:smb2_server: generate a header blob for the sendfile path
We need to pass the NBT header, SMB2 header and SMB2 Read header as header blob to SMB_VFS_SENDFILE(). This allows the usage of MSG_SEND or other tricks to avoid multiple TCP packets on the wire. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: David Disseldorp <ddiss@samba.org>
This commit is contained in:
parent
9d33a3f3e8
commit
36efaac259
@ -470,6 +470,7 @@ NTSTATUS smbXsrv_open_cleanup(uint64_t persistent_id);
|
|||||||
struct smbd_smb2_send_queue {
|
struct smbd_smb2_send_queue {
|
||||||
struct smbd_smb2_send_queue *prev, *next;
|
struct smbd_smb2_send_queue *prev, *next;
|
||||||
|
|
||||||
|
DATA_BLOB *sendfile_header;
|
||||||
struct iovec *vector;
|
struct iovec *vector;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
@ -166,6 +166,7 @@ struct smbd_smb2_read_state {
|
|||||||
uint32_t in_length;
|
uint32_t in_length;
|
||||||
uint64_t in_offset;
|
uint64_t in_offset;
|
||||||
uint32_t in_minimum;
|
uint32_t in_minimum;
|
||||||
|
DATA_BLOB out_headers;
|
||||||
DATA_BLOB out_data;
|
DATA_BLOB out_data;
|
||||||
uint32_t out_remaining;
|
uint32_t out_remaining;
|
||||||
};
|
};
|
||||||
@ -180,10 +181,10 @@ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state)
|
|||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
|
|
||||||
nread = SMB_VFS_SENDFILE(fsp->conn->sconn->sock,
|
nread = SMB_VFS_SENDFILE(fsp->conn->sconn->sock,
|
||||||
fsp,
|
fsp,
|
||||||
NULL,
|
state->smb2req->queue_entry.sendfile_header,
|
||||||
in_offset,
|
in_offset,
|
||||||
in_length);
|
in_length);
|
||||||
DEBUG(10,("smb2_sendfile_send_data: SMB_VFS_SENDFILE returned %d on file %s\n",
|
DEBUG(10,("smb2_sendfile_send_data: SMB_VFS_SENDFILE returned %d on file %s\n",
|
||||||
(int)nread,
|
(int)nread,
|
||||||
fsp_str_dbg(fsp) ));
|
fsp_str_dbg(fsp) ));
|
||||||
@ -301,6 +302,7 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
|
|||||||
}
|
}
|
||||||
*state_copy = *state;
|
*state_copy = *state;
|
||||||
talloc_set_destructor(state_copy, smb2_sendfile_send_data);
|
talloc_set_destructor(state_copy, smb2_sendfile_send_data);
|
||||||
|
state->smb2req->queue_entry.sendfile_header = &state_copy->out_headers;
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2680,7 +2680,7 @@ NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
|
|||||||
do_encryption = true;
|
do_encryption = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = talloc(sconn, struct smbd_smb2_send_oplock_break_state);
|
state = talloc_zero(sconn, struct smbd_smb2_send_oplock_break_state);
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
return NT_STATUS_NO_MEMORY;
|
return NT_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
@ -2983,6 +2983,38 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbd_server_connection *sconn)
|
|||||||
while (sconn->smb2.send_queue != NULL) {
|
while (sconn->smb2.send_queue != NULL) {
|
||||||
struct smbd_smb2_send_queue *e = sconn->smb2.send_queue;
|
struct smbd_smb2_send_queue *e = sconn->smb2.send_queue;
|
||||||
|
|
||||||
|
if (e->sendfile_header != NULL) {
|
||||||
|
size_t size = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
|
for (i=0; i < e->count; i++) {
|
||||||
|
size += e->vector[i].iov_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = talloc_array(e->mem_ctx, uint8_t, size);
|
||||||
|
if (buf == NULL) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
for (i=0; i < e->count; i++) {
|
||||||
|
memcpy(buf+size,
|
||||||
|
e->vector[i].iov_base,
|
||||||
|
e->vector[i].iov_len);
|
||||||
|
size += e->vector[i].iov_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
e->sendfile_header->data = buf;
|
||||||
|
e->sendfile_header->length = size;
|
||||||
|
e->count = 0;
|
||||||
|
|
||||||
|
sconn->smb2.send_queue_len--;
|
||||||
|
DLIST_REMOVE(sconn->smb2.send_queue, e);
|
||||||
|
talloc_free(e->mem_ctx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ret = writev(sconn->sock, e->vector, e->count);
|
ret = writev(sconn->sock, e->vector, e->count);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* propagate end of file */
|
/* propagate end of file */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user