From: VMware, Inc <> Date: Sat, 28 May 2011 20:05:12 +0000 (-0700) Subject: Internal branch sync. Included in this change: X-Git-Tag: 2011.05.27-420096~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=137b52504ca99dbc01876e45db86663a760add3c;p=thirdparty%2Fopen-vm-tools.git Internal branch sync. Included in this change: . Fix confusion about buffer ownership in the HGFS server. . Do not delete files after DnD if all files are copied. . Invalidate HgfsNodeInfo->hostFileId associated with the inode in the open() code path. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index 1dee2c5b1..30a0c3f2a 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -3849,9 +3849,15 @@ HgfsServerSessionSendComplete(HgfsPacket *packet, // IN/OUT: Hgfs packet void *clientData) // IN: session info { HgfsSessionInfo *session = (HgfsSessionInfo *)clientData; - HSPU_PutMetaPacket(packet, session); - HSPU_PutReplyPacket(packet, session); - HSPU_PutDataPacketBuf(packet, session); + + if (packet->guestInitiated) { + HSPU_PutMetaPacket(packet, session); + HSPU_PutReplyPacket(packet, session); + HSPU_PutDataPacketBuf(packet, session); + } else { + free(packet->metaPacket); + free(packet); + } } diff --git a/open-vm-tools/modules/linux/vmhgfs/file.c b/open-vm-tools/modules/linux/vmhgfs/file.c index 60a03e342..db61b1396 100644 --- a/open-vm-tools/modules/linux/vmhgfs/file.c +++ b/open-vm-tools/modules/linux/vmhgfs/file.c @@ -587,6 +587,13 @@ HgfsOpen(struct inode *inode, // IN: Inode of the file to open switch (result) { case 0: iinfo->createdAndUnopened = FALSE; + LOG(10, (KERN_DEBUG "VMware hgfs: HgfsOpen: old hostFileId = " + "%"FMT64"u\n", iinfo->hostFileId)); + /* + * Invalidate the hostFileId as we need to retrieve it from + * the server. + */ + iinfo->hostFileId = 0; result = HgfsUnpackOpenReply(req, opUsed, &replyFile, &replyLock); if (result != 0) { break; diff --git a/open-vm-tools/modules/linux/vmhgfs/inode.c b/open-vm-tools/modules/linux/vmhgfs/inode.c index 6a819d3e4..16b68b0be 100644 --- a/open-vm-tools/modules/linux/vmhgfs/inode.c +++ b/open-vm-tools/modules/linux/vmhgfs/inode.c @@ -2059,6 +2059,7 @@ HgfsRevalidate(struct dentry *dentry) // IN: Dentry to revalidate int error = 0; HgfsSuperInfo *si; unsigned long age; + HgfsInodeInfo *iinfo; ASSERT(dentry); si = HGFS_SB_TO_COMMON(dentry->d_sb); @@ -2072,7 +2073,9 @@ HgfsRevalidate(struct dentry *dentry) // IN: Dentry to revalidate "inum %lu\n", dentry->d_name.name, dentry->d_inode->i_ino)); age = jiffies - dentry->d_time; - if (age > si->ttl) { + iinfo = INODE_GET_II_P(dentry->d_inode); + + if (age > si->ttl || iinfo->hostFileId == 0) { HgfsAttrInfo attr; LOG(6, (KERN_DEBUG "VMware hgfs: HgfsRevalidate: dentry is too old, " "getting new attributes\n")); @@ -2089,9 +2092,8 @@ HgfsRevalidate(struct dentry *dentry) // IN: Dentry to revalidate * the same file name has been used for other file during the period. */ if (attr.mask & HGFS_ATTR_VALID_FILEID) { - HgfsInodeInfo *iinfo = INODE_GET_II_P(dentry->d_inode); if (iinfo->hostFileId == 0) { - /* It should not happen, just in case. */ + /* hostFileId was invalidated, so update it here */ iinfo->hostFileId = attr.hostFileId; } else if (iinfo->hostFileId != attr.hostFileId) { LOG(4, ("VMware hgfs: %s: host file id mismatch. Expected " diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp index 8cbe9c50a..b019ae938 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp +++ b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp @@ -91,7 +91,8 @@ CopyPasteUIX11::CopyPasteUIX11() mHGGetFileStatus(DND_FILE_TRANSFER_NOT_STARTED), mBlockAdded(false), mBlockCtrl(0), - mInited(false) + mInited(false), + mTotalFileSize(0) { GuestDnDCPMgr *p = GuestDnDCPMgr::GetInstance(); ASSERT(p); @@ -170,8 +171,16 @@ CopyPasteUIX11::~CopyPasteUIX11() /* Any files from last unfinished file transfer should be deleted. */ if (DND_FILE_TRANSFER_IN_PROGRESS == mHGGetFileStatus && !mHGStagingDir.empty()) { - g_debug("%s: deleting dir %s\n", __FUNCTION__, mHGStagingDir.c_str()); - DnD_DeleteStagingFiles(mHGStagingDir.c_str(), FALSE); + uint64 totalSize = File_GetSizeEx(mHGStagingDir.c_str()); + if (mTotalFileSize != totalSize) { + g_debug("%s: deleting %s, expecting %"FMT64"d, finished %"FMT64"d\n", + __FUNCTION__, mHGStagingDir.c_str(), + mTotalFileSize, totalSize); + DnD_DeleteStagingFiles(mHGStagingDir.c_str(), FALSE); + } else { + g_debug("%s: file size match %s\n", + __FUNCTION__, mHGStagingDir.c_str()); + } } if (mBlockAdded) { g_debug("%s: removing block for %s\n", __FUNCTION__, mHGStagingDir.c_str()); @@ -1177,6 +1186,7 @@ CopyPasteUIX11::GetRemoteClipboardCB(const CPClipboard *clip) // IN g_debug("%s: File data.\n", __FUNCTION__); DnDFileList flist; flist.FromCPClipboard(buf, sz); + mTotalFileSize = flist.GetFileSize(); mHGFCPData = flist.GetRelPathsStr(); refClipboard->set(mListTargets, diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h index 390625fe9..4a4608d9d 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h +++ b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h @@ -117,6 +117,7 @@ private: bool mBlockAdded; DnDBlockControl *mBlockCtrl; bool mInited; + uint64 mTotalFileSize; }; #endif // __COPYPASTE_UI_X11_H__ diff --git a/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp b/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp index 166322a71..74893ac64 100644 --- a/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp +++ b/open-vm-tools/services/plugins/dndcp/dndUIX11.cpp @@ -75,7 +75,8 @@ DnDUIX11::DnDUIX11(ToolsAppCtx *ctx) m_mousePosY(0), m_dc(NULL), m_numPendingRequest(0), - m_destDropTime(0) + m_destDropTime(0), + mTotalFileSize(0) { g_debug("%s: enter\n", __FUNCTION__); } @@ -96,8 +97,16 @@ DnDUIX11::~DnDUIX11() /* Any files from last unfinished file transfer should be deleted. */ if (DND_FILE_TRANSFER_IN_PROGRESS == m_HGGetFileStatus && !m_HGStagingDir.empty()) { - g_debug("%s: deleting dir %s\n", __FUNCTION__, m_HGStagingDir.c_str()); - DnD_DeleteStagingFiles(m_HGStagingDir.c_str(), FALSE); + uint64 totalSize = File_GetSizeEx(m_HGStagingDir.c_str()); + if (mTotalFileSize != totalSize) { + g_debug("%s: deleting %s, expecting %"FMT64"d, finished %"FMT64"d\n", + __FUNCTION__, m_HGStagingDir.c_str(), + mTotalFileSize, totalSize); + DnD_DeleteStagingFiles(m_HGStagingDir.c_str(), FALSE); + } else { + g_debug("%s: file size match %s\n", + __FUNCTION__, m_HGStagingDir.c_str()); + } } CommonResetCB(); } @@ -891,6 +900,8 @@ DnDUIX11::GtkSourceDragDataGetCB(const Glib::RefPtr &dc, return; } + mTotalFileSize = fList.GetFileSize(); + /* Provide URIs for each path in the guest's file list. */ if (FCP_TARGET_INFO_GNOME_COPIED_FILES == info) { pre = FCP_GNOME_LIST_PRE; diff --git a/open-vm-tools/services/plugins/dndcp/dndUIX11.h b/open-vm-tools/services/plugins/dndcp/dndUIX11.h index 3341ff4ea..d0af46c4d 100644 --- a/open-vm-tools/services/plugins/dndcp/dndUIX11.h +++ b/open-vm-tools/services/plugins/dndcp/dndUIX11.h @@ -207,6 +207,7 @@ private: GdkDragContext *m_dc; int m_numPendingRequest; unsigned long m_destDropTime; + uint64 mTotalFileSize; }; #endif // __DND_UI_X11_H__