diff --git a/include/common/buf.h b/include/common/buf.h index e72de911a..6d4611112 100644 --- a/include/common/buf.h +++ b/include/common/buf.h @@ -517,7 +517,9 @@ static inline size_t b_putblk(struct buffer *b, const char *blk, size_t len) /* b_xfer() : transfers at most bytes from buffer to buffer * and returns the number of bytes copied. The bytes are removed from and * added to . The caller is responsible for ensuring that is not - * larger than b_room(dst). + * larger than b_room(dst). Whenever possible (if the destination is empty and + * at least as much as the source was requested), the buffers are simply + * swapped instead of copied. */ static inline size_t b_xfer(struct buffer *dst, struct buffer *src, size_t count) { @@ -533,6 +535,13 @@ static inline size_t b_xfer(struct buffer *dst, struct buffer *src, size_t count if (ret > count) ret = count; + else if (!b_data(dst)) { + /* zero copy is possible by just swapping buffers */ + struct buffer tmp = *dst; + *dst = *src; + *src = tmp; + goto leave; + } block1 = b_contig_data(src, 0); if (block1 > ret)