]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
HGFS: Server packet abstraction part XI
authorVMware, Inc <>
Wed, 18 Sep 2013 03:27:51 +0000 (20:27 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 23 Sep 2013 05:10:49 +0000 (22:10 -0700)
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>
open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/hgfsServer/hgfsServerInt.h
open-vm-tools/lib/hgfsServer/hgfsServerPacketUtil.c
open-vm-tools/lib/hgfsServerManagerGuest/hgfsChannelGuestBd.c
open-vm-tools/lib/include/hgfsServer.h

index 71ab60626b895fe3a27421441e5531ae049d0fd9..1b670cbb669779208694b0dde7ea39c51500ee4d 100644 (file)
@@ -3140,9 +3140,10 @@ HgfsServerCompleteRequest(HgfsInternalStatus status,   // IN: Status of the requ
       }
    }
 
-   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,
@@ -4587,11 +4588,10 @@ HgfsPacketSend(HgfsPacket *packet,            // IN/OUT: Hgfs Packet
    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) {
@@ -5803,10 +5803,10 @@ HgfsAllocInitReply(HgfsPacket *packet,           // IN/OUT: Hgfs Packet
               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));
 
index 6088b1fbcc137577e67f00c00bcf7d695795396c..088f933bd73a4ac5d774ced16032729156eb0ad8 100644 (file)
@@ -839,8 +839,9 @@ HSPU_PutMetaPacket(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
 
 void
 HSPU_PutReplyPacket(HgfsPacket *packet,                  // IN/OUT: Hgfs Packet
index 73b015f7469fe2a19d73b8c21a5af035c48a5b9e..0395bf079a1836395b931eb596d448753eba883c 100644 (file)
@@ -92,17 +92,19 @@ static void HSPUUnmapBuf(HgfsChannelUnmapVirtAddrFunc unmapVa,
 
 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);
@@ -116,20 +118,30 @@ HSPU_GetReplyPacket(HgfsPacket *packet,                  // IN/OUT: Hgfs Packet
           * 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;
index d7ff8cd4557eda0b06da8b11470b4f76fe7e99ff..52c02369344d4930920a26a3be91f8ddcb969d3b 100644 (file)
@@ -633,23 +633,22 @@ HgfsChannelGuestBdInvalidateInactiveSessions(HgfsGuestConn *connData)  // IN: co
 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,
index 818623bdda1fe98a8099c73d97c179fc9e8541c0..40956b3d0861c0c4e385d44224639177f27a0fdf 100644 (file)
@@ -75,6 +75,7 @@ typedef struct HgfsPacket {
 
    void *replyPacket;
    size_t replyPacketSize;
+   size_t replyPacketDataSize;
    Bool replyPacketIsAllocated;
 
    /* Iov for the packet private to the channel. */