summaryrefslogtreecommitdiff
path: root/open-vm-tools/modules/linux
diff options
context:
space:
mode:
Diffstat (limited to 'open-vm-tools/modules/linux')
-rw-r--r--open-vm-tools/modules/linux/dkms.conf2
-rw-r--r--open-vm-tools/modules/linux/dkms.sh6
-rw-r--r--open-vm-tools/modules/linux/shared/autoconf/dcount.c43
-rw-r--r--open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c46
-rw-r--r--open-vm-tools/modules/linux/shared/compat_cred.h4
-rw-r--r--open-vm-tools/modules/linux/shared/compat_dcache.h4
-rw-r--r--open-vm-tools/modules/linux/shared/compat_skbuff.h12
-rw-r--r--open-vm-tools/modules/linux/shared/kernelStubs.h173
-rw-r--r--open-vm-tools/modules/linux/shared/kernelStubsLinux.c10
-rw-r--r--open-vm-tools/modules/linux/shared/kernelStubsSal.h134
-rw-r--r--open-vm-tools/modules/linux/shared/vmciKernelAPI1.h10
-rw-r--r--open-vm-tools/modules/linux/shared/vmci_defs.h3
-rw-r--r--open-vm-tools/modules/linux/shared/vmci_infrastructure.h16
-rw-r--r--open-vm-tools/modules/linux/shared/vmci_iocontrols.h12
-rw-r--r--open-vm-tools/modules/linux/shared/vmci_kernel_if.h53
-rw-r--r--open-vm-tools/modules/linux/vmblock/Makefile2
-rw-r--r--open-vm-tools/modules/linux/vmci/Makefile2
-rw-r--r--open-vm-tools/modules/linux/vmci/Makefile.kernel4
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciContext.c171
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciContext.h2
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciDatagram.c12
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciDoorbell.c6
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciDriver.c4
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciQPair.c6
-rw-r--r--open-vm-tools/modules/linux/vmci/common/vmciRoute.c13
-rw-r--r--open-vm-tools/modules/linux/vmci/linux/driver.c11
-rw-r--r--open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c22
-rw-r--r--open-vm-tools/modules/linux/vmci/linux/vmci_version.h8
-rw-r--r--open-vm-tools/modules/linux/vmci/shared/pgtbl.h24
-rw-r--r--open-vm-tools/modules/linux/vmci/shared/vmciQueue.h6
-rw-r--r--open-vm-tools/modules/linux/vmci/shared/vmci_handle_array.h7
-rw-r--r--open-vm-tools/modules/linux/vmci/shared/vmci_page_channel.h733
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/Makefile2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/Makefile.kernel4
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/bdhandler.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/dentry.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/dir.c37
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/file.c376
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/filesystem.c132
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/filesystem.h2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/fsutil.c714
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/fsutil.h9
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/inode.c46
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/inode.h2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/link.c11
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/module.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/module.h20
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/page.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/request.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/request.h2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/stubs.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/super.c2
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/transport.c15
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/transport.h3
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/vmci.c815
-rw-r--r--open-vm-tools/modules/linux/vmhgfs/vmhgfs_version.h2
-rw-r--r--open-vm-tools/modules/linux/vmsync/Makefile2
-rw-r--r--open-vm-tools/modules/linux/vmxnet/Makefile2
-rw-r--r--open-vm-tools/modules/linux/vmxnet/vmxnet.c37
-rw-r--r--open-vm-tools/modules/linux/vmxnet/vmxnet_version.h6
-rw-r--r--open-vm-tools/modules/linux/vsock/Makefile2
-rw-r--r--open-vm-tools/modules/linux/vsock/Makefile.kernel6
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/af_vsock.c18
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/af_vsock.h4
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/stats.h4
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/vmci_sockets_int.h4
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/vmci_sockets_packet.h44
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/vsockCommon.h16
-rw-r--r--open-vm-tools/modules/linux/vsock/linux/vsock_version.h8
69 files changed, 1753 insertions, 2167 deletions
diff --git a/open-vm-tools/modules/linux/dkms.conf b/open-vm-tools/modules/linux/dkms.conf
index 908132e6..7d93e317 100644
--- a/open-vm-tools/modules/linux/dkms.conf
+++ b/open-vm-tools/modules/linux/dkms.conf
@@ -1,5 +1,5 @@
PACKAGE_NAME=open-vm-tools
-PACKAGE_VERSION=2013.09.16
+PACKAGE_VERSION=2015.01.29
MAKE_CMD_TMPL="make VM_UNAME=\$kernelver \
MODULEBUILDDIR=$dkms_tree/$PACKAGE_NAME/$PACKAGE_VERSION/build"
diff --git a/open-vm-tools/modules/linux/dkms.sh b/open-vm-tools/modules/linux/dkms.sh
index 6626c183..c0cb59c8 100644
--- a/open-vm-tools/modules/linux/dkms.sh
+++ b/open-vm-tools/modules/linux/dkms.sh
@@ -1,6 +1,6 @@
#!/bin/sh
################################################################################
-### Copyright 2009 VMware, Inc. All rights reserved.
+### Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
###
### Script for creating a dmks-compliant source tree from an open-vm-tools
### distribution.
@@ -28,12 +28,12 @@ then
echo " src: root of unpacked open-vm-tools package"
echo " dst: where to create the dkms tree"
echo
- echo "The script will create an 'open-vm-tools' module with version 2013.09.16."
+ echo "The script will create an 'open-vm-tools' module with version 2015.01.29."
exit 1
fi
src=$1
-dst=$2/open-vm-tools-2013.09.16
+dst=$2/open-vm-tools-2015.01.29
SHARED_HEADERS="backdoor_def.h"
SHARED_HEADERS="$SHARED_HEADERS backdoor_types.h"
diff --git a/open-vm-tools/modules/linux/shared/autoconf/dcount.c b/open-vm-tools/modules/linux/shared/autoconf/dcount.c
new file mode 100644
index 00000000..c78968d0
--- /dev/null
+++ b/open-vm-tools/modules/linux/shared/autoconf/dcount.c
@@ -0,0 +1,43 @@
+/*********************************************************
+ * Copyright (C) 2014 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+#include "compat_version.h"
+#include "compat_autoconf.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
+#include <linux/dcache.h>
+
+/*
+ * After 3.11.0, the dentry d_count field was removed. Red Hat
+ * backported this behavior into a 3.10.0 kernel.
+ *
+ * This test will fail on a kernel with such a patch.
+ */
+void test(void)
+{
+ struct dentry dentry;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+ dentry.d_count = 1;
+#else
+ atomic_set(&dentry.d_count, 1);
+#endif
+}
+#else
+#error "This test intentionally fails on 3.11.0 or newer kernels."
+#endif
diff --git a/open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c b/open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c
new file mode 100644
index 00000000..818aee32
--- /dev/null
+++ b/open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c
@@ -0,0 +1,46 @@
+/*********************************************************
+ * Copyright (C) 2013 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * Linux v2.6.18 added an owner parameter to flush.
+ * But SLES10 has backported the change to its 2.6.16.60 kernel,
+ * so we can't rely solely on kernel version to determine number of
+ * arguments.
+ *
+ * This test will fail on a kernel with such a patch.
+ */
+
+#include "compat_version.h"
+#include "compat_autoconf.h"
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+#error This compile test intentionally fails on 2.6.18 and newer kernels.
+#else
+
+#include <linux/fs.h>
+
+static int TestFlush(struct file *file);
+{
+ return 0;
+}
+
+struct file_operations testFO = {
+ .flush = TestFlush,
+};
+
+#endif
diff --git a/open-vm-tools/modules/linux/shared/compat_cred.h b/open-vm-tools/modules/linux/shared/compat_cred.h
index 8f02001a..95a7baa7 100644
--- a/open-vm-tools/modules/linux/shared/compat_cred.h
+++ b/open-vm-tools/modules/linux/shared/compat_cred.h
@@ -40,4 +40,8 @@
#define cap_set_full(_c) do { (_c) = CAP_FULL_SET; } while (0)
#endif
+#if !defined(GLOBAL_ROOT_UID)
+#define GLOBAL_ROOT_UID (0)
+#endif
+
#endif /* __COMPAT_CRED_H__ */
diff --git a/open-vm-tools/modules/linux/shared/compat_dcache.h b/open-vm-tools/modules/linux/shared/compat_dcache.h
index 0450aeef..d16fd1d3 100644
--- a/open-vm-tools/modules/linux/shared/compat_dcache.h
+++ b/open-vm-tools/modules/linux/shared/compat_dcache.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2013 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -25,7 +25,7 @@
* per-dentry locking was born in 2.5.62.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 62)
-#define compat_lock_dentry(dentry) spin_lock(&dentry->d_lock)
+#define compat_lock_dentry(dentry) spin_lock(&dentry->d_lock)
#define compat_unlock_dentry(dentry) spin_unlock(&dentry->d_lock)
#else
#define compat_lock_dentry(dentry) do {} while (0)
diff --git a/open-vm-tools/modules/linux/shared/compat_skbuff.h b/open-vm-tools/modules/linux/shared/compat_skbuff.h
index d1a72a5e..b6468855 100644
--- a/open-vm-tools/modules/linux/shared/compat_skbuff.h
+++ b/open-vm-tools/modules/linux/shared/compat_skbuff.h
@@ -35,9 +35,15 @@
#define compat_skb_network_header_len(skb) skb_network_header_len(skb)
#define compat_skb_tail_pointer(skb) skb_tail_pointer(skb)
#define compat_skb_end_pointer(skb) skb_end_pointer(skb)
-#define compat_skb_ip_header(skb) ((struct iphdr *)skb_network_header(skb))
-#define compat_skb_ipv6_header(skb) ((struct ipv6hdr *)skb_network_header(skb))
-#define compat_skb_tcp_header(skb) ((struct tcphdr *)skb_transport_header(skb))
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+# define compat_skb_ip_header(skb) ip_hdr(skb)
+# define compat_skb_ipv6_header(skb) ipv6_hdr(skb)
+# define compat_skb_tcp_header(skb) tcp_hdr(skb)
+#else
+# define compat_skb_ip_header(skb) ((struct iphdr *)skb_network_header(skb))
+# define compat_skb_ipv6_header(skb) ((struct ipv6hdr *)skb_network_header(skb))
+# define compat_skb_tcp_header(skb) ((struct tcphdr *)skb_transport_header(skb))
+#endif
#define compat_skb_reset_mac_header(skb) skb_reset_mac_header(skb)
#define compat_skb_reset_network_header(skb) skb_reset_network_header(skb)
#define compat_skb_reset_transport_header(skb) skb_reset_transport_header(skb)
diff --git a/open-vm-tools/modules/linux/shared/kernelStubs.h b/open-vm-tools/modules/linux/shared/kernelStubs.h
index 800a0cf8..c242fccd 100644
--- a/open-vm-tools/modules/linux/shared/kernelStubs.h
+++ b/open-vm-tools/modules/linux/shared/kernelStubs.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -27,6 +27,21 @@
#ifndef __KERNELSTUBS_H__
#define __KERNELSTUBS_H__
+#define KRNL_STUBS_DRIVER_TYPE_POSIX 1
+#define KRNL_STUBS_DRIVER_TYPE_GDI 2
+#define KRNL_STUBS_DRIVER_TYPE_WDM 3
+#define KRNL_STUBS_DRIVER_TYPE_NDIS 4
+
+// For now (vsphere-2015), choose a good default. Later we'll modify all the
+// build files using KernelStubs to set this.
+#ifndef KRNL_STUBS_DRIVER_TYPE
+# if defined(_WIN32)
+# define KRNL_STUBS_DRIVER_TYPE KRNL_STUBS_DRIVER_TYPE_WDM
+# else
+# define KRNL_STUBS_DRIVER_TYPE KRNL_STUBS_DRIVER_TYPE_POSIX
+# endif
+#endif
+
#ifdef linux
# ifndef __KERNEL__
# error "__KERNEL__ is not defined"
@@ -36,12 +51,32 @@
# include <linux/kernel.h>
# include <linux/string.h>
#elif defined(_WIN32)
-# include "vm_basic_types.h"
-# include <ntddk.h> /* kernel memory APIs */
-# include <stdio.h> /* for _vsnprintf, vsprintf */
-# include <stdarg.h> /* for va_start stuff */
-# include <stdlib.h> /* for min macro. */
-# include "vm_assert.h" /* Our assert macros */
+# define _CRT_ALLOCATION_DEFINED // prevent malloc.h from defining malloc et. all
+# if KRNL_STUBS_DRIVER_TYPE == KRNL_STUBS_DRIVER_TYPE_GDI
+# include <d3d9.h>
+# include <winddi.h>
+# include <stdio.h>
+# include "vm_basic_types.h"
+# include "vm_basic_defs.h"
+# include "vm_assert.h"
+# elif KRNL_STUBS_DRIVER_TYPE == KRNL_STUBS_DRIVER_TYPE_NDIS
+# include "vm_basic_types.h"
+# include <ndis.h>
+# elif KRNL_STUBS_DRIVER_TYPE == KRNL_STUBS_DRIVER_TYPE_WDM
+# include "vm_basic_types.h"
+# if defined(NTDDI_WINXP) && (NTDDI_VERSION >= NTDDI_WINXP)
+# include <wdm.h> /* kernel memory APIs, DbgPrintEx */
+# else
+# include <ntddk.h> /* kernel memory APIs */
+# endif
+# include <stdio.h> /* for _vsnprintf, vsprintf */
+# include <stdarg.h> /* for va_start stuff */
+# include <stdlib.h> /* for min macro. */
+# include "vm_basic_defs.h"
+# include "vm_assert.h" /* Our assert macros */
+# else
+# error Type KRNL_STUBS_DRIVER_TYPE must be defined.
+# endif
#elif defined(__FreeBSD__)
# include "vm_basic_types.h"
# ifndef _KERNEL
@@ -65,6 +100,7 @@
# include <sys/types.h>
# include <sys/varargs.h>
#endif
+#include "kernelStubsSal.h"
/*
* Function Prototypes
@@ -84,19 +120,41 @@ void *realloc(void *ptr, size_t newSize);
#elif defined(_WIN32) /* } else if (_WIN32) { */
-#if (_WIN32_WINNT == 0x0400)
-/* The following declarations are missing on NT4. */
-typedef unsigned int UINT_PTR;
-typedef unsigned int SIZE_T;
+_Ret_allocates_malloc_mem_opt_bytecap_(_Size)
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+_CRTNOALIAS _CRTRESTRICT
+void * __cdecl malloc(
+ _In_ size_t _Size);
-/* No free with tag availaible on NT4 kernel! */
-#define KRNL_STUBS_FREE(P,T) ExFreePool((P))
+_Ret_allocates_malloc_mem_opt_bytecount_(_Count*_Size)
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+_CRTNOALIAS _CRTRESTRICT
+void * __cdecl calloc(
+ _In_ size_t _Count,
+ _In_ size_t _Size);
-#else /* _WIN32_WINNT */
-#define KRNL_STUBS_FREE(P,T) ExFreePoolWithTag((P),(T))
-/* Win 2K and later useful kernel function, documented but not declared! */
-NTKERNELAPI VOID ExFreePoolWithTag(IN PVOID P, IN ULONG Tag);
-#endif /* _WIN32_WINNT */
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+_CRTNOALIAS
+void __cdecl free(
+ _In_frees_malloc_mem_opt_ void * _Memory);
+
+_Success_(return != 0)
+_When_(_Memory != 0, _Ret_reallocates_malloc_mem_opt_newbytecap_oldbytecap_(_NewSize, ((uintptr_t*)_Memory)[-1]))
+_When_(_Memory == 0, _Ret_reallocates_malloc_mem_opt_newbytecap_(_NewSize))
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+_CRTNOALIAS _CRTRESTRICT
+void * __cdecl realloc(
+ _In_reallocates_malloc_mem_opt_oldptr_ void * _Memory,
+ _In_ size_t _NewSize);
+
+_Success_(return != 0)
+_Ret_allocates_malloc_mem_opt_z_
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+_CRTIMP
+char * __cdecl _strdup_impl(
+ _In_opt_z_ const char * _Src);
+
+#define strdup _strdup_impl
#elif defined(__FreeBSD__) /* } else if (FreeBSD) { */
@@ -127,23 +185,84 @@ __compat_malloc(unsigned long size, struct malloc_type *type, int flags) {
#endif /* } */
+_Ret_writes_z_(maxSize)
+char *Str_Strcpy(
+ _Out_z_cap_(maxSize) char *buf,
+ _In_z_ const char *src,
+ _In_ size_t maxSize);
+
+_Ret_writes_z_(maxSize)
+char *Str_Strcat(
+ _Inout_z_cap_(maxSize) char *buf,
+ _In_z_ const char *src,
+ _In_ size_t maxSize);
+
+_Success_(return >= 0)
+int Str_Sprintf(
+ _Out_z_cap_(maxSize) _Post_z_count_(return+1) char *buf,
+ _In_ size_t maxSize,
+ _In_z_ _Printf_format_string_ const char *fmt,
+ ...) PRINTF_DECL(3, 4);
+
+_Success_(return != -1)
+int Str_Vsnprintf(
+ _Out_z_cap_(size) _Post_z_count_(return+1) char *str,
+ _In_ size_t size,
+ _In_z_ _Printf_format_string_ const char *format,
+ _In_ va_list ap) PRINTF_DECL(3, 0);
+
+_Success_(return != 0)
+_When_(length != 0, _Ret_allocates_malloc_mem_opt_z_bytecount_(*length))
+_When_(length == 0, _Ret_allocates_malloc_mem_opt_z_)
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+char *Str_Vasprintf(
+ _Out_opt_ size_t *length,
+ _In_z_ _Printf_format_string_ const char *format,
+ _In_ va_list arguments) PRINTF_DECL(2, 0);
+
+_Success_(return != 0)
+_When_(length != 0, _Ret_allocates_malloc_mem_opt_z_bytecount_(*length))
+_When_(length == 0, _Ret_allocates_malloc_mem_opt_z_)
+_When_windrv_(_IRQL_requires_max_(DISPATCH_LEVEL))
+char *Str_Asprintf(
+ _Out_opt_ size_t *length,
+ _In_z_ _Printf_format_string_ const char *format,
+ ...) PRINTF_DECL(2, 3);
+
+#ifdef _WIN32
+#pragma warning(push)
+#pragma warning(disable: 28301) // Suppress complaint that first declaration lacked annotations
+#endif
+
+// For now (vsphere-2015), we don't implement Panic, Warning, or Debug in the
+// GDI case.
+#if KRNL_STUBS_DRIVER_TYPE != KRNL_STUBS_DRIVER_TYPE_GDI
+
/*
* Stub functions we provide.
*/
+#ifdef _WIN32
+NORETURN
+#endif
+void Panic(
+ _In_z_ _Printf_format_string_ const char *fmt,
+ ...) PRINTF_DECL(1, 2);
-void Panic(const char *fmt, ...);
-
-char *Str_Strcpy(char *buf, const char *src, size_t maxSize);
-int Str_Vsnprintf(char *str, size_t size, const char *format,
- va_list arguments);
-char *Str_Vasprintf(size_t *length, const char *format,
- va_list arguments);
-char *Str_Asprintf(size_t *length, const char *Format, ...);
+void Warning(
+ _In_z_ _Printf_format_string_ const char *fmt,
+ ...) PRINTF_DECL(1, 2);
/*
* Functions the driver must implement for the stubs.
*/
-EXTERN void Debug(const char *fmt, ...);
+EXTERN void Debug(
+ _In_z_ _Printf_format_string_ const char *fmt,
+ ...) PRINTF_DECL(1, 2);
+#endif // KRNL_STUBS_DRIVER_TYPE != KRNL_STUBS_DRIVER_TYPE_GDI
+
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
#endif /* __KERNELSTUBS_H__ */
diff --git a/open-vm-tools/modules/linux/shared/kernelStubsLinux.c b/open-vm-tools/modules/linux/shared/kernelStubsLinux.c
index 221f88a6..b8579fca 100644
--- a/open-vm-tools/modules/linux/shared/kernelStubsLinux.c
+++ b/open-vm-tools/modules/linux/shared/kernelStubsLinux.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -91,13 +91,15 @@ Str_Strcpy(char *buf, // OUT
const char *src, // IN
size_t maxSize) // IN
{
- unsigned int *stack = (unsigned int *)&buf;
size_t len;
len = strlen(src);
if (len >= maxSize) {
- Panic("%s:%d Buffer too small 0x%x\n", __FILE__,__LINE__,
- stack[-1]);
+#ifdef GetReturnAddress
+ Panic("%s:%d Buffer too small 0x%p\n", __FILE__, __LINE__, GetReturnAddress());
+#else
+ Panic("%s:%d Buffer too small\n", __FILE__, __LINE__);
+#endif
}
return memcpy(buf, src, len + 1);
}
diff --git a/open-vm-tools/modules/linux/shared/kernelStubsSal.h b/open-vm-tools/modules/linux/shared/kernelStubsSal.h
new file mode 100644
index 00000000..6938aed5
--- /dev/null
+++ b/open-vm-tools/modules/linux/shared/kernelStubsSal.h
@@ -0,0 +1,134 @@
+/*********************************************************
+ * Copyright (C) 2014 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *********************************************************/
+
+/*
+ * kernelStubsSal.h
+ *
+ * Contains definitions source annotation language definitions for kernel drivers.
+ * This solves two issues:
+ * 1. Microsoft changed their annotation language from SAL 1.0 (original one
+ * widely distributed by the Windows team) to their more final SAL 2.0
+ * langauge (championed by the VS team). We target multiple versions of
+ * Driver Kits, so we have to map 2.0 to 1.0.
+ * 2. We want these annotations to do nothing during non-Win32 compiles.
+ *
+ * A longer term goal is to rationalize this into Bora.
+ */
+#ifndef __KERNELSTUBSSAL_H__
+#define __KERNELSTUBSSAL_H__
+
+#if defined(_WIN32)
+# include <DriverSpecs.h>
+# if !defined(_SAL_VERSION)
+# define _SAL_VERSION 10
+# endif
+#endif
+
+#if !defined(_SAL_VERSION)
+#define _In_
+#define _In_z_
+#define _In_opt_
+#define _In_opt_z_
+#define _Out_
+#define _Out_opt_
+#define _Out_z_cap_(e)
+#define _Inout_
+#define _Inout_z_cap_(e)
+#define _Post_z_count_(e)
+#define _Ret_writes_z_(e)
+#define _Ret_writes_maybenull_z_(e)
+#define _Ret_maybenull_z_
+#define _Success_(expr)
+#define _Check_return_
+#define _Must_inspect_result_
+#define _Group_(annos)
+#define _When_(expr, annos)
+#define _Printf_format_string_
+#define _Use_decl_annotations_
+#elif _SAL_VERSION == 10
+// Microsoft didn't create a header mapping SAL 2.0 to 1.0. We do that here.
+#define _In_ __in
+#define _In_z_ __in_z
+#define _In_opt_ __in_opt
+#define _In_opt_z_ __in_z_opt
+#define _Out_ __out
+#define _Out_opt_ __out_opt
+#define _Out_z_cap_(expr) __out_ecount_z(expr)
+#define _Inout_ __inout
+#define _Inout_z_cap_(expr) __inout_ecount_z(expr)
+#define _Post_z_count_(expr)
+#define _Ret_writes_z_(expr) __out_ecount_z(expr)
+#define _Ret_writes_maybenull_z_(expr) __out_ecount_z_opt(expr)
+#define _Ret_maybenull_z_ __out_z
+#define _Check_return_ __checkReturn
+#define _Must_inspect_result_ __checkReturn
+#define _Success_(annos) __success(annos)
+#define _Printf_format_string_ __format_string
+#define _Use_decl_annotations_
+
+// DriverSpecs.h was pretty much empty until the DDK that defined
+// NTDDK_WIN6SP1 appeared.
+#if defined(NTDDI_WIN6SP1)
+#define _Group_(annos) __$drv_group(annos)
+#define _When_(expr, annos) __drv_when(expr, annos)
+#define _IRQL_requires_max_(irql) __drv_maxIRQL(irql)
+#else
+#define _Group_(annos)
+#define _When_(expr, annos)
+#define _IRQL_requires_max_(irql)
+#define __drv_allocatesMem(kind)
+#define __drv_freesMem(kind)
+#endif
+
+#else
+// Sal 2.0 path - everything is already defined.
+#endif // _SAL_VERSION
+
+// Now define our own annotations
+#if !defined(_SAL_VERSION)
+#define _When_windrv_(annos)
+#define _Ret_allocates_malloc_mem_opt_bytecap_(_Size)
+#define _Ret_allocates_malloc_mem_opt_bytecount_(_Size)
+#define _Ret_allocates_malloc_mem_opt_bytecap_post_bytecount_(_Cap,_Count)
+#define _Ret_allocates_malloc_mem_opt_z_bytecount_(_Size)
+#define _Ret_allocates_malloc_mem_opt_z_
+#define _In_frees_malloc_mem_opt_
+#elif _SAL_VERSION == 10
+#define _When_windrv_(annos) annos
+#define _Ret_allocates_malloc_mem_opt_bytecap_(_Cap) __drv_allocatesMem("Memory") __checkReturn __post __byte_writableTo(_Cap) __exceptthat __maybenull
+#define _Ret_allocates_malloc_mem_opt_bytecount_(_Count) __drv_allocatesMem("Memory") __checkReturn __post __byte_readableTo(_Count) __exceptthat __maybenull
+#define _Ret_allocates_malloc_mem_opt_bytecap_post_bytecount_(_Cap,_Count) __drv_allocatesMem("Memory") __checkReturn __post __byte_writableTo(_Cap) __byte_readableTo(_Count) __exceptthat __maybenull
+#define _Ret_allocates_malloc_mem_opt_z_bytecount_(_Count) __drv_allocatesMem("Memory") __checkReturn __post __byte_readableTo(_Count) __valid __nullterminated __exceptthat __maybenull
+#define _Ret_allocates_malloc_mem_opt_z_ __drv_allocatesMem("Memory") __checkReturn __post __valid __nullterminated __exceptthat __maybenull
+#define _In_frees_malloc_mem_opt_ __drv_freesMem("Memory") __in_opt __post __notvalid
+#else
+#define _When_windrv_(annos) annos
+#define _Ret_allocates_malloc_mem_opt_bytecap_(_Cap) __drv_allocatesMem("Memory") _Must_inspect_result_ _Ret_opt_bytecap_(_Cap)
+#define _Ret_allocates_malloc_mem_opt_bytecount_(_Count) __drv_allocatesMem("Memory") _Must_inspect_result_ _Ret_opt_bytecount_(_Count)
+#define _Ret_allocates_malloc_mem_opt_bytecap_post_bytecount_(_Cap,_Count) __drv_allocatesMem("Memory") _Must_inspect_result_ _Ret_opt_bytecap_(_Cap) _Ret_opt_bytecount_(_Count)
+#define _Ret_allocates_malloc_mem_opt_z_bytecount_(_Count) __drv_allocatesMem("Memory") _Must_inspect_result_ _Ret_opt_z_bytecount_(_Count)
+#define _Ret_allocates_malloc_mem_opt_z_ __drv_allocatesMem("Memory") _Must_inspect_result_ _Ret_opt_z_
+#define _In_frees_malloc_mem_opt_ __drv_freesMem("Memory") _Pre_maybenull_ _Post_invalid_
+#endif // _SAL_VERSION
+
+// Best we can do for reallocate with simple annotations: assume old size was fully initialized.
+#define _Ret_reallocates_malloc_mem_opt_newbytecap_oldbytecap_(_NewSize, _OldSize) _Ret_allocates_malloc_mem_opt_bytecap_post_bytecount_(_NewSize, _OldSize <= _NewSize ? _OldSize : _NewSize)
+#define _Ret_reallocates_malloc_mem_opt_newbytecap_(_NewSize) _Ret_allocates_malloc_mem_opt_z_bytecount_(_NewSize)
+#define _In_reallocates_malloc_mem_opt_oldptr_ _In_frees_malloc_mem_opt_
+
+#endif // __KERNELSTUBSSAL_H__
diff --git a/open-vm-tools/modules/linux/shared/vmciKernelAPI1.h b/open-vm-tools/modules/linux/shared/vmciKernelAPI1.h
index 10ce7912..dc528180 100644
--- a/open-vm-tools/modules/linux/shared/vmciKernelAPI1.h
+++ b/open-vm-tools/modules/linux/shared/vmciKernelAPI1.h
@@ -91,7 +91,11 @@ VMCIId vmci_get_context_id(void);
#if defined(linux) && !defined(VMKERNEL)
/* Returned value is a bool, 0 for false, 1 for true. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+int vmci_is_context_owner(VMCIId contextID, kuid_t uid);
+#else
int vmci_is_context_owner(VMCIId contextID, uid_t uid);
+#endif
#else // !linux || VMKERNEL
/* Returned value is a VMCI error code. */
int vmci_is_context_owner(VMCIId contextID, void *hostUser);
@@ -140,9 +144,9 @@ ssize_t vmci_qpair_dequeue(VMCIQPair *qpair, void *buf, size_t bufSize,
int mode);
ssize_t vmci_qpair_peek(VMCIQPair *qpair, void *buf, size_t bufSize, int mode);
-#if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
- (defined(__linux__) && defined(__KERNEL__)) || \
- (defined(_WIN32) && defined(WINNT_DDK))
+#if (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
+ (defined(__linux__) && defined(__KERNEL__)) || \
+ (defined(_WIN32) && defined(WINNT_DDK))
/*
* Environments that support struct iovec
*/
diff --git a/open-vm-tools/modules/linux/shared/vmci_defs.h b/open-vm-tools/modules/linux/shared/vmci_defs.h
index c0843359..74d314ff 100644
--- a/open-vm-tools/modules/linux/shared/vmci_defs.h
+++ b/open-vm-tools/modules/linux/shared/vmci_defs.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2005-2012 VMware, Inc. All rights reserved.
+ * Copyright (C) 2005-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -30,6 +30,7 @@
#include "includeCheck.h"
#include "vm_basic_types.h"
+#include "vm_basic_defs.h"
#include "vm_atomic.h"
#include "vm_assert.h"
diff --git a/open-vm-tools/modules/linux/shared/vmci_infrastructure.h b/open-vm-tools/modules/linux/shared/vmci_infrastructure.h
index 73e37c3c..099b5268 100644
--- a/open-vm-tools/modules/linux/shared/vmci_infrastructure.h
+++ b/open-vm-tools/modules/linux/shared/vmci_infrastructure.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -65,12 +65,14 @@ typedef struct VMCIDoorbellCptState {
} VMCIDoorbellCptState;
/* Used to determine what checkpoint state to get and set. */
-#define VMCI_NOTIFICATION_CPT_STATE 0x1
-#define VMCI_WELLKNOWN_CPT_STATE 0x2
-#define VMCI_DG_OUT_STATE 0x3
-#define VMCI_DG_IN_STATE 0x4
-#define VMCI_DG_IN_SIZE_STATE 0x5
-#define VMCI_DOORBELL_CPT_STATE 0x6
+#define VMCI_NOTIFICATION_CPT_STATE 0x1
+#define VMCI_WELLKNOWN_CPT_STATE 0x2
+#define VMCI_DG_OUT_STATE 0x3
+#define VMCI_DG_IN_STATE 0x4
+#define VMCI_DG_IN_SIZE_STATE 0x5
+#define VMCI_DOORBELL_CPT_STATE 0x6
+#define VMCI_DG_HYPERVISOR_SAVE_STATE_SIZE 0x7
+#define VMCI_DG_HYPERVISOR_SAVE_STATE 0x8
/* Used to control the VMCI device in the vmkernel */
#define VMCI_DEV_RESET 0x01
diff --git a/open-vm-tools/modules/linux/shared/vmci_iocontrols.h b/open-vm-tools/modules/linux/shared/vmci_iocontrols.h
index e1355ec3..ce99894a 100644
--- a/open-vm-tools/modules/linux/shared/vmci_iocontrols.h
+++ b/open-vm-tools/modules/linux/shared/vmci_iocontrols.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2013 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -154,7 +154,7 @@ VMCIPtrToVA64(void const *ptr) // IN
#define VMCI_SOCKETS_MAKE_VERSION(_p) \
((((_p)[0] & 0xFF) << 24) | (((_p)[1] & 0xFF) << 16) | ((_p)[2]))
-#if defined(__linux__) || defined(SOLARIS) || defined(VMKERNEL)
+#if defined(__linux__) || defined(VMKERNEL)
/*
* Linux defines _IO* macros, but the core kernel code ignore the encoded
* ioctl value. It is up to individual drivers to decode the value (for
@@ -317,12 +317,12 @@ enum IOCTLCmd_VMCI {
* The size of this must match the size of VSockIoctlPrivSyms in
* modules/vsock/common/vsockIoctl.h.
*/
-#include "vmware_pack_begin.h"
+#pragma pack(push, 1)
struct IOCTLCmd_VMCIMacOS_PrivSyms {
char data[344];
-}
-#include "vmware_pack_end.h"
-;
+};
+#pragma pack(pop)
+
enum IOCTLCmd_VMCIMacOS {
IOCTLCMD_I(SOCKETS_SET_SYMBOLS, struct IOCTLCmd_VMCIMacOS_PrivSyms),
IOCTLCMD_O(SOCKETS_VERSION, unsigned int),
diff --git a/open-vm-tools/modules/linux/shared/vmci_kernel_if.h b/open-vm-tools/modules/linux/shared/vmci_kernel_if.h
index 29c609df..ef8a5520 100644
--- a/open-vm-tools/modules/linux/shared/vmci_kernel_if.h
+++ b/open-vm-tools/modules/linux/shared/vmci_kernel_if.h
@@ -28,7 +28,7 @@
#define _VMCI_KERNEL_IF_H_
#if !defined(linux) && !defined(_WIN32) && !defined(__APPLE__) && \
- !defined(VMKERNEL) && !defined(SOLARIS)
+ !defined(VMKERNEL)
# error "Platform not supported."
#endif
@@ -55,21 +55,12 @@
#ifdef VMKERNEL
# include "splock.h"
+# include "splock_customRanks.h"
# include "semaphore_ext.h"
# include "vmkapi.h"
# include "world_dist.h"
#endif
-#ifdef SOLARIS
-# include <sys/ddi.h>
-# include <sys/kmem.h>
-# include <sys/mutex.h>
-# include <sys/poll.h>
-# include <sys/semaphore.h>
-# include <sys/sunddi.h>
-# include <sys/types.h>
-#endif
-
#include "vm_basic_types.h"
#include "vmci_defs.h"
@@ -110,7 +101,11 @@
typedef wait_queue_head_t VMCIEvent;
typedef struct semaphore VMCIMutex;
typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ typedef kuid_t VMCIHostUser;
+#else
typedef uid_t VMCIHostUser;
+#endif
typedef VA64 VMCIQPGuestMem;
#elif defined(__APPLE__)
typedef IOLock *VMCILock;
@@ -132,14 +127,6 @@
typedef PMDL VMCIPpnList; /* MDL to map the produce/consume queue. */
typedef PSID VMCIHostUser;
typedef VA64 *VMCIQPGuestMem;
-#elif defined(SOLARIS)
- typedef kmutex_t VMCILock;
- typedef unsigned long VMCILockFlags;
- typedef ksema_t VMCIEvent;
- typedef kmutex_t VMCIMutex;
- typedef PPN *VMCIPpnList; /* List of PPNs in produce/consume queue. */
- typedef uid_t VMCIHostUser;
- typedef VA64 VMCIQPGuestMem;
#endif // VMKERNEL
/* Callback needed for correctly waiting on events. */
@@ -205,11 +192,6 @@ typedef struct VMCIHost {
KEVENT *callEvent; /* Ptr to userlevel event used when signalling
* new pending guestcalls in kernel.
*/
-#elif defined(SOLARIS)
- struct pollhead pollhead; /* Per datagram handle pollhead structure to
- * be treated as a black-box. None of its
- * fields should be referenced.
- */
#endif
} VMCIHost;
@@ -223,9 +205,6 @@ typedef struct VMCIHost {
#elif defined(_WIN32)
typedef PUCHAR VMCIIoPort;
typedef int VMCIIoHandle;
-#elif defined(SOLARIS)
- typedef uint8_t * VMCIIoPort;
- typedef ddi_acc_handle_t VMCIIoHandle;
#elif defined(__APPLE__)
typedef unsigned short int VMCIIoPort;
typedef void *VMCIIoHandle;
@@ -260,6 +239,8 @@ void VMCIHost_SetInactiveHnd(VMCIHost *hostContext, uintptr_t eventHnd);
uint32 VMCIHost_NumHnds(VMCIHost *hostContext);
uintptr_t VMCIHost_GetActiveHnd(VMCIHost *hostContext);
void VMCIHost_SignalBitmap(VMCIHost *hostContext);
+void VMCIHost_SignalBitmapAlways(VMCIHost *hostContext);
+void VMCIHost_SignalCallAlways(VMCIHost *hostContext);
#endif
#if defined(_WIN32)
@@ -296,7 +277,7 @@ Bool VMCI_WaitOnEventInterruptible(VMCIEvent *event,
#endif
#if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \
- defined(__APPLE__) || defined(SOLARIS))
+ defined(__APPLE__))
int VMCI_CopyFromUser(void *dst, VA64 src, size_t len);
#endif
@@ -309,16 +290,16 @@ void VMCIMutex_Destroy(VMCIMutex *mutex);
void VMCIMutex_Acquire(VMCIMutex *mutex);
void VMCIMutex_Release(VMCIMutex *mutex);
-#if defined(SOLARIS) || defined(_WIN32) || defined(__APPLE__)
+#if defined(_WIN32) || defined(__APPLE__)
int VMCIKernelIf_Init(void);
void VMCIKernelIf_Exit(void);
#if defined(_WIN32)
void VMCIKernelIf_DrainDelayedWork(void);
#endif // _WIN32
-#endif // SOLARIS || _WIN32 || __APPLE__
+#endif // _WIN32 || __APPLE__
-#if !defined(VMKERNEL) && (defined(__linux__) || defined(_WIN32) || \
- defined(SOLARIS) || defined(__APPLE__))
+#if !defined(VMKERNEL) && \
+ (defined(__linux__) || defined(_WIN32) || defined(__APPLE__))
void *VMCI_AllocQueue(uint64 size, uint32 flags);
void VMCI_FreeQueue(void *q, uint64 size);
typedef struct PPNSet {
@@ -393,12 +374,12 @@ typedef uint32 VMCIGuestMemID;
void VMCI_LockQueueHeader(struct VMCIQueue *queue);
void VMCI_UnlockQueueHeader(struct VMCIQueue *queue);
#else
-# define VMCI_LockQueueHeader(_q) ASSERT_NOT_IMPLEMENTED(FALSE)
-# define VMCI_UnlockQueueHeader(_q) ASSERT_NOT_IMPLEMENTED(FALSE)
+# define VMCI_LockQueueHeader(_q) NOT_IMPLEMENTED()
+# define VMCI_UnlockQueueHeader(_q) NOT_IMPLEMENTED()
#endif
#if (!defined(VMKERNEL) && defined(__linux__)) || defined(_WIN32) || \
- defined(__APPLE__) || defined(SOLARIS)
+ defined(__APPLE__)
int VMCIHost_GetUserMemory(VA64 produceUVA, VA64 consumeUVA,
struct VMCIQueue *produceQ,
struct VMCIQueue *consumeQ);
@@ -406,7 +387,7 @@ typedef uint32 VMCIGuestMemID;
struct VMCIQueue *consumeQ);
#else
# define VMCIHost_GetUserMemory(_puva, _cuva, _pq, _cq) VMCI_ERROR_UNAVAILABLE
-# define VMCIHost_ReleaseUserMemory(_pq, _cq) ASSERT_NOT_IMPLEMENTED(FALSE)
+# define VMCIHost_ReleaseUserMemory(_pq, _cq) NOT_IMPLEMENTED()
#endif
#if defined(_WIN32)
diff --git a/open-vm-tools/modules/linux/vmblock/Makefile b/open-vm-tools/modules/linux/vmblock/Makefile
index 36529cd6..21e5dc16 100644
--- a/open-vm-tools/modules/linux/vmblock/Makefile
+++ b/open-vm-tools/modules/linux/vmblock/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmci/Makefile b/open-vm-tools/modules/linux/vmci/Makefile
index 3ff28c4b..05aa915c 100644
--- a/open-vm-tools/modules/linux/vmci/Makefile
+++ b/open-vm-tools/modules/linux/vmci/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmci/Makefile.kernel b/open-vm-tools/modules/linux/vmci/Makefile.kernel
index ba343eea..8e6e7d0b 100644
--- a/open-vm-tools/modules/linux/vmci/Makefile.kernel
+++ b/open-vm-tools/modules/linux/vmci/Makefile.kernel
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 2007 VMware, Inc. All rights reserved.
+# Copyright (C) 2007,2014 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -55,7 +55,7 @@ endif
#
# If this build generated a Module.symvers, copy it to a public place where
-# the VMCI Sockets build will be able to find it.
+# the vSockets build will be able to find it.
#
postbuild::
ifeq ($(call vm_check_file,$(SRCROOT)/Module.symvers), yes)
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciContext.c b/open-vm-tools/modules/linux/vmci/common/vmciContext.c
index 513e93d4..5ebd28ab 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciContext.c
+++ b/open-vm-tools/modules/linux/vmci/common/vmciContext.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006-2012 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2012,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -577,8 +577,9 @@ VMCIContext_PendingDatagrams(VMCIId cid, // IN
*/
int
-VMCIContext_EnqueueDatagram(VMCIId cid, // IN: Target VM
- VMCIDatagram *dg) // IN:
+VMCIContext_EnqueueDatagram(VMCIId cid, // IN: Target VM
+ VMCIDatagram *dg, // IN:
+ Bool notify) // IN:
{
DatagramQueueEntry *dqEntry;
VMCIContext *context;
@@ -648,8 +649,12 @@ VMCIContext_EnqueueDatagram(VMCIId cid, // IN: Target VM
VMCIList_Insert(&dqEntry->listItem, &context->datagramQueue);
context->pendingDatagrams++;
context->datagramQueueSize += vmciDgSize;
- VMCIContextSignalNotify(context);
- VMCIHost_SignalCall(&context->hostContext);
+
+ if (notify) {
+ VMCIContextSignalNotify(context);
+ VMCIHost_SignalCall(&context->hostContext);
+ }
+
VMCI_ReleaseLock(&context->lock, flags);
VMCIContext_Release(context);
@@ -809,7 +814,7 @@ VMCIContext_Release(VMCIContext *context) // IN
{
uint32 refCount;
ASSERT(context);
- refCount = Atomic_FetchAndDec(&context->refCount);
+ refCount = Atomic_ReadDec32(&context->refCount);
if (refCount == 1) {
VMCIContextFreeContext(context);
}
@@ -1489,6 +1494,143 @@ VMCIContextFireNotification(VMCIId contextID, // IN
return VMCI_SUCCESS;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCIContextDgHypervisorSaveStateSize --
+ *
+ * Calculate the size for the hypervisor datagram checkpoint
+ * save data.
+ *
+ * The format is as follows:
+ *
+ * uint32 count - number of entries
+ * uint32 size - size of first entry
+ * char bytes[] - contents of first entry
+ * uint32 size - size of second entry
+ * char bytes[] - contents of second entry
+ * ...
+ *
+ * Results:
+ * VMCI_SUCCESS on success, error code otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+VMCIContextDgHypervisorSaveStateSize(VMCIContext *context, // IN
+ uint32 *bufSize, // IN/OUT
+ char **cptBufPtr) // UNUSED
+{
+ uint32 total;
+ VMCIListItem *iter;
+
+ *bufSize = total = 0;
+
+ VMCIList_Scan(iter, &context->datagramQueue) {
+ DatagramQueueEntry *dqEntry =
+ VMCIList_Entry(iter, DatagramQueueEntry, listItem);
+
+ if (dqEntry->dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID) {
+ /* Size of the datagram followed by the contents of the datagram. */
+ total += sizeof(uint32) + dqEntry->dgSize;
+ }
+ }
+
+ if (total > 0) {
+ /* Don't forget the datagram count. */
+ *bufSize = total + sizeof(uint32);
+ }
+
+ return VMCI_SUCCESS;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VMCIContextDgHypervisorSaveState --
+ *
+ * Get the hypervisor datagram checkpoint save data.
+ *
+ * Results:
+ * VMCI_SUCCESS on success, error code otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+VMCIContextDgHypervisorSaveState(VMCIContext *context, // IN
+ uint32 *bufSize, // IN/OUT
+ char **cptBufPtr) // OUT
+{
+ uint8 *p;
+ uint32 total;
+ uint32 count;
+ VMCIListItem *iter;
+
+ /* Need at least the count field and the size of one entry. */
+ if (*bufSize < sizeof(uint32) * 2) {
+ return VMCI_ERROR_INVALID_ARGS;
+ }
+
+ p = VMCI_AllocKernelMem(*bufSize, VMCI_MEMORY_NORMAL);
+ if (p == NULL) {
+ return VMCI_ERROR_NO_MEM;
+ }
+
+ *cptBufPtr = p;
+
+ /* Leave space for the datagram count at the start. */
+ total = sizeof(uint32);
+ p += sizeof(uint32);
+
+ count = 0;
+ VMCIList_Scan(iter, &context->datagramQueue) {
+ DatagramQueueEntry *dqEntry =
+ VMCIList_Entry(iter, DatagramQueueEntry, listItem);
+
+ if (dqEntry->dg->src.context == VMCI_HYPERVISOR_CONTEXT_ID) {
+
+ /*
+ * VMX might have capped the amount of space we can use to checkpoint
+ * hypervisor datagrams. Respect that here. Those that are not written
+ * to the buffer will get dropped.
+ */
+
+ if (total + sizeof(uint32) + dqEntry->dgSize > *bufSize) {
+ break;
+ }
+
+ total += sizeof(uint32) + dqEntry->dgSize;
+
+ /*
+ * Write in the size of the datagram followed by the contents of the
+ * datagram itself.
+ */
+
+ *(uint32 *)p = dqEntry->dgSize;
+ p += sizeof(uint32);
+
+ memcpy(p, dqEntry->dg, dqEntry->dgSize);
+ p += dqEntry->dgSize;
+
+ count++;
+ }
+ }
+
+ /* Now rollback and write the count at the start of the block. */
+ *(uint32 *)(*cptBufPtr) = count;
+
+ return VMCI_SUCCESS;
+}
+
/*
*----------------------------------------------------------------------
@@ -1546,6 +1688,12 @@ VMCIContext_GetCheckpointState(VMCIId contextID, // IN:
ASSERT(context->doorbellArray);
array = context->doorbellArray;
getContextID = FALSE;
+ } else if (cptType == VMCI_DG_HYPERVISOR_SAVE_STATE_SIZE) {
+ result = VMCIContextDgHypervisorSaveStateSize(context, bufSize, cptBufPtr);
+ goto release;
+ } else if (cptType == VMCI_DG_HYPERVISOR_SAVE_STATE) {
+ result = VMCIContextDgHypervisorSaveState(context, bufSize, cptBufPtr);
+ goto release;
} else {
VMCI_DEBUG_LOG(4, (LGPFX"Invalid cpt state (type=%d).\n", cptType));
result = VMCI_ERROR_INVALID_ARGS;
@@ -1589,10 +1737,9 @@ VMCIContext_GetCheckpointState(VMCIId contextID, // IN:
}
result = VMCI_SUCCESS;
- release:
+release:
VMCI_ReleaseLock(&context->lock, flags);
VMCIContext_Release(context);
-
return result;
}
@@ -2081,7 +2228,7 @@ VMCIContext_SignalPendingDoorbells(VMCIId contextID)
VMCI_ReleaseLock(&context->lock, flags);
if (pending) {
- VMCIHost_SignalBitmap(&context->hostContext);
+ VMCIHost_SignalBitmapAlways(&context->hostContext);
}
VMCIContext_Release(context);
@@ -2125,7 +2272,7 @@ VMCIContext_SignalPendingDatagrams(VMCIId contextID)
VMCI_ReleaseLock(&context->lock, flags);
if (pending) {
- VMCIHost_SignalCall(&context->hostContext);
+ VMCIHost_SignalCallAlways(&context->hostContext);
}
VMCIContext_Release(context);
@@ -2207,7 +2354,7 @@ VMCI_EXPORT_SYMBOL(vmci_is_context_owner)
#if defined(linux) && !defined(VMKERNEL)
int
vmci_is_context_owner(VMCIId contextID, // IN
- uid_t uid) // IN
+ VMCIHostUser uid) // IN
{
int isOwner = 0;
@@ -2215,7 +2362,7 @@ vmci_is_context_owner(VMCIId contextID, // IN
VMCIContext *context = VMCIContext_Get(contextID);
if (context) {
if (context->validUser) {
- if (VMCIHost_CompareUser((VMCIHostUser *)&uid,
+ if (VMCIHost_CompareUser(&uid,
&context->user) == VMCI_SUCCESS) {
isOwner = 1;
}
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciContext.h b/open-vm-tools/modules/linux/vmci/common/vmciContext.h
index de0201ef..07fc3658 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciContext.h
+++ b/open-vm-tools/modules/linux/vmci/common/vmciContext.h
@@ -68,7 +68,7 @@ void VMCIContext_SetId(VMCIContext *context, VMCIId cid);
#endif
Bool VMCIContext_SupportsHostQP(VMCIContext *context);
void VMCIContext_ReleaseContext(VMCIContext *context);
-int VMCIContext_EnqueueDatagram(VMCIId cid, VMCIDatagram *dg);
+int VMCIContext_EnqueueDatagram(VMCIId cid, VMCIDatagram *dg, Bool notify);
int VMCIContext_DequeueDatagram(VMCIContext *context, size_t *maxSize,
VMCIDatagram **dg);
int VMCIContext_PendingDatagrams(VMCIId cid, uint32 *pending);
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c b/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c
index 2f17a182..7fd7674a 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c
+++ b/open-vm-tools/modules/linux/vmci/common/vmciDatagram.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2011,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -622,7 +622,7 @@ VMCIDatagramDispatchAsHost(VMCIId contextID, // IN:
VMCI_CanScheduleDelayedWork())) {
VMCIDelayedDatagramInfo *dgInfo;
- if (Atomic_FetchAndAdd(&delayedDGHostQueueSize, 1) ==
+ if (Atomic_ReadInc32(&delayedDGHostQueueSize) ==
VMCI_MAX_DELAYED_DG_HOST_QUEUE_SIZE) {
Atomic_Dec(&delayedDGHostQueueSize);
VMCIResource_Release(resource);
@@ -692,7 +692,7 @@ VMCIDatagramDispatchAsHost(VMCIId contextID, // IN:
return VMCI_ERROR_NO_MEM;
}
memcpy(newDG, dg, dgSize);
- retval = VMCIContext_EnqueueDatagram(dg->dst.context, newDG);
+ retval = VMCIContext_EnqueueDatagram(dg->dst.context, newDG, TRUE);
if (retval < VMCI_SUCCESS) {
VMCI_FreeKernelMem(newDG, dgSize);
VMCI_DEBUG_LOG(4, (LGPFX"Enqueue failed\n"));
@@ -844,6 +844,12 @@ VMCIDatagram_InvokeGuestHandler(VMCIDatagram *dg) // IN
ASSERT(dg);
+ if (dg->payloadSize > VMCI_MAX_DG_PAYLOAD_SIZE) {
+ VMCI_DEBUG_LOG(4, (LGPFX"Payload (size=%"FMT64"u bytes) too large to "
+ "deliver.\n", dg->payloadSize));
+ return VMCI_ERROR_PAYLOAD_TOO_LARGE;
+ }
+
resource = VMCIResource_Get(dg->dst, VMCI_RESOURCE_TYPE_DATAGRAM);
if (NULL == resource) {
VMCI_DEBUG_LOG(4, (LGPFX"destination (handle=0x%x:0x%x) doesn't exist.\n",
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciDoorbell.c b/open-vm-tools/modules/linux/vmci/common/vmciDoorbell.c
index 74053e15..5a3fbfd5 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciDoorbell.c
+++ b/open-vm-tools/modules/linux/vmci/common/vmciDoorbell.c
@@ -41,7 +41,7 @@
#define LGPFX "VMCIDoorbell: "
-#if !defined(SOLARIS) && !defined(__APPLE__)
+#if !defined(__APPLE__)
#define VMCI_DOORBELL_INDEX_TABLE_SIZE 64
#define VMCI_DOORBELL_HASH(_idx) \
@@ -1160,7 +1160,7 @@ VMCI_ScanNotificationBitmap(uint8 *bitmap)
}
-#else // SOLARIS) || __APPLE__
+#else // __APPLE__
/*
*-----------------------------------------------------------------------------
@@ -1238,4 +1238,4 @@ VMCIDoorbell_Exit(void)
{
}
-#endif // SOLARIS) || __APPLE__
+#endif // __APPLE__
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciDriver.c b/open-vm-tools/modules/linux/vmci/common/vmciDriver.c
index bd0b4964..4a379585 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciDriver.c
+++ b/open-vm-tools/modules/linux/vmci/common/vmciDriver.c
@@ -124,7 +124,7 @@ VMCI_HostCleanup(void)
}
-#if defined(__APPLE__) || defined(SOLARIS) || defined(VMKERNEL)
+#if defined(__APPLE__) || defined(VMKERNEL)
/* Windows has its own implementation of this, and Linux doesn't need one. */
/*
*----------------------------------------------------------------------
@@ -189,7 +189,7 @@ void
vmci_device_release(void *deviceRegistration) // UNUSED
{
}
-#endif // __APPLE__ || SOLARIS || VMKERNEL
+#endif // __APPLE__ || VMKERNEL
/*
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciQPair.c b/open-vm-tools/modules/linux/vmci/common/vmciQPair.c
index dbc64922..7a021278 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciQPair.c
+++ b/open-vm-tools/modules/linux/vmci/common/vmciQPair.c
@@ -1234,9 +1234,9 @@ vmci_qpair_peek(VMCIQPair *qpair, // IN
}
-#if defined (SOLARIS) || (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
- (defined(__linux__) && defined(__KERNEL__)) || \
- (defined(_WIN32) && defined(WINNT_DDK))
+#if (defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
+ (defined(__linux__) && defined(__KERNEL__)) || \
+ (defined(_WIN32) && defined(WINNT_DDK))
/*
*-----------------------------------------------------------------------------
diff --git a/open-vm-tools/modules/linux/vmci/common/vmciRoute.c b/open-vm-tools/modules/linux/vmci/common/vmciRoute.c
index b73d3867..cc98b93c 100644
--- a/open-vm-tools/modules/linux/vmci/common/vmciRoute.c
+++ b/open-vm-tools/modules/linux/vmci/common/vmciRoute.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2012 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2012,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -114,17 +114,6 @@ VMCI_Route(VMCIHandle *src, // IN/OUT
return VMCI_ERROR_INVALID_ARGS;
}
- /*
- * If the client passed the ANON source handle then respect it (both
- * context and resource are invalid). However, if they passed only
- * an invalid context, then they probably mean ANY, in which case we
- * should set the real context here before passing it down.
- */
-
- if (VMCI_INVALID_ID == src->context && VMCI_INVALID_ID != src->resource) {
- src->context = vmci_get_context_id();
- }
-
/* Send from local client down to the hypervisor. */
*route = VMCI_ROUTE_AS_GUEST;
return VMCI_SUCCESS;
diff --git a/open-vm-tools/modules/linux/vmci/linux/driver.c b/open-vm-tools/modules/linux/vmci/linux/driver.c
index c9519ca2..58e23c2a 100644
--- a/open-vm-tools/modules/linux/vmci/linux/driver.c
+++ b/open-vm-tools/modules/linux/vmci/linux/driver.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2013 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -1801,8 +1801,9 @@ vmci_probe_device(struct pci_dev *pdev, // IN: vmci PCI device
*/
if (capabilities & VMCI_CAPS_NOTIFICATIONS) {
capabilities = VMCI_CAPS_DATAGRAM;
- notification_bitmap = pci_alloc_consistent(pdev, PAGE_SIZE,
- &notification_base);
+ notification_bitmap = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
+ &notification_base,
+ GFP_KERNEL);
if (notification_bitmap == NULL) {
printk(KERN_ERR "VMCI device unable to allocate notification bitmap.\n");
} else {
@@ -1948,8 +1949,8 @@ vmci_probe_device(struct pci_dev *pdev, // IN: vmci PCI device
compat_mutex_unlock(&vmci_dev.lock);
release:
if (notification_bitmap) {
- pci_free_consistent(pdev, PAGE_SIZE, notification_bitmap,
- notification_base);
+ dma_free_coherent(&pdev->dev, PAGE_SIZE, notification_bitmap,
+ notification_base);
notification_bitmap = NULL;
}
release_region(ioaddr, ioaddr_size);
diff --git a/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c b/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c
index 4e72c33f..8b1788fa 100644
--- a/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c
+++ b/open-vm-tools/modules/linux/vmci/linux/vmciKernelIf.c
@@ -428,11 +428,13 @@ int VMCIHost_CompareUser(VMCIHostUser *user1,
return VMCI_ERROR_INVALID_ARGS;
}
- if (*user1 == *user2) {
- return VMCI_SUCCESS;
- } else {
- return VMCI_ERROR_GENERIC;
- }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+# define vmw_uid_eq(a, b) uid_eq(a, b)
+#else
+# define vmw_uid_eq(a, b) ((a) == (b))
+#endif
+
+ return vmw_uid_eq(*user1, *user2) ? VMCI_SUCCESS : VMCI_ERROR_GENERIC;
}
@@ -930,8 +932,8 @@ VMCI_AllocQueue(uint64 size, // IN: size of queue (not including header)
for (i = 0; i < numPages; i++) {
queue->kernelIf->u.g.vas[i] =
- pci_alloc_consistent(vmci_pdev, PAGE_SIZE,
- &queue->kernelIf->u.g.pas[i]);
+ dma_alloc_coherent(&vmci_pdev->dev, PAGE_SIZE,
+ &queue->kernelIf->u.g.pas[i], GFP_KERNEL);
if (!queue->kernelIf->u.g.vas[i]) {
VMCI_FreeQueue(queue, i * PAGE_SIZE); /* Size excl. the header. */
return NULL;
@@ -973,9 +975,9 @@ VMCI_FreeQueue(void *q, // IN:
/* Given size does not include header, so add in a page here. */
for (i = 0; i < CEILING(size, PAGE_SIZE) + 1; i++) {
- pci_free_consistent(vmci_pdev, PAGE_SIZE,
- queue->kernelIf->u.g.vas[i],
- queue->kernelIf->u.g.pas[i]);
+ dma_free_coherent(&vmci_pdev->dev, PAGE_SIZE,
+ queue->kernelIf->u.g.vas[i],
+ queue->kernelIf->u.g.pas[i]);
}
vfree(queue);
}
diff --git a/open-vm-tools/modules/linux/vmci/linux/vmci_version.h b/open-vm-tools/modules/linux/vmci/linux/vmci_version.h
index 497a9175..ee56876d 100644
--- a/open-vm-tools/modules/linux/vmci/linux/vmci_version.h
+++ b/open-vm-tools/modules/linux/vmci/linux/vmci_version.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007-2013 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -25,8 +25,8 @@
#ifndef _VMCI_VERSION_H_
#define _VMCI_VERSION_H_
-#define VMCI_DRIVER_VERSION 9.6.0.0
-#define VMCI_DRIVER_VERSION_COMMAS 9,6,0,0
-#define VMCI_DRIVER_VERSION_STRING "9.6.0.0"
+#define VMCI_DRIVER_VERSION 9.7.1.0
+#define VMCI_DRIVER_VERSION_COMMAS 9,7,1,0
+#define VMCI_DRIVER_VERSION_STRING "9.7.1.0"
#endif /* _VMCI_VERSION_H_ */
diff --git a/open-vm-tools/modules/linux/vmci/shared/pgtbl.h b/open-vm-tools/modules/linux/vmci/shared/pgtbl.h
index 461ef483..ed1ae8a1 100644
--- a/open-vm-tools/modules/linux/vmci/shared/pgtbl.h
+++ b/open-vm-tools/modules/linux/vmci/shared/pgtbl.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2002 VMware, Inc. All rights reserved.
+ * Copyright (C) 2002,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -37,8 +37,8 @@
* holding a spinlock --hpreg
*
* Results:
- * INVALID_MPN64 on failure
- * mpn on success
+ * INVALID_MPN on failure
+ * mpn on success
*
* Side effects:
* None
@@ -51,11 +51,11 @@ PgtblPte2MPN(pte_t *pte) // IN
{
MPN64 mpn;
if (pte_present(*pte) == 0) {
- return INVALID_MPN64;
+ return INVALID_MPN;
}
mpn = pte_pfn(*pte);
- if (mpn >= INVALID_MPN64) {
- return INVALID_MPN64;
+ if (mpn >= INVALID_MPN) {
+ return INVALID_MPN;
}
return mpn;
}
@@ -176,8 +176,8 @@ PgtblVa2PTELocked(struct mm_struct *mm, // IN: Mm structure of a process
* must be held, so this function is not allowed to schedule() --hpreg
*
* Results:
- * INVALID_MPN64 on failure
- * mpn on success
+ * INVALID_MPN on failure
+ * mpn on success
*
* Side effects:
* None
@@ -197,7 +197,7 @@ PgtblVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a process
pte_unmap(pte);
return mpn;
}
- return INVALID_MPN64;
+ return INVALID_MPN;
}
@@ -213,8 +213,8 @@ PgtblVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a process
* must be held, so this function is not allowed to schedule() --hpreg
*
* Results:
- * INVALID_MPN64 on failure
- * mpn on success
+ * INVALID_MPN on failure
+ * mpn on success
*
* Side effects:
* None
@@ -234,7 +234,7 @@ PgtblKVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a caller
pte_unmap(pte);
return mpn;
}
- return INVALID_MPN64;
+ return INVALID_MPN;
}
#endif
diff --git a/open-vm-tools/modules/linux/vmci/shared/vmciQueue.h b/open-vm-tools/modules/linux/vmci/shared/vmciQueue.h
index 11225e7c..000784f6 100644
--- a/open-vm-tools/modules/linux/vmci/shared/vmciQueue.h
+++ b/open-vm-tools/modules/linux/vmci/shared/vmciQueue.h
@@ -33,7 +33,7 @@
#define INCLUDE_ALLOW_VMKERNEL
#include "includeCheck.h"
-#if defined(SOLARIS) || defined(__APPLE__)
+#if defined(__APPLE__)
# include <sys/uio.h>
#endif
@@ -150,10 +150,10 @@ int VMCIMemcpyFromQueueLocal(void *dest, size_t destOffset, const VMCIQueue *que
uint64 queueOffset, size_t size, BUF_TYPE bufType,
Bool canBlock);
-#if defined VMKERNEL || defined (SOLARIS) || \
+#if defined VMKERNEL || \
(defined(__APPLE__) && !defined (VMX86_TOOLS)) || \
(defined(__linux__) && defined(__KERNEL__)) || \
- (defined(_WIN32) && defined(WINNT_DDK))
+ (defined(_WIN32) && defined(WINNT_DDK))
int VMCIMemcpyToQueueV(VMCIQueue *queue, uint64 queueOffset, const void *src,
size_t srcOffset, size_t size, BUF_TYPE bufType,
Bool canBlock);
diff --git a/open-vm-tools/modules/linux/vmci/shared/vmci_handle_array.h b/open-vm-tools/modules/linux/vmci/shared/vmci_handle_array.h
index b31ab823..13a46f5d 100644
--- a/open-vm-tools/modules/linux/vmci/shared/vmci_handle_array.h
+++ b/open-vm-tools/modules/linux/vmci/shared/vmci_handle_array.h
@@ -40,13 +40,6 @@
#include "vm_libc.h"
#endif // VMKERNEL
-#ifdef SOLARIS
-#include <sys/ddi.h>
-#include <sys/kmem.h>
-#include <sys/types.h>
-#include <sys/systm.h>
-#endif
-
#define VMCI_HANDLE_ARRAY_DEFAULT_SIZE 4
typedef struct VMCIHandleArray {
diff --git a/open-vm-tools/modules/linux/vmci/shared/vmci_page_channel.h b/open-vm-tools/modules/linux/vmci/shared/vmci_page_channel.h
deleted file mode 100644
index 22e94069..00000000
--- a/open-vm-tools/modules/linux/vmci/shared/vmci_page_channel.h
+++ /dev/null
@@ -1,733 +0,0 @@
-/*********************************************************
- * Copyright (C) 2011-2012 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmci_page_channel.h
- *
- * vPageChannel structure and functions.
- */
-
-#ifndef _VMCI_PAGE_CHANNEL_H_
-#define _VMCI_PAGE_CHANNEL_H_
-
-#define INCLUDE_ALLOW_MODULE
-#define INCLUDE_ALLOW_VMK_MODULE
-#define INCLUDE_ALLOW_VMKERNEL
-#include "includeCheck.h"
-
-#include "vmci_defs.h"
-#include "vmci_call_defs.h"
-
-/** \cond PRIVATE */
-#define VPAGECHANNEL_MAX_TX_BUF_SIZE (1 << 14)
-#define VPAGECHANNEL_MAX_PAGES_PER_TX_BUFFER \
- (VPAGECHANNEL_MAX_TX_BUF_SIZE / PAGE_SIZE + 1)
-/** \endcond */
-
-/**
- * \brief Get a pointer to the elements in a packet.
- *
- * Returns a pointer to the elements at the end of a page channel packet.
- *
- * \see VPageChannelElem
- * \see VPageChannelPacket
- */
-
-#define VPAGECHANNEL_PACKET_ELEMS(packet) \
- (VPageChannelElem *)((char *)(packet) + \
- sizeof(VPageChannelPacket) + \
- packet->msgLen)
-
-/**
- * \brief Get a pointer to the message in a packet.
- *
- * Returns a pointer to the message embedded in a page channel packet.
- *
- * \see VPageChannelPacket
- */
-
-#define VPAGECHANNEL_PACKET_MESSAGE(packet) \
- (char *)((char *)(packet) + sizeof(VPageChannelPacket))
-
-/**
- * \brief Notify client directly, and do not read packets.
- *
- * This flag indicates that the channel should invoke the client's receive
- * callback directly when any packets are available. If not specified, then
- * when a notification is received, packets are read from the channel and the
- * callback invoked for each one separately.
- *
- * \note Not applicable to VMKernel.
- *
- * \see VPageChannel_CreateInVM()
- */
-
-#define VPAGECHANNEL_FLAGS_NOTIFY_ONLY 0x1
-
-/**
- * \brief Invoke client's receive callback in delayed context.
- *
- * This flag indicates that all callbacks run in a delayed context, and the
- * caller and callback are allowed to block. If not specified, then callbacks
- * run in interrupt context and the channel will not block, and the caller
- * is not allowed to block.
- *
- * \note Not applicable to VMKernel.
- *
- * \see VPageChannel_CreateInVM()
- */
-
-#define VPAGECHANNEL_FLAGS_RECV_DELAYED 0x2
-
-/**
- * \brief Send from an atomic context.
- *
- * This flag indicates that the client wishes to call Send() from an atomic
- * context and that the channel should not block. If the channel is not
- * allowed to block, then the channel's pages are permanently mapped and
- * pinned. Note that this will limit the total size of the channel to
- * VMCI_MAX_PINNED_QP_MEMORY.
- *
- * \note Not applicable to VMKernel.
- *
- * \see VPageChannel_CreateInVM()
- */
-
-#define VPAGECHANNEL_FLAGS_SEND_WHILE_ATOMIC 0x4
-
-/**
- * \brief An element describing a data range.
- *
- * Describes a data range, starting at a base address and for a given
- * length, i.e., an element of a scatter-gather list. Indicates physical
- * address for the guest and machine address for hypervisor. Can be passed
- * via packets or buffers.
- *
- * \note Structure is packed.
- *
- * \see VPageChannelPacket
- * \see VPageChanelBuffer
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct VPageChannelElem {
- union {
- /** \brief Physical address for guest. */
- uint64 pa;
-
- /** \brief Machine address for hypervisor. */
- uint64 ma;
- };
-
- /** \brief Length of range. */
- uint32 le;
-}
-#include "vmware_pack_end.h"
-VPageChannelElem;
-
-/**
- * \brief Page channel page types.
- *
- * The various types of page channel packets.
- *
- * \see VPageChannelPacket
- */
-typedef enum {
- /** \brief Data packet. */
- VPCPacket_Data = 1,
-
- /** \brief Completion notification, from hypervisor to guest. */
- VPCPacket_Completion_Notify,
-
- /** \cond PRIVATE */
- /** \brief Connect to hypervisor, internal. */
- VPCPacket_GuestConnect,
-
- /** \brief Complete connection handshake, internal. */
- VPCPacket_HyperConnect,
-
- /** \brief Request buffers, internal. */
- VPCPacket_RequestBuffer,
-
- /** \brief Set buffers, internal. */
- VPCPacket_SetRecvBuffer,
-
- /** \brief Hypervisor channel disconnect, internal. */
- VPCPacket_HyperDisconnect,
-
- /** \brief Guest channel ACK hypervisor disconnect, internal. */
- VPCPacket_GuestDisconnect,
- /** \endcond */
-} VPageChannelPacketType;
-
-/**
- * \brief Page channel packet structure.
- *
- * A packet structure for passing control/data between guest and hypervisor.
- * Can optionally contain a message and also a number of elements.
- *
- * \note Structure is packed.
- *
- * \see VPageChannelPacketType
- */
-typedef
-#include "vmware_pack_begin.h"
-struct VPageChannelPacket {
- /** \brief Type of packet. */
- VPageChannelPacketType type;
-
- /** \brief Length of optional message. */
- uint32 msgLen;
-
- /** \brief Number of optional elements in packet. */
- uint32 numElems;
-
- /** \brief Followed by msgLen of message and numElems VPageChannelElem. */
-}
-#include "vmware_pack_end.h"
-VPageChannelPacket;
-
-/**
- * \brief Page channel buffer structure.
- *
- * A buffer of elements (a scatter-gather list).
- *
- * \note Structure is packed.
- *
- * \see VPageChannelElem
- */
-
-typedef
-#include "vmware_pack_begin.h"
-struct VPageChannelBuffer {
- /** \brief Number of elements. */
- uint32 numElems;
-
- /** \brief First element. */
- VPageChannelElem elems[1];
-
- /** \brief Followed by numElems - 1 of VPageChannelElem. */
-}
-#include "vmware_pack_end.h"
-VPageChannelBuffer;
-
-/** \cond PRIVATE */
-typedef
-#include "vmware_pack_begin.h"
-struct VPageChannelGuestConnectMessage {
-
- /** \brief Guest channel's datagram handle for control channel. */
- VMCIHandle dgHandle;
-
- /** \brief Guest channel's queuepair handle. */
- VMCIHandle qpHandle;
-
- /** \brief Size of producer queue in queuepair in bytes. */
- uint64 produceQSize;
-
- /** \brief Size of consumer queue in queuepair in bytes. */
- uint64 consumeQSize;
-
- /** \brief Guest channel's doorbell handle. */
- VMCIHandle doorbellHandle;
-}
-#include "vmware_pack_end.h"
-VPageChannelGuestConnectMessage;
-
-typedef
-#include "vmware_pack_begin.h"
-struct VPageChannelHyperConnectMessage {
- /** \brief Hypervisor's doorbell handle. */
- VMCIHandle doorbellHandle;
-}
-#include "vmware_pack_end.h"
-VPageChannelHyperConnectMessage;
-/** \endcond PRIVATE */
-
-/** \cond PRIVATE */
-typedef enum VPageChannelState {
- VPCState_Free = 0,
- VPCState_Unconnected,
- VPCState_Connecting,
- VPCState_Connected,
- VPCState_Disconnecting,
- VPCState_Disconnected,
-} VPageChannelState;
-/** \endcond PRIVATE */
-
-/**
- * \brief Opaque page channel type.
- */
-
-struct VPageChannel;
-typedef struct VPageChannel VPageChannel;
-
-/**
- * \brief Client receive callback type.
- *
- * Type of receive callback, invoked when there are data packets in the
- * channel. The client provides a callback with this type to
- * VPageChannel_CreateInVM(). If VPAGECHANNEL_FLAGS_NOTIFY_ONLY is specified
- * in the channel creation flags, then \c packet is \c NULL; otherwise,
- * \c packet points to a channel packet.
- *
- * \see VPageChannel_CreateInVM()
- * \see VPageChannelPacket
- */
-
-typedef void (*VPageChannelRecvCB)(void *clientData,
- VPageChannelPacket *packet);
-
-
-#if !defined(VMKERNEL)
-
-/**
- * \brief Client element allocation callback type.
- *
- * Type of element allocation callback, invoked when the channel needs
- * elements. The client provides a callback of this type to
- * VPageChannel_CreateInVM().
- *
- * \see VPageChannel_CreateInVM()
- * \see VPageChannelElem
- * \see VPageChannelFreeElemFn
- */
-
-typedef int (*VPageChannelAllocElemFn)(void *clientData,
- VPageChannelElem *elems,
- int numElems);
-
-/**
- * \brief Client element release callback type.
- *
- * Type of element release callback, invoked when the channel releases
- * elements. The client provides a callback of this type to
- * VPageChannel_CreateInVM().
- *
- * \see VPageChannel_CreateInVM()
- * \see VPageChannelElem
- * \see VPageChannelAllocElemFn
- */
-
-typedef void (*VPageChannelFreeElemFn)(void *clientData,
- VPageChannelElem *elems,
- int numElems);
-
-/*
- ************************************************************************
- * VPageChannel_CreateInVM */ /**
- *
- * \brief Create guest page channel.
- *
- * Creates a page channel in the guest. The channel should be released
- * with VPageChannel_Destroy().
- *
- * \note Only applicable in the guest.
- *
- * \see VPageChannel_CreateInVMK()
- * \see VPageChannel_Destroy()
- *
- * \param[out] channel Pointer to a newly constructed page
- * channel if successful.
- * \param[in] resourceId Resource ID on which the channel should
- * register its control channel.
- * \param[in] peerResourceId Resource ID of peer's control channel.
- * \param[in] produceQSize Size of producer queue in queuepair in
- * bytes.
- * \param[in] consumeQSize Size of consumer queue in queuepair in
- * bytes.
- * \param[in] flags Channel flags.
- * \param[in] recvCB Client's receive callback.
- * \param[in] clientRecvData Client data for client's receive
- * callback.
- * \param[in] elemAlloc Element allocation callback for
- * allocating page ranges (scatter-gather
- * elements).
- * \param[in] allocClientData Client data for element allocation
- * callback.
- * \param[in] elemFree Element release callback for elements.
- * \param[in] freeClientData Client data for element release
- * callback.
- * \param[in] defRecvBufs Default number of elements sent to
- * hypervisor channel.
- * \param[in] maxRecvBufs Maximum number of elements that can be
- * sent to the hypervisor channel.
- *
- * \retval VMCI_SUCCESS Creation succeeded, \c *channel contains
- * a pointer to a valid channel.
- * \retval other Failure.
- *
- ************************************************************************
- */
-
-int VPageChannel_CreateInVM(VPageChannel **channel,
- VMCIId resourceId,
- VMCIId peerResourceId,
- uint64 produceQSize,
- uint64 consumeQSize,
- uint32 flags,
- VPageChannelRecvCB recvCB,
- void *clientRecvData,
- VPageChannelAllocElemFn elemAlloc,
- void *allocClientData,
- VPageChannelFreeElemFn elemFree,
- void *freeClientData,
- int defRecvBufs,
- int maxRecvBufs);
-
-#else // VMKERNEL
-
-/**
- * \brief Type of VM memory access off callback.
- *
- * This callback is invoked when the memory of the VM containing the peer
- * endpoint becomes inaccessible, for example due to a crash. When this
- * occurs, the client should unmap any guest pages and cleanup any state.
- * This callback runs in a blockable context. The client is not allowed to
- * call VPageChannel_Destroy() from inside the callback, or it will deadlock,
- * since that function will wait for the callback to complete.
- *
- * \note Only applicable on VMKernel.
- *
- * \see VPageChannel_CreateInVMK()
- */
-
-typedef void (*VPageChannelMemAccessOffCB)(void *clientData);
-
-/*
- ************************************************************************
- * VPageChannel_CreateInVMK */ /**
- *
- * \brief Create a page channel in VMKernel.
- *
- * Creates a page channel. The channel should be released with
- * VPageChannel_Destroy().
- *
- * \note Only applicable on VMKernel.
- *
- * \see VPageChannel_CreateInVM()
- * \see VPageChannel_Destroy()
- *
- * \param[out] channel Pointer to a newly constructed page
- * channel if successful.
- * \param[in] resourceId Resource ID on which to register
- * control channel.
- * \param[in] recvCB Client's receive callback.
- * \param[in] clientRecvData Client data for receive callback.
- * \param[in] memAccessOffCB Client's mem access off callback.
- * \param[in] memAccessOffData Client data for mem access off.
- *
- * \retval VMCI_SUCCESS Creation succeeded, \c *channel
- * contains a pointer to a valid channel.
- * \retval other Failure.
- *
- ***********************************************************************
- */
-
-int VPageChannel_CreateInVMK(VPageChannel **channel,
- VMCIId resourceId,
- VPageChannelRecvCB recvCB,
- void *clientRecvData,
- VPageChannelMemAccessOffCB memAccessOffCB,
- void *memAccessOffData);
-
-/*
- ************************************************************************
- * VPageChannel_ReserveBuffers */ /**
- *
- * \brief Reserve guest elements.
- *
- * Reserve sufficient guest elements to cover the given length. The
- * buffers can then be posted to the guest. This allocates both the
- * buffer and the elements within the buffer.
- *
- * \note Only applicable on VMKernel.
- *
- * \see VPageChannel_ReleaseBuffers()
- *
- * \param[in] channel Page channel.
- * \param[in] dataLen Length to reserve in bytes.
- * \param[out] buffer Pointer to a buffer containing elements to cover
- * the given length if successful.
- *
- * \retval VMCI_SUCCESS Reservation succeeded, \c *buffer contains
- * a pointer to a valid buffer.
- * \retval other Failure.
- *
- ************************************************************************
- */
-
-int VPageChannel_ReserveBuffers(VPageChannel *channel,
- size_t dataLen,
- VPageChannelBuffer **buffer);
-
-/*
- ************************************************************************
- * VPageChannel_ReleaseBuffers */ /**
- *
- * \brief Release guest elements.
- *
- * \note Only applicable on VMKernel.
- *
- * \see VPageChannel_ReserveBuffers()
- *
- * Release guest elements previous reserved with
- * VPageChannel_ReserveBuffers(). If the buffers were sent to the guest,
- * then only the buffer itself should be released, i.e.,
- * \c returnToFreePool should be \c FALSE; the guest will release the
- * buffers on completion. Otherwise, if for some reason they are not
- * sent after reserving them, then \c returnToFreePool should be set to
- * \c TRUE.
- *
- * \param[in] channel Page channel.
- * \param[in] buffer Buffer to be released.
- * \param[in] returnToFreePool If \c TRUE, then release the elements
- * of the buffer along with the buffer
- * itself. If \c FALSE, then release only
- * the buffer pointer itself.
- *
- ************************************************************************
- */
-
-void VPageChannel_ReleaseBuffers(VPageChannel *channel,
- VPageChannelBuffer *buffer,
- Bool returnToFreePool);
-
-/*
- ************************************************************************
- * VPageChannel_CompletionNotify */ /**
- *
- * \brief Notify channel of completion.
- *
- * This function is called when the client is finished using the elements
- * (scatter-gather list) of a packet. This will generated a notification
- * to the guest to pass ownership of the buffers back to the guest. This
- * can also be used to read back the data from the hypervisor and send
- * it to the guest.
- *
- * \note Only applicable on VMKernel.
- *
- * \see VPageChannel_ReserveBuffers
- *
- * \param[in] channel Channel on which I/O is complete.
- * \param[in] message Optional message to send to guest.
- * \param[in] len Length of optional message.
- * \param[in] buffer Buffer used for I/O.
- *
- ************************************************************************
- */
-
-int VPageChannel_CompletionNotify(VPageChannel *channel,
- char *message,
- int len,
- VPageChannelBuffer *buffer);
-
-/*
- ************************************************************************
- * VPageChannel_MapToMa */ /**
- *
- * \brief Map guest PA in an element to a list of MAs.
- *
- * Map a guest physical address to a list of hypervisor machine
- * addresses.
- *
- * \note Only applicable on VMKernel.
- *
- * \param[in] channel Channel on which to map.
- * \param[in] paElem Guest's physical address.
- * \param[out] maElems Hypervisor machine addresses.
- * \param[in] numElems Max number of hypervisor elements.
- *
- * \retval elems Number of mapped elements.
- *
- ************************************************************************
- */
-
-int VPageChannel_MapToMa(VPageChannel *channel,
- VPageChannelElem paElem,
- VPageChannelElem *maElems,
- uint32 numElems);
-
-/*
- ************************************************************************
- * VPageChannel_UnmapMa */ /**
- *
- * \brief Unmap MA for a buffer.
- *
- * Unmap hypervisor machine addresses referring to a guest physical
- * addresses.
- *
- * \note Only applicable on VMKernel.
- *
- * \see VPageChannel_MapToMa
- *
- * \param[in] channel Channel for which to unmap.
- * \param[in] buffer Buffer containing elements to unmap.
- * \param[in] numElems Number of elements to unmap.
- *
- * \retval 0 Unmap successful.
- * \retval -1 World not found for channel.
- *
- ************************************************************************
- */
-
-int VPageChannel_UnmapMa(VPageChannel *channel,
- VPageChannelBuffer *buffer,
- int numElems);
-
-#endif // VMKERNEL
-
-/*
- ************************************************************************
- * VPageChannel_Destroy */ /**
- *
- * \brief Destroy the given channel.
- *
- * Destroy the given channel. This will disconnect from the peer
- * channel (if connected) and release all resources.
- *
- * \see VPageChannel_CreateInVMK
- * \see VPageChannel_CreateInVM
- *
- * \param[in] channel The channel to be destroyed.
- *
- ************************************************************************
- */
-
-void VPageChannel_Destroy(VPageChannel *channel);
-
-/*
- ************************************************************************
- * VPageChannel_Send */ /**
- *
- * \brief Send a packet to the channel's peer.
- *
- * Send a packet to the channel's peer. A message and a number of
- * elements may optionally be sent. If the send is successful, the
- * elements are owned by the peer and only the buffer itself should
- * be released, but not the elements within. If the send fails, the
- * client should release the buffer and the elements.
- *
- * \see VPageChannel_SendPacket
- *
- * \param[in] channel Channel on which to send.
- * \param[in] type Type of packet to send.
- * \param[in] message Optional message to send.
- * \param[in] len Length of optional message.
- * \param[in] buffer Buffer (of elements) to send.
- *
- * \retval VMCI_SUCCESS Packet successfully sent, buffer elements
- * owned by peer.
- * \retval other Failure to send, client should release
- * elements.
- *
- ************************************************************************
- */
-
-int VPageChannel_Send(VPageChannel *channel,
- VPageChannelPacketType type,
- char *message,
- int len,
- VPageChannelBuffer *buffer);
-
-/*
- ************************************************************************
- * VPageChannel_SendPacket */ /**
- *
- * \brief Send the given packet to the channel's peer.
- *
- * Send a client-constructed packet to the channel's peer. If the
- * send is successful, any elements in the packet are owned by the
- * peer. Otherwise, the client retains ownership.
- *
- * \see VPageChannel_Send
- *
- * \param[in] channel Channel on which to send.
- * \param[in] packet Packet to be sent.
- *
- * \retval VMCI_SUCCESS Packet successfully sent, buffer elements
- * owned by peer.
- * \retval other Failure to send, client should release
- * elements.
- *
- ************************************************************************
- */
-
-int VPageChannel_SendPacket(VPageChannel *channel,
- VPageChannelPacket *packet);
-
-/*
- ************************************************************************
- * VPageChannel_PollRecvQ */ /**
- *
- * \brief Poll the channel's receive queue for packets.
- *
- * Poll the channel's receive queue for packets from the peer. If any
- * packets are available, the channel's receive callback will be invoked.
- *
- * \param[in] channel Channel to poll.
- *
- ************************************************************************
- */
-
-void VPageChannel_PollRecvQ(VPageChannel *channel);
-
-/*
- ************************************************************************
- * VPageChannel_BufferLen */ /**
- *
- * \brief Determine the length of a packet.
- *
- * Determine the length of the given packet in bytes.
- *
- * \param[in] packet Packet for which length is to be determined.
- *
- * \retval bytes Size of the packet in bytes.
- *
- ************************************************************************
- */
-
-static INLINE size_t
-VPageChannelPacket_BufferLen(VPageChannelPacket *packet) // IN
-{
- size_t len, i;
- VPageChannelElem *elems;
-
- ASSERT(packet);
-
- len = 0;
- elems = VPAGECHANNEL_PACKET_ELEMS(packet);
- for (i = 0; i < packet->numElems; i++) {
- len += elems[i].le;
- }
-
- return len;
-}
-
-/** \cond PRIVATE */
-#if defined(linux) && !defined(VMKERNEL)
-#include "compat_pci.h"
-#define vmci_pci_map_page(_pg, _off, _sz, _dir) \
- pci_map_page(NULL, (_pg), (_off), (_sz), (_dir))
-#define vmci_pci_unmap_page(_dma, _sz, _dir) \
- pci_unmap_page(NULL, (_dma), (_sz), (_dir))
-#endif // linux && !VMKERNEL
-/** \endcond PRIVATE */
-
-#endif // _VMCI_PACKET_H_
diff --git a/open-vm-tools/modules/linux/vmhgfs/Makefile b/open-vm-tools/modules/linux/vmhgfs/Makefile
index e7e3eaf4..648dab58 100644
--- a/open-vm-tools/modules/linux/vmhgfs/Makefile
+++ b/open-vm-tools/modules/linux/vmhgfs/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/Makefile.kernel b/open-vm-tools/modules/linux/vmhgfs/Makefile.kernel
index a8a2caab..c68a8087 100644
--- a/open-vm-tools/modules/linux/vmhgfs/Makefile.kernel
+++ b/open-vm-tools/modules/linux/vmhgfs/Makefile.kernel
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -28,11 +28,13 @@ EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector.c, -DVMW_KMEMCR_CTOR_HAS_3_ARGS, )
EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/cachector1.c, -DVMW_KMEMCR_CTOR_HAS_2_ARGS, )
EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/file_operations_fsync.c, -DVMW_FSYNC_31, )
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/file_operations_flush.c, -DVMW_FLUSH_HAS_1_ARG, )
# Note: These tests are inverted
EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/getsb1.c,, -DVMW_GETSB_2618)
EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/statfs1.c,, -DVMW_STATFS_2618)
EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/inode1.c,, -DVMW_INODE_2618)
+EXTRA_CFLAGS += $(call vm_check_build, $(AUTOCONF_DIR)/dcount.c,, -DVMW_DCOUNT_311)
MODPOST_VMCI_SYMVERS := $(wildcard $(MODULEBUILDDIR)/VMwareVMCIModule.symvers)
diff --git a/open-vm-tools/modules/linux/vmhgfs/bdhandler.c b/open-vm-tools/modules/linux/vmhgfs/bdhandler.c
index 5bcac3f5..b891019e 100644
--- a/open-vm-tools/modules/linux/vmhgfs/bdhandler.c
+++ b/open-vm-tools/modules/linux/vmhgfs/bdhandler.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/dentry.c b/open-vm-tools/modules/linux/vmhgfs/dentry.c
index 873ef103..2da16dcc 100644
--- a/open-vm-tools/modules/linux/vmhgfs/dentry.c
+++ b/open-vm-tools/modules/linux/vmhgfs/dentry.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/dir.c b/open-vm-tools/modules/linux/vmhgfs/dir.c
index e4e82b48..809611a1 100644
--- a/open-vm-tools/modules/linux/vmhgfs/dir.c
+++ b/open-vm-tools/modules/linux/vmhgfs/dir.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -1157,7 +1157,8 @@ HgfsDoReaddir(struct file *file, // IN:
Bool dotAndDotDotIgnore, // IN: ignore "." and ".."
filldir_t filldirCb, // IN: system filler callback
void *filldirCtx, // IN/OUT: system filler context
- loff_t *entryPos) // IN/OUT: entry position
+ loff_t *fillPos, // IN/OUT: fill entry position
+ loff_t *currentPos) // IN/OUT: current position
{
char *entryName = NULL; // buf for escaped version of name
size_t entryNameBufLen = NAME_MAX + 1;
@@ -1179,7 +1180,7 @@ HgfsDoReaddir(struct file *file, // IN:
__func__,
file->f_dentry->d_name.name,
file->f_dentry->d_inode->i_ino,
- *entryPos));
+ *currentPos));
/*
* Refresh entries if required. See rm -rf 6.10+ breaking issue.
@@ -1189,7 +1190,6 @@ HgfsDoReaddir(struct file *file, // IN:
return result;
}
-
/*
* Some day when we're out of things to do we can move this to a slab
* allocator.
@@ -1207,7 +1207,7 @@ HgfsDoReaddir(struct file *file, // IN:
uint32 entryType = DT_UNKNOWN;
result = HgfsReaddirNextEntry(file,
- *entryPos,
+ *currentPos,
dotAndDotDotIgnore,
entryNameBufLen,
entryName,
@@ -1228,20 +1228,20 @@ HgfsDoReaddir(struct file *file, // IN:
}
if (entryIgnore) {
- *entryPos += 1;
+ *currentPos += 1;
continue;
}
/*
* Call the HGFS wrapper to the system fill function to set this dentry.
*/
- LOG(6, (KERN_DEBUG "VMware hgfs: %s: dir_emit(%s, %u, %Lu)\n",
- __func__, entryName, entryNameLength, *entryPos));
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: dir_emit(%s, %u, @ (fill %Lu HGFS %Lu)\n",
+ __func__, entryName, entryNameLength, *fillPos, *currentPos));
if (!HgfsReaddirFillEntry(filldirCb, /* filldir callback function */
filldirCtx, /* filldir callback struct */
entryName, /* name of dirent */
entryNameLength, /* length of name */
- *entryPos, /* entry position */
+ *fillPos, /* fill entry position */
entryIno, /* inode number (0 makes it not show) */
entryType)) { /* type of dirent */
/*
@@ -1254,7 +1254,8 @@ HgfsDoReaddir(struct file *file, // IN:
result = 0;
break;
}
- *entryPos += 1;
+ *currentPos += 1;
+ *fillPos += 1;
}
LOG(6, (KERN_DEBUG "VMware hgfs: %s: return\n",__func__));
@@ -1284,6 +1285,12 @@ static int
HgfsReaddir(struct file *file, // IN:
struct dir_context *ctx) // IN:
{
+ HgfsFileInfo *fInfo = FILE_GET_FI_P(file);
+
+ if (0 == ctx->pos) {
+ fInfo->direntPos = 0;
+ }
+
/* If either dot and dotdot are filled in for us we can exit. */
if (!dir_emit_dots(file, ctx)) {
LOG(6, (KERN_DEBUG "VMware hgfs: %s: dir_emit_dots(%s, @ %Lu)\n",
@@ -1292,7 +1299,7 @@ HgfsReaddir(struct file *file, // IN:
}
/* It is sufficient to pass the context as it contains the filler function. */
- return HgfsDoReaddir(file, TRUE, NULL, ctx, &ctx->pos);
+ return HgfsDoReaddir(file, TRUE, NULL, ctx, &ctx->pos, &fInfo->direntPos);
}
@@ -1367,7 +1374,13 @@ HgfsReaddir(struct file *file, // IN: Directory to read from
void *dirent, // OUT: Buffer to copy dentries into
filldir_t filldir) // IN: Filler function
{
- return HgfsDoReaddir(file, FALSE, filldir, dirent, &file->f_pos);
+ HgfsFileInfo *fInfo = FILE_GET_FI_P(file);
+
+ if (0 == file->f_pos) {
+ fInfo->direntPos = 0;
+ }
+
+ return HgfsDoReaddir(file, FALSE, filldir, dirent, &file->f_pos, &fInfo->direntPos);
}
diff --git a/open-vm-tools/modules/linux/vmhgfs/file.c b/open-vm-tools/modules/linux/vmhgfs/file.c
index 3ddbfefd..bbde3f4b 100644
--- a/open-vm-tools/modules/linux/vmhgfs/file.c
+++ b/open-vm-tools/modules/linux/vmhgfs/file.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -47,6 +47,31 @@
#include "vm_assert.h"
#include "vm_basic_types.h"
+/*
+ * Before Linux 2.6.33 only O_DSYNC semantics were implemented, but using
+ * the O_SYNC flag. We continue to use the existing numerical value
+ * for O_DSYNC semantics now, but using the correct symbolic name for it.
+ * This new value is used to request true Posix O_SYNC semantics. It is
+ * defined in this strange way to make sure applications compiled against
+ * new headers get at least O_DSYNC semantics on older kernels.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
+#define HGFS_FILECTL_SYNC(flags) ((flags) & O_DSYNC)
+#else
+#define HGFS_FILECTL_SYNC(flags) ((flags) & O_SYNC)
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+typedef struct iov_iter *hgfs_iov;
+#define HGFS_IOV_TO_COUNT(iov, nr_segs) (iov_iter_count(iov))
+#define HGFS_IOV_TO_SEGS(iov, nr_segs) (0)
+#define HGFS_IOCB_TO_POS(iocb, pos) (iocb->ki_pos)
+#else
+typedef const struct iovec *hgfs_iov;
+#define HGFS_IOV_TO_COUNT(iov, nr_segs) (iov_length(iov, nr_segs))
+#define HGFS_IOV_TO_SEGS(iov, nr_segs) (nr_segs)
+#define HGFS_IOCB_TO_POS(iocb, pos) (pos)
+#endif
+
/* Private functions. */
static int HgfsPackOpenRequest(struct inode *inode,
struct file *file,
@@ -61,14 +86,21 @@ static int HgfsUnpackOpenReply(HgfsReq *req,
static int HgfsOpen(struct inode *inode,
struct file *file);
#if defined VMW_USE_AIO
-static ssize_t HgfsAioRead(struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long numSegs,
- loff_t offset);
-static ssize_t HgfsAioWrite(struct kiocb *iocb,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+static ssize_t HgfsFileRead(struct kiocb *iocb,
+ struct iov_iter *to);
+static ssize_t HgfsFileWrite(struct kiocb *iocb,
+ struct iov_iter *from);
+#else // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+static ssize_t HgfsFileRead(struct kiocb *iocb,
const struct iovec *iov,
unsigned long numSegs,
loff_t offset);
+static ssize_t HgfsFileWrite(struct kiocb *iocb,
+ const struct iovec *iov,
+ unsigned long numSegs,
+ loff_t offset);
+#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
#else
static ssize_t HgfsRead(struct file *file,
char __user *buf,
@@ -83,6 +115,15 @@ static ssize_t HgfsWrite(struct file *file,
static loff_t HgfsSeek(struct file *file,
loff_t offset,
int origin);
+static int HgfsFlush(struct file *file
+#if !defined VMW_FLUSH_HAS_1_ARG
+ ,fl_owner_t id
+#endif
+ );
+
+#if !defined VMW_FSYNC_31
+static int HgfsDoFsync(struct inode *inode);
+#endif
static int HgfsFsync(struct file *file,
#if defined VMW_FSYNC_OLD
@@ -125,9 +166,19 @@ struct file_operations HgfsFileFileOperations = {
.owner = THIS_MODULE,
.open = HgfsOpen,
.llseek = HgfsSeek,
+ .flush = HgfsFlush,
#if defined VMW_USE_AIO
- .aio_read = HgfsAioRead,
- .aio_write = HgfsAioWrite,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+ .read = new_sync_read,
+ .write = new_sync_write,
+ .read_iter = HgfsFileRead,
+ .write_iter = HgfsFileWrite,
+#else // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+ .read = do_sync_read,
+ .write = do_sync_write,
+ .aio_read = HgfsFileRead,
+ .aio_write = HgfsFileWrite,
+#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
#else
.read = HgfsRead,
.write = HgfsWrite,
@@ -642,7 +693,51 @@ out:
/*
*----------------------------------------------------------------------
*
- * HgfsAioRead --
+ * HgfsGenericFileRead --
+ *
+ * Called when the kernel initiates an asynchronous read from a file in
+ * our filesystem. Our function is just a thin wrapper around
+ * system generic read function.
+ *
+ *
+ * Results:
+ * Returns the number of bytes read on success, or an error on
+ * failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ssize_t
+HgfsGenericFileRead(struct kiocb *iocb, // IN: I/O control block
+ hgfs_iov iov, // IN: Array of I/O vectors
+ unsigned long iovSegs, // IN: Count of I/O vectors
+ loff_t pos) // IN: Position at which to read
+{
+ ssize_t result;
+
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s(%lu@%Ld)\n",
+ __func__, (unsigned long)HGFS_IOV_TO_COUNT(iov, iovSegs),
+ (long long) pos));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+ result = generic_file_read_iter(iocb, iov);
+#else
+ result = generic_file_aio_read(iocb, iov, iovSegs, pos);
+#endif
+
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s return %"FMTSZ"d\n",
+ __func__, result));
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsFileRead --
*
* Called when the kernel initiates an asynchronous read to a file in
* our filesystem. Our function is just a thin wrapper around
@@ -658,35 +753,90 @@ out:
*----------------------------------------------------------------------
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
static ssize_t
-HgfsAioRead(struct kiocb *iocb, // IN: I/O control block
- const struct iovec *iov, // OUT: Array of I/O buffers
- unsigned long numSegs, // IN: Number of buffers
- loff_t offset) // IN: Offset at which to read
+HgfsFileRead(struct kiocb *iocb, // IN: I/O control block
+ struct iov_iter *iov) // OUT: Array of I/O buffers
+#else // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+static ssize_t
+HgfsFileRead(struct kiocb *iocb, // IN: I/O control block
+ const struct iovec *iov, // OUT: Array of I/O buffers
+ unsigned long numSegs, // IN: Number of buffers
+ loff_t offset) // IN: Offset at which to read
+#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
{
- int result;
+ ssize_t result;
struct dentry *readDentry;
+ loff_t pos;
+ unsigned long iovSegs;
ASSERT(iocb);
ASSERT(iocb->ki_filp);
ASSERT(iocb->ki_filp->f_dentry);
ASSERT(iov);
+ pos = HGFS_IOCB_TO_POS(iocb, offset);
+ iovSegs = HGFS_IOV_TO_SEGS(iov, numSegs);
+
readDentry = iocb->ki_filp->f_dentry;
- LOG(4, (KERN_DEBUG "VMware hgfs: %s(%s/%s, %lu@%lu)\n",
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s(%s/%s)\n",
__func__, readDentry->d_parent->d_name.name,
- readDentry->d_name.name,
- (unsigned long) iov_length(iov, numSegs), (unsigned long) offset));
+ readDentry->d_name.name));
result = HgfsRevalidate(readDentry);
if (result) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsAioRead: invalid dentry\n"));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: invalid dentry\n", __func__));
goto out;
}
- result = generic_file_aio_read(iocb, iov, numSegs, offset);
- out:
+ result = HgfsGenericFileRead(iocb, iov, iovSegs, pos);
+
+out:
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsGenericFileWrite --
+ *
+ * Called when the kernel initiates an asynchronous write to a file in
+ * our filesystem. Our function is just a thin wrapper around
+ * system generic write function.
+ *
+ *
+ * Results:
+ * Returns the number of bytes written on success, or an error on
+ * failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ssize_t
+HgfsGenericFileWrite(struct kiocb *iocb, // IN: I/O control block
+ hgfs_iov iov, // IN: Array of I/O vectors
+ unsigned long iovSegs, // IN: Count of I/O vectors
+ loff_t pos) // IN: Position at which to write
+{
+ ssize_t result;
+
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s(%lu@%Ld)\n",
+ __func__, (unsigned long)HGFS_IOV_TO_COUNT(iov, iovSegs),
+ (long long) pos));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+ result = generic_file_write_iter(iocb, iov);
+#else
+ result = generic_file_aio_write(iocb, iov, iovSegs, pos);
+#endif
+
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s return %"FMTSZ"d\n",
+ __func__, result));
return result;
}
@@ -694,7 +844,7 @@ HgfsAioRead(struct kiocb *iocb, // IN: I/O control block
/*
*----------------------------------------------------------------------
*
- * HgfsAioWrite --
+ * HgfsFileWrite --
*
* Called when the kernel initiates an asynchronous write to a file in
* our filesystem. Our function is just a thin wrapper around
@@ -713,34 +863,60 @@ HgfsAioRead(struct kiocb *iocb, // IN: I/O control block
*----------------------------------------------------------------------
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+ssize_t
+HgfsFileWrite(struct kiocb *iocb, // IN: I/O control block
+ struct iov_iter *iov) // IN: Array of I/O buffers
+#else // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
static ssize_t
-HgfsAioWrite(struct kiocb *iocb, // IN: I/O control block
- const struct iovec *iov, // IN: Array of I/O buffers
- unsigned long numSegs, // IN: Number of buffers
- loff_t offset) // IN: Offset at which to read
+HgfsFileWrite(struct kiocb *iocb, // IN: I/O control block
+ const struct iovec *iov, // IN: Array of I/O buffers
+ unsigned long numSegs, // IN: Number of buffers
+ loff_t offset) // IN: Offset at which to write
+#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
{
- int result;
+ ssize_t result;
struct dentry *writeDentry;
+ loff_t pos;
+ unsigned long iovSegs;
ASSERT(iocb);
ASSERT(iocb->ki_filp);
ASSERT(iocb->ki_filp->f_dentry);
ASSERT(iov);
+ pos = HGFS_IOCB_TO_POS(iocb, offset);
+ iovSegs = HGFS_IOV_TO_SEGS(iov, numSegs);
+
writeDentry = iocb->ki_filp->f_dentry;
- LOG(4, (KERN_DEBUG "VMware hgfs: %s(%s/%s, %lu@%Ld)\n",
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s(%s/%s)\n",
__func__, writeDentry->d_parent->d_name.name,
- writeDentry->d_name.name,
- (unsigned long) iov_length(iov, numSegs), (long long) offset));
+ writeDentry->d_name.name));
result = HgfsRevalidate(writeDentry);
if (result) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsAioWrite: invalid dentry\n"));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: invalid dentry\n", __func__));
goto out;
}
- result = generic_file_aio_write(iocb, iov, numSegs, offset);
+ result = HgfsGenericFileWrite(iocb, iov, iovSegs, pos);
+
+ if (result >= 0) {
+ if (IS_SYNC(writeDentry->d_inode) ||
+ HGFS_FILECTL_SYNC(iocb->ki_filp->f_flags)) {
+ int error;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+ error = vfs_fsync(iocb->ki_filp, 0);
+#else
+ error = HgfsDoFsync(writeDentry->d_inode);
+#endif
+ if (error < 0) {
+ result = error;
+ }
+ }
+ }
+
out:
return result;
}
@@ -896,6 +1072,101 @@ HgfsSeek(struct file *file, // IN: File to seek
}
+#if !defined VMW_FSYNC_31
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsDoFsync --
+ *
+ * Helper for HgfsFlush() and HgfsFsync().
+ *
+ * The hgfs protocol doesn't support fsync explicityly yet.
+ * So for now, we flush all the pages to presumably honor the
+ * intent of an app calling fsync() which is to get the
+ * data onto persistent storage. As things stand now we're at
+ * the whim of the hgfs server code running on the host to fsync or
+ * not if and when it pleases.
+ *
+ *
+ * Results:
+ * Returns zero on success. Otherwise an error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsDoFsync(struct inode *inode) // IN: File we operate on
+{
+ int ret;
+
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s(%"FMT64"u)\n",
+ __func__, INODE_GET_II_P(inode)->hostFileId));
+
+ ret = compat_filemap_write_and_wait(inode->i_mapping);
+
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: returns %d\n",
+ __func__, ret));
+
+ return ret;
+}
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsFlush --
+ *
+ * Called when user process calls fflush() on an hgfs file.
+ * Flush all dirty pages and check for write errors.
+ *
+ *
+ * Results:
+ * Returns zero on success. (Currently always succeeds).
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsFlush(struct file *file // IN: file to flush
+#if !defined VMW_FLUSH_HAS_1_ARG
+ ,fl_owner_t id // IN: id not used
+#endif
+ )
+{
+ int ret = 0;
+
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s(%s/%s)\n",
+ __func__, file->f_dentry->d_parent->d_name.name,
+ file->f_dentry->d_name.name));
+
+ if ((file->f_mode & FMODE_WRITE) == 0) {
+ goto exit;
+ }
+
+
+ /* Flush writes to the server and return any errors */
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling vfs_sync ... \n",
+ __func__));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+ ret = vfs_fsync(file, 0);
+#else
+ ret = HgfsDoFsync(file->f_dentry->d_inode);
+#endif
+
+exit:
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: returns %d\n",
+ __func__, ret));
+ return ret;
+}
+
+
/*
*----------------------------------------------------------------------
*
@@ -903,21 +1174,13 @@ HgfsSeek(struct file *file, // IN: File to seek
*
* Called when user process calls fsync() on hgfs file.
*
- * The hgfs protocol doesn't support fsync yet, so for now, we punt
- * and just return success. This is a little less sketchy than it
- * might sound, because hgfs skips the buffer cache in the guest
- * anyway (we always write to the host immediately).
- *
- * In the future we might want to try harder though, since
- * presumably the intent of an app calling fsync() is to get the
+ * The hgfs protocol doesn't support fsync explicitly yet,
+ * so for now, we flush all the pages to presumably honor the
+ * intent of an app calling fsync() which is to get the
* data onto persistent storage, and as things stand now we're at
* the whim of the hgfs server code running on the host to fsync or
* not if and when it pleases.
*
- * Note that do_fsync will call filemap_fdatawrite() before us and
- * filemap_fdatawait() after us, so there's no need to do anything
- * here w.r.t. writing out dirty pages.
- *
* Results:
* Returns zero on success. (Currently always succeeds).
*
@@ -937,18 +1200,37 @@ HgfsFsync(struct file *file, // IN: File we operate on
#endif
int datasync) // IN: fdatasync or fsync
{
- LOG(6, (KERN_DEBUG "VMware hgfs: %s(%s/%s, %lld, %lld, %d)\n",
+ int ret = 0;
+ loff_t startRange;
+ loff_t endRange;
+ struct inode *inode;
+
+#if defined VMW_FSYNC_31
+ startRange = start;
+ endRange = end;
+#else
+ startRange = 0;
+ endRange = MAX_INT64;
+#endif
+
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s(%s/%s, %lld, %lld, %d)\n",
__func__,
file->f_dentry->d_parent->d_name.name,
file->f_dentry->d_name.name,
+ startRange, endRange,
+ datasync));
+
+ /* Flush writes to the server and return any errors */
+ inode = file->f_dentry->d_inode;
#if defined VMW_FSYNC_31
- start, end,
+ ret = filemap_write_and_wait_range(inode->i_mapping, startRange, endRange);
#else
- (loff_t)0, (loff_t)0,
+ ret = HgfsDoFsync(inode);
#endif
- datasync));
- return 0;
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: written pages %lld, %lld returns %d)\n",
+ __func__, startRange, endRange, ret));
+ return ret;
}
diff --git a/open-vm-tools/modules/linux/vmhgfs/filesystem.c b/open-vm-tools/modules/linux/vmhgfs/filesystem.c
index f101ca7a..33c4c56f 100644
--- a/open-vm-tools/modules/linux/vmhgfs/filesystem.c
+++ b/open-vm-tools/modules/linux/vmhgfs/filesystem.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -83,7 +83,6 @@ HgfsOp hgfsVersionCreateSymlink;
static inline unsigned long HgfsComputeBlockBits(unsigned long blockSize);
static compat_kmem_cache_ctor HgfsInodeCacheCtor;
static HgfsSuperInfo *HgfsInitSuperInfo(HgfsMountInfo *mountInfo);
-static int HgfsGetRootDentry(struct super_block *sb, struct dentry **rootDentry);
static int HgfsReadSuper(struct super_block *sb,
void *rawData,
int flags);
@@ -123,8 +122,6 @@ static struct file_system_type hgfsType = {
.kill_sb = kill_anon_super,
};
-extern int USE_VMCI;
-
/*
* Private functions implementations.
*/
@@ -228,16 +225,23 @@ HgfsInitSuperInfo(HgfsMountInfo *mountInfo) // IN: Passed down from the user
* or gid given to us by the server.
*/
si->uidSet = mountInfo->uidSet;
+ si->uid = current_uid();
if (si->uidSet) {
- si->uid = mountInfo->uid;
- } else {
- si->uid = current_uid();
+ kuid_t mntUid = make_kuid(current_user_ns(), mountInfo->uid);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (uid_valid(mntUid))
+#endif
+ si->uid = mntUid;
}
+
si->gidSet = mountInfo->gidSet;
+ si->gid = current_gid();
if (si->gidSet) {
- si->gid = mountInfo->gid;
- } else {
- si->gid = current_gid();
+ kgid_t mntGid = make_kgid(current_user_ns(), mountInfo->gid);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (gid_valid(mntGid))
+#endif
+ si->gid = mntGid;
}
si->fmask = mountInfo->fmask;
si->dmask = mountInfo->dmask;
@@ -327,103 +331,6 @@ HgfsInitSuperInfo(HgfsMountInfo *mountInfo) // IN: Passed down from the user
/*
- *----------------------------------------------------------------------------
- *
- * HgfsGetRootDentry --
- *
- * Gets the root dentry for a given super block.
- *
- * Results:
- * zero and a valid root dentry on success
- * negative value on failure
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsGetRootDentry(struct super_block *sb, // IN: Super block object
- struct dentry **rootDentry) // OUT: Root dentry
-{
- int result = -ENOMEM;
- struct inode *rootInode;
- struct dentry *tempRootDentry = NULL;
- struct HgfsAttrInfo rootDentryAttr;
- HgfsInodeInfo *iinfo;
-
- ASSERT(sb);
- ASSERT(rootDentry);
-
- LOG(6, (KERN_DEBUG "VMware hgfs: %s: entered\n", __func__));
-
- rootInode = HgfsGetInode(sb, HGFS_ROOT_INO);
- if (rootInode == NULL) {
- LOG(6, (KERN_DEBUG "VMware hgfs: %s: Could not get the root inode\n",
- __func__));
- goto exit;
- }
-
- /*
- * On an allocation failure in read_super, the inode will have been
- * marked "bad". If it was, we certainly don't want to start playing with
- * the HgfsInodeInfo. So quietly put the inode back and fail.
- */
- if (is_bad_inode(rootInode)) {
- LOG(6, (KERN_DEBUG "VMware hgfs: %s: encountered bad inode\n",
- __func__));
- goto exit;
- }
-
- tempRootDentry = d_make_root(rootInode);
- /*
- * d_make_root() does iput() on failure; if d_make_root() completes
- * successfully then subsequent dput() will do iput() for us, so we
- * should just ignore root inode from now on.
- */
- rootInode = NULL;
-
- if (tempRootDentry == NULL) {
- LOG(4, (KERN_WARNING "VMware hgfs: %s: Could not get "
- "root dentry\n", __func__));
- goto exit;
- }
-
- result = HgfsPrivateGetattr(tempRootDentry, &rootDentryAttr, NULL);
- if (result) {
- LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not"
- "instantiate the root dentry\n"));
- goto exit;
- }
-
- iinfo = INODE_GET_II_P(tempRootDentry->d_inode);
- iinfo->isFakeInodeNumber = FALSE;
- iinfo->isReferencedInode = TRUE;
-
- if (rootDentryAttr.mask & HGFS_ATTR_VALID_FILEID) {
- iinfo->hostFileId = rootDentryAttr.hostFileId;
- }
-
- HgfsChangeFileAttributes(tempRootDentry->d_inode, &rootDentryAttr);
- HgfsDentryAgeReset(tempRootDentry);
- tempRootDentry->d_op = &HgfsDentryOperations;
-
- *rootDentry = tempRootDentry;
- result = 0;
-
- LOG(6, (KERN_DEBUG "VMware hgfs: %s: finished\n", __func__));
-exit:
- if (result) {
- iput(rootInode);
- dput(tempRootDentry);
- *rootDentry = NULL;
- }
- return result;
-}
-
-
-/*
*-----------------------------------------------------------------------------
*
* HgfsReadSuper --
@@ -503,7 +410,10 @@ HgfsReadSuper(struct super_block *sb, // OUT: Superblock object
sb->s_blocksize_bits = HgfsComputeBlockBits(HGFS_BLOCKSIZE);
sb->s_blocksize = 1 << sb->s_blocksize_bits;
- result = HgfsGetRootDentry(sb, &rootDentry);
+ /*
+ * Create the root dentry and its corresponding inode.
+ */
+ result = HgfsInstantiateRoot(sb, &rootDentry);
if (result) {
LOG(4, (KERN_WARNING "VMware hgfs: HgfsReadSuper: Could not instantiate "
"root dentry\n"));
@@ -646,12 +556,6 @@ HgfsResetOps(void)
hgfsVersionRename = HGFS_OP_RENAME_V3;
hgfsVersionQueryVolumeInfo = HGFS_OP_QUERY_VOLUME_INFO_V3;
hgfsVersionCreateSymlink = HGFS_OP_CREATE_SYMLINK_V3;
-
- if (USE_VMCI) {
- hgfsVersionRead = HGFS_OP_READ_FAST_V4;
- hgfsVersionWrite = HGFS_OP_WRITE_FAST_V4;
- }
-
}
diff --git a/open-vm-tools/modules/linux/vmhgfs/filesystem.h b/open-vm-tools/modules/linux/vmhgfs/filesystem.h
index b04c415b..b0bcb5b4 100644
--- a/open-vm-tools/modules/linux/vmhgfs/filesystem.h
+++ b/open-vm-tools/modules/linux/vmhgfs/filesystem.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/fsutil.c b/open-vm-tools/modules/linux/vmhgfs/fsutil.c
index 2b1bcff5..50233242 100644
--- a/open-vm-tools/modules/linux/vmhgfs/fsutil.c
+++ b/open-vm-tools/modules/linux/vmhgfs/fsutil.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -53,10 +53,13 @@ static int HgfsUnpackGetattrReply(HgfsReq *req,
HgfsAttrInfo *attr,
char **fileName);
static int HgfsPackGetattrRequest(HgfsReq *req,
- struct dentry *dentry,
+ HgfsOp opUsed,
Bool allowHandleReuse,
- HgfsOp opUsed,
+ struct dentry *dentry,
HgfsAttrInfo *attr);
+static int HgfsBuildRootPath(char *buffer,
+ size_t bufferLen,
+ HgfsSuperInfo *si);
/*
* Private function implementations.
@@ -236,13 +239,17 @@ HgfsUnpackGetattrReply(HgfsReq *req, // IN: Reply packet
/*
*----------------------------------------------------------------------
*
- * HgfsPackGetattrRequest --
+ * HgfsPackCommonattr --
*
- * Setup the getattr request, depending on the op version. When possible,
- * we will issue the getattr using an existing open HGFS handle.
+ * This function abstracts the HgfsAttr struct behind HgfsAttrInfo.
+ * Callers can pass one of four replies into it and receive back the
+ * attributes for those replies.
+ *
+ * Callers must populate attr->requestType so that we know whether to
+ * expect a V1 or V2 Attr struct.
*
* Results:
- * Returns zero on success, or negative error on failure.
+ * Zero on success, non-zero otherwise.
*
* Side effects:
* None
@@ -251,22 +258,18 @@ HgfsUnpackGetattrReply(HgfsReq *req, // IN: Reply packet
*/
static int
-HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer
- struct dentry *dentry, // IN: Dentry containing name
- Bool allowHandleReuse, // IN: Can we use a handle?
- HgfsOp opUsed, // IN: Op to be used
- HgfsAttrInfo *attr) // OUT: Attrs to update
+HgfsPackCommonattr(HgfsReq *req, // IN/OUT: request buffer
+ HgfsOp opUsed, // IN: Op to be used
+ Bool allowHandleReuse, // IN: Can we use a handle?
+ struct inode *fileInode, // IN: file inode
+ size_t *reqSize, // OUT: request size
+ size_t *reqBufferSize, // OUT: request buffer size
+ char **fileName, // OUT: pointer to request file name
+ uint32 **fileNameLength, // OUT: pointer to request file name length
+ HgfsAttrInfo *attr) // OUT: Attrs to update
{
- size_t reqBufferSize;
- size_t reqSize;
- int result = 0;
HgfsHandle handle;
- char *fileName = NULL;
- uint32 *fileNameLength = NULL;
-
- ASSERT(attr);
- ASSERT(dentry);
- ASSERT(req);
+ int result = 0;
attr->requestType = opUsed;
@@ -289,24 +292,25 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer
* by name.
*/
requestV3->hints = 0;
- if (allowHandleReuse && HgfsGetHandle(dentry->d_inode,
+ if (allowHandleReuse && HgfsGetHandle(fileInode,
0,
&handle) == 0) {
requestV3->fileName.flags = HGFS_FILE_NAME_USE_FILE_DESC;
requestV3->fileName.fid = handle;
requestV3->fileName.length = 0;
requestV3->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE;
- fileName = NULL;
+ *fileName = NULL;
+ *fileNameLength = NULL;
} else {
- fileName = requestV3->fileName.name;
- fileNameLength = &requestV3->fileName.length;
+ *fileName = requestV3->fileName.name;
+ *fileNameLength = &requestV3->fileName.length;
requestV3->fileName.flags = 0;
requestV3->fileName.fid = HGFS_INVALID_HANDLE;
requestV3->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
}
requestV3->reserved = 0;
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(req->bufferSize, reqSize);
+ *reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(requestV3);
+ *reqBufferSize = HGFS_NAME_BUFFER_SIZET(req->bufferSize, *reqSize);
break;
}
@@ -323,19 +327,20 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer
* correct regardless. If we don't find a handle, fall back on getattr
* by name.
*/
- if (allowHandleReuse && HgfsGetHandle(dentry->d_inode,
+ if (allowHandleReuse && HgfsGetHandle(fileInode,
0,
&handle) == 0) {
requestV2->hints = HGFS_ATTR_HINT_USE_FILE_DESC;
requestV2->file = handle;
- fileName = NULL;
+ *fileName = NULL;
+ *fileNameLength = NULL;
} else {
requestV2->hints = 0;
- fileName = requestV2->fileName.name;
- fileNameLength = &requestV2->fileName.length;
+ *fileName = requestV2->fileName.name;
+ *fileNameLength = &requestV2->fileName.length;
}
- reqSize = sizeof *requestV2;
- reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV2);
+ *reqSize = sizeof *requestV2;
+ *reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV2);
break;
}
@@ -346,17 +351,67 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer
requestV1->header.op = opUsed;
requestV1->header.id = req->id;
- fileName = requestV1->fileName.name;
- fileNameLength = &requestV1->fileName.length;
- reqSize = sizeof *requestV1;
- reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV1);
+ *fileName = requestV1->fileName.name;
+ *fileNameLength = &requestV1->fileName.length;
+ *reqSize = sizeof *requestV1;
+ *reqBufferSize = HGFS_NAME_BUFFER_SIZE(req->bufferSize, requestV1);
break;
}
default:
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: unexpected "
- "OP type encountered\n"));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: unexpected OP type encountered\n", __func__));
result = -EPROTO;
+ break;
+ }
+
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsPackGetattrRequest --
+ *
+ * Setup the getattr request, depending on the op version. When possible,
+ * we will issue the getattr using an existing open HGFS handle.
+ *
+ * Results:
+ * Returns zero on success, or negative error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer
+ HgfsOp opUsed, // IN: Op to be used
+ Bool allowHandleReuse, // IN: Can we use a handle?
+ struct dentry *dentry, // IN: Dentry containing name
+ HgfsAttrInfo *attr) // OUT: Attrs to update
+{
+ size_t reqBufferSize;
+ size_t reqSize;
+ char *fileName = NULL;
+ uint32 *fileNameLength = NULL;
+ int result = 0;
+
+ ASSERT(attr);
+ ASSERT(dentry);
+ ASSERT(req);
+
+ result = HgfsPackCommonattr(req,
+ opUsed,
+ allowHandleReuse,
+ dentry->d_inode,
+ &reqSize,
+ &reqBufferSize,
+ &fileName,
+ &fileNameLength,
+ attr);
+ if (0 > result) {
goto out;
}
@@ -366,29 +421,112 @@ HgfsPackGetattrRequest(HgfsReq *req, // IN/OUT: Request buffer
/* Build full name to send to server. */
if (HgfsBuildPath(fileName, reqBufferSize,
dentry) < 0) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: build path "
- "failed\n"));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: build path failed\n", __func__));
result = -EINVAL;
goto out;
}
- LOG(6, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: getting attrs "
- "for \"%s\"\n", fileName));
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: getting attrs for \"%s\"\n",
+ __func__, fileName));
/* Convert to CP name. */
result = CPName_ConvertTo(fileName,
reqBufferSize,
fileName);
if (result < 0) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPackGetattrRequest: CP "
- "conversion failed\n"));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: CP conversion failed\n", __func__));
result = -EINVAL;
goto out;
}
*fileNameLength = result;
}
+
req->payloadSize = reqSize + result;
result = 0;
+
+out:
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsPackGetattrRootRequest --
+ *
+ * Setup the getattr request for the root of the HGFS file system.
+ *
+ * When possible, we will issue the getattr using an existing open HGFS handle.
+ *
+ * Results:
+ * Returns zero on success, or negative error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HgfsPackGetattrRootRequest(HgfsReq *req, // IN/OUT: Request buffer
+ HgfsOp opUsed, // IN: Op to be used
+ struct super_block *sb, // IN: Super block entry
+ HgfsAttrInfo *attr) // OUT: Attrs to update
+{
+ size_t reqBufferSize;
+ size_t reqSize;
+ char *fileName = NULL;
+ uint32 *fileNameLength = NULL;
+ int result = 0;
+
+ ASSERT(attr);
+ ASSERT(sb);
+ ASSERT(req);
+
+ result = HgfsPackCommonattr(req,
+ opUsed,
+ FALSE,
+ NULL,
+ &reqSize,
+ &reqBufferSize,
+ &fileName,
+ &fileNameLength,
+ attr);
+ if (0 > result) {
+ goto out;
+ }
+
+ /* Avoid all this extra work when we're doing a getattr by handle. */
+ if (fileName != NULL) {
+ HgfsSuperInfo *si = HGFS_SB_TO_COMMON(sb);
+
+ /* Build full name to send to server. */
+ if (HgfsBuildRootPath(fileName,
+ reqBufferSize,
+ si) < 0) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: build path failed\n", __func__));
+ result = -EINVAL;
+ goto out;
+ }
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: getting attrs for \"%s\"\n",
+ __func__, fileName));
+
+ /* Convert to CP name. */
+ result = CPName_ConvertTo(fileName,
+ reqBufferSize,
+ fileName);
+ if (result < 0) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: CP conversion failed\n", __func__));
+ result = -EINVAL;
+ goto out;
+ }
+
+ *fileNameLength = result;
+ }
+
+ req->payloadSize = reqSize + result;
+ result = 0;
+
out:
return result;
}
@@ -548,7 +686,7 @@ HgfsUnpackCommonAttr(HgfsReq *req, // IN: Reply packet
/*
*----------------------------------------------------------------------
*
- * HgfsChangeFileAttributes --
+ * HgfsCalcBlockSize --
*
* Calculate the number of 512 byte blocks used.
*
@@ -565,6 +703,7 @@ HgfsUnpackCommonAttr(HgfsReq *req, // IN: Reply packet
*
*----------------------------------------------------------------------
*/
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 17)
static inline blkcnt_t
HgfsCalcBlockSize(uint64 tsize)
@@ -585,6 +724,69 @@ HgfsCalcBlockSize(uint64 tsize)
/*
*----------------------------------------------------------------------
*
+ * HgfsSetInodeUidGid --
+ *
+ * Set the UID and GID of the inode.
+ *
+ * Update an inode's UID and GID to match those of the HgfsAttr returned
+ * by the server.
+ *
+ * Results:
+ * The number of 512 byte blocks for the size.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+HgfsSetInodeUidGid(struct inode *inode, // IN/OUT: Inode
+ HgfsSuperInfo *si, // IN: New attrs
+ HgfsAttrInfo const *attr) // IN: New attrs
+{
+ /*
+ * Use the stored uid and gid if we were given them at mount-time, or if
+ * the server didn't give us a uid or gid.
+ */
+ if (si->uidSet || (attr->mask & HGFS_ATTR_VALID_USERID) == 0) {
+ inode->i_uid = si->uid;
+ } else {
+ kuid_t attrUid = make_kuid(&init_user_ns, attr->userId);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (uid_valid(attrUid)) {
+ inode->i_uid = attrUid;
+ } else {
+ inode->i_uid = si->uid;
+ }
+#else
+ inode->i_uid = attrUid;
+#endif
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: inode uid %u\n",
+ __func__, from_kuid(&init_user_ns, inode->i_uid)));
+ }
+ if (si->gidSet || (attr->mask & HGFS_ATTR_VALID_GROUPID) == 0) {
+ inode->i_gid = si->gid;
+ } else {
+ kgid_t attrGid = make_kgid(&init_user_ns, attr->groupId);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ if (gid_valid(attrGid)) {
+ inode->i_gid = attrGid;
+ } else {
+ inode->i_gid = si->gid;
+ }
+#else
+ inode->i_gid = attrGid;
+#endif
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: inode gid %u\n",
+ __func__, from_kgid(&init_user_ns, inode->i_gid)));
+ }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
* HgfsChangeFileAttributes --
*
* Update an inode's attributes to match those of the HgfsAttr. May
@@ -674,20 +876,7 @@ HgfsChangeFileAttributes(struct inode *inode, // IN/OUT: Inode
*/
set_nlink(inode, 1);
- /*
- * Use the stored uid and gid if we were given them at mount-time, or if
- * the server didn't give us a uid or gid.
- */
- if (si->uidSet || (attr->mask & HGFS_ATTR_VALID_USERID) == 0) {
- inode->i_uid = si->uid;
- } else {
- inode->i_uid = attr->userId;
- }
- if (si->gidSet || (attr->mask & HGFS_ATTR_VALID_GROUPID) == 0) {
- inode->i_gid = si->gid;
- } else {
- inode->i_gid = attr->groupId;
- }
+ HgfsSetInodeUidGid(inode, si, attr);
inode->i_rdev = 0; /* Device nodes are not supported */
#if !defined VMW_INODE_2618
@@ -768,17 +957,14 @@ HgfsChangeFileAttributes(struct inode *inode, // IN/OUT: Inode
/*
*----------------------------------------------------------------------
*
- * HgfsPrivateGetattr --
+ * HgfsCanRetryGetattrRequest --
*
- * Internal getattr routine. Send a getattr request to the server
- * for the indicated remote name, and if it succeeds copy the
- * results of the getattr into the provided HgfsAttrInfo.
- *
- * fileName (if supplied) will be set to a newly allocated string
- * if the file is a symlink; it's the caller's duty to free it.
+ * Checks the getattr request version and downgrades the global getattr
+ * version if we can.
*
* Results:
- * Returns zero on success, or a negative error on failure.
+ * Returns TRUE on success and downgrades the global getattr protocol version,
+ * or FALSE if no retry is possible.
*
* Side effects:
* None
@@ -786,42 +972,60 @@ HgfsChangeFileAttributes(struct inode *inode, // IN/OUT: Inode
*----------------------------------------------------------------------
*/
-int
-HgfsPrivateGetattr(struct dentry *dentry, // IN: Dentry containing name
- HgfsAttrInfo *attr, // OUT: Attr to copy into
- char **fileName) // OUT: pointer to allocated file name
+static Bool
+HgfsCanRetryGetattrRequest(HgfsOp getattrOp) // IN: getattrOp version used
{
- HgfsReq *req;
- HgfsStatus replyStatus;
- HgfsOp opUsed;
- int result = 0;
- Bool allowHandleReuse = TRUE;
+ Bool canRetry = FALSE;
+
+ /* Retry with older version(s). Set globally. */
+ if (getattrOp == HGFS_OP_GETATTR_V3) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: Version 3 "
+ "not supported. Falling back to version 2.\n", __func__));
+ hgfsVersionGetattr = HGFS_OP_GETATTR_V2;
+ canRetry = TRUE;
+ } else if (getattrOp == HGFS_OP_GETATTR_V2) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: Version 2 "
+ "not supported. Falling back to version 1.\n", __func__));
+ hgfsVersionGetattr = HGFS_OP_GETATTR;
+ canRetry = TRUE;
+ }
+ return canRetry;
+}
- ASSERT(dentry);
- ASSERT(dentry->d_sb);
- ASSERT(attr);
- req = HgfsGetNewRequest();
- if (!req) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: out of memory "
- "while getting new request\n"));
- result = -ENOMEM;
- goto out;
- }
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsSendGetattrRequest --
+ *
+ * Send the getattr request and handle the reply.
+ *
+ * Results:
+ * Returns zero on success, or a negative error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
- retry:
+int
+HgfsSendGetattrRequest(HgfsReq *req, // IN: getattr request
+ Bool *doRetry, // OUT: Retry getattr request
+ Bool *allowHandleReuse, // IN/OUT: handle reuse
+ HgfsAttrInfo *attr, // OUT: Attr to copy into
+ char **fileName) // OUT: pointer to allocated file name
+{
+ int result;
- opUsed = hgfsVersionGetattr;
- result = HgfsPackGetattrRequest(req, dentry, allowHandleReuse, opUsed, attr);
- if (result != 0) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: no attrs\n"));
- goto out;
- }
+ *doRetry = FALSE;
result = HgfsSendRequest(req);
if (result == 0) {
- replyStatus = HgfsReplyStatus(req);
+ HgfsStatus replyStatus = HgfsReplyStatus(req);
+
result = HgfsStatusConvertToLinux(replyStatus);
+
LOG(6, (KERN_DEBUG "VMware hgfs: %s: reply status %d -> %d\n",
__func__, replyStatus, result));
@@ -843,7 +1047,7 @@ HgfsPrivateGetattr(struct dentry *dentry, // IN: Dentry containing name
* and it doesn't display any valid shares too. So as a workaround, we
* remap EIO to success and create minimal fake attributes.
*/
- LOG(1, (KERN_DEBUG "Hgfs:Server returned EIO on unknown file\n"));
+ LOG(1, (KERN_DEBUG "Hgfs: %s: Server returned EIO on unknown file\n", __func__));
/* Create fake attributes */
attr->mask = HGFS_ATTR_VALID_TYPE | HGFS_ATTR_VALID_SIZE;
attr->type = HGFS_FILE_TYPE_DIRECTORY;
@@ -860,9 +1064,9 @@ HgfsPrivateGetattr(struct dentry *dentry, // IN: Dentry containing name
* "goto retry" would cause an infinite loop. Instead, let's retry
* with a getattr by name.
*/
- if (allowHandleReuse) {
- allowHandleReuse = FALSE;
- goto retry;
+ if (*allowHandleReuse) {
+ *allowHandleReuse = FALSE;
+ *doRetry = TRUE;
}
/*
@@ -874,30 +1078,143 @@ HgfsPrivateGetattr(struct dentry *dentry, // IN: Dentry containing name
case -EPROTO:
/* Retry with older version(s). Set globally. */
- if (attr->requestType == HGFS_OP_GETATTR_V3) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: Version 3 "
- "not supported. Falling back to version 2.\n"));
- hgfsVersionGetattr = HGFS_OP_GETATTR_V2;
- goto retry;
- } else if (attr->requestType == HGFS_OP_GETATTR_V2) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: Version 2 "
- "not supported. Falling back to version 1.\n"));
- hgfsVersionGetattr = HGFS_OP_GETATTR;
- goto retry;
+ if (HgfsCanRetryGetattrRequest(attr->requestType)) {
+ *doRetry = TRUE;
}
+ break;
- /* Fallthrough. */
default:
break;
}
} else if (result == -EIO) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: timed out\n"));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: timed out\n", __func__));
} else if (result == -EPROTO) {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: server "
- "returned error: %d\n", result));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: protocol error: %d\n",
+ __func__, result));
} else {
- LOG(4, (KERN_DEBUG "VMware hgfs: HgfsPrivateGetattr: unknown error: "
- "%d\n", result));
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: unknown error: %d\n",
+ __func__, result));
+ }
+
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsPrivateGetattrRoot --
+ *
+ * The getattr for the root. Send a getattr request to the server
+ * for the indicated remote name, and if it succeeds copy the
+ * results of the getattr into the provided HgfsAttrInfo.
+ *
+ * fileName (of the root) will be set to a newly allocated string.
+ *
+ * Results:
+ * Returns zero on success, or a negative error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+HgfsPrivateGetattrRoot(struct super_block *sb, // IN: Super block object
+ HgfsAttrInfo *attr) // OUT: Attr to copy into
+{
+ HgfsReq *req;
+ HgfsOp opUsed;
+ int result = 0;
+ Bool doRetry;
+ Bool allowHandleReuse = FALSE;
+
+ ASSERT(sb);
+ ASSERT(attr);
+
+ req = HgfsGetNewRequest();
+ if (!req) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: out of memory "
+ "while getting new request\n", __func__));
+ result = -ENOMEM;
+ goto out;
+ }
+
+retry:
+ opUsed = hgfsVersionGetattr;
+ result = HgfsPackGetattrRootRequest(req, opUsed, sb, attr);
+ if (result != 0) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: no attrs\n", __func__));
+ goto out;
+ }
+
+ result = HgfsSendGetattrRequest(req, &doRetry, &allowHandleReuse, attr, NULL);
+ if (0 != result && doRetry) {
+ goto retry;
+ }
+
+out:
+ HgfsFreeRequest(req);
+ return result;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HgfsPrivateGetattr --
+ *
+ * Internal getattr routine. Send a getattr request to the server
+ * for the indicated remote name, and if it succeeds copy the
+ * results of the getattr into the provided HgfsAttrInfo.
+ *
+ * fileName (if supplied) will be set to a newly allocated string
+ * if the file is a symlink; it's the caller's duty to free it.
+ *
+ * Results:
+ * Returns zero on success, or a negative error on failure.
+ *
+ * Side effects:
+ * None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+HgfsPrivateGetattr(struct dentry *dentry, // IN: Dentry containing name
+ HgfsAttrInfo *attr, // OUT: Attr to copy into
+ char **fileName) // OUT: pointer to allocated file name
+{
+ HgfsReq *req;
+ HgfsOp opUsed;
+ int result = 0;
+ Bool doRetry;
+ Bool allowHandleReuse = TRUE;
+
+ ASSERT(dentry);
+ ASSERT(dentry->d_sb);
+ ASSERT(attr);
+
+ req = HgfsGetNewRequest();
+ if (!req) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: out of memory "
+ "while getting new request\n", __func__));
+ result = -ENOMEM;
+ goto out;
+ }
+
+retry:
+ opUsed = hgfsVersionGetattr;
+ result = HgfsPackGetattrRequest(req, opUsed, allowHandleReuse, dentry, attr);
+ if (result != 0) {
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: no attrs\n", __func__));
+ goto out;
+ }
+
+ result = HgfsSendGetattrRequest(req, &doRetry, &allowHandleReuse, attr, fileName);
+ if (0 != result && doRetry) {
+ goto retry;
}
out:
@@ -1053,6 +1370,108 @@ HgfsIget(struct super_block *sb, // IN: Superblock of this fs
/*
*-----------------------------------------------------------------------------
*
+ * HgfsInstantiateRoot --
+ *
+ * Gets the root dentry for a given super block.
+ *
+ * Results:
+ * zero and a valid root dentry on success
+ * negative value on failure
+ *
+ * Side effects:
+ * None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+HgfsInstantiateRoot(struct super_block *sb, // IN: Super block object
+ struct dentry **rootDentry) // OUT: Root dentry
+{
+ int result = -ENOMEM;
+ struct inode *rootInode;
+ struct dentry *tempRootDentry = NULL;
+ struct HgfsAttrInfo rootDentryAttr;
+ HgfsInodeInfo *iinfo;
+
+ ASSERT(sb);
+ ASSERT(rootDentry);
+
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: entered\n", __func__));
+
+ rootInode = HgfsGetInode(sb, HGFS_ROOT_INO);
+ if (rootInode == NULL) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: Could not get the root inode\n",
+ __func__));
+ goto exit;
+ }
+
+ /*
+ * On an allocation failure in read_super, the inode will have been
+ * marked "bad". If it was, we certainly don't want to start playing with
+ * the HgfsInodeInfo. So quietly put the inode back and fail.
+ */
+ if (is_bad_inode(rootInode)) {
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: encountered bad inode\n",
+ __func__));
+ goto exit;
+ }
+
+ LOG(8, (KERN_DEBUG "VMware hgfs: %s: retrieve root attrs\n", __func__));
+ result = HgfsPrivateGetattrRoot(sb, &rootDentryAttr);
+ if (result) {
+ LOG(4, (KERN_WARNING "VMware hgfs: %s: Could not the root attrs\n", __func__));
+ goto exit;
+ }
+
+ iinfo = INODE_GET_II_P(rootInode);
+ iinfo->isFakeInodeNumber = FALSE;
+ iinfo->isReferencedInode = TRUE;
+
+ if (rootDentryAttr.mask & HGFS_ATTR_VALID_FILEID) {
+ iinfo->hostFileId = rootDentryAttr.hostFileId;
+ }
+
+ HgfsChangeFileAttributes(rootInode, &rootDentryAttr);
+
+ /*
+ * Now the initialization of the inode is complete we can create
+ * the root dentry which has flags initialized from the inode itself.
+ */
+ tempRootDentry = d_make_root(rootInode);
+ /*
+ * d_make_root() does iput() on failure; if d_make_root() completes
+ * successfully then subsequent dput() will do iput() for us, so we
+ * should just ignore root inode from now on.
+ */
+ rootInode = NULL;
+
+ if (tempRootDentry == NULL) {
+ LOG(4, (KERN_WARNING "VMware hgfs: %s: Could not get "
+ "root dentry\n", __func__));
+ goto exit;
+ }
+
+ HgfsDentryAgeReset(tempRootDentry);
+ tempRootDentry->d_op = &HgfsDentryOperations;
+
+ *rootDentry = tempRootDentry;
+ result = 0;
+
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: finished\n", __func__));
+exit:
+ if (result) {
+ iput(rootInode);
+ dput(tempRootDentry);
+ *rootDentry = NULL;
+ }
+ return result;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
* HgfsInstantiate --
*
* Tie a dentry to a looked up or created inode. Callers may choose to
@@ -1117,6 +1536,45 @@ HgfsInstantiate(struct dentry *dentry, // IN: Dentry to use
/*
*-----------------------------------------------------------------------------
*
+ * HgfsBuildRootPath --
+ *
+ * Constructs the root path given the super info.
+ *
+ * Results:
+ * If non-negative, the length of the buffer written.
+ * Otherwise, an error code.
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+HgfsBuildRootPath(char *buffer, // IN/OUT: Buffer to write into
+ size_t bufferLen, // IN: Size of buffer
+ HgfsSuperInfo *si) // IN: First dentry to walk
+{
+ size_t shortestNameLength;
+ /*
+ * Buffer must hold at least the share name (which is already prefixed with
+ * a forward slash), and nul.
+ */
+ shortestNameLength = si->shareNameLen + 1;
+ if (bufferLen < shortestNameLength) {
+ return -ENAMETOOLONG;
+ }
+ memcpy(buffer, si->shareName, shortestNameLength);
+
+ /* Short-circuit if we're at the root already. */
+ LOG(4, (KERN_DEBUG "VMware hgfs: %s: root path \"%s\"\n", __func__, buffer));
+ return shortestNameLength;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
* HgfsBuildPath --
*
* Constructs the full path given a dentry by walking the dentry and its
@@ -1138,7 +1596,7 @@ HgfsBuildPath(char *buffer, // IN/OUT: Buffer to write into
size_t bufferLen, // IN: Size of buffer
struct dentry *dentry) // IN: First dentry to walk
{
- int retval = 0;
+ int retval;
size_t shortestNameLength;
HgfsSuperInfo *si;
@@ -1148,26 +1606,23 @@ HgfsBuildPath(char *buffer, // IN/OUT: Buffer to write into
si = HGFS_SB_TO_COMMON(dentry->d_sb);
- /*
- * Buffer must hold at least the share name (which is already prefixed with
- * a forward slash), and nul.
- */
- shortestNameLength = si->shareNameLen + 1;
- if (bufferLen < shortestNameLength) {
- return -ENAMETOOLONG;
+ retval = HgfsBuildRootPath(buffer, bufferLen, si);
+ if (0 > retval) {
+ return retval;
}
- memcpy(buffer, si->shareName, shortestNameLength);
/* Short-circuit if we're at the root already. */
if (IS_ROOT(dentry)) {
LOG(4, (KERN_DEBUG "VMware hgfs: HgfsBuildPath: Sending root \"%s\"\n",
buffer));
- return shortestNameLength;
+ return retval;
}
/* Skip the share name, but overwrite our previous nul. */
+ shortestNameLength = retval;
buffer += shortestNameLength - 1;
bufferLen -= shortestNameLength - 1;
+ retval = 0;
/*
* Build the path string walking the tree backward from end to ROOT
@@ -1499,6 +1954,7 @@ HgfsCreateFileInfo(struct file *file, // IN: File pointer to attach to
/* So that readdir() reissues open request */
fileInfo->isStale = TRUE;
+ fileInfo->direntPos = 0;
/*
* I don't think we need any VFS locks since we're only touching the HGFS
@@ -1747,11 +2203,13 @@ HgfsStatusConvertToLinux(HgfsStatus hgfsStatus) // IN: Status code to convert
void
HgfsSetUidGid(struct inode *parent, // IN: parent inode
struct dentry *dentry, // IN: dentry of file to update
- uid_t uid, // IN: uid to set
- gid_t gid) // IN: gid to set
+ kuid_t uid, // IN: uid to set
+ kgid_t gid) // IN: gid to set
{
struct iattr setUidGid;
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: entered \n", __func__));
+
setUidGid.ia_valid = ATTR_UID;
setUidGid.ia_uid = uid;
@@ -1775,6 +2233,8 @@ HgfsSetUidGid(struct inode *parent, // IN: parent inode
HgfsDentryAgeForce(dentry);
HgfsSetattr(dentry, &setUidGid);
HgfsRevalidate(dentry);
+
+ LOG(6, (KERN_DEBUG "VMware hgfs: %s: returns\n", __func__));
}
diff --git a/open-vm-tools/modules/linux/vmhgfs/fsutil.h b/open-vm-tools/modules/linux/vmhgfs/fsutil.h
index f332fb6d..ff15b15f 100644
--- a/open-vm-tools/modules/linux/vmhgfs/fsutil.h
+++ b/open-vm-tools/modules/linux/vmhgfs/fsutil.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -32,6 +32,7 @@
#include <linux/signal.h>
#include "compat_fs.h"
+#include "module.h" /* For kuid_t kgid_t types. */
#include "inode.h"
#include "request.h"
#include "vm_basic_types.h"
@@ -73,6 +74,8 @@ int HgfsPrivateGetattr(struct dentry *dentry,
struct inode *HgfsIget(struct super_block *sb,
ino_t ino,
HgfsAttrInfo const *attr);
+int HgfsInstantiateRoot(struct super_block *sb,
+ struct dentry **rootDentry);
int HgfsInstantiate(struct dentry *dentry,
ino_t ino,
HgfsAttrInfo const *attr);
@@ -92,8 +95,8 @@ int HgfsGetHandle(struct inode *inode,
int HgfsStatusConvertToLinux(HgfsStatus hgfsStatus);
void HgfsSetUidGid(struct inode *parent,
struct dentry *dentry,
- uid_t uid,
- gid_t gid);
+ kuid_t uid,
+ kgid_t gid);
struct inode *HgfsGetInode(struct super_block *sb, ino_t ino);
void HgfsDoReadInode(struct inode *inode);
diff --git a/open-vm-tools/modules/linux/vmhgfs/inode.c b/open-vm-tools/modules/linux/vmhgfs/inode.c
index 2999b940..77b16691 100644
--- a/open-vm-tools/modules/linux/vmhgfs/inode.c
+++ b/open-vm-tools/modules/linux/vmhgfs/inode.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -33,6 +33,7 @@
#include <linux/highmem.h>
#include "compat_cred.h"
+#include "compat_dcache.h"
#include "compat_fs.h"
#include "compat_kernel.h"
#include "compat_mm.h"
@@ -50,6 +51,23 @@
#include "fsutil.h"
#include "vm_assert.h"
+
+#if defined VMW_DCOUNT_311 || LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
+/*
+ * Linux Kernel versions that are version 3.11 version and newer or are compatible
+ * by having the d_count function replacement backported.
+ */
+#define hgfs_d_count(dentry) d_count(dentry)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+/*
+ * Kernel versions that are not 3.11 version compatible or are just older will
+ * use the d_count field.
+ */
+#define hgfs_d_count(dentry) dentry->d_count
+#else
+#define hgfs_d_count(dentry) atomic_read(&dentry->d_count)
+#endif
+
/* Private functions. */
static int HgfsDelete(struct inode *dir,
struct dentry *dentry,
@@ -429,6 +447,8 @@ HgfsPackSetattrRequest(struct iattr *iattr, // IN: Inode attrs to update from
size_t reqBufferSize;
size_t reqSize;
int result = 0;
+ uid_t attrUid = -1;
+ gid_t attrGid = -1;
ASSERT(iattr);
ASSERT(dentry);
@@ -437,6 +457,14 @@ HgfsPackSetattrRequest(struct iattr *iattr, // IN: Inode attrs to update from
valid = iattr->ia_valid;
+ if (valid & ATTR_UID) {
+ attrUid = from_kuid(&init_user_ns, iattr->ia_uid);
+ }
+
+ if (valid & ATTR_GID) {
+ attrGid = from_kgid(&init_user_ns, iattr->ia_gid);
+ }
+
switch (opUsed) {
case HGFS_OP_SETATTR_V3: {
HgfsRequest *requestHeader;
@@ -513,13 +541,13 @@ HgfsPackSetattrRequest(struct iattr *iattr, // IN: Inode attrs to update from
if (valid & ATTR_UID) {
attrV2->mask |= HGFS_ATTR_VALID_USERID;
- attrV2->userId = iattr->ia_uid;
+ attrV2->userId = attrUid;
*changed = TRUE;
}
if (valid & ATTR_GID) {
attrV2->mask |= HGFS_ATTR_VALID_GROUPID;
- attrV2->groupId = iattr->ia_gid;
+ attrV2->groupId = attrGid;
*changed = TRUE;
}
@@ -616,13 +644,13 @@ HgfsPackSetattrRequest(struct iattr *iattr, // IN: Inode attrs to update from
if (valid & ATTR_UID) {
attrV2->mask |= HGFS_ATTR_VALID_USERID;
- attrV2->userId = iattr->ia_uid;
+ attrV2->userId = attrUid;
*changed = TRUE;
}
if (valid & ATTR_GID) {
attrV2->mask |= HGFS_ATTR_VALID_GROUPID;
- attrV2->groupId = iattr->ia_gid;
+ attrV2->groupId = attrGid;
*changed = TRUE;
}
@@ -1890,7 +1918,7 @@ HgfsPermission(struct inode *inode,
#endif
&inode->i_dentry,
d_alias) {
- int dcount = dentry->d_count;
+ int dcount = hgfs_d_count(dentry);
if (dcount) {
LOG(4, ("Found %s %d \n", dentry->d_name.name, dcount));
return HgfsAccessInt(dentry, mask & (MAY_READ | MAY_WRITE | MAY_EXEC));
@@ -1943,11 +1971,7 @@ HgfsPermission(struct inode *inode,
list_for_each(pos, &inode->i_dentry) {
int dcount;
struct dentry *dentry = list_entry(pos, struct dentry, d_alias);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
- dcount = atomic_read(&dentry->d_count);
-#else
- dcount = dentry->d_count;
-#endif
+ dcount = hgfs_d_count(dentry);
if (dcount) {
LOG(4, ("Found %s %d \n", (dentry)->d_name.name, dcount));
return HgfsAccessInt(dentry, mask & (MAY_READ | MAY_WRITE | MAY_EXEC));
diff --git a/open-vm-tools/modules/linux/vmhgfs/inode.h b/open-vm-tools/modules/linux/vmhgfs/inode.h
index e5f758bb..c86f848d 100644
--- a/open-vm-tools/modules/linux/vmhgfs/inode.h
+++ b/open-vm-tools/modules/linux/vmhgfs/inode.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/link.c b/open-vm-tools/modules/linux/vmhgfs/link.c
index 65d8a237..06f693b9 100644
--- a/open-vm-tools/modules/linux/vmhgfs/link.c
+++ b/open-vm-tools/modules/linux/vmhgfs/link.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -136,6 +136,13 @@ HgfsFollowlink(struct dentry *dentry, // IN: Dentry containing link
#endif
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)
+#define HGFS_DO_READLINK(dentry,buffer,buflen,fileName) \
+ readlink_copy(buffer, buflen, fileName)
+#else
+#define HGFS_DO_READLINK(dentry,buffer,buflen,fileName) \
+ vfs_readlink(dentry, buffer, buflen, fileName)
+#endif
/*
*----------------------------------------------------------------------
@@ -185,7 +192,7 @@ HgfsReadlink(struct dentry *dentry, // IN: Dentry containing link
} else {
LOG(6, (KERN_DEBUG "VMware hgfs: %s: calling vfs_readlink %s\n",
__func__, fileName));
- error = vfs_readlink(dentry, buffer, buflen, fileName);
+ error = HGFS_DO_READLINK(dentry, buffer, buflen, fileName);
LOG(6, (KERN_DEBUG "VMware hgfs: %s: vfs_readlink %s ret %dn",
__func__, fileName, error));
}
diff --git a/open-vm-tools/modules/linux/vmhgfs/module.c b/open-vm-tools/modules/linux/vmhgfs/module.c
index 4bce943f..aa961283 100644
--- a/open-vm-tools/modules/linux/vmhgfs/module.c
+++ b/open-vm-tools/modules/linux/vmhgfs/module.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/module.h b/open-vm-tools/modules/linux/vmhgfs/module.h
index 911ba8b7..9c123323 100644
--- a/open-vm-tools/modules/linux/vmhgfs/module.h
+++ b/open-vm-tools/modules/linux/vmhgfs/module.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -74,6 +74,17 @@ extern int LOGLEVEL_THRESHOLD;
* Macros for accessing members that are private to this code in
* sb/inode/file structs.
*/
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)
+typedef uid_t kuid_t;
+typedef gid_t kgid_t;
+#define from_kuid(_ns, _kuid) (_kuid)
+#define from_kgid(_ns, _kgid) (_kgid)
+#define make_kuid(_ns, _uid) (_uid)
+#define make_kgid(_ns, _gid) (_gid)
+#endif
+
+
#define HGFS_SET_SB_TO_COMMON(sb, common) do { (sb)->s_fs_info = (common); } while (0)
#define HGFS_SB_TO_COMMON(sb) ((HgfsSuperInfo *)(sb)->s_fs_info)
@@ -110,9 +121,9 @@ extern int LOGLEVEL_THRESHOLD;
/* Data kept in each superblock in sb->u. */
typedef struct HgfsSuperInfo {
- uid_t uid; /* UID of user who mounted this fs. */
+ kuid_t uid; /* UID of user who mounted this fs. */
+ kgid_t gid; /* GID of user who mounted this fs. */
Bool uidSet; /* Was the UID specified at mount-time? */
- gid_t gid; /* GID of user who mounted this fs. */
Bool gidSet; /* Was the GID specified at mount-time? */
mode_t fmask; /* File permission mask. */
mode_t dmask; /* Directory permission mask. */
@@ -167,6 +178,9 @@ typedef struct HgfsFileInfo {
*/
Bool isStale;
+ /* Directory read position for tracking. */
+ loff_t direntPos;
+
} HgfsFileInfo;
diff --git a/open-vm-tools/modules/linux/vmhgfs/page.c b/open-vm-tools/modules/linux/vmhgfs/page.c
index 387bc02f..56f98621 100644
--- a/open-vm-tools/modules/linux/vmhgfs/page.c
+++ b/open-vm-tools/modules/linux/vmhgfs/page.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/request.c b/open-vm-tools/modules/linux/vmhgfs/request.c
index 71758371..dccf481e 100644
--- a/open-vm-tools/modules/linux/vmhgfs/request.c
+++ b/open-vm-tools/modules/linux/vmhgfs/request.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/request.h b/open-vm-tools/modules/linux/vmhgfs/request.h
index 055f857d..4303924b 100644
--- a/open-vm-tools/modules/linux/vmhgfs/request.h
+++ b/open-vm-tools/modules/linux/vmhgfs/request.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/stubs.c b/open-vm-tools/modules/linux/vmhgfs/stubs.c
index f79b7656..029d833c 100644
--- a/open-vm-tools/modules/linux/vmhgfs/stubs.c
+++ b/open-vm-tools/modules/linux/vmhgfs/stubs.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/super.c b/open-vm-tools/modules/linux/vmhgfs/super.c
index 1502513b..04a21920 100644
--- a/open-vm-tools/modules/linux/vmhgfs/super.c
+++ b/open-vm-tools/modules/linux/vmhgfs/super.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmhgfs/transport.c b/open-vm-tools/modules/linux/vmhgfs/transport.c
index a45e3e77..760ae7bf 100644
--- a/open-vm-tools/modules/linux/vmhgfs/transport.c
+++ b/open-vm-tools/modules/linux/vmhgfs/transport.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -52,8 +52,6 @@
#include "transport.h"
#include "vm_assert.h"
-extern int USE_VMCI;
-
static HgfsTransportChannel *hgfsChannel; /* Current active channel. */
static compat_mutex_t hgfsChannelLock; /* Lock to protect hgfsChannel. */
static struct list_head hgfsRepPending; /* Reply pending queue. */
@@ -156,17 +154,6 @@ HgfsTransportSetupNewChannel(void)
{
HgfsTransportChannel *newChannel;
- newChannel = HgfsGetVmciChannel();
- if (newChannel != NULL) {
- if (HgfsTransportOpenChannel(newChannel)) {
- hgfsChannel = newChannel;
- LOG(10, ("CHANNEL: Vmci channel\n"));
- return TRUE;
- }
- }
-
- USE_VMCI = 0;
-
newChannel = HgfsGetBdChannel();
LOG(10, ("CHANNEL: Bd channel\n"));
ASSERT(newChannel);
diff --git a/open-vm-tools/modules/linux/vmhgfs/transport.h b/open-vm-tools/modules/linux/vmhgfs/transport.h
index 7caac3e8..0c0c9542 100644
--- a/open-vm-tools/modules/linux/vmhgfs/transport.h
+++ b/open-vm-tools/modules/linux/vmhgfs/transport.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -66,7 +66,6 @@ void HgfsTransportFinishRequest(HgfsReq *req, Bool success, Bool do_put);
void HgfsTransportFlushRequests(void);
void HgfsTransportMarkDead(void);
-HgfsTransportChannel* HgfsGetVmciChannel(void);
HgfsTransportChannel *HgfsGetBdChannel(void);
#endif // _HGFS_DRIVER_TRANSPORT_H_
diff --git a/open-vm-tools/modules/linux/vmhgfs/vmci.c b/open-vm-tools/modules/linux/vmhgfs/vmci.c
deleted file mode 100644
index 027fec77..00000000
--- a/open-vm-tools/modules/linux/vmhgfs/vmci.c
+++ /dev/null
@@ -1,815 +0,0 @@
-/*********************************************************
- * Copyright (C) 2010 VMware, Inc. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 and no later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *********************************************************/
-
-/*
- * vmci.c --
- *
- * Provides VMCI transport channel to the HGFS client.
- */
-
-/* Must come before any kernel header file. */
-#include "driver-config.h"
-
-#include <linux/errno.h>
-#include <linux/moduleparam.h>
-#include <linux/interrupt.h> /* for spin_lock_bh */
-#include <asm/io.h>
-
-#include "compat_mm.h"
-#include "hgfsProto.h"
-#include "hgfsTransport.h"
-#include "module.h"
-#include "request.h"
-#include "transport.h"
-#include "vm_assert.h"
-#include "vmci_call_defs.h"
-#include "vmci_defs.h"
-#include "vmciKernelAPI1.h"
-
-static Bool HgfsVmciChannelOpen(HgfsTransportChannel *channel);
-static void HgfsVmciChannelClose(HgfsTransportChannel *channel);
-static HgfsReq * HgfsVmciChannelAllocate(size_t payloadSize);
-void HgfsVmciChannelFree(HgfsReq *req);
-static int HgfsVmciChannelSend(HgfsTransportChannel *channel, HgfsReq *req);
-static void HgfsRequestAsyncDispatch(char *payload, uint32 size);
-
-int USE_VMCI = 0;
-module_param(USE_VMCI, int, 0444);
-
-static HgfsTransportChannel channel = {
- .name = "vmci",
- .ops.open = HgfsVmciChannelOpen,
- .ops.close = HgfsVmciChannelClose,
- .ops.allocate = HgfsVmciChannelAllocate,
- .ops.free = HgfsVmciChannelFree,
- .ops.send = HgfsVmciChannelSend,
- .priv = NULL,
- .status = HGFS_CHANNEL_NOTCONNECTED
-};
-
-static spinlock_t vmciRequestProcessLock;
-
-typedef struct HgfsShmemPage {
- uint64 va;
- uint64 pa;
- Bool free;
-} HgfsShmemPage;
-
-typedef struct HgfsShmemPages {
- HgfsShmemPage *list;
- uint32 totalPageCount;
- uint32 freePageCount;
-} HgfsShmemPages;
-
-HgfsShmemPages gHgfsShmemPages;
-#define HGFS_VMCI_SHMEM_PAGES (16)
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsRequestAsyncDispatch --
- *
- * XXX Main dispatcher function. Currently just a stub. Needs to run
- * in atomic context.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-HgfsRequestAsyncDispatch(char *payload, // IN: request header
- uint32 size) // IN: size of payload
-{
- HgfsRequest *reqHeader = (HgfsRequest *)payload;
-
- LOG(4, (KERN_WARNING "Size in Dispatch %u\n", size));
-
- switch (reqHeader->op) {
- case HGFS_OP_NOTIFY_V4: {
- LOG(4, (KERN_WARNING "Calling HGFS_OP_NOTIFY_V4 dispatch function\n"));
- break;
- }
- default:
- LOG(4, (KERN_WARNING "%s: Unknown opcode = %d", __func__, reqHeader->op));
- }
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsRequestAsyncShmemDispatch --
- *
- * Shared memory dispatcher. It extracts packets from the shared
- * memory and dispatches to the main hgfs dispatcher function. When
- * the buffer is larger than 4K, we may fail do deliver notifications.
- * Main dispatcher function should run in atomic context.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static void
-HgfsRequestAsyncShmemDispatch(HgfsAsyncIov *iov, // IN: request vectors
- uint32 count) // IN: number of iovs
-{
- uint32 i;
- char *buf = NULL;
- uint32 size = 0;
- Bool chainStarted = FALSE;
- uint32 offset = 0;
- uint32 copySize;
- uint64 prevIndex = -1;
- uint64 currIndex;
- size_t va;
-
- LOG(10, (KERN_WARNING "%s count = %u\n",__FUNCTION__, count));
-
- /*
- * When requests cross 4K boundary we have to chain pages together
- * since guest passes 4k pages to the host. Here is how chaining works
- *
- * - All the vectors except the last one in the chain sets iov[].chain
- * to TRUE.
- * - Every iov[].len field indicates remaining bytes. So the first
- * vector will contain total size of the request while the last vector
- * will contain only size of data present in last vector.
- */
-
- for (i = 0; i < count; i++) {
- va = (size_t)iov[i].va;
- currIndex = iov[i].index;
-
- if (LIKELY(!iov[i].chain)) {
- /* When the chain ends we dispatch the datagram.*/
- if (!chainStarted) {
- buf = (char *)va;
- LOG(8, (KERN_WARNING " Chain wasn't started...\n"));
- size = iov[i].len;
- } else {
- memcpy(buf + offset, (char *)va, iov[i].len);
- }
- ASSERT(buf && size);
- HgfsRequestAsyncDispatch(buf, size);
- if (chainStarted) {
- /* Well chain just ended, we shall free the buffer. */
- chainStarted = FALSE;
- kfree(buf);
- }
- } else {
- if (!chainStarted) {
- LOG(8, (KERN_WARNING "Started chain ...\n"));
- size = iov[i].len;
- buf = kmalloc(size, GFP_ATOMIC);
- ASSERT_DEVEL(buf);
- if (!buf) {
- /* Skip this notification, move onto next. */
- i += (size - 1) / PAGE_SIZE;
- continue;
- }
- chainStarted = TRUE;
- offset = 0;
- }
- copySize = MIN(iov[i].len, PAGE_SIZE);
- memcpy(buf + offset, (char *)va, copySize);
- offset += copySize;
- }
-
- if (currIndex != prevIndex) {
- /* This is new page. Mark is as free. */
- gHgfsShmemPages.list[currIndex].free = TRUE;
- gHgfsShmemPages.freePageCount++;
- }
- prevIndex = currIndex;
- }
-
- ASSERT(gHgfsShmemPages.freePageCount <= gHgfsShmemPages.totalPageCount);
- LOG(8, (KERN_WARNING "Page count %u %u ...\n", gHgfsShmemPages.freePageCount,
- gHgfsShmemPages.totalPageCount));
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelPassGuestPages --
- *
- * Passes down free pages to the hgfs Server. HgfsServer will use this pages
- * for sending change notification, oplock breaks etc.
- *
- * XXX It seems safe to call vmci_datagram_send in atomic context.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-HgfsVmciChannelPassGuestPages(HgfsTransportChannel *channel) // IN:
-{
- Bool retVal = TRUE;
- int ret;
- int i;
- int j = 0;
- size_t transportHeaderSize;
- HgfsVmciTransportHeader *transportHeader = NULL;
- HgfsVmciHeaderNode *headerNode;
- VMCIDatagram *dg;
-
- if (!gHgfsShmemPages.freePageCount) {
- return TRUE;
- }
-
- transportHeaderSize = sizeof (HgfsVmciTransportHeader) +
- (gHgfsShmemPages.freePageCount - 1) * sizeof (HgfsAsyncIov);
-
- dg = kmalloc(sizeof *dg + transportHeaderSize, GFP_ATOMIC);
- if (!dg) {
- LOG(4, (KERN_WARNING "%s failed to allocate\n", __func__));
- retVal = FALSE;
- goto exit;
- }
-
- transportHeader = VMCI_DG_PAYLOAD(dg);
- headerNode = &transportHeader->node;
-
- for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) {
- if (gHgfsShmemPages.list[i].free) {
- transportHeader->asyncIov[j].index = i;
- transportHeader->asyncIov[j].va = gHgfsShmemPages.list[i].va;
- transportHeader->asyncIov[j].pa = gHgfsShmemPages.list[i].pa;
- transportHeader->asyncIov[j].len = PAGE_SIZE;
- j++;
- }
- }
-
- dg->src = *(VMCIHandle *)channel->priv;
- dg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_HGFS_TRANSPORT);
- dg->payloadSize = transportHeaderSize;
-
- headerNode->version = HGFS_VMCI_VERSION_1;
- headerNode->pktType = HGFS_TH_REP_GET_PAGES;
-
- ASSERT(gHgfsShmemPages.freePageCount == j);
- transportHeader->iovCount = j;
-
- LOG(10, (KERN_WARNING "Sending %d Guest pages \n", i));
- if ((ret = vmci_datagram_send(dg)) < VMCI_SUCCESS) {
- if (ret == HGFS_VMCI_TRANSPORT_ERROR) {
- LOG(0, (KERN_WARNING "HGFS Transport error occured. Don't blame VMCI\n"));
- }
- retVal = FALSE;
- }
-
-exit:
- if (retVal) {
- /* We successfully sent pages the the host. Mark all pages as allocated */
- for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) {
- gHgfsShmemPages.list[i].free = FALSE;
- }
- gHgfsShmemPages.freePageCount = 0;
- }
- kfree(dg);
- return retVal;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelCompleteRequest --
- *
- * Completes the request that was serviced asynchronously by the server.
- *
- * Results:
- * None
- *
- * Side effects:
- * Request may be removed from the queue and sleeping thread is woken up.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-HgfsVmciChannelCompleteRequest(uint64 id) // IN: Request ID
-{
- HgfsVmciTransportStatus *transportStatus;
- HgfsReq *req;
-
- spin_lock_bh(&vmciRequestProcessLock);
-
- /* Reference is taken here */
- req = HgfsTransportGetPendingRequest(id);
- if (!req) {
- LOG(0, (KERN_WARNING "No request with id %"FMT64"u \n", id));
- goto exit;
- }
-
- transportStatus = (HgfsVmciTransportStatus *)req->buffer;
- if (transportStatus->status != HGFS_TS_IO_COMPLETE) {
- LOG(0, (KERN_WARNING "Request not completed with id %"FMT64"u \n", id));
- goto exit;
- }
-
- /* Request is completed (yay!), let's remove it from the list */
- HgfsTransportRemovePendingRequest(req);
-
- req->payloadSize = transportStatus->size;
- HgfsCompleteReq(req);
-
-exit:
- if (req) {
- /* Drop the reference taken in *GetPendingRequest */
- HgfsRequestPutRef(req);
- }
- spin_unlock_bh(&vmciRequestProcessLock);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelCallback --
- *
- * Called when VMCI datagram is received. Note: This function runs inside
- * tasklet. It means that this function cannot run concurrently with
- * itself, thus it is safe to manipulate gHgfsShmemPages without locks. If this
- * ever changes, please consider using appropriate locks.
- *
- * Results:
- * 0 on Success, < 0 on Failure.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static int HgfsVmciChannelCallback(void *data, // IN: unused
- VMCIDatagram *dg) // IN: datagram
-{
- HgfsVmciAsyncReply *reply = (HgfsVmciAsyncReply *)VMCI_DG_PAYLOAD(dg);
- HgfsVmciHeaderNode *replyNode = &reply->node;
- HgfsTransportChannel *channel;
-
- LOG(10, (KERN_WARNING "Received VMCI channel Callback \n"));
-
- if (replyNode->version != HGFS_VMCI_VERSION_1) {
- return HGFS_VMCI_VERSION_MISMATCH;
- }
-
- switch (replyNode->pktType) {
-
- case HGFS_ASYNC_IOREP:
- LOG(10, (KERN_WARNING "Received ID%"FMT64"x \n", reply->response.id));
- HgfsVmciChannelCompleteRequest(reply->response.id);
- break;
-
- case HGFS_ASYNC_IOREQ_SHMEM:
- HgfsRequestAsyncShmemDispatch(reply->shmem.iov, reply->shmem.count);
- break;
-
- case HGFS_ASYNC_IOREQ_GET_PAGES:
- channel = HgfsGetVmciChannel();
- LOG(10, (KERN_WARNING "Should send pages to the host\n"));
- HgfsVmciChannelPassGuestPages(channel);
- break;
-
- default:
- ASSERT(0);
- return HGFS_VMCI_TRANSPORT_ERROR;
- }
-
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelOpen --
- *
- * Opens VMCI channel and passes guest pages to the host.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-HgfsVmciChannelOpen(HgfsTransportChannel *channel) // IN: Channel
-{
- int ret;
- int i;
-
- ASSERT(channel->status == HGFS_CHANNEL_NOTCONNECTED);
- ASSERT(channel->priv == NULL);
- memset(&gHgfsShmemPages, 0, sizeof gHgfsShmemPages);
-
- if (USE_VMCI == 0) {
- goto error;
- }
-
- spin_lock_init(&vmciRequestProcessLock);
-
- channel->priv = kmalloc(sizeof(VMCIHandle), GFP_KERNEL);
- if (!channel->priv) {
- goto error;
- }
-
- ret = vmci_datagram_create_handle(
- VMCI_INVALID_ID, /* Resource ID */
- VMCI_FLAG_DG_NONE, /* Flags */
- HgfsVmciChannelCallback,/* Datagram Recv Callback */
- NULL, /* Callback data */
- channel->priv); /* VMCI outhandle */
- if (ret != VMCI_SUCCESS) {
- LOG(1, (KERN_WARNING "Failed to create VMCI handle %d\n", ret));
- goto error;
- }
-
- gHgfsShmemPages.list = kmalloc(sizeof *gHgfsShmemPages.list * HGFS_VMCI_SHMEM_PAGES,
- GFP_KERNEL);
- if (!gHgfsShmemPages.list) {
- goto error;
- }
-
- memset(gHgfsShmemPages.list, 0, sizeof *gHgfsShmemPages.list * HGFS_VMCI_SHMEM_PAGES);
-
- for (i = 0; i < HGFS_VMCI_SHMEM_PAGES; i++) {
- gHgfsShmemPages.list[i].va = __get_free_page(GFP_KERNEL);
- if (!gHgfsShmemPages.list[i].va) {
- LOG(1, (KERN_WARNING "__get_free_page returned error \n"));
- if (i == 0) {
- /* Ouch. We failed on first call to __get_free_page */
- goto error;
- }
- /* It's ok. We can still send few pages to the host */
- break;
- }
- gHgfsShmemPages.list[i].pa = virt_to_phys((void *)(size_t)gHgfsShmemPages.list[i].va);
- gHgfsShmemPages.list[i].free = TRUE;
- }
-
- gHgfsShmemPages.totalPageCount = i;
- gHgfsShmemPages.freePageCount = i;
-
- ret = HgfsVmciChannelPassGuestPages(channel);
- if (!ret) {
- for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) {
- LOG(1, (KERN_WARNING "Freeing pages\n"));
- free_page(gHgfsShmemPages.list[i].va);
- }
- LOG(1, (KERN_WARNING "Failed to pass pages to the guest %d\n", ret));
- goto error;
- }
-
- return TRUE;
-
-error:
- kfree(gHgfsShmemPages.list);
- kfree(channel->priv);
- return FALSE;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelTerminateSession --
- *
- * Terminate session with the server.
- *
- * Results:
- * 0 on success and < 0 on error.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVmciChannelTerminateSession(HgfsTransportChannel *channel) {
-
- int ret = 0;
- VMCIDatagram *dg;
- HgfsVmciTransportHeader *transportHeader;
- HgfsVmciHeaderNode *headerNode;
-
- dg = kmalloc(sizeof *dg + sizeof *transportHeader, GFP_KERNEL);
- if (NULL == dg) {
- LOG(4, (KERN_WARNING "%s failed to allocate\n", __func__));
- return -ENOMEM;
- }
-
- /* Initialize datagram */
- dg->src = *(VMCIHandle *)channel->priv;
- dg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_HGFS_TRANSPORT);
- dg->payloadSize = sizeof *transportHeader;
-
- transportHeader = VMCI_DG_PAYLOAD(dg);
- headerNode = &transportHeader->node;
-
- headerNode->pktType = HGFS_TH_TERMINATE_SESSION;
- headerNode->version = HGFS_VMCI_VERSION_1;
-
- transportHeader->iovCount = 0;
-
- LOG(1, (KERN_WARNING "Terminating session with host \n"));
- if ((ret = vmci_datagram_send(dg)) < VMCI_SUCCESS) {
- if (ret == HGFS_VMCI_TRANSPORT_ERROR) {
- LOG(0, (KERN_WARNING "HGFS Transport error occured. Don't blame VMCI\n"));
- }
- LOG(0, (KERN_WARNING "Cannot communicate with Server.\n"));
- } else {
- int i;
- for (i = 0; i < gHgfsShmemPages.totalPageCount; i++) {
- free_page(gHgfsShmemPages.list[i].va);
- }
- }
-
- kfree(dg);
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelClose --
- *
- * Destroy vmci handle.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-HgfsVmciChannelClose(HgfsTransportChannel *channel) // IN: Channel
-{
- ASSERT(channel->priv != NULL);
- HgfsVmciChannelTerminateSession(channel);
- vmci_datagram_destroy_handle(*(VMCIHandle *)channel->priv);
- kfree(channel->priv);
- kfree(gHgfsShmemPages.list);
- channel->priv = NULL;
-
- LOG(8, ("VMware hgfs: %s: vmci closed.\n", __func__));
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelAllocate --
- *
- * Allocate request in the way that is suitable for sending through
- * vmci. Today, we just allocate a page for the request and we ignore
- * payloadSize. We need this to support variable sized requests in future.
- *
- * Results:
- * NULL on failure; otherwise address of the new request.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static HgfsReq *
-HgfsVmciChannelAllocate(size_t payloadSize) // IN: Ignored
-{
- HgfsReq *req = NULL;
- const size_t size = PAGE_SIZE;
-
- req = kmalloc(size, GFP_KERNEL);
- if (likely(req)) {
- req->payload = req->buffer + sizeof (HgfsVmciTransportStatus);
- req->bufferSize = size - sizeof (HgfsVmciTransportStatus) - sizeof *req;
- }
-
- LOG(10, (KERN_WARNING "%s: Allocated Request\n", __func__));
- return req;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVmciChannelFree --
- *
- * Free previously allocated request.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-HgfsVmciChannelFree(HgfsReq *req)
-{
- ASSERT(req);
- kfree(req);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsVmciChannelSend --
- *
- * Send a request via vmci.
- *
- * Results:
- * 0 on success, negative error on failure.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static int
-HgfsVmciChannelSend(HgfsTransportChannel *channel, // IN: Channel
- HgfsReq *req) // IN: request to send
-{
- int ret;
- int iovCount = 0;
- VMCIDatagram *dg;
- HgfsVmciTransportHeader *transportHeader;
- HgfsVmciHeaderNode *headerNode;
- HgfsVmciTransportStatus *transportStatus;
- size_t transportHeaderSize;
- size_t bufferSize;
- size_t total;
- uint64 pa;
- uint64 len;
- uint64 id;
- int j;
-
- ASSERT(req);
- ASSERT(req->buffer);
- ASSERT(req->state == HGFS_REQ_STATE_UNSENT || req->state == HGFS_REQ_STATE_ALLOCATED);
- ASSERT(req->payloadSize <= req->bufferSize);
-
- /* Note that req->bufferSize does not include chunk used by the transport. */
- total = req->bufferSize + sizeof (HgfsVmciTransportStatus);
-
- /* Calculate number of entries for metaPacket */
- iovCount = (total + (size_t)req->buffer % PAGE_SIZE - 1)/ PAGE_SIZE + 1;
- ASSERT(total + (size_t)req->buffer % PAGE_SIZE <= PAGE_SIZE);
-
- transportHeaderSize = sizeof *transportHeader +
- (iovCount + req->numEntries - 1) * sizeof (HgfsIov);
- dg = kmalloc(sizeof *dg + transportHeaderSize, GFP_KERNEL);
- if (NULL == dg) {
- LOG(4, (KERN_WARNING "%s failed to allocate\n", __func__));
- return -ENOMEM;
- }
-
- /* Initialize datagram */
- dg->src = *(VMCIHandle *)channel->priv;
- dg->dst = VMCI_MAKE_HANDLE(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_HGFS_TRANSPORT);
- dg->payloadSize = transportHeaderSize;
-
- transportHeader = VMCI_DG_PAYLOAD(dg);
- headerNode = &transportHeader->node;
-
- headerNode->version = HGFS_VMCI_VERSION_1;
- headerNode->pktType = HGFS_TH_REQUEST;
-
- total = req->bufferSize + sizeof (HgfsVmciTransportStatus);
- bufferSize = 0;
- for (iovCount = 0; bufferSize < req->bufferSize; iovCount++) {
- /*
- * req->buffer should have been allocated by kmalloc()/ __get_free_pages().
- * Specifically, it cannot be a buffer that is mapped from high memory.
- * virt_to_phys() does not work for those.
- */
- pa = virt_to_phys(req->buffer + bufferSize);
- len = total < (PAGE_SIZE - pa % PAGE_SIZE) ? total : (PAGE_SIZE - pa % PAGE_SIZE);
- bufferSize += len;
- total -= len;
- transportHeader->iov[iovCount].pa = pa;
- transportHeader->iov[iovCount].len = len;
- LOG(8, ("iovCount = %u PA = %"FMT64"x len=%u\n", iovCount,
- transportHeader->iov[iovCount].pa, transportHeader->iov[iovCount].len));
- }
-
- /* Right now we do not expect discontigous request packet */
- ASSERT(iovCount == 1);
- ASSERT(total == 0);
- ASSERT(bufferSize == req->bufferSize + sizeof (HgfsVmciTransportStatus));
-
- LOG(0, (KERN_WARNING "Size of request is %Zu\n", req->payloadSize));
-
- for (j = 0; j < req->numEntries; j++, iovCount++) {
- /* I will have to probably do page table walk here, haven't figured it out yet */
- ASSERT(req->dataPacket);
- transportHeader->iov[iovCount].pa = page_to_phys(req->dataPacket[j].page);
- transportHeader->iov[iovCount].pa += req->dataPacket[j].offset;
- transportHeader->iov[iovCount].len = req->dataPacket[j].len;
- LOG(8, ("iovCount = %u PA = %"FMT64"x len=%u\n", iovCount,
- transportHeader->iov[iovCount].pa,
- transportHeader->iov[iovCount].len));
- }
-
- transportHeader->iovCount = iovCount;
-
- /* Initialize transport Status */
- transportStatus = (HgfsVmciTransportStatus *)req->buffer;
- transportStatus->status = HGFS_TS_IO_PENDING;
- transportStatus->size = req->bufferSize + sizeof (HgfsVmciTransportStatus);
-
- /*
- * Don't try to set req->state after vmci_datagram_send().
- * It may be too late then. We could have received a datagram by then and
- * datagram handler expects request's state to be submitted.
- */
- req->state = HGFS_REQ_STATE_SUBMITTED;
- id = req->id;
-
- if ((ret = vmci_datagram_send(dg)) < VMCI_SUCCESS) {
- if (ret == HGFS_VMCI_TRANSPORT_ERROR) {
- LOG(0, (KERN_WARNING "HGFS Transport error occured. Don't blame VMCI\n"));
- } else if (ret == HGFS_VMCI_VERSION_MISMATCH) {
- LOG(0, (KERN_WARNING "Version mismatch\n"));
- }
- req->state = HGFS_REQ_STATE_UNSENT;
- kfree(dg);
- return -EIO;
- }
-
- LOG(0, (KERN_WARNING "Hgfs Received response\n"));
- HgfsVmciChannelCompleteRequest(id);
-
- kfree(dg);
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsGetVmciChannel --
- *
- * Initialize Vmci channel.
- *
- * Results:
- * Always return pointer to Vmci channel.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-HgfsTransportChannel*
-HgfsGetVmciChannel(void)
-{
- return &channel;
-}
diff --git a/open-vm-tools/modules/linux/vmhgfs/vmhgfs_version.h b/open-vm-tools/modules/linux/vmhgfs/vmhgfs_version.h
index 1ed35935..c5f19dcc 100644
--- a/open-vm-tools/modules/linux/vmhgfs/vmhgfs_version.h
+++ b/open-vm-tools/modules/linux/vmhgfs/vmhgfs_version.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2015 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmsync/Makefile b/open-vm-tools/modules/linux/vmsync/Makefile
index 4d81760c..3c681a36 100644
--- a/open-vm-tools/modules/linux/vmsync/Makefile
+++ b/open-vm-tools/modules/linux/vmsync/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmxnet/Makefile b/open-vm-tools/modules/linux/vmxnet/Makefile
index 4264b475..1c1bfd80 100644
--- a/open-vm-tools/modules/linux/vmxnet/Makefile
+++ b/open-vm-tools/modules/linux/vmxnet/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vmxnet/vmxnet.c b/open-vm-tools/modules/linux/vmxnet/vmxnet.c
index 54b4590c..33afb9b9 100644
--- a/open-vm-tools/modules/linux/vmxnet/vmxnet.c
+++ b/open-vm-tools/modules/linux/vmxnet/vmxnet.c
@@ -80,10 +80,6 @@ static int vmxnet_close(struct net_device *dev);
static void vmxnet_set_multicast_list(struct net_device *dev);
static int vmxnet_set_mac_address(struct net_device *dev, void *addr);
static struct net_device_stats *vmxnet_get_stats(struct net_device *dev);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
-static int vmxnet_set_features(struct net_device *netdev, compat_netdev_features_t
- features);
-#endif
#if defined(HAVE_CHANGE_MTU) || defined(HAVE_NET_DEVICE_OPS)
static int vmxnet_change_mtu(struct net_device *dev, int new_mtu);
#endif
@@ -992,14 +988,18 @@ vmxnet_probe_device(struct pci_dev *pdev, // IN: vmxnet PCI device
const struct pci_device_id *id) // IN: matching device ID
{
#ifdef HAVE_NET_DEVICE_OPS
+ /*
+ * .ndo_set_features not required as existing initialization
+ * takes care of the necessary checks. The init routine appropriately
+ * sets netdev->hw_features after validating the device capabilities.
+ * ndo_set_features only required if driver is changing
+ * any other intenal variables besides the netdev->features.
+ */
static const struct net_device_ops vmxnet_netdev_ops = {
.ndo_open = &vmxnet_open,
.ndo_start_xmit = &vmxnet_start_tx,
.ndo_stop = &vmxnet_close,
.ndo_get_stats = &vmxnet_get_stats,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
- .ndo_set_features = vmxnet_set_features,
-#endif
#if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0)
.ndo_set_multicast_list = &vmxnet_set_multicast_list,
#else
@@ -1315,6 +1315,11 @@ vmxnet_probe_features(struct net_device *dev, // IN:
}
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+ dev->features |= NETIF_F_RXCSUM;
+ printk( " rxCsum");
+#endif
+
#ifdef VMXNET_DO_ZERO_COPY
if (lp->capabilities & VMNET_CAP_SG &&
lp->features & VMXNET_FEATURE_ZERO_COPY_TX){
@@ -1362,6 +1367,10 @@ vmxnet_probe_features(struct net_device *dev, // IN:
#endif
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+ dev->hw_features = dev->features & (~NETIF_F_RXCSUM);
+#endif
+
printk("\n");
/* check if this is enhanced vmxnet device */
@@ -3119,20 +3128,6 @@ vmxnet_get_stats(struct net_device *dev)
return &lp->stats;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
-static int
-vmxnet_set_features(struct net_device *netdev, compat_netdev_features_t features)
-{
- compat_netdev_features_t changed = features ^ netdev->features;
-
- if (changed & (NETIF_F_RXCSUM)) {
- if (features & NETIF_F_RXCSUM)
- return 0;
- }
- return -1;
-}
-#endif
-
module_init(vmxnet_init);
module_exit(vmxnet_exit);
MODULE_DEVICE_TABLE(pci, vmxnet_chips);
diff --git a/open-vm-tools/modules/linux/vmxnet/vmxnet_version.h b/open-vm-tools/modules/linux/vmxnet/vmxnet_version.h
index a58bb408..fe2ad538 100644
--- a/open-vm-tools/modules/linux/vmxnet/vmxnet_version.h
+++ b/open-vm-tools/modules/linux/vmxnet/vmxnet_version.h
@@ -25,8 +25,8 @@
#ifndef _VMXNET_VERSION_H_
#define _VMXNET_VERSION_H_
-#define VMXNET_DRIVER_VERSION 2.0.15.0
-#define VMXNET_DRIVER_VERSION_COMMAS 2,0,15,0
-#define VMXNET_DRIVER_VERSION_STRING "2.0.15.0"
+#define VMXNET_DRIVER_VERSION 2.1.0.0
+#define VMXNET_DRIVER_VERSION_COMMAS 2,1,0,0
+#define VMXNET_DRIVER_VERSION_STRING "2.1.0.0"
#endif /* _VMXNET_VERSION_H_ */
diff --git a/open-vm-tools/modules/linux/vsock/Makefile b/open-vm-tools/modules/linux/vsock/Makefile
index 852c9345..7549fa50 100644
--- a/open-vm-tools/modules/linux/vsock/Makefile
+++ b/open-vm-tools/modules/linux/vsock/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 1998 VMware, Inc. All rights reserved.
+# Copyright (C) 1998-2015 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
diff --git a/open-vm-tools/modules/linux/vsock/Makefile.kernel b/open-vm-tools/modules/linux/vsock/Makefile.kernel
index b4629eee..5218df2f 100644
--- a/open-vm-tools/modules/linux/vsock/Makefile.kernel
+++ b/open-vm-tools/modules/linux/vsock/Makefile.kernel
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 2007 VMware, Inc. All rights reserved.
+# Copyright (C) 2007,2014 VMware, Inc. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -64,9 +64,9 @@ clean:
prebuild::
ifneq ($(MODULEBUILDDIR),)
ifeq ($(MODPOST_VMCI_SYMVERS),)
- $(shell echo >&2 "Building VMCI Sockets without VMCI module symbols.")
+ $(shell echo >&2 "Building vSockets without VMCI module symbols.")
else
- $(shell echo >&2 "Building VMCI Sockets with VMCI module symbols.")
+ $(shell echo >&2 "Building vSockets with VMCI module symbols.")
cp -f $(MODPOST_VMCI_SYMVERS) $(SRCROOT)/Module.symvers
endif
endif
diff --git a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c
index e278e152..bde14970 100644
--- a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c
+++ b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007-2011 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -19,7 +19,7 @@
/*
* af_vsock.c --
*
- * Linux socket module for the VMCI Sockets protocol family.
+ * Linux socket module for the vSockets protocol family.
*/
@@ -591,7 +591,7 @@ VSockVmciAllowDgram(VSockVmciSock *vsock, // IN: Local socket
* VMCISock_GetAFValue --
*
* Kernel interface that allows external kernel modules to get the current
- * VMCI Sockets address family.
+ * vSockets address family.
* This version of the function is exported to kernel clients and should not
* change.
*
@@ -613,7 +613,7 @@ VMCISock_GetAFValue(void)
/*
* Kernel clients are required to explicitly register themselves before they
- * can use VMCI Sockets.
+ * can use vSockets.
*/
if (vsockVmciKernClientCount <= 0) {
afvalue = -1;
@@ -657,7 +657,7 @@ VMCISock_GetLocalCID(void)
/*
* Kernel clients are required to explicitly register themselves before they
- * can use VMCI Sockets.
+ * can use vSockets.
*/
if (vsockVmciKernClientCount <= 0) {
cid = -1;
@@ -678,7 +678,7 @@ EXPORT_SYMBOL(VMCISock_GetLocalCID);
*
* VMCISock_KernelRegister --
*
- * Allows a kernel client to register with VMCI Sockets. Must be called
+ * Allows a kernel client to register with vSockets. Must be called
* before VMCISock_GetAFValue within a kernel module. Note that we don't
* actually register the address family until the first time the module
* needs to use it.
@@ -707,7 +707,7 @@ EXPORT_SYMBOL(VMCISock_KernelRegister);
*
* VMCISock_KernelDeregister --
*
- * Allows a kernel client to unregister with VMCI Sockets. Every call
+ * Allows a kernel client to unregister with vSockets. Every call
* to VMCISock_KernRegister must be matched with a call to
* VMCISock_KernUnregister.
*
@@ -3080,7 +3080,7 @@ VSockVmciQueueRcvSkb(struct sock *sk, // IN
*
* VSockVmciRegisterProto --
*
- * Registers the vmci sockets protocol family.
+ * Registers the vSockets protocol family.
*
* Results:
* Zero on success, error code on failure.
@@ -3124,7 +3124,7 @@ VSockVmciRegisterProto(void)
*
* VSockVmciUnregisterProto --
*
- * Unregisters the vmci sockets protocol family.
+ * Unregisters the vSockets protocol family.
*
* Results:
* None.
diff --git a/open-vm-tools/modules/linux/vsock/linux/af_vsock.h b/open-vm-tools/modules/linux/vsock/linux/af_vsock.h
index 30600ae5..08e437d0 100644
--- a/open-vm-tools/modules/linux/vsock/linux/af_vsock.h
+++ b/open-vm-tools/modules/linux/vsock/linux/af_vsock.h
@@ -60,7 +60,11 @@ typedef struct VSockVmciSock {
Bool trusted;
Bool cachedPeerAllowDgram; /* Dgram communication allowed to cached peer? */
VMCIId cachedPeer; /* Context ID of last dgram destination check. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
+ kuid_t owner;
+#else
uid_t owner;
+#endif
VMCIHandle dgHandle; /* For SOCK_DGRAM only. */
/* Rest are SOCK_STREAM only. */
VMCIHandle qpHandle;
diff --git a/open-vm-tools/modules/linux/vsock/linux/stats.h b/open-vm-tools/modules/linux/vsock/linux/stats.h
index b47b3552..c42f5757 100644
--- a/open-vm-tools/modules/linux/vsock/linux/stats.h
+++ b/open-vm-tools/modules/linux/vsock/linux/stats.h
@@ -68,9 +68,9 @@ extern Atomic_uint64 vSockStatsProduceTotal;
++vSockStatsCtlPktCount[pktType]; \
} while (0)
#define VSOCK_STATS_STREAM_CONSUME(bytes) \
- Atomic_FetchAndAdd64(&vSockStatsConsumeTotal, bytes)
+ Atomic_ReadAdd64(&vSockStatsConsumeTotal, bytes)
#define VSOCK_STATS_STREAM_PRODUCE(bytes) \
- Atomic_FetchAndAdd64(&vSockStatsProduceTotal, bytes)
+ Atomic_ReadAdd64(&vSockStatsProduceTotal, bytes)
#define VSOCK_STATS_CTLPKT_DUMP_ALL() VSockVmciStatsCtlPktDumpAll()
#define VSOCK_STATS_HIST_DUMP_ALL() VSockVmciStatsHistDumpAll()
#define VSOCK_STATS_TOTALS_DUMP_ALL() VSockVmciStatsTotalsDumpAll()
diff --git a/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_int.h b/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_int.h
index 4c5d9904..91654c34 100644
--- a/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_int.h
+++ b/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_int.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -19,7 +19,7 @@
/*
* vmci_sockets_int.h --
*
- * VMCI sockets private constants and types.
+ * vSockets private constants and types.
*
* This file is internal only, we do not ship the kernel interface yet.
* You need to include this file *before* vmci_sockets.h in your kernel
diff --git a/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_packet.h b/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_packet.h
index 603835b5..abc42ade 100644
--- a/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_packet.h
+++ b/open-vm-tools/modules/linux/vsock/linux/vmci_sockets_packet.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2012 VMware, Inc. All rights reserved.
+ * Copyright (C) 2012,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -19,7 +19,7 @@
/*
* vmci_sockets_packet.h --
*
- * Definition of VMCI Sockets packet format, constants, and types.
+ * Definition of vSockets packet format, constants, and types.
*/
#ifndef _VMCI_SOCKETS_PACKET_H_
@@ -108,51 +108,11 @@ typedef struct VSockPacket {
} VSockPacket;
/*
- * SEQPACKET packets.
- */
-
-#define VSOCK_SEQ_PACKET_VERSION_1 1
-#define VSOCK_SEQ_PACKET_VERSION VSOCK_SEQ_PACKET_VERSION_1
-
-/* Get the packet's payload size in bytes. */
-#define VSOCK_SEQ_PACKET_PAYLOAD_SIZE(_pkt) \
- (VMCI_DG_SIZE(&(_pkt)->hdr.dg) - (_pkt)->hdr.offset)
-
-/* Get a pointer to the packet's payload. */
-#define VSOCK_SEQ_PACKET_PAYLOAD(_pkt) \
- (void *)((char *)_pkt + (_pkt)->hdr.offset)
-
-typedef enum VSockSeqPacketType {
- VSOCK_SEQ_PACKET_TYPE_INVALID = 0, // Invalid type.
- VSOCK_SEQ_PACKET_TYPE_CONNECT, // Connection request.
- VSOCK_SEQ_PACKET_TYPE_DATA, // Data.
- VSOCK_SEQ_PACKET_TYPE_SHUTDOWN, // Shutdown.
- VSOCK_SEQ_PACKET_TYPE_CLOSE, // Close (graceful or error).
-} VSockSeqPacketType;
-
-/* Header for all packet versions. */
-typedef struct VSockSeqPacketHdr {
- VMCIDatagram dg; // Datagram header.
- uint8 version; // Version.
- uint8 type; // Type of message.
- uint16 offset; // Offset of data from start of packet.
- int32 val; // Value.
-} VSockSeqPacketHdr;
-
-/* Combination of all versions. */
-typedef struct VSockSeqPacket {
- VSockSeqPacketHdr hdr;
- /* Other versions go here. */
- /* Data is at base + hdr.offset. */
-} VSockSeqPacket;
-
-/*
* Size assertions.
*/
MY_ASSERTS(VSockSeqPacketAsserts,
ASSERT_ON_COMPILE(sizeof (VSockPacket) == 56);
- ASSERT_ON_COMPILE(sizeof (VSockSeqPacket) == 32);
)
#endif // _VMCI_SOCKETS_PACKET_H_
diff --git a/open-vm-tools/modules/linux/vsock/linux/vsockCommon.h b/open-vm-tools/modules/linux/vsock/linux/vsockCommon.h
index 745c8474..f86f2148 100644
--- a/open-vm-tools/modules/linux/vsock/linux/vsockCommon.h
+++ b/open-vm-tools/modules/linux/vsock/linux/vsockCommon.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007,2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -31,7 +31,7 @@
* it is used in several different contexts. In particular it is called from
* vsockAddr.c which gets compiled into both our kernel modules as well as
* the user level vsock library. In the linux kernel we need different behavior
- * than external kernel modules using VMCI Sockets api inside the kernel.
+ * than external kernel modules using vSockets API inside the kernel.
*/
#if defined VMX86_VMX
@@ -51,7 +51,7 @@
/* In the kernel we can't call into the provider. */
# define VMCISockGetAFValueInt() VMCI_SOCKETS_AF_VALUE
# else // WINNT_DDK
- /* In userland, just use the normal exported userlevel api. */
+ /* In userland, just use the normal exported userlevel API. */
# define VMCISockGetAFValueInt() VMCISock_GetAFValue()
# include <windows.h>
# endif // WINNT_DDK
@@ -72,7 +72,7 @@
extern int VSockVmci_GetAFValue(void);
# define VMCISockGetAFValueInt() VSockVmci_GetAFValue()
# else // __KERNEL__
- /* In userland, just use the normal exported userlevel api. */
+ /* In userland, just use the normal exported userlevel API. */
# define VMCISockGetAFValueInt() VMCISock_GetAFValue()
# endif
#elif defined __APPLE__
@@ -189,7 +189,7 @@ __declspec(selectany) extern const WSAPROTOCOL_INFOW vsockProtocolInfos[] = {
0, /* Assigned by Winsock. */
{ 1, 0 }, /* Base provider. */
0, /* Version 0. */
- VMCI_SOCKETS_AF_VALUE, /* VMCI sockets protocol. */
+ VMCI_SOCKETS_AF_VALUE, /* vSockets protocol. */
16, /* Maximum address length in bytes. */
16, /* Minimum address length in bytes. */
SOCK_DGRAM, /* STREAM. */
@@ -199,7 +199,7 @@ __declspec(selectany) extern const WSAPROTOCOL_INFOW vsockProtocolInfos[] = {
SECURITY_PROTOCOL_NONE, /* No security. */
0, /* Message size unimportant. */
0, /* None. */
- L"VMCI sockets DGRAM" /* Protocol name. */
+ L"vSockets DGRAM" /* Protocol name. */
},
{
(XP1_GUARANTEED_DELIVERY | /* Guaranteed delivery. */
@@ -213,7 +213,7 @@ __declspec(selectany) extern const WSAPROTOCOL_INFOW vsockProtocolInfos[] = {
0, /* Assigned by Winsock. */
{ 1, 0 }, /* Base provider. */
0, /* Version 0. */
- VMCI_SOCKETS_AF_VALUE, /* VMCI sockets protocol. */
+ VMCI_SOCKETS_AF_VALUE, /* vSockets protocol. */
16, /* Maximum address length in bytes. */
16, /* Minimum address length in bytes. */
SOCK_STREAM, /* STREAM. */
@@ -223,7 +223,7 @@ __declspec(selectany) extern const WSAPROTOCOL_INFOW vsockProtocolInfos[] = {
SECURITY_PROTOCOL_NONE, /* No security. */
0, /* Message size unimportant. */
0, /* None. */
- L"VMCI sockets STREAM" /* Protocol name. */
+ L"vSockets STREAM" /* Protocol name. */
},
};
diff --git a/open-vm-tools/modules/linux/vsock/linux/vsock_version.h b/open-vm-tools/modules/linux/vsock/linux/vsock_version.h
index ae39173a..f46bf539 100644
--- a/open-vm-tools/modules/linux/vsock/linux/vsock_version.h
+++ b/open-vm-tools/modules/linux/vsock/linux/vsock_version.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2011-2013 VMware, Inc. All rights reserved.
+ * Copyright (C) 2011-2014 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -25,8 +25,8 @@
#ifndef _VSOCK_VERSION_H_
#define _VSOCK_VERSION_H_
-#define VSOCK_DRIVER_VERSION 9.6.0.0
-#define VSOCK_DRIVER_VERSION_COMMAS 9,6,0,0
-#define VSOCK_DRIVER_VERSION_STRING "9.6.0.0"
+#define VSOCK_DRIVER_VERSION 9.7.1.0
+#define VSOCK_DRIVER_VERSION_COMMAS 9,7,1,0
+#define VSOCK_DRIVER_VERSION_STRING "9.7.1.0"
#endif /* _VSOCK_VERSION_H_ */