Deal with the broken reply packet part of the abstraction.
Fix the get reply packet function call to separate out the reply data
size passed in and the reply packet buffer size which is returned.
Add the reply data size field in the HgfsPacket object so that the reply
data size and reply buffer size can be separated out and not overloaded.
This allows the transport channel send routines to extract the reply
details from the packet object and not need the buffer and size
arguments. The send function channel callback API will be cleaned up in
a separate change.
The get reply function for the packet now sets the meta packet data size
too when it is used for the reply packet. This is used by the VMCI
channel which now only maps and copies the correct amount of reply data
into the guest VM shared memory.
The reply packet size is randomly overwritten from the total packet size
available for the reply to hold the amount of written data in the reply.
This however, does not have any effect, since, the reply data size is
passed to the send function which then knows how much data to send, and
for VMCI, the meta part of the packet is used to transfer data to the
guest shared memory so the reply part is essentially unused. This is now
deleted.
Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
}
}
- replyTotalSize = replySize;
- reply = HSPU_GetReplyPacket(input->packet, &replyTotalSize,
- input->transportSession->channelCbTable);
+ reply = HSPU_GetReplyPacket(input->packet,
+ input->transportSession->channelCbTable,
+ replySize,
+ &replyTotalSize);
ASSERT_DEVEL(reply && (replySize <= replyTotalSize));
if (!HgfsPackReplyHeader(status, replyPayloadSize, input->sessionEnabled, replySessionId,
ASSERT(transportSession);
if (transportSession->state == HGFS_SESSION_STATE_OPEN) {
- packet->replyPacketSize = packetOutLen;
ASSERT(transportSession->type == HGFS_SESSION_TYPE_REGULAR);
result = transportSession->channelCbTable->send(transportSession->transportData,
- packet, packetOut,
- packetOutLen, flags);
+ packet, packetOut,
+ packetOutLen, flags);
}
if (notificationNeeded) {
request->op > HGFS_OP_RENAME_V2) {
headerSize = sizeof(HgfsReply);
}
- replyPacketSize = headerSize + replyDataSize;
replyHeader = HSPU_GetReplyPacket(packet,
- &replyPacketSize,
- session->transportSession->channelCbTable);
+ session->transportSession->channelCbTable,
+ headerSize + replyDataSize,
+ &replyPacketSize);
ASSERT_DEVEL(replyHeader && (replyPacketSize >= headerSize + replyDataSize));
void *
HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet
- size_t *replyPacketSize, //IN/OUT: Size of reply Packet
- HgfsServerChannelCallbacks *chanCb); // IN: Channel callbacks
+ HgfsServerChannelCallbacks *chanCb, // IN: Channel callbacks
+ size_t replyDataSize, // IN: Size of reply data
+ size_t *replyPacketSize); // OUT: Size of reply Packet
void
HSPU_PutReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet
void *
HSPU_GetReplyPacket(HgfsPacket *packet, // IN/OUT: Hgfs Packet
- size_t *replyPacketSize, // IN/OUT: Size of reply Packet
- HgfsServerChannelCallbacks *chanCb) // IN: Channel callbacks
+ HgfsServerChannelCallbacks *chanCb, // IN: Channel callbacks
+ size_t replyDataSize, // IN: Size of reply data
+ size_t *replyPacketSize) // OUT: Size of reply Packet
{
if (packet->replyPacket != NULL) {
/*
* When we are transferring packets over backdoor, reply packet
* is a static buffer. Backdoor should always return from here.
*/
+ packet->replyPacketDataSize = replyDataSize;
LOG(4, ("Existing reply packet %s %"FMTSZ"u %"FMTSZ"u\n", __FUNCTION__,
- *replyPacketSize, packet->replyPacketSize));
- ASSERT_DEVEL(*replyPacketSize <= packet->replyPacketSize);
+ replyDataSize, packet->replyPacketSize));
+ ASSERT_DEVEL(replyDataSize <= packet->replyPacketSize);
} else if (chanCb != NULL && chanCb->getWriteVa != NULL) {
/* Can we write directly into guest memory? */
ASSERT_DEVEL(packet->metaPacket != NULL);
* is always mapped and copied no matter how much data it really contains.
*/
LOG(10, ("%s Using meta packet for reply packet\n", __FUNCTION__));
- ASSERT_DEVEL(*replyPacketSize <= packet->metaPacketDataSize);
+ ASSERT_DEVEL(replyDataSize <= packet->metaPacketDataSize);
ASSERT_DEVEL(BUF_READWRITEABLE == packet->metaMappingType);
- ASSERT_DEVEL(*replyPacketSize <= packet->metaPacketSize);
+ ASSERT_DEVEL(replyDataSize <= packet->metaPacketSize);
packet->replyPacket = packet->metaPacket;
- packet->replyPacketSize = packet->metaPacketDataSize;
+ packet->replyPacketDataSize = replyDataSize;
+ packet->replyPacketSize = packet->metaPacketSize;
packet->replyPacketIsAllocated = FALSE;
+ /*
+ * The reply is using the meta buffer so update the valid data size.
+ *
+ * Note, currently We know the reply size is going to be less than the
+ * incoming request valid data size. This will updated when that part is
+ * fixed. See the above comment about the assumptions and asserts.
+ */
+ packet->metaPacketDataSize = packet->replyPacketDataSize;
}
} else {
/* For sockets channel we always need to allocate buffer */
LOG(10, ("%s Allocating reply packet\n", __FUNCTION__));
- packet->replyPacket = Util_SafeMalloc(*replyPacketSize);
+ packet->replyPacket = Util_SafeMalloc(replyDataSize);
packet->replyPacketIsAllocated = TRUE;
- packet->replyPacketSize = *replyPacketSize;
+ packet->replyPacketDataSize = replyDataSize;
+ packet->replyPacketSize = replyDataSize;
}
*replyPacketSize = packet->replyPacketSize;
static Bool
HgfsChannelGuestBdSend(void *conn, // IN: our connection data
HgfsPacket *packet, // IN/OUT: Hgfs Packet
- char *buffer, // IN: buffer to be sent
- size_t bufferLen, // IN: buffer length
+ char *buffer, // IN: unused reply in hgfs packet
+ size_t bufferLen, // IN: unused reply len in hgfs packet
HgfsSendFlags flags) // IN: Flags to say how to process
{
HgfsGuestConn *connData = conn;
ASSERT(NULL != connData);
ASSERT(NULL != packet);
- ASSERT(NULL != buffer);
- ASSERT(bufferLen <= HGFS_LARGE_PACKET_MAX &&
- bufferLen <= packet->replyPacketSize);
+ ASSERT(NULL != packet->replyPacket);
+ ASSERT(packet->replyPacketDataSize <= connData->packetOutLen);
+ ASSERT(packet->replyPacketSize == connData->packetOutLen);
- ASSERT(bufferLen <= connData->packetOutLen);
- if (bufferLen > connData->packetOutLen) {
- bufferLen = connData->packetOutLen;
+ if (packet->replyPacketDataSize > connData->packetOutLen) {
+ packet->replyPacketDataSize = connData->packetOutLen;
}
- connData->packetOutLen = (uint32)bufferLen;
+ connData->packetOutLen = (uint32)packet->replyPacketDataSize;
if (!(flags & HGFS_SEND_NO_COMPLETE)) {
connData->serverCbTable->sendComplete(packet,
void *replyPacket;
size_t replyPacketSize;
+ size_t replyPacketDataSize;
Bool replyPacketIsAllocated;
/* Iov for the packet private to the channel. */