From 64222e845d5d97ee9e9234232bd72d3e8fe3d780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 4 Dec 2006 16:14:07 +0000 Subject: [PATCH] Make sure that buffers that have more than one iovec can still be sent (by copying them). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19421 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/devices/ethernet/ethernet.cpp | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp index d9413d23b3..afd174a35d 100644 --- a/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp +++ b/src/add-ons/kernel/network/devices/ethernet/ethernet.cpp @@ -134,9 +134,23 @@ dprintf("try to send ethernet packet of %lu bytes (flags %ld):\n", buffer->size, if (buffer->size > device->frame_size || buffer->size < ETHER_HEADER_LENGTH) return B_BAD_VALUE; + net_buffer *allocated = NULL; + net_buffer *original = buffer; + if (gBufferModule->count_iovecs(buffer) > 1) { - dprintf("scattered I/O is not yet supported by ethernet device.\n"); - return B_NOT_SUPPORTED; + // TODO: for now, create a new buffer containing the data + net_buffer *original = buffer; + + buffer = gBufferModule->duplicate(original); + if (buffer == NULL) + return ENOBUFS; + + allocated = buffer; + + if (gBufferModule->count_iovecs(buffer) > 1) { + dprintf("scattered I/O is not yet supported by ethernet device.\n"); + return B_NOT_SUPPORTED; + } } struct iovec iovec; @@ -145,15 +159,20 @@ dprintf("try to send ethernet packet of %lu bytes (flags %ld):\n", buffer->size, dump_block((const char *)iovec.iov_base, buffer->size, " "); ssize_t bytesWritten = write(device->fd, iovec.iov_base, iovec.iov_len); dprintf("sent: %ld\n", bytesWritten); + if (bytesWritten < 0) { device->stats.send.errors++; + if (allocated) + gBufferModule->free(allocated); return bytesWritten; } device->stats.send.packets++; device->stats.send.bytes += bytesWritten; - - gBufferModule->free(buffer); + + gBufferModule->free(original); + if (allocated) + gBufferModule->free(allocated); return B_OK; }