|
|
9bf74a |
From 9e56b84c41efcaf3349f82a93c3dc854e172e5c4 Mon Sep 17 00:00:00 2001
|
|
|
9bf74a |
From: Kamil Dudka <kdudka@redhat.com>
|
|
|
9bf74a |
Date: Fri, 9 Aug 2013 16:22:08 +0200
|
|
|
9bf74a |
Subject: [PATCH 4/5] partially revert "window_size: explicit adjustments only"
|
|
|
9bf74a |
|
|
|
9bf74a |
This partially reverts commit 03ca9020756a4e16f0294e5b35e9826ee6af2364
|
|
|
9bf74a |
in order to fix extreme slowdown when uploading to localhost via SFTP.
|
|
|
9bf74a |
|
|
|
9bf74a |
I was able to repeat the issue on RHEL-7 on localhost only. It did not
|
|
|
9bf74a |
occur when uploading via network and it did not occur on a RHEL-6 box
|
|
|
9bf74a |
with the same version of libssh2.
|
|
|
9bf74a |
|
|
|
9bf74a |
The problem was that sftp_read() used a read-ahead logic to figure out
|
|
|
9bf74a |
the window_size, but sftp_packet_read() called indirectly from
|
|
|
9bf74a |
sftp_write() did not use any read-ahead logic.
|
|
|
9bf74a |
---
|
|
|
9bf74a |
src/channel.c | 29 +++++++++++++++++++++++++++++
|
|
|
9bf74a |
1 files changed, 29 insertions(+), 0 deletions(-)
|
|
|
9bf74a |
|
|
|
9bf74a |
diff --git a/src/channel.c b/src/channel.c
|
|
|
9bf74a |
index 4f41e1f..d4ffdce 100644
|
|
|
9bf74a |
--- a/src/channel.c
|
|
|
9bf74a |
+++ b/src/channel.c
|
|
|
9bf74a |
@@ -1759,6 +1759,15 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
|
|
9bf74a |
channel->read_state = libssh2_NB_state_created;
|
|
|
9bf74a |
}
|
|
|
9bf74a |
|
|
|
9bf74a |
+ /*
|
|
|
9bf74a |
+ * =============================== NOTE ===============================
|
|
|
9bf74a |
+ * I know this is very ugly and not a really good use of "goto", but
|
|
|
9bf74a |
+ * this case statement would be even uglier to do it any other way
|
|
|
9bf74a |
+ */
|
|
|
9bf74a |
+ if (channel->read_state == libssh2_NB_state_jump1) {
|
|
|
9bf74a |
+ goto channel_read_window_adjust;
|
|
|
9bf74a |
+ }
|
|
|
9bf74a |
+
|
|
|
9bf74a |
rc = 1; /* set to >0 to let the while loop start */
|
|
|
9bf74a |
|
|
|
9bf74a |
/* Process all pending incoming packets in all states in order to "even
|
|
|
9bf74a |
@@ -1867,6 +1876,26 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
|
|
9bf74a |
more off the network again */
|
|
|
9bf74a |
channel->read_state = libssh2_NB_state_created;
|
|
|
9bf74a |
|
|
|
9bf74a |
+ if(channel->remote.window_size < (LIBSSH2_CHANNEL_WINDOW_DEFAULT*30)) {
|
|
|
9bf74a |
+ /* the window is getting too narrow, expand it! */
|
|
|
9bf74a |
+
|
|
|
9bf74a |
+ channel_read_window_adjust:
|
|
|
9bf74a |
+ channel->read_state = libssh2_NB_state_jump1;
|
|
|
9bf74a |
+ /* the actual window adjusting may not finish so we need to deal with
|
|
|
9bf74a |
+ this special state here */
|
|
|
9bf74a |
+ rc = _libssh2_channel_receive_window_adjust(channel,
|
|
|
9bf74a |
+ (LIBSSH2_CHANNEL_WINDOW_DEFAULT*60), 0, NULL);
|
|
|
9bf74a |
+ if (rc)
|
|
|
9bf74a |
+ return rc;
|
|
|
9bf74a |
+
|
|
|
9bf74a |
+ _libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
|
|
9bf74a |
+ "channel_read() filled %d adjusted %d",
|
|
|
9bf74a |
+ bytes_read, buflen);
|
|
|
9bf74a |
+ /* continue in 'created' state to drain the already read packages
|
|
|
9bf74a |
+ first before starting to empty the socket further */
|
|
|
9bf74a |
+ channel->read_state = libssh2_NB_state_created;
|
|
|
9bf74a |
+ }
|
|
|
9bf74a |
+
|
|
|
9bf74a |
return bytes_read;
|
|
|
9bf74a |
}
|
|
|
9bf74a |
|
|
|
9bf74a |
--
|
|
|
9bf74a |
1.7.1
|
|
|
9bf74a |
|