diff options
author | Jeremy Allison <jra@samba.org> | 2017-03-02 09:13:23 -0800 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2017-03-06 16:02:16 +0100 |
commit | 083ff22e0a89b6efb982c750c3ebb39130626516 (patch) | |
tree | 8d2e2785ce839f76ec0995d710850a29ee76bc66 | |
parent | 3f71253ae50d4d51d24956245b254fb8c9fa5f1d (diff) | |
download | samba-083ff22e0a89b6efb982c750c3ebb39130626516.tar.gz |
s3: smbd: Restart reading the incoming SMB2 fd when the send queue is drained.
When the send queue grows greater than xconn->smb2.credits.max/16,
smbd_smb2_request_next_incoming() doesn't allocate a new request in state->req.
After smbd_smb2_io_handler() is called, it marks the fd not readable as
state->req == NULL, and never marks it readable again.
Fix by calling smbd_smb2_request_next_incoming() to restart
reads inside smbd_smb2_flush_send_queue() which drains the
send queue.
Reported by <chen.yehua@h3c.com>
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12608
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Fri Mar 3 02:23:20 CET 2017 on sn-devel-144
(cherry picked from commit 1e0c79ddb34be9a2b9fa92d35387c443c4a381ae)
Autobuild-User(v4-4-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-4-test): Mon Mar 6 16:02:16 CET 2017 on sn-devel-144
-rw-r--r-- | source3/smbd/smb2_server.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 8a4aa96fe9c..e1a24f63f75 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -3567,6 +3567,7 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn) int ret; int err; bool retry; + NTSTATUS status; if (xconn->smb2.send_queue == NULL) { TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde); @@ -3578,11 +3579,12 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn) bool ok; if (e->sendfile_header != NULL) { - NTSTATUS status = NT_STATUS_INTERNAL_ERROR; size_t size = 0; size_t i = 0; uint8_t *buf; + status = NT_STATUS_INTERNAL_ERROR; + for (i=0; i < e->count; i++) { size += e->vector[i].iov_len; } @@ -3654,6 +3656,16 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn) talloc_free(e->mem_ctx); } + /* + * Restart reads if we were blocked on + * draining the send queue. + */ + + status = smbd_smb2_request_next_incoming(xconn); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + return NT_STATUS_OK; } |