From f8970471e06da3e1dee53b1f62df54ca001deed5 Mon Sep 17 00:00:00 2001 From: Brian Bockelman Date: Sat, 30 Jan 2021 09:40:01 -0600 Subject: [PATCH] XrdTpc: Do not allow partial buffer writes The multistream code uses an occupied buffer as an indication that a request is ongoing; for now, we can't do partial buffer writes as this causes the back-off code to think the buffer is free and start too many requests. --- src/XrdTpc/XrdTpcStream.hh | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/XrdTpc/XrdTpcStream.hh b/src/XrdTpc/XrdTpcStream.hh index 29851a99efc..0e854334d53 100644 --- a/src/XrdTpc/XrdTpcStream.hh +++ b/src/XrdTpc/XrdTpcStream.hh @@ -82,29 +82,22 @@ private: int Write(Stream &stream, bool force) { if (Available() || !CanWrite(stream)) {return 0;} - // Currently, only full writes are accepted along megabyte boundaries - // unless the stream forces a flush (i.e., we are at EOF). - size_t size_desired = m_size; - if (!force) { - size_desired -= (size_desired % (1024*1024)); - if (!size_desired) {return 0;} + // Only full buffer writes are accepted unless the stream forces a flush + // (i.e., we are at EOF) because the multistream code uses buffer occupancy + // to determine how many streams are currently in-flight. If we do an early + // write, then the buffer will be empty and the multistream code may decide + // to start another request (which we don't have the capacity to serve!). + if (!force && (m_size != m_capacity)) { + return 0; } ssize_t retval = stream.WriteImpl(m_offset, &m_buffer[0], m_size); // Currently the only valid negative value is SFS_ERROR (-1); checking for // all negative values to future-proof the code. - if ((retval < 0) || (static_cast(retval) != size_desired)) { + if ((retval < 0) || (static_cast(retval) != m_size)) { return -1; } - // If partial data remains, copy it to the beginning of the buffer. - // Otherwise, mark the buffer as available. - if (size_desired < m_size) { - m_offset += size_desired; - m_size -= size_desired; - memcpy(&m_buffer[0], &m_buffer[size_desired], m_size); - } else { - m_offset = -1; - m_size = 0; - } + m_offset = -1; + m_size = 0; return retval; }