summaryrefslogtreecommitdiff
path: root/open-vm-tools/modules
diff options
context:
space:
mode:
Diffstat (limited to 'open-vm-tools/modules')
-rw-r--r--open-vm-tools/modules/Makefile.in550
-rw-r--r--open-vm-tools/modules/freebsd/shared/compat_freebsd.h3
-rw-r--r--open-vm-tools/modules/freebsd/shared/compat_mount.h3
-rw-r--r--open-vm-tools/modules/freebsd/shared/compat_priv.h3
-rw-r--r--open-vm-tools/modules/freebsd/shared/compat_vop.h3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/COPYING3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/Makefile3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/os.h3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/os_panic.c3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/subr.c3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/vfsops.c5
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/vmblock_k.h3
-rw-r--r--open-vm-tools/modules/freebsd/vmblock/vnops.c16
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/COPYING339
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/Makefile114
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/bdhandler.c236
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/channel.h60
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/debug.c346
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/debug.h104
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/fsutil.c1030
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/fsutil.h196
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/hgfs_kernel.h175
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/kernelStubs.h149
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/kernelStubsBSD.c259
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/os.c928
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/os.h135
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/request.c868
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/request.h88
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/requestInt.h188
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/state.c1780
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/state.h216
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/transport.c389
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/transport.h39
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/vfsops.c477
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/vfsopscommon.c148
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/vnops.c864
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.c3274
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.h94
-rw-r--r--open-vm-tools/modules/freebsd/vmhgfs/worker.c280
-rw-r--r--open-vm-tools/modules/freebsd/vmmemctl/os.c23
-rw-r--r--open-vm-tools/modules/freebsd/vmxnet/net_compat.h5
-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.c (renamed from open-vm-tools/modules/freebsd/vmhgfs/vmci.c)43
-rw-r--r--open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c (renamed from open-vm-tools/modules/freebsd/vmhgfs/vfsopscommon.h)42
-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
-rw-r--r--open-vm-tools/modules/shared/vmblock/block.c3
-rw-r--r--open-vm-tools/modules/shared/vmblock/block.h3
-rw-r--r--open-vm-tools/modules/shared/vmblock/stubs.c3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.c3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.h3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/balloonInt.h3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/balloon_def.h3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/dbllnklst.h5
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/kernelStubs.h176
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/os.h3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/vmballoon.c3
-rw-r--r--open-vm-tools/modules/shared/vmmemctl/vmballoon.h3
-rw-r--r--open-vm-tools/modules/shared/vmxnet/eth_public.h2
-rw-r--r--open-vm-tools/modules/shared/vmxnet/vmnet_def.h107
-rw-r--r--open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h30
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/Makefile2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/debug.c2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/debug.h2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/filesystem.c2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/filesystem.h2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.c3
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.h2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/hgfsSolaris.h3
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/hgfsState.c5
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/hgfsState.h2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/kernelStubs.h173
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/kernelStubsSolaris.c2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/module.c2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/module.h2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/request.c2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/request.h2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/vnode.c2
-rw-r--r--open-vm-tools/modules/solaris/vmhgfs/vnode.h2
-rw-r--r--open-vm-tools/modules/solaris/vmmemctl/kernelStubsSolaris.c2
-rw-r--r--open-vm-tools/modules/solaris/vmxnet3/vmxnet3_main.c112
-rw-r--r--open-vm-tools/modules/solaris/vmxnet3/vmxnet3_solaris.h3
-rw-r--r--open-vm-tools/modules/solaris/vmxnet3/vmxnet3_tx.c21
147 files changed, 2802 insertions, 15219 deletions
diff --git a/open-vm-tools/modules/Makefile.in b/open-vm-tools/modules/Makefile.in
new file mode 100644
index 00000000..9c594ec2
--- /dev/null
+++ b/open-vm-tools/modules/Makefile.in
@@ -0,0 +1,550 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = modules
+DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/vmtools.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__include_HEADERS_DIST = $(top_srcdir)/lib/include/vmci_sockets.h
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(includedir)"
+includeHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_PLUGIN_INSTALLDIR = @COMMON_PLUGIN_INSTALLDIR@
+COMMON_XLIBS = @COMMON_XLIBS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CUNIT_CPPFLAGS = @CUNIT_CPPFLAGS@
+CUNIT_LIBS = @CUNIT_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DNET_CPPFLAGS = @DNET_CPPFLAGS@
+DNET_LIBS = @DNET_LIBS@
+DOT = @DOT@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FUSE_CPPFLAGS = @FUSE_CPPFLAGS@
+FUSE_LIBS = @FUSE_LIBS@
+GLIB2_CPPFLAGS = @GLIB2_CPPFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMODULE_CPPFLAGS = @GMODULE_CPPFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GOBJECT_CPPFLAGS = @GOBJECT_CPPFLAGS@
+GOBJECT_LIBS = @GOBJECT_LIBS@
+GREP = @GREP@
+GTHREAD_CPPFLAGS = @GTHREAD_CPPFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKMM_CPPFLAGS = @GTKMM_CPPFLAGS@
+GTKMM_LIBS = @GTKMM_LIBS@
+GTK_CPPFLAGS = @GTK_CPPFLAGS@
+GTK_LIBS = @GTK_LIBS@
+HAVE_DOT = @HAVE_DOT@
+HAVE_PKG_CONFIG = @HAVE_PKG_CONFIG@
+HGFS_LIBS = @HGFS_LIBS@
+ICU_CPPFLAGS = @ICU_CPPFLAGS@
+ICU_LIBS = @ICU_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTVMSG = @INSTVMSG@
+KERNEL_RELEASE = @KERNEL_RELEASE@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBVMTOOLS_LIBADD = @LIBVMTOOLS_LIBADD@
+LIB_AUTH_CPPFLAGS = @LIB_AUTH_CPPFLAGS@
+LIB_IMPERSONATE_CPPFLAGS = @LIB_IMPERSONATE_CPPFLAGS@
+LIB_USER_CPPFLAGS = @LIB_USER_CPPFLAGS@
+LINUXINCLUDE = @LINUXINCLUDE@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULES = @MODULES@
+MODULES_DIR = @MODULES_DIR@
+MODULES_OS = @MODULES_OS@
+MSCGEN = @MSCGEN@
+MSCGEN_DIR = @MSCGEN_DIR@
+MSPACK_CPPFLAGS = @MSPACK_CPPFLAGS@
+MSPACK_LIBS = @MSPACK_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PAM_CPPFLAGS = @PAM_CPPFLAGS@
+PAM_LIBS = @PAM_LIBS@
+PAM_PREFIX = @PAM_PREFIX@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@
+PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@
+PROCPS_CPPFLAGS = @PROCPS_CPPFLAGS@
+PROCPS_LIBS = @PROCPS_LIBS@
+RANLIB = @RANLIB@
+RPCGEN = @RPCGEN@
+RPCGENFLAGS = @RPCGENFLAGS@
+RPCGEN_WRAPPER = @RPCGEN_WRAPPER@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SSL_CPPFLAGS = @SSL_CPPFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STRIP = @STRIP@
+SYSDIR = @SYSDIR@
+TARGET_OS = @TARGET_OS@
+TEST_PLUGIN_INSTALLDIR = @TEST_PLUGIN_INSTALLDIR@
+TOOLS_VERSION = @TOOLS_VERSION@
+VERSION = @VERSION@
+VGAUTH_LIBADD = @VGAUTH_LIBADD@
+VIX_LIBADD = @VIX_LIBADD@
+VMSVC_PLUGIN_INSTALLDIR = @VMSVC_PLUGIN_INSTALLDIR@
+VMTOOLS_CPPFLAGS = @VMTOOLS_CPPFLAGS@
+VMTOOLS_LIBS = @VMTOOLS_LIBS@
+VMUSR_PLUGIN_INSTALLDIR = @VMUSR_PLUGIN_INSTALLDIR@
+XCOMPOSITE_LIBS = @XCOMPOSITE_LIBS@
+XDR_LIBS = @XDR_LIBS@
+XERCES_CPPFLAGS = @XERCES_CPPFLAGS@
+XERCES_LIBS = @XERCES_LIBS@
+XMKMF = @XMKMF@
+XMLSECURITY_CPPFLAGS = @XMLSECURITY_CPPFLAGS@
+XMLSECURITY_LIBS = @XMLSECURITY_LIBS@
+XSM_LIBS = @XSM_LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_vmw_lib_cfg = @ac_vmw_lib_cfg@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+have_cxx = @have_cxx@
+have_doxygen = @have_doxygen@
+have_genmarshal = @have_genmarshal@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+modulesrc = $(abs_top_srcdir)/modules
+@FREEBSD_CUSTOM_SYSDIR_TRUE@EXTRA_ARGS = "SYSDIR=@SYSDIR@"
+# Solaris does not have Kbuild-like system so we need to supply
+# compiler and linker and other items discovered by configure
+# script.
+@SOLARIS_TRUE@EXTRA_ARGS = "CC=$(CC)" "CC_WARNINGS=$(CC_WARNINGS)" \
+@SOLARIS_TRUE@ "GLOBAL_DEFS=$(GLOBAL_DEFS)" "LD=$(LD)" \
+@SOLARIS_TRUE@ "HAVE_GNU_LD=$(HAVE_GNU_LD)"
+@LINUX_TRUE@include_HEADERS = $(top_srcdir)/lib/include/vmci_sockets.h
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \
+ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(includedir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+
+.MAKE: install-am install-exec-am install-strip uninstall-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-local ctags distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-exec-hook install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags uninstall uninstall-am uninstall-hook \
+ uninstall-includeHEADERS
+
+all: modules
+
+.PHONY: modules $(MODULES)
+modules: $(MODULES)
+
+$(MODULES):
+ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \
+ OVT_SOURCE_DIR=$(abs_top_srcdir) \
+ MODULEBUILDDIR=$(modulesrc)/$(MODULES_OS) \
+ $(EXTRA_ARGS) -C "$(modulesrc)/$(MODULES_OS)/$@"
+
+@LINUX_TRUE@export LINUXINCLUDE := @LINUXINCLUDE@
+@LINUX_TRUE@export vmblockdir := $(MODULES_DIR)/fs/vmblock
+@LINUX_TRUE@export vmcidir := $(MODULES_DIR)/drivers/misc
+@LINUX_TRUE@export vmhgfsdir := $(MODULES_DIR)/fs/vmhgfs
+@LINUX_TRUE@export vmsyncdir := $(MODULES_DIR)/drivers/misc
+@LINUX_TRUE@export vmxnetdir := $(MODULES_DIR)/drivers/net
+@LINUX_TRUE@export vsockdir := $(MODULES_DIR)/net/vsock
+@LINUX_TRUE@@WITH_ROOT_PRIVILEGES_TRUE@export DEPMOD := depmod -a $(KERNEL_RELEASE)
+
+@SOLARIS_TRUE@export vmhgfsdir := $(MODULES_DIR)
+
+clean-local:
+ for MOD in $(MODULES); do \
+ if [ -d "$(modulesrc)/$(MODULES_OS)/$$MOD" ]; then \
+ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \
+ -C "$(modulesrc)/$(MODULES_OS)/$$MOD" clean || exit 1; \
+ fi \
+ done
+ rm -f $(modulesrc)/$(MODULES_OS)/*.o $(modulesrc)/$(MODULES_OS)/*.ko
+ rm -f $(modulesrc)/$(MODULES_OS)/VMwareVMCIModule.symvers
+
+install-exec-hook:
+@SOLARIS_TRUE@ for MOD in $(MODULES); do \
+@SOLARIS_TRUE@ $(MAKE) VM_UNAME=$(KERNEL_RELEASE) MV=mv RM=rm \
+@SOLARIS_TRUE@ -C "$(modulesrc)/$(MODULES_OS)/$$MOD" install || exit 1; \
+@SOLARIS_TRUE@ done
+@FREEBSD_TRUE@ for MOD in $(MODULES); do \
+@FREEBSD_TRUE@ $(INSTALL) -d $(DESTDIR)$(MODULES_DIR); \
+@FREEBSD_TRUE@ $(INSTALL) -m644 $(modulesrc)/$(MODULES_OS)/$$MOD.ko \
+@FREEBSD_TRUE@ $(DESTDIR)$(MODULES_DIR); \
+@FREEBSD_TRUE@ done
+@LINUX_TRUE@ for MOD in $(MODULES); do \
+@LINUX_TRUE@ $(INSTALL) -d $(DESTDIR)`eval echo '$$'$${MOD}dir`; \
+@LINUX_TRUE@ $(INSTALL) -m644 $(modulesrc)/$(MODULES_OS)/$$MOD/$$MOD.ko \
+@LINUX_TRUE@ $(DESTDIR)`eval echo '$$'$${MOD}dir`; \
+@LINUX_TRUE@ done
+@LINUX_TRUE@ eval "$$DEPMOD"
+
+uninstall-hook:
+ for MOD in $(MODULES); do \
+ rm -f $(DESTDIR)`eval echo '$$'$${MOD}dir`/$$MOD.ko &> /dev/null;\
+ done
+ eval "$$DEPMOD"
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/open-vm-tools/modules/freebsd/shared/compat_freebsd.h b/open-vm-tools/modules/freebsd/shared/compat_freebsd.h
index 4bbb5d2e..41f52a5b 100644
--- a/open-vm-tools/modules/freebsd/shared/compat_freebsd.h
+++ b/open-vm-tools/modules/freebsd/shared/compat_freebsd.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/shared/compat_mount.h b/open-vm-tools/modules/freebsd/shared/compat_mount.h
index 5a823dab..2a8074c0 100644
--- a/open-vm-tools/modules/freebsd/shared/compat_mount.h
+++ b/open-vm-tools/modules/freebsd/shared/compat_mount.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/shared/compat_priv.h b/open-vm-tools/modules/freebsd/shared/compat_priv.h
index 14ebfeb2..69653247 100644
--- a/open-vm-tools/modules/freebsd/shared/compat_priv.h
+++ b/open-vm-tools/modules/freebsd/shared/compat_priv.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/shared/compat_vop.h b/open-vm-tools/modules/freebsd/shared/compat_vop.h
index 43ecc69d..f76bba50 100644
--- a/open-vm-tools/modules/freebsd/shared/compat_vop.h
+++ b/open-vm-tools/modules/freebsd/shared/compat_vop.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/COPYING b/open-vm-tools/modules/freebsd/vmblock/COPYING
index f92946e0..e41a6d36 100644
--- a/open-vm-tools/modules/freebsd/vmblock/COPYING
+++ b/open-vm-tools/modules/freebsd/vmblock/COPYING
@@ -7,9 +7,6 @@ are met:
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
-3. Neither the name of VMware Inc. nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission of VMware Inc.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/Makefile b/open-vm-tools/modules/freebsd/vmblock/Makefile
index ff23c9c1..f67af072 100644
--- a/open-vm-tools/modules/freebsd/vmblock/Makefile
+++ b/open-vm-tools/modules/freebsd/vmblock/Makefile
@@ -11,9 +11,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
-# 3. Neither the name of VMware Inc. nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission of VMware Inc.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/os.h b/open-vm-tools/modules/freebsd/vmblock/os.h
index 5528f2a5..075fcbaa 100644
--- a/open-vm-tools/modules/freebsd/vmblock/os.h
+++ b/open-vm-tools/modules/freebsd/vmblock/os.h
@@ -10,9 +10,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/os_panic.c b/open-vm-tools/modules/freebsd/vmblock/os_panic.c
index 94e79aae..cacf41c0 100644
--- a/open-vm-tools/modules/freebsd/vmblock/os_panic.c
+++ b/open-vm-tools/modules/freebsd/vmblock/os_panic.c
@@ -10,9 +10,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/subr.c b/open-vm-tools/modules/freebsd/vmblock/subr.c
index 17865a04..393110af 100644
--- a/open-vm-tools/modules/freebsd/vmblock/subr.c
+++ b/open-vm-tools/modules/freebsd/vmblock/subr.c
@@ -24,9 +24,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/vfsops.c b/open-vm-tools/modules/freebsd/vmblock/vfsops.c
index bd53a8c1..fb7a12f7 100644
--- a/open-vm-tools/modules/freebsd/vmblock/vfsops.c
+++ b/open-vm-tools/modules/freebsd/vmblock/vfsops.c
@@ -23,9 +23,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -231,7 +228,7 @@ VMBlockVFSMount(struct mount *mp, // IN: mount(2) parameters
*/
MNT_ILOCK(mp);
mp->mnt_flag |= lowerrootvp->v_mount->mnt_flag & MNT_LOCAL;
-#if __FreeBSD_version >= 600000
+#if __FreeBSD_version >= 600000 && __FreeBSD_version < 1000000
mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag & MNTK_MPSAFE;
#endif
MNT_IUNLOCK(mp);
diff --git a/open-vm-tools/modules/freebsd/vmblock/vmblock_k.h b/open-vm-tools/modules/freebsd/vmblock/vmblock_k.h
index ce8f516b..eb038c77 100644
--- a/open-vm-tools/modules/freebsd/vmblock/vmblock_k.h
+++ b/open-vm-tools/modules/freebsd/vmblock/vmblock_k.h
@@ -17,9 +17,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/freebsd/vmblock/vnops.c b/open-vm-tools/modules/freebsd/vmblock/vnops.c
index 129be2eb..4f0ad90c 100644
--- a/open-vm-tools/modules/freebsd/vmblock/vnops.c
+++ b/open-vm-tools/modules/freebsd/vmblock/vnops.c
@@ -23,9 +23,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -755,14 +752,12 @@ struct vop_open_args {
*/
{
VMBlockMount *mp;
- VMBlockNode *mip;
struct vnode *vp, *ldvp;
struct file *fp;
int retval;
vp = ap->a_vp;
ldvp = VMBVPTOLOWERVP(vp);
- mip = VPTOVMB(ap->a_vp);
mp = MNTTOVMBLOCKMNT(ap->a_vp->v_mount);
if (ap->a_vp == mp->rootVnode) {
@@ -1365,7 +1360,9 @@ struct vop_inactive_args {
*/
{
struct vnode *vp = ap->a_vp;
+#if __FreeBSD_version < 1000000
struct thread *td = ap->a_td;
+#endif
vp->v_object = NULL;
@@ -1373,8 +1370,11 @@ struct vop_inactive_args {
* If this is the last reference, then free up the vnode so as not to
* tie up the lower vnode.
*/
- vrecycle(vp, td);
-
+#if __FreeBSD_version < 1000000
+ vrecycle(vp, td);
+#else
+ vrecycle(vp);
+#endif
return 0;
}
@@ -1414,7 +1414,6 @@ struct vop_reclaim_args {
struct vnode *vp = ap->a_vp;
struct VMBlockNode *xp = VPTOVMB(vp);
struct vnode *lowervp = xp->lowerVnode;
- struct lock *vnlock;
KASSERT(lowervp != NULL, ("reclaiming node with no lower vnode"));
@@ -1427,7 +1426,6 @@ struct vop_reclaim_args {
VI_LOCK(vp);
vp->v_data = NULL;
vp->v_object = NULL;
- vnlock = vp->v_vnlock;
/*
* Reassign lock pointer to this vnode's lock. (Originally assigned
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/COPYING b/open-vm-tools/modules/freebsd/vmhgfs/COPYING
deleted file mode 100644
index d511905c..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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; either version 2 of the License, or
- (at your option) any 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/Makefile b/open-vm-tools/modules/freebsd/vmhgfs/Makefile
deleted file mode 100644
index 9f065f18..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/Makefile
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/make -f
-##########################################################
-# Copyright (C) 2007 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
-#
-##########################################################
-
-HEADERS := vnode_if.h
-HEADERS += hgfs_kernel.h
-HEADERS += request.h
-HEADERS += requestInt.h
-HEADERS += debug.h
-HEADERS += state.h
-HEADERS += kernelStubs.h
-HEADERS += fsutil.h
-HEADERS += vnopscommon.h
-HEADERS += os.h
-HEADERS += vfsopscommon.h
-HEADERS += transport.h
-HEADERS += channel.h
-
-COMMON_SRCS := cpName.c
-COMMON_SRCS += cpNameLinux.c
-COMMON_SRCS += cpNameLite.c
-COMMON_SRCS += sha1.c
-COMMON_SRCS += hgfsEscape.c
-COMMON_SRCS += hgfsBd.c
-COMMON_SRCS += rpcout.c
-COMMON_SRCS += message.c
-COMMON_SRCS += backdoor.c
-.if $(MACHINE_ARCH) == "amd64"
-COMMON_SRCS += backdoorGcc64.c
-.else
-COMMON_SRCS += backdoorGcc32.c
-.endif
-
-COMMON_HGFS_SRCS := debug.c
-COMMON_HGFS_SRCS := bdhandler.c
-COMMON_HGFS_SRCS += request.c
-COMMON_HGFS_SRCS += worker.c
-COMMON_HGFS_SRCS += fsutil.c
-COMMON_HGFS_SRCS += vnopscommon.c
-COMMON_HGFS_SRCS += state.c
-COMMON_HGFS_SRCS += vfsopscommon.c
-COMMON_HGFS_SRCS += transport.c
-
-MODULE_SRCS := vnops.c
-MODULE_SRCS += vfsops.c
-MODULE_SRCS += os.c
-MODULE_SRCS += vmci.c
-MODULE_SRCS += hgfsUtil.c
-MODULE_SRCS += kernelStubsBSD.c
-
-#
-# The FreeBSD kernel module build tree iterates over the following variable
-# for build targets. C files will be compiled, and headers will just be
-# tested for presence.
-#
-SRCS = $(MODULE_SRCS) $(COMMON_SRCS) $(COMMON_HGFS_SRCS) $(HEADERS)
-
-KMOD = vmhgfs
-PROG = ../$(KMOD).ko
-NOMAN = t
-NO_MAN = t
-KLDMOD = t
-NOOBJ = 1
-NO_OBJ = 1
-
-.ifdef OVT_SOURCE_DIR
- CFLAGS += -I$(OVT_SOURCE_DIR)/lib/include
- CFLAGS += -I$(OVT_SOURCE_DIR)/lib/backdoor
- CFLAGS += -I$(OVT_SOURCE_DIR)/lib/hgfs
- CFLAGS += -I$(OVT_SOURCE_DIR)/modules/freebsd/shared
- VPATH := $(OVT_SOURCE_DIR)/lib/backdoor
- VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/hgfs
- VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/hgfsBd
- VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/message
- VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/misc
- VPATH := $(VPATH):$(OVT_SOURCE_DIR)/lib/rpcOut
-.else
- CFLAGS += -Ishared
-.endif
-
-#
-# FreeBSD's kernel module build system defines a bunch of additional warning
-# flags for the compiler in addition to -Wall -Werror. However, some of these,
-# like -Wredundant-decls, are overkill. To get around this, I copied their list
-# of warning flags, but explicitly disabled a few.
-#
-CWARNFLAGS := -Wall
-CWARNFLAGS += -Werror
-CWARNFLAGS += -Wno-redundant-decls
-CWARNFLAGS += -Wnested-externs
-CWARNFLAGS += -Wstrict-prototypes
-CWARNFLAGS += -Wno-missing-prototypes
-CWARNFLAGS += -Wpointer-arith
-CWARNFLAGS += -Winline
-CWARNFLAGS += -Wcast-qual
-
-EXPORT_SYMS = NO
-
-.include <bsd.kmod.mk>
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/bdhandler.c b/open-vm-tools/modules/freebsd/vmhgfs/bdhandler.c
deleted file mode 100644
index 3c92343c..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/bdhandler.c
+++ /dev/null
@@ -1,236 +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
- *
- *********************************************************/
-
-/*
- * bdhandler.c --
- *
- */
-
-#include "hgfsBd.h"
-#include "rpcout.h"
-#include "channel.h"
-
-static Bool HgfsBdChannelOpen(HgfsTransportChannel *channel);
-static void HgfsBdChannelClose(HgfsTransportChannel *channel);
-static HgfsKReqObject * HgfsBdChannelAllocate(size_t payloadSize, int flags);
-void HgfsBdChannelFree(HgfsKReqObject *req, size_t payloadSize);
-static int HgfsBdChannelSend(HgfsTransportChannel *channel, HgfsKReqObject *req);
-
-static HgfsTransportChannel gBdChannel = {
- .name = "backdoor",
- .ops.open = HgfsBdChannelOpen,
- .ops.close = HgfsBdChannelClose,
- .ops.allocate = HgfsBdChannelAllocate,
- .ops.free = HgfsBdChannelFree,
- .ops.send = HgfsBdChannelSend,
- .priv = NULL,
- .status = HGFS_CHANNEL_NOTCONNECTED
-};
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsBdChannelOpen --
- *
- * Open the backdoor in an idempotent way.
- *
- * Results:
- * TRUE on success, FALSE on failure.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static Bool
-HgfsBdChannelOpen(HgfsTransportChannel *channel) // IN: Channel
-{
- Bool ret;
-
- if ((ret = HgfsBd_OpenBackdoor((RpcOut **)&channel->priv))) {
- DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor opened.\n", __func__);
- ASSERT(channel->priv != NULL);
- channel->status = HGFS_CHANNEL_CONNECTED;
- }
-
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsBdChannelClose --
- *
- * Close the backdoor in an idempotent way.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-HgfsBdChannelClose(HgfsTransportChannel *channel) // IN: Channel
-{
- int ret;
-
- if (channel->priv == NULL) {
- return;
- }
-
- ret = HgfsBd_CloseBackdoor((RpcOut **)&channel->priv);
- if (!ret) {
- DEBUG(VM_DEBUG_FAIL, "VMware hgfs: %s: Failed to close backdoor.\n", __func__);
- } else {
- DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor closed.\n", __func__);
- }
- channel->status = HGFS_CHANNEL_NOTCONNECTED;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsBdChannelAllocate --
- *
- * Allocate request in a way that is suitable for sending through
- * backdoor.
- *
- * Results:
- * NULL on failure; otherwise address of the new request.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static HgfsKReqObject *
-HgfsBdChannelAllocate(size_t payloadSize, // IN: Size of allocation
- int flags) // IN:
-{
- return os_malloc(payloadSize, flags);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsBdChannelFree --
- *
- * Free previously allocated request.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-HgfsBdChannelFree(HgfsKReqObject *req, // IN:
- size_t payloadSize) // IN:
-{
- ASSERT(req);
- os_free(req, payloadSize);
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsBdChannelSend --
- *
- * Send a request via backdoor.
- *
- * Results:
- * 0 on success, negative error on failure.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-static int
-HgfsBdChannelSend(HgfsTransportChannel *channel, // IN: Channel
- HgfsKReqObject *req) // IN: request to send
-{
- char const *replyPacket = NULL;
- int ret;
-
- ASSERT(req);
-
- DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: backdoor sending.\n", __func__);
-
- bcopy(HGFS_SYNC_REQREP_CLIENT_CMD, req->__rpc_packet._command,
- HGFS_SYNC_REQREP_CLIENT_CMD_LEN);
-
- ret = HgfsBd_Dispatch(channel->priv, req->payload, &req->payloadSize,
- &replyPacket);
- os_mutex_lock(req->stateLock);
-
- /*
- * We have a response. (Maybe.) Re-lock the request, update its state,
- * etc.
- */
- if ((ret == 0) && (req->state == HGFS_REQ_SUBMITTED)) {
- DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: Success in backdoor.\n", __func__);
- bcopy(replyPacket, req->payload, req->payloadSize);
- req->state = HGFS_REQ_COMPLETED;
- } else {
- DEBUG(VM_DEBUG_INFO, "hgfs: %s: Error in backdoor.\n", __func__);
- req->state = HGFS_REQ_ERROR;
- }
-
- os_cv_signal(&req->stateCv);
- os_mutex_unlock(req->stateLock);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsGetBdChannel --
- *
- * Get backdoor channel.
- *
- * Results:
- * Always return pointer to back door channel.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-HgfsTransportChannel*
-HgfsGetBdChannel(void)
-{
- return &gBdChannel;
-}
-
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/channel.h b/open-vm-tools/modules/freebsd/vmhgfs/channel.h
deleted file mode 100644
index 0fcae727..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/channel.h
+++ /dev/null
@@ -1,60 +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
- *
- *********************************************************/
-
-/*
- * channel.h --
- */
-
-#ifndef _HGFS_CHANNEL_H_
-#define _HGFS_CHANNEL__H_
-
-#include "hgfs_kernel.h"
-#include "requestInt.h"
-
-/*
- * There are the operations a channel should implement.
- */
-struct HgfsTransportChannel;
-typedef struct HgfsTransportChannelOps {
- Bool (*open)(struct HgfsTransportChannel *);
- void (*close)(struct HgfsTransportChannel *);
- HgfsKReqObject* (*allocate)(size_t payloadSize, int flags);
- int (*send)(struct HgfsTransportChannel *, HgfsKReqObject *);
- void (*free)(HgfsKReqObject *, size_t payloadSize);
-} HgfsTransportChannelOps;
-
-typedef enum {
- HGFS_CHANNEL_UNINITIALIZED,
- HGFS_CHANNEL_NOTCONNECTED,
- HGFS_CHANNEL_CONNECTED,
- HGFS_CHANNEL_DEAD, /* Error has been detected, need to shut it down. */
-} HgfsChannelStatus;
-
-typedef struct HgfsTransportChannel {
- const char *name; /* Channel name. */
- HgfsTransportChannelOps ops; /* Channel ops. */
- HgfsChannelStatus status; /* Connection status. */
- void *priv; /* Channel private data. */
-} HgfsTransportChannel;
-
-HgfsTransportChannel *HgfsGetBdChannel(void);
-HgfsTransportChannel *HgfsGetVmciChannel(void);
-Bool HgfsSetupNewChannel(void);
-extern HgfsTransportChannel *gHgfsChannel;
-
-#endif // _HGFS_CHANNEL_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/debug.c b/open-vm-tools/modules/freebsd/vmhgfs/debug.c
deleted file mode 100644
index e39da2d5..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/debug.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * debug.c --
- *
- * Routine(s) for debugging the FreeBSD / Mac OS Hgfs module.
- */
-
-
-#if defined __APPLE__
-#include <sys/proc.h> // for proc_selfpid/name
-#include <string.h>
-#include "kernelStubs.h"
-#endif // defined __APPLE__
-#include "vm_basic_types.h"
-#include "debug.h"
-
-/*
- * Global functions
- */
-static const char *gHgfsOperationNames[] = {
- "HGFS_OP_OPEN",
- "HGFS_OP_READ",
- "HGFS_OP_WRITE",
- "HGFS_OP_CLOSE",
- "HGFS_OP_SEARCH_OPEN",
- "HGFS_OP_SEARCH_READ",
- "HGFS_OP_SEARCH_CLOSE",
- "HGFS_OP_GETATTR",
- "HGFS_OP_SETATTR",
- "HGFS_OP_CREATE_DIR",
- "HGFS_OP_DELETE_FILE",
- "HGFS_OP_DELETE_DIR",
- "HGFS_OP_RENAME",
- "HGFS_OP_QUERY_VOLUME_INFO",
- "HGFS_OP_OPEN_V2",
- "HGFS_OP_GETATTR_V2",
- "HGFS_OP_SETATTR_V2",
- "HGFS_OP_SEARCH_READ_V2",
- "HGFS_OP_CREATE_SYMLINK",
- "HGFS_OP_SERVER_LOCK_CHANGE",
- "HGFS_OP_CREATE_DIR_V2",
- "HGFS_OP_DELETE_FILE_V2",
- "HGFS_OP_DELETE_DIR_V2",
- "HGFS_OP_RENAME_V2",
- "HGFS_OP_OPEN_V3",
- "HGFS_OP_READ_V3",
- "HGFS_OP_WRITE_V3",
- "HGFS_OP_CLOSE_V3",
- "HGFS_OP_SEARCH_OPEN_V3",
- "HGFS_OP_SEARCH_READ_V3",
- "HGFS_OP_SEARCH_CLOSE_V3",
- "HGFS_OP_GETATTR_V3",
- "HGFS_OP_SETATTR_V3",
- "HGFS_OP_CREATE_DIR_V3",
- "HGFS_OP_DELETE_FILE_V3",
- "HGFS_OP_DELETE_DIR_V3",
- "HGFS_OP_RENAME_V3",
- "HGFS_OP_QUERY_VOLUME_INFO_V3",
- "HGFS_OP_CREATE_SYMLINK_V3",
- "HGFS_OP_SERVER_LOCK_CHANGE_V3",
- "HGFS_OP_WRITE_WIN32_STREAM_V3",
- "HGFS_OP_CREATE_SESSION_V4",
- "HGFS_OP_DESTROY_SESSION_V4",
- "HGFS_OP_READ_FAST_V4",
- "HGFS_OP_WRITE_FAST_V4",
- "HGFS_OP_SET_WATCH_V4",
- "HGFS_OP_REMOVE_WATCH_V4",
- "HGFS_OP_NOTIFY_V4",
- "HGFS_OP_SEARCH_READ_V4",
-};
-
-#if defined VMX86_DEVEL
-uint32_t gHgfsVmDebugLevel = VM_DEBUG_DEFAULT_LEV;
-
-static uint32 HgfsDebugGetSequenceNumber(void);
-static int HgfsDebugGetProcessInfo(char *pidName, size_t pidNameBufsize);
-static void *HgfsDebugGetCurrentThread(void);
-#endif // defined VMX86_DEVEL
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDebugPrint --
- *
- * Prints the operation of an request structure.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsDebugPrint(int type, const char *funcname, unsigned int linenum, const char *fmt, ...)
-{
-#if defined VMX86_DEVEL
-#if defined __APPLE__
- if (0 != (type & gHgfsVmDebugLevel) ||
- VM_DEBUG_ALWAYS == type) {
- char *fmsg;
- size_t fmsgLen;
- va_list args;
-
- va_start(args, fmt);
- fmsg = Str_Vasprintf(&fmsgLen, fmt, args);
- va_end(args);
-
- if (NULL != fmsg) {
- int pid;
- void *thrd;
- char pidname[64];
- uint32 seqNo;
-
- thrd = HgfsDebugGetCurrentThread();
- pid = HgfsDebugGetProcessInfo(pidname, sizeof pidname);
- seqNo = HgfsDebugGetSequenceNumber();
-
- kprintf("|%08u|%p.%08d.%s| %s:%2.2u: %s",
- seqNo, thrd, pid, pidname, funcname, linenum, fmsg);
-
- free(fmsg);
- }
- }
-#endif // defined __APPLE__
-#endif // defined VMX86_DEVEL
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDebugPrintOperation --
- *
- * Prints the operation of an request structure.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsDebugPrintOperation(HgfsKReqHandle req)
-{
- HgfsRequest *requestHeader;
-
- ASSERT(NULL != req);
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
-
- if (requestHeader->op < ARRAYSIZE(gHgfsOperationNames)) {
- DEBUG(VM_DEBUG_STRUCT, " operation: %s\n", gHgfsOperationNames[requestHeader->op]);
- } else {
- DEBUG(VM_DEBUG_STRUCT, " operation: INVALID %d\n", requestHeader->op);
- }
-}
-
-
-#if defined VMX86_DEVEL
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDebugGetProcessInfo --
- *
- * Gets the process name and ID making a request.
- *
- * Results:
- * PID of current process, and name in the buffer.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsDebugGetProcessInfo(char *pidname, // OUT: buffer for name
- size_t pidNameBufsize) // IN: size of buffer
-{
- int curPid = -1;
- *pidname = '\0';
-#if defined __APPLE__
- curPid = proc_selfpid();
- proc_name(curPid, pidname, pidNameBufsize);
-#endif // defined __APPLE__
- return curPid;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDebugGetCurrentThreadId --
- *
- * Gets the current thread making a request.
- *
- * Results:
- * TID of current thread.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void *
-HgfsDebugGetCurrentThread(void)
-{
- void *thread = NULL;
-#if defined __APPLE__
- thread = current_thread();
-#endif // defined __APPLE__
- return thread;
-}
-#endif // defined VMX86_DEVEL
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDebugPrintVattr --
- *
- * Prints the contents of an attributes structure.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsDebugPrintVattr(const HgfsVnodeAttr *vap)
-{
- DEBUG(VM_DEBUG_STRUCT, " va_type: %d\n", vap->va_type);
- DEBUG(VM_DEBUG_STRUCT, " va_mode: %o\n", vap->va_mode);
- DEBUG(VM_DEBUG_STRUCT, " va_uid: %u\n", vap->va_uid);
- DEBUG(VM_DEBUG_STRUCT, " va_gid: %u\n", vap->va_gid);
- DEBUG(VM_DEBUG_STRUCT, " va_fsid: %u\n", vap->va_fsid);
- DEBUG(VM_DEBUG_STRUCT, " va_rdev: %u\n", vap->va_rdev);
- DEBUG(VM_DEBUG_STRUCT, " va_filerev: %"FMT64"u\n", vap->va_filerev);
- DEBUG(VM_DEBUG_STRUCT, " va_vaflags: %x\n", vap->va_vaflags);
-
-#if defined __FreeBSD__
- /*
- * The next group of attributes have the same name but different sizes on
- * xnu-1228 and FreeBSD 6.2.
- */
- DEBUG(VM_DEBUG_STRUCT, " va_flags: %lx\n", vap->va_flags);
- DEBUG(VM_DEBUG_STRUCT, " va_gen: %lu\n", vap->va_gen);
- DEBUG(VM_DEBUG_STRUCT, " va_fileid: %ld\n", vap->va_fileid);
- DEBUG(VM_DEBUG_STRUCT, " va_nlink: %hd\n", vap->va_nlink);
-
- /* These attributes names changed have between xnu-1228 and FreeBSD 6.2. */
- DEBUG(VM_DEBUG_STRUCT, " va_size: %ju\n", vap->va_size);
- DEBUG(VM_DEBUG_STRUCT, " va_blocksize: %ld\n", vap->va_blocksize);
- /*
- * XXX time_t is __int32_t on 32-bit architectures and __int64_t on 64-bit
- * architectures. Would this be better as add'l formats in vm_basic_types.h?
- */
- DEBUG(VM_DEBUG_STRUCT, " va_atime.tv_sec: %jd\n", (intmax_t)vap->va_atime.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_atime.tv_nsec: %ld\n", vap->va_atime.tv_nsec);
- DEBUG(VM_DEBUG_STRUCT, " va_mtime.tv_sec: %jd\n", (intmax_t)vap->va_mtime.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_mtime.tv_nsec: %ld\n", vap->va_mtime.tv_nsec);
- DEBUG(VM_DEBUG_STRUCT, " va_ctime.tv_sec: %jd\n", (intmax_t)vap->va_ctime.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_ctime.tv_nsec: %ld\n", vap->va_ctime.tv_nsec);
- DEBUG(VM_DEBUG_STRUCT, " va_birthtime.tv_sec: %jd\n",
- (intmax_t)vap->va_birthtime.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_birthtime.tv_nsec: %ld\n",
- vap->va_birthtime.tv_nsec);
- DEBUG(VM_DEBUG_STRUCT, " va_bytes: %"FMT64"u\n", vap->va_bytes);
-
-#elif defined __APPLE__
- /*
- * The next group of attributes have the same name but different sizes on
- * xnu-1228 and FreeBSD 6.2.
- */
- DEBUG(VM_DEBUG_STRUCT, " va_flags: %x\n", vap->va_flags);
- DEBUG(VM_DEBUG_STRUCT, " va_gen: %u\n", vap->va_gen);
- DEBUG(VM_DEBUG_STRUCT, " va_fileid: %"FMT64"u\n", vap->va_fileid);
- DEBUG(VM_DEBUG_STRUCT, " va_nlink: %"FMT64"u\n", vap->va_nlink);
-
- /* These attribute names have changed between xnu-1228 and FreeBSD 6.2. */
- DEBUG(VM_DEBUG_STRUCT, " va_size: %"FMT64"u\n", vap->va_data_size);
- DEBUG(VM_DEBUG_STRUCT, " va_iosize: %u\n", vap->va_iosize);
-
- DEBUG(VM_DEBUG_STRUCT, " va_access_time.tv_sec: %ld\n", vap->va_access_time.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_access_time.tv_nsec: %ld\n", vap->va_access_time.tv_nsec);
- DEBUG(VM_DEBUG_STRUCT, " va_modify_time.tv_sec: %ld\n", vap->va_modify_time.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_modify_time.tv_nsec: %ld\n", vap->va_modify_time.tv_nsec);
- DEBUG(VM_DEBUG_STRUCT, " va_create_time.tv_sec: %ld\n", vap->va_create_time.tv_sec);
- DEBUG(VM_DEBUG_STRUCT, " va_create_time.tv_nsec: %ld\n", vap->va_create_time.tv_nsec);
-#endif
-}
-
-
-#if defined VMX86_DEVEL
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDebugGetSequenceNumber --
- *
- * Log a sequence number in case we suspect log messages getting dropped
- *
- * Results:
- * The next sequence number.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static uint32
-HgfsDebugGetSequenceNumber(void)
-{
- static uint32 ghgfsDebugLogSeq = 0;
- return ++ghgfsDebugLogSeq;
-}
-#endif // defined VMX86_DEVEL
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/debug.h b/open-vm-tools/modules/freebsd/vmhgfs/debug.h
deleted file mode 100644
index 68043d51..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/debug.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * debug.h --
- *
- * Macros and includes for debugging.
- */
-
-#ifndef _DEBUG_H_
-#define _DEBUG_H_
-
-#include <sys/param.h>
-
-#if defined __FreeBSD__
-# include <sys/types.h> // for log(9)
-# include <sys/systm.h> // for log(9)
-# include <sys/syslog.h> // for log(9), LOG_* macros
-#elif defined __APPLE__
-# include <kern/debug.h> // for panic
-# if defined VMX86_DEVEL
-# include <pexpert/pexpert.h> // for kprintf
-# endif
-#endif
-
-#include <sys/vnode.h> // for struct vattr
-
-#include "hgfs_kernel.h"
-
-/*
- * Macros
- */
-
-#define Panic(fmt, ...) panic(fmt, ##__VA_ARGS__)
-
-#define VM_DEBUG_ALWAYS (1)
-#define VM_DEBUG_FAIL VM_DEBUG_ALWAYS
-#define VM_DEBUG_NOTSUP VM_DEBUG_ALWAYS
-#define VM_DEBUG_ENTRY (1 << 1)
-#define VM_DEBUG_EXIT (1 << 2)
-#define VM_DEBUG_LOAD (1 << 3)
-#define VM_DEBUG_INFO (1 << 4)
-#define VM_DEBUG_STRUCT (1 << 5)
-#define VM_DEBUG_LIST (1 << 6)
-#define VM_DEBUG_CHPOLL (1 << 7)
-#define VM_DEBUG_RARE (1 << 8)
-#define VM_DEBUG_COMM (1 << 9)
-#define VM_DEBUG_REQUEST (1 << 10)
-#define VM_DEBUG_LOG (1 << 11)
-#define VM_DEBUG_ATTR (1 << 12)
-#define VM_DEBUG_DEVENTRY (1 << 13)
-#define VM_DEBUG_DEVDONE (1 << 14)
-#define VM_DEBUG_SIG (1 << 15)
-#define VM_DEBUG_ERROR (1 << 16)
-#define VM_DEBUG_HSHTBL (1 << 17)
-#define VM_DEBUG_HANDLE (1 << 18)
-#define VM_DEBUG_STATE (1 << 19)
-#define VM_DEBUG_VNODE (1 << 20)
-#define VM_DEBUG_ALL (~0)
-
-#if defined VMX86_DEVEL
-extern uint32_t gHgfsVmDebugLevel;
-#define VM_DEBUG_DEFAULT_LEV (VM_DEBUG_ALWAYS | VM_DEBUG_ENTRY | VM_DEBUG_EXIT | VM_DEBUG_FAIL)
-#endif
-
-#ifdef VMX86_DEVEL
-# if defined __FreeBSD__
-# define DEBUG(type, fmt, ...) \
- ((type & gHgfsVmDebugLevel) ? \
- (log(LOG_NOTICE, "%s:%u: " fmt, \
- __func__, __LINE__, ##__VA_ARGS__)) \
- : 0)
-# elif defined __APPLE__
-# define DEBUG(type, fmt, ...) \
- HgfsDebugPrint(type, __func__, __LINE__, fmt, ##__VA_ARGS__)
-# endif
-#else
-# define DEBUG(type, ...)
-#endif
-
-/*
- * Global functions
- */
-
-void HgfsDebugPrint(int type, const char *funcname, unsigned int linenum, const char *fmt, ...);
-void HgfsDebugPrintVattr(const HgfsVnodeAttr *vap);
-void HgfsDebugPrintOperation(HgfsKReqHandle req);
-
-#endif // _DEBUG_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/fsutil.c b/open-vm-tools/modules/freebsd/vmhgfs/fsutil.c
deleted file mode 100644
index ce8784d5..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/fsutil.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * fsutil.c --
- *
- * VFS helper functions that are shared between the FreeBSD and Mac OS
- * implementaitons of HGFS.
- */
-
-#include <sys/types.h>
-#include <sys/malloc.h>
-
-#if defined __APPLE__
-# include <libkern/libkern.h> // for rindex
-#endif
-
-#include "fsutil.h"
-#include "cpName.h"
-#include "hgfsEscape.h"
-#include "cpNameLite.h"
-#include "os.h"
-
-#if defined __APPLE__
-char *rindex(const char *ptr, int chr);
-#endif
-
-/*
- * Mac OS sets vnode attributes through the use of a VATTR_RETURN function.
- * FreeBSD sets vnode attributes directly in the structure. To enable a shared
- * implementation of HgfsAttrToBSD and HgfsSetattrCopy, we define VATTR_RETURN
- * for FreeBSD.
- */
-#if defined __FreeBSD__
-#define VATTR_RETURN(vn, attr, val) \
- do { (vn)-> attr = (val); } while (0)
-#endif
-
-/* Local Function Prototypes */
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSubmitRequest --
- *
- * Places a request on the queue for submission by the worker thread,
- * then waits for the response.
- *
- * Both submitting request and waiting for reply are in this function
- * because the signaling of the request list's condition variable and
- * waiting on the request's condition variable must be atomic.
- *
- * Results:
- * Returns zero on success, and an appropriate error code on error.
- * Note: EINTR is returned if cv_wait_sig() is interrupted.
- *
- * Side effects:
- * The request list's condition variable is signaled.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsSubmitRequest(HgfsSuperInfo *sip, // IN: Superinfo containing request list,
- // condition variable, and mutex
- HgfsKReqHandle req) // IN: Request to submit
-{
- int ret = 0;
-
- ASSERT(sip);
- ASSERT(req);
-
- /*
- * The process of submitting the request involves putting it on the request
- * list, waking up the backdoor req thread if it is waiting for a request,
- * then atomically waiting for the reply.
- */
-
- /*
- * Fail the request if a forcible unmount is in progress.
- */
- if (HGFS_MP_IS_FORCEUNMOUNT(sip->vfsp)) {
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- return EIO;
- }
-
- /* Submit the request & wait for a result. */
- ret = HgfsKReq_SubmitRequest(req);
-
- if (ret == 0) {
- /* The reply should now be in HgfsKReq_GetPayload(req). */
- DEBUG(VM_DEBUG_SIG, "awoken because reply received.\n");
- } else {
- /* HgfsKReq_SubmitRequest was interrupted, so we'll abandon now. */
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsGetStatus --
- *
- * Gets the status of the reply packet. If the size of the reply packet
- * does not lie between the minimum expected size and maximum allowed packet
- * size, then EPROTO is returned.
- *
- * Results:
- * Returns zero on success, and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsGetStatus(HgfsKReqHandle req, // IN: Request that contains reply data
- uint32_t minSize) // IN: Minimum size expected for the reply
-{
- HgfsReply *replyHeader;
- size_t repSize = 0;
- int ret = 0;
-
- ASSERT(req);
- ASSERT(minSize <= HGFS_PACKET_MAX); /* we want to know if this fails */
-
- switch (HgfsKReq_GetState(req)) {
-
- case HGFS_REQ_ERROR:
- DEBUG(VM_DEBUG_FAIL, "received reply with error.\n");
- ret = EPROTO;
- break;
-
- case HGFS_REQ_COMPLETED:
- repSize = HgfsKReq_GetPayloadSize(req);
- /*
- * Server sets the packet size equal to size of HgfsReply when it
- * encounters an error. In order to return correct error code,
- * we should first check the status and then check if packet size
- * lies between minimum expected size and maximum allowed packet size.
- */
-
- if (repSize >= sizeof *replyHeader) {
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- ret = HgfsStatusToBSD(replyHeader->status);
- if (ret) {
- break;
- }
- }
-
- if (repSize < minSize || repSize > HGFS_PACKET_MAX) {
- DEBUG(VM_DEBUG_FAIL, "successfully "
- "completed reply is too small/big: !(%d < %" FMTSZ "d < %d).\n",
- minSize, repSize, HGFS_PACKET_MAX);
- ret = EPROTO;
- }
- break;
-
- /*
- * If we get here then there is a programming error in this module:
- * HGFS_REQ_UNUSED should be for requests in the free list
- * HGFS_REQ_SUBMITTED should be for requests only that are awaiting
- * a response
- * HGFS_REQ_ABANDONED should have returned an error to the client
- */
- default:
- NOT_REACHED();
- ret = EPROTO; /* avoid compiler warning */
- }
-
- return ret;
-}
-
-/*
- * XXX
- * These were taken and slightly modified from hgfs/driver/solaris/vnode.c.
- * (Which, in turn, took them from hgfs/driver/linux/driver.c.) Should we
- * move them into a hgfs/driver/posix/driver.c?
- */
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsGetOpenMode --
- *
- * Based on the flags requested by the process making the open()
- * syscall, determine which open mode (access type) to request from
- * the server.
- *
- * Results:
- * Returns the correct HgfsOpenMode enumeration to send to the
- * server, or -1 on failure.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-int
-HgfsGetOpenMode(uint32 flags) // IN: Open flags
-{
- /*
- * Preprocessor wrapper kept for when this function is factored out
- * into a common file.
- */
-#if defined _KERNEL || defined KERNEL
- /*
- * FreeBSD / Mac OS use different values from those in the linux kernel. These are defined in
- * <sys/fcntl.h>.
- */
- #undef O_RDONLY
- #undef O_WRONLY
- #undef O_RDWR
-
- #define O_RDONLY FREAD
- #define O_WRONLY FWRITE
- #define O_RDWR (FREAD | FWRITE)
-#endif
-
- uint32 mask = O_RDONLY | O_WRONLY | O_RDWR;
- int result = -1;
-
- DEBUG(VM_DEBUG_LOG, "entered\n");
-
- /*
- * Mask the flags to only look at the access type.
- */
- flags &= mask;
-
- /* Pick the correct HgfsOpenMode. */
- switch (flags) {
-
- case O_RDONLY:
- DEBUG(VM_DEBUG_COMM, "O_RDONLY\n");
- result = HGFS_OPEN_MODE_READ_ONLY;
- break;
-
- case O_WRONLY:
- DEBUG(VM_DEBUG_COMM, "O_WRONLY\n");
- result = HGFS_OPEN_MODE_WRITE_ONLY;
- break;
-
- case O_RDWR:
- DEBUG(VM_DEBUG_COMM, "O_RDWR\n");
- result = HGFS_OPEN_MODE_READ_WRITE;
- break;
-
- default:
- /* This should never happen. */
- NOT_REACHED();
- DEBUG(VM_DEBUG_LOG, "invalid open flags %o\n", flags);
- result = -1;
- break;
- }
-
- return result;
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsGetOpenFlags --
- *
- * Based on the flags requested by the process making the open()
- * syscall, determine which flags to send to the server to open the
- * file.
- *
- * Results:
- * Returns the correct HgfsOpenFlags enumeration to send to the
- * server, or -1 on failure.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-int
-HgfsGetOpenFlags(uint32 flags) // IN: Open flags
-{
- uint32 mask = O_CREAT | O_TRUNC | O_EXCL;
- int result = -1;
-
- DEBUG(VM_DEBUG_INFO, "entered\n");
-
- /*
- * Mask the flags to only look at O_CREAT, O_EXCL, and O_TRUNC.
- */
-
- flags &= mask;
-
- /* O_EXCL has no meaning if O_CREAT is not set. */
- if (!(flags & O_CREAT)) {
- flags &= ~O_EXCL;
- }
-
- /* Pick the right HgfsOpenFlags. */
- switch (flags) {
-
- case 0:
- /* Regular open; fails if file nonexistant. */
- DEBUG(VM_DEBUG_COMM, "0\n");
- result = HGFS_OPEN;
- break;
-
- case O_CREAT:
- /* Create file; if it exists already just open it. */
- DEBUG(VM_DEBUG_COMM, "O_CREAT\n");
- result = HGFS_OPEN_CREATE;
- break;
-
- case O_TRUNC:
- /* Truncate existing file; fails if nonexistant. */
- DEBUG(VM_DEBUG_COMM, "O_TRUNC\n");
- result = HGFS_OPEN_EMPTY;
- break;
-
- case (O_CREAT | O_EXCL):
- /* Create file; fail if it exists already. */
- DEBUG(VM_DEBUG_COMM, "O_CREAT | O_EXCL\n");
- result = HGFS_OPEN_CREATE_SAFE;
- break;
-
- case (O_CREAT | O_TRUNC):
- /* Create file; if it exists already, truncate it. */
- DEBUG(VM_DEBUG_COMM, "O_CREAT | O_TRUNC\n");
- result = HGFS_OPEN_CREATE_EMPTY;
- break;
-
- default:
- /*
- * This can only happen if all three flags are set, which
- * conceptually makes no sense because O_EXCL and O_TRUNC are
- * mutually exclusive if O_CREAT is set.
- *
- * However, the open(2) man page doesn't say you can't set all
- * three flags, and certain apps (*cough* Nautilus *cough*) do
- * so. To be friendly to those apps, we just silenty drop the
- * O_TRUNC flag on the assumption that it's safer to honor
- * O_EXCL.
- */
- DEBUG(VM_DEBUG_INFO, "invalid open flags %o. "
- "Ignoring the O_TRUNC flag.\n", flags);
- result = HGFS_OPEN_CREATE_SAFE;
- break;
- }
-
- return result;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsMakeFullName --
- *
- * Concatenates the path and filename to construct the full path. This
- * handles the special cases of . and .. filenames so the Hgfs server
- * doesn't return an error.
- *
- * Results:
- * Returns the length of the full path on success, and a negative value on
- * error. The full pathname is placed in outBuf.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsMakeFullName(const char *path, // IN: Path of directory containing file
- uint32_t pathLen, // IN: Length of path
- const char *file, // IN: Name of file
- size_t fileLen, // IN: Length of filename
- char *outBuf, // OUT: Location to write full path
- ssize_t bufSize) // IN: Size of the out buffer
-{
- uint32 pathSeparatorLen;
- ASSERT(path);
- ASSERT(file);
- ASSERT(outBuf);
-
-
- DEBUG(VM_DEBUG_INFO, "HgfsMakeFullName:\n"
- " path: \"%.*s\" (%d)\n"
- " file: \"%s\" (%zu)\n",
- pathLen, path, pathLen, file, fileLen);
-
- /*
- * Here there are three possibilities:
- * o file is ".", in which case we just place path in outBuf
- * o file is "..", in which case we strip the last component from path and
- * put that in outBuf
- * o for all other cases, we concatenate path, a path separator, file, and
- * a NUL terminator and place it in outBuf
- */
-
- /* Make sure that the path and a NUL terminator will fit. */
- if (bufSize < pathLen + 1) {
- return HGFS_ERR_INVAL;
- }
-
-
- /*
- * Copy path for this file into the caller's buffer.
- * The memset call is important here because it implicitly null terminates
- * outBuf so that rindex can be called in the second case below.
- */
- memset(outBuf, 0, bufSize);
- memcpy(outBuf, path, pathLen);
-
- /* Handle three cases. */
- if (fileLen == 1 && strncmp(file, ".", 1) == 0) {
- /* NUL terminate and return provided length. */
- outBuf[pathLen] = '\0';
- return pathLen;
-
- } else if (fileLen == 2 && strncmp(file, "..", 2) == 0) {
- /*
- * Replace the last path separator with a NUL terminator, then return the
- * size of the buffer.
- */
- char *newEnd = rindex(outBuf, DIRSEPC);
- if (!newEnd) {
- /*
- * We should never get here since we name the root vnode "/" in
- * HgfsMount().
- */
- return HGFS_ERR_INVAL;
- }
-
- *newEnd = '\0';
- return ((uintptr_t)newEnd - (uintptr_t)outBuf);
- } else {
- if (bufSize < pathLen + 1 + fileLen + 1) {
- return HGFS_ERR_INVAL;
- }
-
- /*
- * If the path consists of just a single path separator, then
- * do not add another path separator. This will ensure that
- * we have only single path separator at the beginning of the
- * filename.
- */
- if (pathLen == 1 && *path == DIRSEPC) {
- pathSeparatorLen = 0;
- } else {
- outBuf[pathLen] = DIRSEPC;
- pathSeparatorLen = DIRSEPSLEN;
- }
- /* Now append the filename and NUL terminator. */
- memcpy(outBuf + pathSeparatorLen + pathLen, file, fileLen);
- outBuf[pathLen + pathSeparatorLen + fileLen] = '\0';
-
- return pathLen + pathSeparatorLen + fileLen;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSetattrCopy --
- *
- * Sets the Hgfs attributes that need to be modified based on the provided
- * Solaris attribute structure.
- *
- * Results:
- * Returns TRUE if changes need to be made, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-HgfsSetattrCopy(HgfsVnodeAttr *vap, // IN: Attributes to change to
- HgfsAttrV2 *hgfsAttrV2, // OUT: Hgfs attributes to fill in
- HgfsAttrHint *hints) // OUT: Hgfs attribute hints
-{
- Bool ret = FALSE;
-
- ASSERT(vap);
- ASSERT(hgfsAttrV2);
- ASSERT(hints);
-
- memset(hgfsAttrV2, 0, sizeof *hgfsAttrV2);
- memset(hints, 0, sizeof *hints);
-
- /*
- * Hgfs supports changing these attributes:
- * o mode bits (permissions)
- * o uid/gid
- * o size
- * o access/write times
- */
-
- if (HGFS_VATTR_MODE_IS_ACTIVE(vap, HGFS_VA_MODE)){
- DEBUG(VM_DEBUG_COMM, "updating permissions.\n");
- hgfsAttrV2->mask |= HGFS_ATTR_VALID_SPECIAL_PERMS |
- HGFS_ATTR_VALID_OWNER_PERMS |
- HGFS_ATTR_VALID_GROUP_PERMS |
- HGFS_ATTR_VALID_OTHER_PERMS;
- hgfsAttrV2->specialPerms = (vap->HGFS_VA_MODE & (S_ISUID | S_ISGID |
- S_ISVTX)) >> HGFS_ATTR_SPECIAL_PERM_SHIFT;
- hgfsAttrV2->ownerPerms = (vap->HGFS_VA_MODE & S_IRWXU) >>
- HGFS_ATTR_OWNER_PERM_SHIFT;
- hgfsAttrV2->groupPerms = (vap->HGFS_VA_MODE & S_IRWXG) >>
- HGFS_ATTR_GROUP_PERM_SHIFT;
- hgfsAttrV2->otherPerms = vap->HGFS_VA_MODE & S_IRWXO;
- ret = TRUE;
- }
-
- if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_UID)) {
- DEBUG(VM_DEBUG_COMM, "updating user id.\n");
- hgfsAttrV2->mask |= HGFS_ATTR_VALID_USERID;
- hgfsAttrV2->userId = vap->HGFS_VA_UID;
- ret = TRUE;
- }
-
- if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_GID)) {
- DEBUG(VM_DEBUG_COMM, "updating group id.\n");
- hgfsAttrV2->mask |= HGFS_ATTR_VALID_GROUPID;
- hgfsAttrV2->groupId = vap->HGFS_VA_GID;
- ret = TRUE;
- }
-
- if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_ACCESS_TIME_SEC)) {
- DEBUG(VM_DEBUG_COMM, "updating access time.\n");
- *hints |= HGFS_ATTR_HINT_SET_ACCESS_TIME;
- hgfsAttrV2->mask |= HGFS_ATTR_VALID_ACCESS_TIME;
- hgfsAttrV2->accessTime = HGFS_GET_TIME(vap->HGFS_VA_ACCESS_TIME);
- ret = TRUE;
- }
-
- if (HGFS_VATTR_IS_ACTIVE(vap, HGFS_VA_MODIFY_TIME_SEC)) {
- DEBUG(VM_DEBUG_COMM, "updating write time.\n");
- *hints |= HGFS_ATTR_HINT_SET_WRITE_TIME;
- hgfsAttrV2->mask |= HGFS_ATTR_VALID_WRITE_TIME;
- hgfsAttrV2->writeTime = HGFS_GET_TIME(vap->HGFS_VA_MODIFY_TIME);
- ret = TRUE;
- }
-
- if (HGFS_VATTR_SIZE_IS_ACTIVE(vap, HGFS_VA_DATA_SIZE)) {
- DEBUG(VM_DEBUG_COMM, "updating size.\n");
- hgfsAttrV2->mask |= HGFS_ATTR_VALID_SIZE;
- hgfsAttrV2->size = vap->HGFS_VA_DATA_SIZE;
- ret = TRUE;
- }
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsAttrToBSD --
- *
- * Maps Hgfs attributes to Mac OS/BSD attributes, filling the provided BSD
- * attribute structure appropriately.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsAttrToBSD(struct vnode *vp, // IN: The vnode for this file
- const HgfsAttrV2 *hgfsAttrV2, // IN: Hgfs attributes to copy
- HgfsVnodeAttr *vap) // OUT: BSD attributes to fill
-{
- short mode = 0;
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
-
- ASSERT(vp);
- ASSERT(hgfsAttrV2);
- ASSERT(vap);
-
- /* XXX Update this function to support all V2 attributes. */
-
- DEBUG(VM_DEBUG_ENTRY, "%p -> %p\n", hgfsAttrV2, vap);
-
- /*
- * Initialize all fields to zero. We don't need to do this for Mac OS
- * because the VATTR_RETURN macros take care of it for us.
- */
-#if defined __FreeBSD__
- VATTR_NULL(vap);
-#endif
-
- if ((hgfsAttrV2->mask & HGFS_ATTR_VALID_TYPE)) {
- /* Set the file type. */
- switch (hgfsAttrV2->type) {
- case HGFS_FILE_TYPE_REGULAR:
- HGFS_VATTR_TYPE_RETURN(vap, VREG);
- DEBUG(VM_DEBUG_ATTR, " Type: VREG\n");
- break;
-
- case HGFS_FILE_TYPE_DIRECTORY:
- HGFS_VATTR_TYPE_RETURN(vap, VDIR);
- DEBUG(VM_DEBUG_ATTR, " Type: VDIR\n");
- break;
-
- case HGFS_FILE_TYPE_SYMLINK:
- HGFS_VATTR_TYPE_RETURN(vap, VLNK);
- DEBUG(VM_DEBUG_ATTR, " Type: VLNK\n");
- break;
-
- default:
- /*
- * There are only the above three filetypes. If there is an error
- * elsewhere that provides another value, we set the Solaris type to
- * none and ASSERT in devel builds.
- */
- HGFS_VATTR_TYPE_RETURN(vap, VNON);
- DEBUG(VM_DEBUG_FAIL, "invalid HgfsFileType provided.\n");
- }
- } else {
- HGFS_VATTR_TYPE_RETURN(vap, VNON);
- DEBUG(VM_DEBUG_FAIL, "invalid HgfsFileType provided\n");
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_SPECIAL_PERMS) {
- mode |= hgfsAttrV2->specialPerms << HGFS_ATTR_SPECIAL_PERM_SHIFT;
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_OWNER_PERMS) {
- mode |= hgfsAttrV2->ownerPerms << HGFS_ATTR_OWNER_PERM_SHIFT;
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_GROUP_PERMS) {
- mode |= hgfsAttrV2->groupPerms << HGFS_ATTR_GROUP_PERM_SHIFT;
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_OWNER_PERMS) {
- mode |= hgfsAttrV2->otherPerms;
- }
-
- HGFS_VATTR_MODE_RETURN(vap, mode);
-
- HGFS_VATTR_NLINK_RETURN(vap, 1); /* fake */
-
- if (sip->uidSet || (hgfsAttrV2->mask & HGFS_ATTR_VALID_USERID) == 0) {
- HGFS_VATTR_UID_RETURN(vap, sip->uid);
- } else {
- HGFS_VATTR_UID_RETURN(vap, hgfsAttrV2->userId);
- }
-
- if (sip->gidSet || (hgfsAttrV2->mask & HGFS_ATTR_VALID_GROUPID) == 0) {
- HGFS_VATTR_GID_RETURN(vap, sip->gid);
- } else {
- HGFS_VATTR_GID_RETURN(vap, hgfsAttrV2->groupId);
- }
-
- HGFS_VATTR_FSID_RETURN(vap, HGFS_VP_TO_STATFS(vp)->f_fsid.val[0]);
-
- /* Get the node id calculated for this file in HgfsVnodeGet() */
- HGFS_VATTR_FILEID_RETURN(vap, HGFS_VP_TO_NODEID(vp));
-
- HGFS_VATTR_BLOCKSIZE_RETURN(vap, HGFS_BLOCKSIZE);
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_SIZE) {
- HGFS_VATTR_BYTES_RETURN(vap, hgfsAttrV2->size);
- HGFS_VATTR_SIZE_RETURN(vap, hgfsAttrV2->size);
- }
-
- /*
- * HGFS_SET_TIME does not mark the attribute as supported (unlike
- * VATTR_RETURN on Mac OS) so we have to do it explicitly with calls to
- * VATTR_SET_SUPPORTED. For FreeBSD, HGFS_VATTR_*_SET_SUPPORTED is just a NULL
- * macro.
- */
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_ACCESS_TIME) {
- HGFS_SET_TIME(vap->HGFS_VA_ACCESS_TIME, hgfsAttrV2->accessTime);
- HGFS_VATTR_ACCESS_TIME_SET_SUPPORTED(vap);
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_WRITE_TIME) {
- HGFS_SET_TIME(vap->HGFS_VA_MODIFY_TIME, hgfsAttrV2->writeTime);
- HGFS_VATTR_MODIFY_TIME_SET_SUPPORTED(vap);
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_CHANGE_TIME) {
- HGFS_SET_TIME(vap->HGFS_VA_CHANGE_TIME, hgfsAttrV2->attrChangeTime);
- HGFS_VATTR_CHANGE_TIME_SET_SUPPORTED(vap);
- }
-
- if (hgfsAttrV2->mask & HGFS_ATTR_VALID_CREATE_TIME) {
- /* Since Windows doesn't keep ctime, we may need to use mtime instead. */
- HGFS_SET_TIME(vap->HGFS_VA_CREATE_TIME, hgfsAttrV2->creationTime);
- HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap);
- } else if (hgfsAttrV2->mask & HGFS_ATTR_VALID_WRITE_TIME) {
- DEBUG(VM_DEBUG_ATTR, "Set create time from write time\n");
- vap->HGFS_VA_CREATE_TIME = vap->HGFS_VA_MODIFY_TIME;
- HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap);
- } else {
- DEBUG(VM_DEBUG_ATTR, "Do not set create time\n");
- }
-
- DEBUG(VM_DEBUG_ATTR, "Attrib mask %"FMT64"d\n", hgfsAttrV2->mask);
-
-#if defined __APPLE__
- DEBUG(VM_DEBUG_ATTR, "Supported %lld, active %lld\n", vap->va_supported,
- vap->va_active);
-#endif
-
- HgfsDebugPrintVattr(vap);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsStatusToBSD --
- *
- * Convert a cross-platform HGFS status code to its Linux-kernel specific
- * counterpart.
- *
- * Results:
- * Zero if the converted status code represents success, negative error
- * otherwise. Unknown status codes are converted to the more generic
- * "protocol error" status code to maintain forwards compatibility.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-HgfsStatusToBSD(HgfsStatus hgfsStatus) // IN: Hgfs status msg to be converted
-{
- switch (hgfsStatus) {
- case HGFS_STATUS_SUCCESS:
- return 0;
-
- case HGFS_STATUS_NO_SUCH_FILE_OR_DIR:
- case HGFS_STATUS_INVALID_NAME:
- return ENOENT;
-
- case HGFS_STATUS_INVALID_HANDLE:
- return EBADF;
-
- case HGFS_STATUS_OPERATION_NOT_PERMITTED:
- return EPERM;
-
- case HGFS_STATUS_FILE_EXISTS:
- return EEXIST;
-
- case HGFS_STATUS_NOT_DIRECTORY:
- return ENOTDIR;
-
- case HGFS_STATUS_DIR_NOT_EMPTY:
- return ENOTEMPTY;
-
- case HGFS_STATUS_PROTOCOL_ERROR:
- return EPROTO;
-
- case HGFS_STATUS_ACCESS_DENIED:
- case HGFS_STATUS_SHARING_VIOLATION:
- return EACCES;
-
- case HGFS_STATUS_NO_SPACE:
- return ENOSPC;
-
- case HGFS_STATUS_OPERATION_NOT_SUPPORTED:
- return EOPNOTSUPP;
-
- case HGFS_STATUS_NAME_TOO_LONG:
- return ENAMETOOLONG;
-
- case HGFS_STATUS_GENERIC_ERROR:
- return EIO;
-
- default:
- DEBUG(VM_DEBUG_LOG, "VMware hgfs: %s: unknown "
- "error: %u\n", __FUNCTION__, hgfsStatus);
- return EIO;
- }
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * rindex --
- *
- * Search a character string for the last instance of chr. This is only
- * implemented for Mac OS because it is not exported by the Mac OS kernel.
- *
- * Results:
- * Pointer to the last instance of chr in the string.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-#if defined __APPLE__
-char *
-rindex(const char *ptr, // IN: String to search.
- int chr) // IN: Char to look for.
-{
- char *result = NULL;
-
- ASSERT(ptr);
-
- for (; *ptr != '\0'; ptr++) {
- if (*ptr == chr) {
- result = (char *)ptr;
- }
- }
-
- return result;
-}
-#endif
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsAttemptToCreateShare --
- *
- * Checks if an attempt to create a new share is made.
- *
- * Results:
- * Returns FALSE if not such attempt is made, TRUE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-HgfsAttemptToCreateShare(const char *path, // IN: Path
- int flag) // IN: flag
-{
- int ret = FALSE;
- ASSERT(path);
-
- /*
- * If the first character is the path seperator and
- * and there are no more path seperators present in the
- * path, then with the create flag (O_CREAT) set, we believe
- * that user has attempted to create new a share. This operation
- * is not permitted and hence EPERM error code is returned.
- */
- if ((flag & O_CREAT) && path[0] == DIRSEPC &&
- strchr(path + DIRSEPSLEN, DIRSEPC) == NULL) {
- ret = TRUE;
- }
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsNameToWireEncoding --
- * 1) Input string is converted into precomposed form.
- * 2) Precomposed string is then converted to cross platform string.
- * 3) Cross platform string is finally unescaped.
- *
- * Results:
- * Returns the size (excluding the NULL terminator) on success and
- * negative error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsNameToWireEncoding(const char *bufIn, // IN: Buffer to be normalized
- uint32 bufInSize, // IN: Size of input buffer
- char *bufOut, // OUT: Normalized string will be stored here
- uint32 bufOutSize) // IN: Size of output buffer
-{
- char *precomposedBuf = NULL; // allocated from M_TEMP; free when done.
- const char *utf8Buf;
- int ret = 0;
-
- if (os_utf8_conversion_needed()) {
- /* Allocating precomposed buffer to be equal to Output buffer. */
- precomposedBuf = os_malloc(bufOutSize, M_WAITOK);
- if (!precomposedBuf) {
- return -ENOMEM;
- }
-
- ret = os_path_to_utf8_precomposed(bufIn, bufInSize, precomposedBuf, bufOutSize);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "os_path_to_utf8_precomposed failed.");
- ret = -EINVAL;
- goto out;
- }
- utf8Buf = precomposedBuf;
- } else {
- utf8Buf = bufIn;
- }
-
- ret = CPName_ConvertTo(utf8Buf, bufOutSize, bufOut);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL,
- "CPName_ConvertTo: Conversion to cross platform name failed.\n");
- ret = -ENAMETOOLONG;
- goto out;
- }
-
-out:
- if (precomposedBuf != NULL) {
- os_free(precomposedBuf, bufOutSize);
- }
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsNameFromWireEncoding --
- * 1) Converts input from CPName form if necessary.
- * 2) Result is converted into decomposed form.
- *
- * Results:
- * Returns the size (excluding the NULL terminator) on success and
- * negative error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsNameFromWireEncoding(const char *bufIn, // IN: Buffer to be encoded
- uint32 inputLength, // IN: Number of characters in the input
- char *bufOut, // OUT: Encoded buffer will be stored here
- uint32 bufOutSize) // IN: Size of output buffer
-{
- size_t escapedLen;
- int ret = 0;
-
- /* Output buffer needs one additional byte for NUL terminator. */
- if (inputLength >= bufOutSize) {
- return -ENOMEM;
- }
- escapedLen = HgfsEscape_GetSize(bufIn, inputLength);
- if (escapedLen != 0) {
- HgfsEscape_Do(bufIn, inputLength, bufOutSize, bufOut);
- } else {
- escapedLen = inputLength;
- memcpy(bufOut, bufIn, inputLength);
- }
- CPNameLite_ConvertFrom(bufOut, escapedLen, '/');
-
- if (os_utf8_conversion_needed()) {
- size_t decomposedLen;
- char *decomposedBuf = NULL;
- /*
- * The decomposed form a string can be a lot bigger than the input
- * buffer size. We allocate a buffer equal to the output buffer.
- */
- decomposedBuf = os_malloc(bufOutSize, M_WAITOK);
- if (!decomposedBuf) {
- DEBUG(VM_DEBUG_FAIL, "Not enough memory for decomposed buffer size %d.\n",
- bufOutSize);
- return -ENOMEM;
- }
- /*
- * Convert the input buffer into decomposed form. Higher layers in
- * Mac OS expects the name to be in decomposed form.
- */
- ret = os_component_to_utf8_decomposed(bufOut, escapedLen, decomposedBuf,
- &decomposedLen, bufOutSize);
- /*
- * If the decomposed name didn't fit in the buffer or it contained
- * illegal utf8 characters, return back to the caller.
- * os_component_to_utf8_decomposed returns 0 on success or OS_ERR on failure.
- */
- if (ret != 0){
- DEBUG(VM_DEBUG_FAIL, "os_component_to_utf8_decomposed failed.\n");
- ret = -EINVAL;
- } else {
- if (decomposedLen < bufOutSize) {
- ret = decomposedLen;
- memcpy(bufOut, decomposedBuf, decomposedLen + 1);
- } else {
- DEBUG(VM_DEBUG_FAIL, "Output buffer is too small.\n");
- ret = -ENOMEM;
- }
- }
- os_free(decomposedBuf, bufOutSize);
- } else {
- ret = escapedLen;
- }
- return ret;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/fsutil.h b/open-vm-tools/modules/freebsd/vmhgfs/fsutil.h
deleted file mode 100644
index 9d1a7ec7..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/fsutil.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * fsutil.h --
- *
- * VFS helper functions that are shared between the FreeBSD and Mac OS
- * implementations of HGFS.
- */
-
-#ifndef _HGFS_FSUTIL_H_
-#define _HGFS_FSUTIL_H_
-
-#include <sys/param.h> // for everything
-#include <sys/vnode.h> // for struct vnode
-#include <sys/mount.h> // for struct mount
-#include <sys/namei.h> // for name lookup goodness
-#include <sys/fcntl.h> // for in-kernel file access flags (FREAD, etc)
-#include <sys/stat.h> // for file flag bitmasks (S_IRWXU, etc)
-#include <sys/uio.h> // for uiomove
-
-#include "debug.h"
-#include "hgfsUtil.h"
-#include "hgfs_kernel.h"
-#include "request.h"
-
-/*
- * Macros
- */
-
-/* Sets the values of request headers properly */
-#define HGFS_INIT_REQUEST_HDR(header, req, _op) \
- do { \
- header->id = HgfsKReq_GetId(req); \
- header->op = _op; \
- } while(0)
-
-/* Determine if this is the root vnode. */
-#define HGFS_IS_ROOT_VNODE(sip, vp) \
- (sip->rootVnode == vp)
-
-#define DIRSEPC '/'
-#define DIRSEPS "/"
-#define DIRSEPSLEN 1
-
-#define HGFS_VA_MODE va_mode
-#define HGFS_VA_UID va_uid
-#define HGFS_VA_GID va_gid
-#define HGFS_VA_TYPE va_type
-#define HGFS_VA_NLINK va_nlink
-#define HGFS_VA_FSID va_fsid
-#define HGFS_VA_FILEID va_fileid
-
-#define HGFS_VATTR_TYPE_RETURN(vap, val) \
- VATTR_RETURN(vap, va_type, val)
-
-#define HGFS_VATTR_MODE_RETURN(vap, val) \
- VATTR_RETURN(vap, va_mode, val)
-
-#define HGFS_VATTR_NLINK_RETURN(vap, val) \
- VATTR_RETURN(vap, va_nlink, val)
-
-#define HGFS_VATTR_UID_RETURN(vap, val) \
- VATTR_RETURN(vap, va_uid, val)
-
-#define HGFS_VATTR_GID_RETURN(vap, val) \
- VATTR_RETURN(vap, va_gid, val)
-
-#define HGFS_VATTR_FSID_RETURN(vap, val) \
- VATTR_RETURN(vap, va_fsid, val)
-
-#define HGFS_VATTR_FILEID_RETURN(vap, val) \
- VATTR_RETURN(vap, va_fileid, val)
-
-#if defined __APPLE__
- #define HGFS_VA_DATA_SIZE va_data_size
- #define HGFS_VA_DATA_BYTES va_data_size
- #define HGFS_VA_ACCESS_TIME_SEC va_access_time
- #define HGFS_VA_ACCESS_TIME va_access_time
- #define HGFS_VA_MODIFY_TIME_SEC va_modify_time
- #define HGFS_VA_MODIFY_TIME va_modify_time
- #define HGFS_VA_CREATE_TIME_SEC va_create_time
- #define HGFS_VA_CREATE_TIME va_create_time
- #define HGFS_VA_CHANGE_TIME_SEC va_change_time
- #define HGFS_VA_CHANGE_TIME va_change_time
- #define HGFS_VA_BLOCK_SIZE va_iosize
- #define HGFS_VATTR_IS_ACTIVE(vap, attr) \
- VATTR_IS_ACTIVE(vap, attr)
- #define HGFS_VATTR_MODE_IS_ACTIVE(vap, mode) \
- VATTR_IS_ACTIVE(vap, mode)
- #define HGFS_VATTR_SIZE_IS_ACTIVE(vap, size) \
- VATTR_IS_ACTIVE(vap, size)
- #define HGFS_VATTR_BLOCKSIZE_RETURN(vap, val) \
- VATTR_RETURN(vap, va_iosize, val)
- #define HGFS_VATTR_BYTES_RETURN(vap, val)
- #define HGFS_VATTR_SIZE_RETURN(vap, val) \
- VATTR_RETURN(vap, va_data_size, val)
- #define HGFS_VATTR_ACCESS_TIME_SET_SUPPORTED(vap) \
- VATTR_SET_SUPPORTED(vap, va_access_time)
- #define HGFS_VATTR_MODIFY_TIME_SET_SUPPORTED(vap) \
- VATTR_SET_SUPPORTED(vap, va_modify_time)
- #define HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap) \
- VATTR_SET_SUPPORTED(vap, va_create_time)
- #define HGFS_VATTR_CHANGE_TIME_SET_SUPPORTED(vap) \
- VATTR_SET_SUPPORTED(vap, va_change_time)
-
-#elif defined __FreeBSD__
- #define HGFS_VA_DATA_SIZE va_size
- #define HGFS_VA_DATA_BYTES va_bytes
- #define HGFS_VA_ACCESS_TIME_SEC va_atime.tv_sec
- #define HGFS_VA_ACCESS_TIME va_atime
- #define HGFS_VA_MODIFY_TIME_SEC va_mtime.tv_sec
- #define HGFS_VA_MODIFY_TIME va_mtime
- #define HGFS_VA_CHANGE_TIME_SEC va_ctime.tv_sec
- #define HGFS_VA_CHANGE_TIME va_ctime
- #define HGFS_VA_CREATE_TIME_SEC va_birthtime.tv_sec
- #define HGFS_VA_CREATE_TIME va_birthtime
- #define HGFS_VA_BLOCK_SIZE va_blocksize
- #define HGFS_VATTR_IS_ACTIVE(vap, attr) \
- (vap->attr != VNOVAL)
- #define HGFS_VATTR_MODE_IS_ACTIVE(vap, mode) \
- (vap->mode != (mode_t)VNOVAL)
- #define HGFS_VATTR_SIZE_IS_ACTIVE(vap, size) \
- (vap->size != (u_quad_t)VNOVAL)
- #define VATTR_SET_SUPPORTED(vap, time)
- #define HGFS_VATTR_BLOCKSIZE_RETURN(vap, val) \
- VATTR_RETURN(vap, va_blocksize, val)
- #define HGFS_VATTR_BYTES_RETURN(vap, val) \
- VATTR_RETURN(vap, va_bytes, val)
- #define HGFS_VATTR_SIZE_RETURN(vap, val) \
- VATTR_RETURN(vap, va_size, val)
-
- /* NULL macros */
- #define HGFS_VATTR_ACCESS_TIME_SET_SUPPORTED(vap)
- #define HGFS_VATTR_MODIFY_TIME_SET_SUPPORTED(vap)
- #define HGFS_VATTR_CREATE_TIME_SET_SUPPORTED(vap)
- #define HGFS_VATTR_CHANGE_TIME_SET_SUPPORTED(vap)
-#endif
-
-/*
- * Types
- */
-
-/*
- * Hgfs permissions are similar to Unix permissions in that they both include
- * bits for read vs. write vs. execute permissions. Since permissions of
- * owner, groups and others are passed as individual components by Hgfs,
- * we need simple bit shift operations for translation between Hgfs and Unix
- * permissions.
- */
-
-#define HGFS_ATTR_SPECIAL_PERM_SHIFT 9
-#define HGFS_ATTR_OWNER_PERM_SHIFT 6
-#define HGFS_ATTR_GROUP_PERM_SHIFT 3
-
-/* Solaris times support nsecs, so only use these functions directly */
-#define HGFS_SET_TIME(unixtm, nttime) \
- HgfsConvertFromNtTimeNsec(&unixtm, nttime)
-#define HGFS_GET_TIME(unixtm) \
- HgfsConvertTimeSpecToNtTime(&unixtm)
-
-/* Utility functions */
-
-int HgfsSubmitRequest(HgfsSuperInfo *sip, HgfsKReqHandle req);
-int HgfsGetStatus(HgfsKReqHandle req, uint32_t minSize);
-int HgfsEscapeBuffer(char const *bufIn, uint32 sizeIn,
- uint32 sizeBufOut, char *bufOut);
-int HgfsUnescapeBuffer(char *bufIn, uint32 sizeIn);
-int HgfsGetOpenMode(uint32 flags);
-int HgfsGetOpenFlags(uint32 flags);
-int HgfsMakeFullName(const char *path, uint32_t pathLen, const char *file,
- size_t fileLen, char *outBuf, ssize_t bufSize);
-void HgfsAttrToBSD(struct vnode *vp, const HgfsAttrV2 *hgfsAttrV2, HgfsVnodeAttr *vap);
-Bool HgfsSetattrCopy(HgfsVnodeAttr *vap, HgfsAttrV2 *hgfsAttrV2, HgfsAttrHint *hints);
-int HgfsStatusToBSD(HgfsStatus hgfsStatus);
-Bool HgfsAttemptToCreateShare(const char *path, int flag);
-int HgfsNameFromWireEncoding(const char *bufIn, uint32 bufInSize, char *bufOut, uint32 bufOutSize);
-int HgfsNameToWireEncoding(const char *bufIn, uint32 bufInSize, char *bufOut, uint32 bufOutSize);
-
-
-#endif // _HGFS_FSUTIL_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/hgfs_kernel.h b/open-vm-tools/modules/freebsd/vmhgfs/hgfs_kernel.h
deleted file mode 100644
index 766bdbce..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/hgfs_kernel.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * hgfs_kernel.h --
- *
- * Declarations for the FreeBSD Hgfs client kernel module. All
- * FreeBSD-specifc source files will include this.
- */
-
-#ifndef _HGFSKERNEL_H_
-#define _HGFSKERNEL_H_
-
-/*
- * Intended for the Hgfs client kernel module only.
- */
-#define INCLUDE_ALLOW_MODULE
-#include "includeCheck.h"
-
-/*
- * System includes
- */
-
-#include <sys/param.h> // for <everything>
-#include <sys/vnode.h> // for struct vnode
-
-/*
- * VMware includes
- */
-
-#include "dbllnklst.h"
-
-#include "request.h"
-#include "state.h"
-#include "hgfs.h"
-#include "hgfsProto.h"
-
-#include "vm_basic_types.h"
-#include "vm_assert.h"
-
-
-/*
- * Macros
- */
-
-#define HGFS_PAYLOAD_MAX(size) (HGFS_PACKET_MAX - size)
-#define HGFS_FS_NAME "vmhgfs"
-#define HGFS_FS_NAME_LONG "VMware Hgfs client"
-/*
- * NB: Used only to provide a value for struct vattr::va_blocksize, "blocksize
- * preferred for i/o".
- */
-#define HGFS_BLOCKSIZE 1024
-
-/* Internal error code(s) */
-#define HGFS_ERR (-1)
-#define HGFS_ERR_NULL_INPUT (-50)
-#define HGFS_ERR_NODEV (-51)
-#define HGFS_ERR_INVAL (-52)
-
-#if defined __FreeBSD__
-# define HGFS_MP_TO_MNTFLAGS(mp) \
- ((mp)->mnt_flag)
-# define HGFS_MP_SET_SIP(mp, sip) \
- ((mp)->mnt_data = (sip))
-# define HGFS_VP_TO_MP(vp) ((vp)->v_mount)
-/* Return a pointer to mnt_stat to preserve the interface between Mac OS and FreeBSD. */
-# define HGFS_MP_TO_STATFS(mp) (&(mp)->mnt_stat)
- /* Getting to sip via any vnode */
-# define HGFS_VP_TO_SIP(vp) \
- ((HgfsSuperInfo*)HGFS_VP_TO_MP(vp)->mnt_data)
-
-# define HGFS_VP_VI_LOCK(vp) \
- (VI_LOCK(vp))
-# define HGFS_VP_VI_UNLOCK(vp) \
- (VI_UNLOCK(vp))
-# define HGFS_VP_ISINUSE(vp, usecount) \
- ((vp)->v_usecount > usecount)
-# define HGFS_MP_IS_FORCEUNMOUNT(mp) \
- (mp->mnt_kern_flag & MNTK_UNMOUNTF)
-#elif defined __APPLE__
-# define HGFS_MP_TO_MNTFLAGS(mp) \
- (vfs_flags(mp))
-# define HGFS_MP_SET_SIP(mp, sip) \
- (vfs_setfsprivate(mp, sip))
-# define HGFS_VP_TO_MP(vp) (vnode_mount(vp))
-# define HGFS_MP_TO_STATFS(mp) (vfs_statfs(mp))
-# define HGFS_VP_TO_SIP(vp) \
- ((HgfsSuperInfo*)vfs_fsprivate(HGFS_VP_TO_MP(vp)))
-
-/*
- * No concept of vnode locks are exposed to the Mac OS VFS layer, so do nothing here for
- * VI_LOCK AND VI_UNLOCK. However, make sure to call the lock functions before using
- * HGFS_VP_ISINUSE to preserve compatability with FreeBSD.
- */
-# define HGFS_VP_VI_LOCK(vp)
-# define HGFS_VP_VI_UNLOCK(vp)
-# define HGFS_VP_ISINUSE(vp, usecount) \
- (vnode_isinuse(vp, usecount))
-# define HGFS_MP_IS_FORCEUNMOUNT(mp) \
- (vfs_isforce(mp))
-#endif
-
-#define HGFS_VP_TO_STATFS(vp) (HGFS_MP_TO_STATFS(HGFS_VP_TO_MP(vp)))
-
-/*
- * Types
- */
-
-
-
-/* We call them *Header in the kernel code for clarity. */
-typedef HgfsReply HgfsReplyHeader;
-typedef HgfsRequest HgfsRequestHeader;
-
-/*
- * The global state structure for a single filesystem mount. This is allocated
- * in HgfsVfsMount() and destroyed in HgfsVfsUnmount().
- */
-typedef struct HgfsSuperInfo {
- Bool uidSet;
- uid_t uid;
- Bool gidSet;
- gid_t gid;
- /* Request container */
- HgfsKReqContainerHandle reqs; /* See request.h. */
- /* For filesystem */
- struct mount *vfsp; /* Our filesystem structure */
- struct vnode *rootVnode; /* Root vnode of the filesystem */
- HgfsFileHashTable fileHashTable; /* File hash table */
- char volumeName[MAXPATHLEN]; /* Name of the volume or share. */
-} HgfsSuperInfo;
-
-
-/*
- * Global variables
- */
-
-/*
- * The vnode attributes between Mac OS and FreeBSD are very similar but not exactly the
- * same. Fields have names have changed. However, only HgfsAttrToBSD and
- * HgfsSetattrCopy care about the differences so we mash the types together to enable
- * single function signatures.
- */
-#if defined __FreeBSD__
- typedef struct vattr HgfsVnodeAttr;
-#elif defined __APPLE__
- typedef struct vnode_attr HgfsVnodeAttr;
-#endif
-
-#if defined __FreeBSD__
- /* Defined in vnops.c. */
- extern struct vop_vector HgfsVnodeOps;
-#elif defined __APPLE__
- /* Export vnops.c file operations. */
- extern errno_t (**HgfsVnodeOps)(void *);
- extern struct vnodeopv_desc *HgfsVnodeOperationVectorDescList[1];
-#endif
-
-#endif // ifndef _HGFSKERNEL_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/kernelStubs.h b/open-vm-tools/modules/freebsd/vmhgfs/kernelStubs.h
deleted file mode 100644
index 800a0cf8..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/kernelStubs.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*********************************************************
- * Copyright (C) 2006 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
- *
- *********************************************************/
-
-/*
- * kernelStubs.h
- *
- * KernelStubs implements some userspace library functions in terms
- * of kernel functions to allow library userspace code to be used in a
- * kernel.
- */
-
-#ifndef __KERNELSTUBS_H__
-#define __KERNELSTUBS_H__
-
-#ifdef linux
-# ifndef __KERNEL__
-# error "__KERNEL__ is not defined"
-# endif
-# include "driver-config.h" // Must be included before any other header files
-# include "vm_basic_types.h"
-# 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 */
-#elif defined(__FreeBSD__)
-# include "vm_basic_types.h"
-# ifndef _KERNEL
-# error "_KERNEL is not defined"
-# endif
-# include <sys/types.h>
-# include <sys/malloc.h>
-# include <sys/param.h>
-# include <sys/kernel.h>
-# include <machine/stdarg.h>
-# include <sys/libkern.h>
-#elif defined(__APPLE__)
-# include "vm_basic_types.h"
-# ifndef KERNEL
-# error "KERNEL is not defined"
-# endif
-# include <stdarg.h>
-# include <string.h>
-# elif defined(sun)
-# include "vm_basic_types.h"
-# include <sys/types.h>
-# include <sys/varargs.h>
-#endif
-
-/*
- * Function Prototypes
- */
-
-#if defined(linux) || defined(__APPLE__) || defined (sun)
-
-# ifdef linux /* if (linux) { */
-char *strdup(const char *source);
-# endif
-
-/* Shared between Linux and Apple kernel stubs. */
-void *malloc(size_t size);
-void free(void *mem);
-void *calloc(size_t num, size_t len);
-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;
-
-/* No free with tag availaible on NT4 kernel! */
-#define KRNL_STUBS_FREE(P,T) ExFreePool((P))
-
-#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 */
-
-#elif defined(__FreeBSD__) /* } else if (FreeBSD) { */
-
-/* Kernel memory on FreeBSD is tagged for statistics and sanity checking. */
-MALLOC_DECLARE(M_VMWARE_TEMP);
-
-/*
- * On FreeBSD, the general memory allocator for both userland and the kernel is named
- * malloc, but the kernel malloc() takes more arguments. The following alias & macros
- * work around this, to provide the standard malloc() API for userspace code that is
- * being used in the kernel.
- */
-
-# undef malloc
-
-static INLINE void *
-__compat_malloc(unsigned long size, struct malloc_type *type, int flags) {
- return malloc(size, type, flags);
-}
-
-# define malloc(size) __compat_malloc(size, M_VMWARE_TEMP, M_NOWAIT)
-# define calloc(count, size) __compat_malloc((count) * (size), \
- M_VMWARE_TEMP, M_NOWAIT|M_ZERO)
-# define realloc(buf, size) realloc(buf, size, M_VMWARE_TEMP, M_NOWAIT)
-# define free(buf) free(buf, M_VMWARE_TEMP)
-# define strchr(s,c) index(s,c)
-# define strrchr(s,c) rindex(s,c)
-
-#endif /* } */
-
-/*
- * Stub functions we provide.
- */
-
-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, ...);
-
-/*
- * Functions the driver must implement for the stubs.
- */
-EXTERN void Debug(const char *fmt, ...);
-
-
-#endif /* __KERNELSTUBS_H__ */
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/kernelStubsBSD.c b/open-vm-tools/modules/freebsd/vmhgfs/kernelStubsBSD.c
deleted file mode 100644
index b6fb72f5..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/kernelStubsBSD.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * kernelStubsBSD.c --
- *
- * Stub functions for use by miscellaneous VMware code when brought into
- * the FreeBSD kernel.
- */
-
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <machine/stdarg.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-
-#include "kernelStubs.h"
-
-MALLOC_DEFINE(M_VMWARE_TEMP, "VMwareTemp", "VMware: Temporary Allocations");
-
-void Log (const char *fmt, ...) __attribute__ ((alias ("Debug")));
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Debug --
- *
- * Send a debugging message to the system log and/or console.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Debug(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Panic --
- *
- * Print a panic message & induce a kernel panic.
- *
- * Results:
- * Does not return.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-Panic(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-
- panic(" ");
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Str_Strcpy --
- *
- * Wrapper around strcpy that panics if the source is too long.
- *
- * Results:
- * Returns a pointer to buf.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-char *
-Str_Strcpy(char *buf, // OUT: destination buffer
- const char *src, // IN : source buffer
- size_t maxSize) // IN : size of buf
-{
- size_t srcLen = strlen(src);
- if (srcLen >= maxSize) {
- panic("%s:%d Buffer too small %p\n", __FILE__, __LINE__, buf);
- }
- return memcpy(buf, src, srcLen + 1); // Extra byte = terminator
-}
-
-
-/*
- *----------------------------------------------------------------------
- *
- * Str_Vsnprintf --
- *
- * Compatibility wrapper for vsnprintf(1).
- *
- * Results:
- *
- * int - number of bytes stored in 'str' (not including null
- * terminate character), -1 on overflow (insufficient space for
- * null terminate is considered overflow)
- *
- * NB: on overflow the buffer WILL be null terminated
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-int
-Str_Vsnprintf(char *str, // OUT: destination buffer
- size_t size, // IN : size of str
- const char *format, // IN : format for vsnprintf
- va_list arguments) // IN : variadic args for vsnprintf
-{
- int retval;
-
- retval = vsnprintf(str, size, format, arguments);
- if (retval >= size) {
- retval = -1;
- }
- return retval;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Str_Vasprintf --
- *
- * Allocate and format a string, using the GNU libc way to specify the
- * format (i.e. optionally allow the use of positional parameters)
- *
- * Results:
- * The allocated string on success (if 'length' is not NULL, *length
- * is set to the length of the allocated string)
- * NULL on failure
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-char *
-Str_Vasprintf(size_t *length, // OUT
- const char *format, // IN
- va_list arguments) // IN
-{
- /*
- * Simple implementation of Str_Vasprintf when userlevel libraries are not
- * available (e.g. for use in drivers). We just fallback to vsnprintf,
- * doubling if we didn't have enough space.
- */
- unsigned int bufSize;
- char *buf;
- int retval;
-
- bufSize = strlen(format);
- buf = NULL;
-
- do {
- /*
- * Initial allocation of strlen(format) * 2. Should this be tunable?
- * XXX Yes, this could overflow and spin forever when you get near 2GB
- * allocations. I don't care. --rrdharan
- */
-
- va_list tmpArgs;
-
- bufSize *= 2;
- buf = realloc(buf, bufSize);
-
- if (!buf) {
- return NULL;
- }
-
- va_copy(tmpArgs, arguments);
- retval = Str_Vsnprintf(buf, bufSize, format, tmpArgs);
- va_end(tmpArgs);
- } while (retval == -1);
-
- if (length) {
- *length = retval;
- }
-
- /*
- * Try to trim the buffer here to save memory?
- */
- return buf;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Str_Asprintf --
- *
- * Same as Str_Vasprintf(), but parameters are passed inline --hpreg
- *
- * Results:
- * Same as Str_Vasprintf()
- *
- * Side effects:
- * Same as Str_Vasprintf()
- *
- *-----------------------------------------------------------------------------
- */
-
-char *
-Str_Asprintf(size_t *length, // OUT
- const char *format, // IN
- ...) // IN
-{
- va_list arguments;
- char *result;
-
- va_start(arguments, format);
- result = Str_Vasprintf(length, format, arguments);
- va_end(arguments);
-
- return result;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/os.c b/open-vm-tools/modules/freebsd/vmhgfs/os.c
deleted file mode 100644
index 2bfae4d0..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/os.c
+++ /dev/null
@@ -1,928 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * os.c --
- *
- * FreeBSD specific implementations of the hgfs memory allocation
- * and thread synchronization routines.
- */
-
-#if !defined _KERNEL
-# error "This os.c file can only be compiled for the FreeBSD kernel."
-#endif
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/malloc.h>
-#include <sys/lock.h> // for struct mtx
-#include <sys/kernel.h>
-#include <vm/uma.h> // for uma_zone_t
-#include <sys/kthread.h> // for kthread_create()
-#include <vm/vm.h>
-#include <vm/vm_extern.h> // for vnode_pager_setsize
-
-#include "vm_basic_types.h"
-#include "os.h"
-#include "debug.h"
-#include "channel.h"
-#include "compat_freebsd.h"
-
-/*
- * Malloc tag for statistics, debugging, etc.
- */
-MALLOC_DEFINE(M_HGFS, HGFS_FS_NAME, HGFS_FS_NAME_LONG);
-
-/*
- * Since FreeBSD provides a zone allocator, just store a pointer to the FreeBSD
- * zone allocator.
- */
-typedef struct os_zone_struct {
- struct uma_zone *umaZone;
-} os_zone_struct;
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_init --
- *
- * Initialize the global memory allocation variables needed by other
- * functions in this file. Must be called before any other functions in this
- * file.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-os_init(void)
-{
- /* NOP */
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_cleanup --
- *
- * Cleanup the global variables that were created in os_init.
- * Must be called if os_init was called. Other functions in this
- * file cannot be called after os_cleanup is called.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_cleanup(void)
-{
- /* NOP */
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_zone_create --
- *
- * Creates a new zone (OS_ZONE_T) from which memory allocations can
- * be made.
- *
- * Results:
- * Either an uma zone or NULL (if no memory was available).
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-OS_ZONE_T *
-os_zone_create(char *zoneName, // IN
- size_t objectSize, // IN
- os_zone_ctor ctor, // IN
- os_zone_dtor dtor, // IN
- os_zone_init init, // IN
- os_zone_finit finit, // IN
- int align, // IN
- uint32 flags) // IN
-{
- OS_ZONE_T *zone;
-
- zone = os_malloc(sizeof *zone, M_WAITOK);
- zone->umaZone = uma_zcreate(zoneName,
- objectSize, ctor, dtor, init, finit, align, flags);
- return zone;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_zone_destroy --
- *
- * _destroys a zone created with os_zone_create.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_zone_destroy(OS_ZONE_T *zone) // IN
-{
- ASSERT(zone);
-
- uma_zdestroy(zone->umaZone);
- os_free(zone, sizeof *zone);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_zone_alloc --
- *
- * Allocates an object from the specified zone and calls the the zone
- * initializer and constructor.
- *
- * Results:
- * Either an allocated and initizalized object or NULL.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void *
-os_zone_alloc(OS_ZONE_T *zone, // IN
- int flags) // IN
-{
- void *mem;
- HgfsTransportChannel *channel = gHgfsChannel;
- HgfsKReqObject *req;
- ASSERT(zone);
- ASSERT(zone->umaZone);
-
- mem = uma_zalloc(zone->umaZone, flags | M_ZERO);
- if (mem) {
- req = (HgfsKReqObject *)mem;
- req->channel = channel;
- }
- return mem;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_zone_free --
- *
- * Calls the zone destructor and final initialization routine on the
- * specified object and then frees the object.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_zone_free(OS_ZONE_T *zone, // IN
- void *mem) // IN
-{
- ASSERT(zone);
- ASSERT(zone->umaZone);
-
- uma_zfree(zone->umaZone, mem);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_malloc --
- *
- * Malloc some memory in a FreeBSD / Mac OS kernel independent manner.
- * This just calls the internal kernel malloc function. According to the
- * FreeBSD commments, if M_WAITOK is passed to the flags, malloc will never
- * return NULL.
- *
- * Results:
- * A pointer to allocated memory or NULL.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void *
-os_malloc(size_t size, // IN
- int flags) // IN
-{
- return malloc(size, M_HGFS, flags);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_free --
- *
- * Free some memory in a FreeBSD / Mac OS kernel independent manner.
- * This just calls the internal kernel free function.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The memory (mem) is freed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_free(void *mem, // IN
- size_t size) // IN
-{
- free(mem, M_HGFS);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_mutex_alloc_init --
- *
- * Allocate and initialize a FreeBSD mutex in an OS independent way.
- * Mtx_name is not used on Mac OS.
- *
- * Results:
- * A new mtx which has been allocated and is ready for use.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-OS_MUTEX_T *
-os_mutex_alloc_init(const char *mtxName) // IN
-{
- OS_MUTEX_T *mtx;
- mtx = os_malloc(sizeof *mtx,
- M_ZERO | M_WAITOK);
- mtx_init(mtx, mtxName, NULL, MTX_DEF);
- return mtx;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_mutex_free --
- *
- * Frees a FreeBSD mutex in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The mutex (mtx) is destroyed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_mutex_free(OS_MUTEX_T *mtx) // IN
-{
- mtx_destroy(mtx);
- os_free(mtx, sizeof *mtx);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_mutex_lock --
- *
- * Lock a FreeBSD mutex in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_mutex_lock(OS_MUTEX_T *mtx) // IN
-{
- mtx_lock(mtx);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_mutex_unlock --
- *
- * Unlock a FreeBSD mutex in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_mutex_unlock(OS_MUTEX_T *mtx) // IN
-{
- mtx_unlock(mtx);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_rw_lock_alloc_init --
- *
- * Allocate and initialize a FreeBSD rwlock in an OS independent way.
- *
- * Results:
- * A new lock which has been allocated and is ready for use.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-OS_RWLOCK_T *
-os_rw_lock_alloc_init(const char *lckName) // IN
-{
- OS_RWLOCK_T *lck;
- lck = os_malloc(sizeof *lck,
- M_ZERO | M_WAITOK);
- sx_init(lck, lckName);
- return lck;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_rw_lock_free --
- *
- * Frees a FreeBSD rwlock in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The rwlock (lck) is destroyed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_rw_lock_free(OS_RWLOCK_T *lck) // IN
-{
- sx_destroy(lck);
- os_free(lck, sizeof *lck);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_rw_lock_lock_shared --
- *
- * Lock a FreeBSD rwlock for reads in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_rw_lock_lock_shared(OS_RWLOCK_T *lck) // IN
-{
- sx_slock(lck);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_rw_lock_lock_exclusive --
- *
- * Lock a FreeBSD rwlock for writes in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_rw_lock_lock_exclusive(OS_RWLOCK_T *lck) // IN
-{
- sx_xlock(lck);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_rw_lock_unlock_shared --
- *
- * Unlock FreeBSD rwlock in an OS independent way. Results are
- * undefined if the function caller has an exculsive lock on lck.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_rw_lock_unlock_shared(OS_RWLOCK_T *lck) // IN
-{
- sx_sunlock(lck);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_rw_lock_unlock_exclusive --
- *
- * Unlock FreeBSD rwlock in an OS independent way. Results are
- * undefined if the function caller has an exculsive lock on lck.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_rw_lock_unlock_exclusive(OS_RWLOCK_T *lck) // IN
-{
- sx_xunlock(lck);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_cv_init --
- *
- * Initialize a cv under FreeBSD. Under Mac OS, we are actually passed an
- * object address we will use in place of a cv in later functions. Here
- * we simply do nothing.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_cv_init(OS_CV_T *cv, // IN
- const char *name) // IN
-{
- cv_init(cv, name);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_cv_destroy --
- *
- * Destroy a cv under FreeBSD. Under Mac OS, we are actually passed an
- * object address we will use in place of a cv in later functions. Here
- * we simply do nothing.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_cv_destroy(OS_CV_T *cv) // IN
-{
- cv_destroy(cv);
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_cv_signal --
- *
- * Signal a thread to wakeup in a FreeBSD/Mac OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_cv_signal(OS_CV_T *cv) // IN
-{
- cv_signal(cv);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_cv_wait --
- *
- * Have an XNU or FreeBSD kernel thread wait until the specified condition
- * is signaled. This function unlocks the mutex (mtx) before it goes to
- * sleep and reacquires it after the thread wakes up. Under FreeBSD it is a
- * standard condition variable. os_cv_wait will return immediately if the
- * thread was interrupted. It is the callers responsibility to determine
- * if a signal was delivered or the dependent condition actually occurred.
- * Under FreeBSD, it is illegal to sleep while holding a lock. Callers of
- * this function should not hold any locks other than the mutex (mtx) that
- * is passed into the function.
- *
- * Results:
- * Zero on success. On FreeBSD errno if interrupted.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-os_cv_wait(OS_CV_T *cv, // IN
- OS_MUTEX_T *mtx) // IN
-{
- return cv_wait_sig(cv, mtx);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_thread_create --
- *
- * Create an Mac OS or FreeBSD kernel thread in an OS independent way.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-os_thread_create(void *function, // IN
- void *parameter, // IN
- const char *threadName, // IN
- OS_THREAD_T *newThread) // OUT
-{
- return compat_kthread_create(function, parameter,
- newThread, 0, 0, threadName);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_thread_join --
- *
- * Wait until the specified kernel thread exits and then return. Mtx must
- * be held by the calling code and the thread (thread) is not allowed to
- * exit while mtx is held. This prevents (thread) from exiting before
- * the caller goes to sleep.
- *
- * Results:
- * Zero on success.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_thread_join(OS_THREAD_T thread, // IN
- OS_MUTEX_T *mtx) // IN
-{
- ASSERT(mtx);
-
- msleep(thread, mtx, PDROP, NULL, 0);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_thread_release --
- *
- * Release the OS_THREAD_T reference that was acquired in os_thread_create.
- * This is a nop on FreeBSD.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_thread_release(OS_THREAD_T thread) // IN
-{
- /* NOP */
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * Hgfsthreadexit --
- *
- * Called when a thread is exiting. ErrorCode is returned as the thread exit code
- * under FreeBSD and ignored under Mac OS.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-os_thread_exit(int errorCode) // IN
-{
- compat_kthread_exit(errorCode);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_add_atomic --
- *
- * Atomically increment an integer at a given location (address) by a given
- * value (amount).
- *
- * Results:
- * The value before the addition..
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-os_add_atomic(unsigned *address, // IN
- int amount) // IN
-{
- return atomic_fetchadd_int(address, amount);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_utf8_conversion_needed --
- *
- * It returns result depending upon whether a particular operating
- * system expects utf8 strings in a format (decomposed utf8)
- * different from wire format (precomposed utf8) or not. Since FreeBSD
- * does not expect decomposed utf8, we return FALSE.
- *
- * Results:
- * FALSE if conversion is not needed, TRUE if needed.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-os_utf8_conversion_needed(void)
-{
- return FALSE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_component_to_utf8_decomposed --
- *
- * Converts an input component into decomposed form and writes it into
- * output buffer. It simply returns OS_ERR for FreeBSD.
- *
- * Results:
- * 0 on success or OS_ERR on failure. Since this function is not
- * implemented, it always returns OS_ERR.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-os_component_to_utf8_decomposed(char const *bufIn, // IN
- uint32 bufSizeIn, // IN
- char *bufOut, // OUT
- size_t *sizeOut, // OUT
- uint32 bufSizeOut) // IN
-{
- NOT_IMPLEMENTED();
- return OS_ERR;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_component_to_utf8_precomposed --
- *
- * Converts an input component into precomposed form and writes it into
- * output buffer. It simply returns OS_ERR for FreeBSD.
- *
- * Results:
- * 0 on success or OS_ERR on failure. Since this function is not
- * implemented, it always returns OS_ERR.
- *
- * Side effects:
- * None.
- *----------------------------------------------------------------------------
- */
-
-int
-os_component_to_utf8_precomposed(char const *bufIn, // IN
- uint32 bufSizeIn, // IN
- char *bufOut, // OUT
- size_t *sizeOut, // OUT
- uint32 bufSizeOut) // IN
-{
- NOT_IMPLEMENTED();
- return OS_ERR;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_path_to_utf8_precomposed --
- *
- * Converts an input path into precomposed form and writes it into output
- * buffer. It simply returns OS_ERR for FreeBSD.
- *
- * Results:
- * 0 on success or OS_ERR on failure. Since this function is not
- * implemented, it always returns OS_ERR.
- *
- * Side effects:
- * None.
- *----------------------------------------------------------------------------
- */
-
-int
-os_path_to_utf8_precomposed(char const *bufIn, // IN
- uint32 bufSizeIn, // IN
- char *bufOut, // OUT
- uint32 bufSizeOut) // IN
-{
- NOT_IMPLEMENTED();
- return OS_ERR;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_SetSize --
- *
- * Notifies memory management system that file size has been changed.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *----------------------------------------------------------------------------
- */
-
-void
-os_SetSize(struct vnode* vp, // IN: vnode which size has changed
- off_t newSize) // IN: new file size
-{
- vnode_pager_setsize(vp, newSize);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * os_FlushRange --
- *
- * Flushes dirty pages associated with the file.
- *
- * Results:
- * Always retun 0 (success) for now since it is NOOP.
- *
- * Side effects:
- * None.
- *----------------------------------------------------------------------------
- */
-
-int
-os_FlushRange(struct vnode *vp, // IN: vnode which data needs flushing
- off_t start, // IN: starting offset in the file to flush
- uint32_t length) // IN: length of data to flush
-{
- /*
- * XXX: NOOP for now. This routine is needed to maintain coherence
- * between memory mapped data and data for read/write operations.
- * Will need to implement when adding support for memory mapped files to HGFS
- * for FreeBsd.
- */
- return 0;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/os.h b/open-vm-tools/modules/freebsd/vmhgfs/os.h
deleted file mode 100644
index 9e10bc6d..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/os.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-
-/*
- * os.h --
- *
- * Wrappers for OS specific functions that are different between Mac OS and FreeBsd.
- * 1. Implementation Mac OS / FreeBSD independent memory allocation and
- * thread synchronization routines.
- * 2. Interaction with memory manager/pager.
- */
-
-#ifndef _OS_H_
-#define _OS_H_
-
-#if defined __FreeBSD__
-# include <sys/param.h> // for <everything>
-# include <sys/proc.h>
-# include <sys/condvar.h>
-# include <sys/lock.h> // for struct mtx
-# include <sys/mutex.h> // for struct mtx
-# include <sys/sx.h>
-#elif defined __APPLE__
-# include <kern/thread.h>
-# include <kern/locks.h>
-#endif
-
-#include <sys/malloc.h>
-#include "vm_basic_types.h"
-
-#if defined __FreeBSD__
- typedef struct proc *OS_THREAD_T;
- typedef struct mtx OS_MUTEX_T;
- typedef struct sx OS_RWLOCK_T;
- typedef struct cv OS_CV_T;
-#elif defined __APPLE__
- typedef thread_t OS_THREAD_T;
- typedef lck_mtx_t OS_MUTEX_T;
- typedef lck_rw_t OS_RWLOCK_T;
- /*
- * In Mac OS, a kernel thread waits on a 32-bit integer. To avoid collision,
- * Apple recommends that threads wait on the address of an object.
- */
- typedef void *OS_CV_T;
-#endif
-
-/* OS_ERR is the error code returned by os_* functions on error. */
-#define OS_ERR (-1)
-
-int os_init(void);
-void os_cleanup(void);
-
-/*
- * There does not seem to be a public zone allocator exposed in Mac OS. We create
- * a zone wrapper around the FreeBSD zone allocator so that we can keep the
- * FreeBSD zone allocator and support Mac OS at the same time.
- */
-
-struct os_zone_struct;
-typedef struct os_zone_struct OS_ZONE_T;
-
-/*
- * Provide zone allocator function prototypes with the same signature as
- * the ones used in the FreeBSD kernel. This way they can be used both with
- * the FreeBSD uma allocator and the custom Mac OS allocation functions.
- */
-typedef int (*os_zone_ctor)(void *mem, int size, void *arg, int flags);
-typedef void (*os_zone_dtor)(void *mem, int size, void *arg);
-typedef int (*os_zone_init)(void *mem, int size, int flags);
-typedef void (*os_zone_finit)(void *mem, int size);
-
-OS_ZONE_T *os_zone_create(char *zoneName, size_t objectSize,
- os_zone_ctor ctor, os_zone_dtor dtor,
- os_zone_init init, os_zone_finit finit,
- int align, uint32 flags);
-void os_zone_destroy(OS_ZONE_T *zone);
-void *os_zone_alloc(OS_ZONE_T *zone, int flags);
-void os_zone_free(OS_ZONE_T *zone, void *mem);
-
-void *os_malloc(size_t size, int flags);
-void os_free(void *mem, size_t size);
-
-extern OS_MUTEX_T *os_mutex_alloc_init(const char *mtxName);
-extern void os_mutex_free(OS_MUTEX_T *mtx);
-extern void os_mutex_lock(OS_MUTEX_T *mtx);
-extern void os_mutex_unlock(OS_MUTEX_T *mtx);
-
-extern OS_RWLOCK_T *os_rw_lock_alloc_init(const char *lckName);
-extern void os_rw_lock_free(OS_RWLOCK_T *lck);
-extern void os_rw_lock_lock_shared(OS_RWLOCK_T *lck);
-extern void os_rw_lock_lock_exclusive(OS_RWLOCK_T *lck);
-extern void os_rw_lock_unlock_shared(OS_RWLOCK_T *lck);
-extern void os_rw_lock_unlock_exclusive(OS_RWLOCK_T *lck);
-
-extern void os_cv_init(OS_CV_T *cv, const char *name);
-extern void os_cv_destroy(OS_CV_T *cv);
-extern void os_cv_signal(OS_CV_T *cv);
-extern int os_cv_wait(OS_CV_T *cv, OS_MUTEX_T *mtx);
-
-extern int os_thread_create(void *function, void *parameter,
- const char *threadName, OS_THREAD_T *newThread);
-extern void os_thread_join(OS_THREAD_T thread, OS_MUTEX_T *mtx);
-extern void os_thread_release(OS_THREAD_T thread);
-extern void os_thread_exit(int errorCode);
-
-extern int os_add_atomic(unsigned int *address, int amount);
-extern int os_component_to_utf8_decomposed(const char *bufIn, uint32 bufInSize, char *bufOut,
- size_t *sizeOut, uint32 bufOutSize);
-extern int os_component_to_utf8_precomposed(const char *bufIn, uint32 bufInSize, char *bufOut,
- size_t *sizeOut, uint32 bufOutSize);
-extern int os_path_to_utf8_precomposed(const char *bufIn, uint32 bufInSize, char *bufOut,
- uint32 bufOutSize);
-extern Bool os_utf8_conversion_needed(void);
-
-// Memory manager/pager functions
-void os_SetSize(struct vnode *vp, off_t newSize);
-int os_FlushRange(struct vnode *vp, off_t start, uint32_t length);
-
-#endif // ifndef _OS_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/request.c b/open-vm-tools/modules/freebsd/vmhgfs/request.c
deleted file mode 100644
index b3a0cac6..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/request.c
+++ /dev/null
@@ -1,868 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-
-/*
- * request.c --
- *
- * Implementation of routines used to initialize, allocate, and move
- * requests between lists.
- */
-
-/*
- * Includes
- */
-
-#include "hgfs_kernel.h"
-#include "requestInt.h"
-#include "channel.h"
-
-/*
- * Macros
- */
-
-/*
- * Since the DblLnkLst_Links in the requests container is just an anchor, we want to
- * skip it (e.g., get the container for the next element)
- */
-#define HGFS_SIP_LIST_HEAD(sip) \
- (DblLnkLst_Container((sip)->reqs->list.next, HgfsKReqObject, fsNode))
-#define HGFS_SIP_LIST_HEAD_NODE(sip) (sip->reqs->list.next)
-
-
-/*
- * Local data
- */
-
-/*
- * See requestInt.h for details.
- */
-
-DblLnkLst_Links hgfsKReqWorkItemList;
-OS_MUTEX_T *hgfsKReqWorkItemLock;
-OS_ZONE_T *hgfsKReqZone;
-
-OS_CV_T hgfsKReqWorkItemCv;
-
-/*
- * Local functions (prototypes)
- */
-
-static int HgfsKReqZCtor(void *mem, int size, void *arg, int flags);
-static void HgfsKReqZDtor(void *mem, int size, void *arg);
-static int HgfsKReqZInit(void *mem, int size, int flags);
-static void HgfsKReqZFini(void *mem, int size);
-
-/*
- * Global functions (definitions)
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReq_SysInit --
- *
- * This function simply initializes the hgfsKReqZone. This is done
- * separately from the VFS initialization routine, our caller, in order
- * to abstract away the request allocation & support code.
- *
- * Results:
- * Zero on success, HGFS_ERR on error.
- *
- * Side effects:
- * hgfsKReqZone is initialized. This routine may sleep.
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-HgfsKReq_SysInit(void)
-{
- int ret = 0;
-
- hgfsKReqZone = os_zone_create(HGFS_FS_NAME "_zone",
- sizeof (struct HgfsKReqObject),
- HgfsKReqZCtor, HgfsKReqZDtor, HgfsKReqZInit,
- HgfsKReqZFini, 0, 0);
-
- if (!hgfsKReqZone) {
- return HGFS_ERR;
- }
-
- hgfsKReqWorkItemLock = os_mutex_alloc_init(HGFS_FS_NAME "_workmtx");
- if (!hgfsKReqWorkItemLock) {
- os_zone_destroy(hgfsKReqZone);
- return HGFS_ERR;
- }
-
- /*
- * This is a nop on Mac OS because we don't actually have a condition variable
- * to initialize.
- */
- os_cv_init(&hgfsKReqWorkItemCv, HGFS_FS_NAME "_workcv");
- DblLnkLst_Init(&hgfsKReqWorkItemList);
-
- /* Spawn the worker thread. */
- ret = os_thread_create(HgfsKReqWorker, &hgfsKReqWorkerState,
- "HgfsKReqWorker", &hgfsKReqWorkerThread);
-
- if (ret != 0) {
- os_cv_destroy(&hgfsKReqWorkItemCv);
- os_zone_destroy(hgfsKReqZone);
- os_mutex_free(hgfsKReqWorkItemLock);
- return HGFS_ERR;
- }
-
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReq_SysFini --
- *
- * Hgfs request subsystem cleanup routine. This should be called when the
- * Hgfs client module is unloaded from the kernel.
- *
- * Results:
- * Zero on success or errno on failure.
- *
- * Side effects:
- * This routine may (will?) sleep. hgfsKReqZone is destroyed.
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-HgfsKReq_SysFini(void)
-{
- /* Signal the worker thread to exit. */
- os_mutex_lock(hgfsKReqWorkItemLock);
- hgfsKReqWorkerState.exit = TRUE;
- os_cv_signal(&hgfsKReqWorkItemCv);
-
- /*
- * Sleep until the worker thread exits. hgfsKReqWorkItemLock is release by
- * by os_thread_join.
- */
- os_thread_join(hgfsKReqWorkerThread, hgfsKReqWorkItemLock);
-
- /*
- * Destroy resources allocated during _SysInit().
- */
- os_thread_release(hgfsKReqWorkerThread);
- os_zone_destroy(hgfsKReqZone);
- os_cv_destroy(&hgfsKReqWorkItemCv);
- os_mutex_free(hgfsKReqWorkItemLock);
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_AllocateContainer --
- *
- * Allocate a request container for a single file system mount.
- *
- * Results:
- * Pointer to a new allocation container or NULL on failure.
- *
- * Side effects:
- * This routine may sleep.
- *
- *----------------------------------------------------------------------------
- */
-
-HgfsKReqContainerHandle
-HgfsKReq_AllocateContainer(void)
-{
- HgfsKReqContainer *container;
-
- container = os_malloc(sizeof (struct HgfsKReqContainer), M_WAITOK | M_ZERO);
- if (!container) {
- return NULL;
- }
-
- container->listLock = os_mutex_alloc_init("hgfs_reql_mtx");
- if (!container->listLock) {
- os_free(container, sizeof *container);
- return NULL;
- }
-
- DblLnkLst_Init(&container->list);
-
- return container;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_FreeContainer --
- *
- * Free a request container.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsKReq_FreeContainer(HgfsKReqContainerHandle container) // IN: file system's
- // container handle
-{
- ASSERT(container);
- ASSERT(DblLnkLst_IsLinked(&container->list) == FALSE);
-
- os_mutex_free(container->listLock);
- os_free(container, sizeof(*container));
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_CancelRequests --
- *
- * Cancels all allocated requests by updating their status (set to
- * HGFS_REQ_ERROR) and waking up any waiting clients. Also, if linked,
- * removes any items from the work item list.
- *
- * Results:
- * None.
- *
- * Side effects:
- * This file system's entries are removed from the work item list are
- * removed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsKReq_CancelRequests(HgfsKReqContainerHandle container) // IN: request container
-{
- DblLnkLst_Links *currNode;
- DblLnkLst_Links *nextNode;
-
- DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests().\n");
-
- ASSERT(container);
-
- /*
- * 1. Lock this file system's request list.
- * 2. Lock the global pending request list.
- * 3. For each request in the file system's request list:
- * a. Remove from the global pending request list.
- * b. Lock the request.
- * c. Set the request's state to HGFS_REQ_ERROR.
- * d. Signal any waiters.
- * e. Drop our reference, destroying the object if ours was the last.
- * 4. Unlock the global pending request list.
- * 5. Unlock the file system's request list.
- */
-
- os_mutex_lock(container->listLock);
- os_mutex_lock(hgfsKReqWorkItemLock);
-
- DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests(): traversing pending request list.\n");
-
- DblLnkLst_ForEachSafe(currNode, nextNode, &container->list) {
- HgfsKReqObject *req;
- Bool deref = FALSE;
-
- /* Get a pointer to the request represented by currNode. */
- req = DblLnkLst_Container(currNode, HgfsKReqObject, fsNode);
-
- /*
- * If linked in the pending request list, remove it. Note that we're
- * transferring that list's reference to ourself. (I.e., we'll be
- * responsible for decrementing the reference count and freeing if it
- * reaches zero.)
- */
- if (DblLnkLst_IsLinked(&req->pendingNode)) {
- deref = TRUE;
- DblLnkLst_Unlink1(&req->pendingNode);
- }
-
- /* Force this over to the error state & wake up any waiters. */
- os_mutex_lock(req->stateLock);
- req->state = HGFS_REQ_ERROR;
- os_cv_signal(&req->stateCv);
- os_mutex_unlock(req->stateLock);
-
- if (deref) {
- if (os_add_atomic(&req->refcnt, -1) == 1) {
- os_zone_free(hgfsKReqZone, req);
- }
- }
- }
-
- os_mutex_unlock(hgfsKReqWorkItemLock);
- os_mutex_unlock(container->listLock);
-
- DEBUG(VM_DEBUG_REQUEST, "HgfsCancelAllRequests() done.\n");
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_ContainerIsEmpty --
- *
- * Indicates whether a file system, represented by its superinfo, has any
- * outstanding HgfsKReqObjectuests.
- *
- * Results:
- * Returns zero if list is not empty, a positive integer if it is empty.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-HgfsKReq_ContainerIsEmpty(HgfsKReqContainerHandle container) // IN:
-{
- Bool result;
-
- ASSERT(container);
-
- os_mutex_lock(container->listLock);
- result = DblLnkLst_IsLinked(&container->list) ? FALSE : TRUE;
- os_mutex_unlock(container->listLock);
-
- DEBUG(VM_DEBUG_REQUEST, "Container empty value: %d\n", result);
-
- return result;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_AllocateRequest --
- *
- * Allocates and initializes a new request structure from the request pool.
- * This function blocks until a request is available or it has been
- * interrupted by a signal.
- *
- * Results:
- * Pointer to fresh HgfsKReqHandle or NULL on failure.
- *
- * Side effects:
- * Request inserted into caller's requests container. This routine may
- * sleep.
- *
- *----------------------------------------------------------------------------
- */
-
-HgfsKReqHandle
-HgfsKReq_AllocateRequest(HgfsKReqContainerHandle container, // IN:
- int *errorRet) // OUT:
-{
- HgfsKReqObject *req;
-
- ASSERT(errorRet);
- ASSERT(container);
-
- *errorRet = 0;
-
- if (!gHgfsChannel) {
- *errorRet = EIO;
- return NULL;
- }
-
- /*
- * In case we don't have any channel currently, set up a new channel.
- * Note that we remember the channel from which request was allocated
- * and sent, thereby making sure that we free it via correct channel.
- */
- if (gHgfsChannel->status != HGFS_CHANNEL_CONNECTED) {
- if (!HgfsSetupNewChannel()) {
- *errorRet = EIO;
- return NULL;
- }
- }
-
- req = os_zone_alloc(hgfsKReqZone, M_WAITOK);
- if (!req) {
- *errorRet = ENOMEM;
- return NULL;
- }
-
- os_mutex_lock(container->listLock);
- DblLnkLst_LinkLast(&container->list, &req->fsNode);
- os_mutex_unlock(container->listLock);
-
- return req;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_ReleaseReq --
- *
- * Routine for file systems to return a request to the pool.
- *
- * Results:
- * None.
- *
- * Side effects:
- * oldReq->refcnt will be decremented, and oldReq may be freed.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsKReq_ReleaseRequest(HgfsKReqContainerHandle container, // IN:
- HgfsKReqHandle oldRequest) // IN:
-{
- DEBUG(VM_DEBUG_ENTRY, "%s\n", __func__);
-
- ASSERT(container);
- ASSERT(oldRequest);
-
- /* Dissociate request from this file system. */
- os_mutex_lock(container->listLock);
- DblLnkLst_Unlink1(&oldRequest->fsNode);
- os_mutex_unlock(container->listLock);
-
- /* State machine update */
- os_mutex_lock(oldRequest->stateLock);
-
- switch (oldRequest->state) {
- case HGFS_REQ_ALLOCATED:
- case HGFS_REQ_SUBMITTED:
- oldRequest->state = HGFS_REQ_ABANDONED;
- break;
- case HGFS_REQ_ABANDONED:
- panic("%s: Request (%p) already abandoned!\n", __func__, oldRequest);
- break;
- case HGFS_REQ_ERROR:
- case HGFS_REQ_COMPLETED:
- break;
- default:
- NOT_REACHED();
- }
-
- os_mutex_unlock(oldRequest->stateLock);
-
- /* Dereference file system from request. If refcnt goes to zero, free. */
- if (os_add_atomic(&oldRequest->refcnt, -1) == 1) {
- os_zone_free(hgfsKReqZone, oldRequest);
- }
-
- DEBUG(VM_DEBUG_REQUEST, "%s done.\n", __func__);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_SubmitRequest --
- *
- * Queues caller's request for Guest <-> Host processing and waits for
- * it to be processed.
- *
- * Results:
- * Zero on success, errno if interrupted.
- *
- * Side effects:
- * Request's state may change.
- *
- * Synchronization notes:
- * Assumes caller holds newReq->stateLock. (Implicit from _GetNewReq.)
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsKReq_SubmitRequest(HgfsKReqObject *newreq) // IN: Request to enqueue
-{
- int ret = 0;
-
- ASSERT(newreq);
- DEBUG(VM_DEBUG_REQUEST, "HgfsEnqueueRequest().\n");
-
- /*
- * Insert request on pending request list, then alert of its arrival the
- * request processor. Since the list will also reference the request, be
- * sure to bump its count before unlocking the list!
- */
-
- os_mutex_lock(hgfsKReqWorkItemLock);
-
- /*
- * With the work item list locked, lock our object and operate on its state.
- * Typically we expect it to be in the ALLOCATED state, but if the file
- * system asynchronously cancelled all requests, it may be in ERROR instead.
- */
-
- os_mutex_lock(newreq->stateLock);
-
- switch (newreq->state) {
- case HGFS_REQ_ALLOCATED:
- /*
- * Update request's state, bump refcnt, and signal worker thread.
- */
-
- newreq->state = HGFS_REQ_SUBMITTED;
- os_add_atomic(&newreq->refcnt, 1);
- DblLnkLst_LinkLast(&hgfsKReqWorkItemList, &newreq->pendingNode);
- os_cv_signal(&hgfsKReqWorkItemCv);
- os_mutex_unlock(hgfsKReqWorkItemLock);
- /*
- * NB: We're still holding this request's state lock for use with
- * cv_wait_sig.
- */
- break;
-
- case HGFS_REQ_ERROR:
- /*
- * Bail ASAP.
- */
- os_mutex_unlock(newreq->stateLock);
- os_mutex_unlock(hgfsKReqWorkItemLock);
- return EIO;
- break;
-
- case HGFS_REQ_UNUSED:
- case HGFS_REQ_SUBMITTED:
- case HGFS_REQ_ABANDONED:
- case HGFS_REQ_COMPLETED:
- panic("Cannot submit object (%p) in its current state: %u",
- newreq, newreq->state);
- break;
- default:
- panic("Request object (%p) in unknown state: %u", newreq, newreq->state);
- }
-
- /* Sleep until request is processed or we're interrupted. */
- while (newreq->state == HGFS_REQ_SUBMITTED && ret == 0) {
- ret = os_cv_wait(&newreq->stateCv, newreq->stateLock);
- }
-
- /* Okay, we're finished with the state lock for now. */
- os_mutex_unlock(newreq->stateLock);
-
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReq_GetId --
- *
- * Return this object's unique request ID.
- *
- * Results:
- * Object's unique request ID.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-uint32_t
-HgfsKReq_GetId(HgfsKReqHandle request) // IN: Request to get the ID for
-{
- ASSERT(request);
-
- return request->id;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReq_GetPayload --
- *
- * Return a pointer to the payload area of a request. Callers may write
- * Hgfs packet data directly to this area. It's guaranteed to hold at
- * most HGFS_PACKET_MAX (6144) bytes. For Hgfs version 3, the caller should
- * explicitly write request header (HgfsRequest) into this area.
- *
- * Results:
- * Pointer to the payload area.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-char *
-HgfsKReq_GetPayload(HgfsKReqHandle request) // IN: Request to get pointer to payload
-{
- ASSERT(request);
-
- return request->payload;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReq_GetPayloadSize --
- *
- * Returns the amount of data current stored in the payload. (Typically
- * used when the file system receives an Hgfs reply.)
- *
- * Results:
- * Size of current payload in bytes.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-size_t
-HgfsKReq_GetPayloadSize(HgfsKReqHandle request) // IN: Request to get the size of
-{
- ASSERT(request);
-
- return request->payloadSize;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReq_SetPayloadSize --
- *
- * Record the amount of data currently stored in the payload. (Typically
- * used when the file system finishes composing its request.)
- *
- * Results:
- * None.
- *
- * Side effects:
- * Request object's payload size is modified.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-HgfsKReq_SetPayloadSize(HgfsKReqHandle request, // IN: Request object
- size_t payloadSize) // IN: New payload size
-{
- ASSERT(request);
- ASSERT(payloadSize <= HGFS_PACKET_MAX);
- request->payloadSize = payloadSize;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsKReq_GetState --
- *
- * Retrieves state of provided request.
- *
- * Results:
- * Returns state of request.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-HgfsKReqState
-HgfsKReq_GetState(HgfsKReqObject *req) // IN: Request to retrieve state of
-{
- HgfsKReqState state;
-
- ASSERT(req);
-
- os_mutex_lock(req->stateLock);
- state = req->state;
- os_mutex_unlock(req->stateLock);
-
- return state;
-}
-
-
-/*
- * Local functions (definitions)
- */
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReqZInit --
- *
- * "The initializer is called when the memory is cached in the uma zone.
- * this should be the same state that the destructor leaves the object in."
- * - sys/vm/uma.h
- *
- * Results:
- * Zero on success, errno on failure.
- *
- * Side effects:
- * A request's mutex and condvar are initialized, ID recorded, and status
- * set to HGFS_REQ_UNUSED.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsKReqZInit(void *mem, // IN: Pointer to the allocated object
- int size, // IN: Size of item being initialized [ignored]
- int flags) // IN: malloc(9) style flags
-{
- static unsigned int id = 0;
- HgfsKReqObject *req = (HgfsKReqObject *)mem;
- ASSERT(size == sizeof *req);
-
- os_add_atomic(&id, 1);
- req->id = id;
- req->state = HGFS_REQ_UNUSED;
- req->stateLock = os_mutex_alloc_init("hgfs_req_mtx");
- if (!req->stateLock) {
- return ENOMEM;
- }
-
- os_cv_init(&req->stateCv, "hgfs_req_cv");
-
- /* Reset list pointers. */
- DblLnkLst_Init(&req->fsNode);
- DblLnkLst_Init(&req->pendingNode);
- DblLnkLst_Init(&req->sentNode);
-
- /* Clear packet of request before allocating to clients. */
- bzero(&req->__rpc_packet, sizeof req->__rpc_packet);
-
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReqZFini --
- *
- * "This routine is called when memory leaves a zone and is returned
- * to the system for other uses. It is the counter part to the
- * init function." - sys/vm/uma.h
- *
- * Results:
- * None.
- *
- * Side effects:
- * A request's mutex and condvar are destroyed.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-HgfsKReqZFini(void *mem, // IN: Pointer to object leaving the UMA cache
- int size) // IN: Size of object [Ignored]
-{
- HgfsKReqObject *req = (HgfsKReqObject *)mem;
- ASSERT(size == sizeof *req);
- ASSERT(req->state == HGFS_REQ_UNUSED);
- os_mutex_free(req->stateLock);
- os_cv_destroy(&req->stateCv);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReqZCtor
- *
- * "The constructor is called just before the memory is returned
- * to the user. It may block if necessary." - sys/vm/uma.h
- *
- * Results:
- * Zero on success, errno on failure.
- *
- * Side effects:
- * Request's state is set to HGFS_REQ_ALLOCATED, its listNode is
- * initialized, and its packet is zeroed out.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsKReqZCtor(void *mem, // IN: Pointer to memory allocated to user
- int size, // IN: Size of allocated object [ignored]
- void *arg, // IN: Optional argument from uma_zalloc_arg [ignored]
- int flags) // IN: malloc(9) flags
-{
- HgfsKReqObject *req = (HgfsKReqObject *)mem;
-
- ASSERT(size == sizeof *req);
- ASSERT(req->state == HGFS_REQ_UNUSED);
- ASSERT(DblLnkLst_IsLinked(&req->fsNode) == FALSE);
- ASSERT(DblLnkLst_IsLinked(&req->pendingNode) == FALSE);
-
- /* Initialize state & reference count. */
- req->state = HGFS_REQ_ALLOCATED;
- req->refcnt = 1;
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReqZDtor
- *
- * "The destructor may perform operations that differ from those performed
- * by the initializer, but it must leave the object in the same state.
- * This IS type stable storage. This is called after EVERY zfree call."
- * - sys/vm/uma.h
- *
- * Results:
- * None.
- *
- * Side effects:
- * Object's state is set to HGFS_REQ_UNUSED.
- *
- *-----------------------------------------------------------------------------
- */
-
-static void
-HgfsKReqZDtor(void *mem, // IN: Pointer to allocated object
- int size, // IN: Size of allocated object [ignored]
- void *arg) // IN: Argument for uma_zfree_arg [ignored]
-{
- HgfsKReqObject *req = (HgfsKReqObject *)mem;
-
- ASSERT(req->refcnt == 0);
- ASSERT(DblLnkLst_IsLinked(&req->fsNode) == FALSE);
- ASSERT(DblLnkLst_IsLinked(&req->pendingNode) == FALSE);
-
- req->state = HGFS_REQ_UNUSED;
-}
-
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/request.h b/open-vm-tools/modules/freebsd/vmhgfs/request.h
deleted file mode 100644
index d68e9c21..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/request.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * request.h --
- *
- * Declarations for the HgfsRequest module. This interface abstracts Hgfs
- * request processing from the filesystem driver.
- */
-
-#ifndef _REQUEST_H_
-#define _REQUEST_H_
-
-#define INCLUDE_ALLOW_MODULE
-#include "includeCheck.h"
-
-#include "dbllnklst.h" /* Double link list types */
-
-/*
- * Each request will traverse through this set of states. File systems may
- * query the state of their request, but they may not update it.
- */
-typedef enum {
- HGFS_REQ_UNUSED = 1,
- HGFS_REQ_ALLOCATED,
- HGFS_REQ_SUBMITTED,
- HGFS_REQ_ABANDONED,
- HGFS_REQ_ERROR,
- HGFS_REQ_COMPLETED
-} HgfsKReqState;
-
-/*
- * Opaque request handler used by the file system code. Allocated during
- * HgfsKReq_AllocRequest and released at HgfsKReq_ReleaseRequest.
- */
-typedef struct HgfsKReqObject * HgfsKReqHandle;
-
-/*
- * Opaque request object container for the file system. File systems snag one
- * of these during HgfsKReq_InitSip & relinquish during HgfsKReq_UninitSip.
- */
-typedef struct HgfsKReqContainer * HgfsKReqContainerHandle;
-
-
-/*
- * Global functions (prototypes)
- */
-
-extern int HgfsKReq_SysInit(void);
-extern int HgfsKReq_SysFini(void);
-
-extern HgfsKReqContainerHandle HgfsKReq_AllocateContainer(void);
-extern void HgfsKReq_FreeContainer(HgfsKReqContainerHandle handle);
-extern void HgfsKReq_CancelRequests(HgfsKReqContainerHandle handle);
-extern Bool HgfsKReq_ContainerIsEmpty(HgfsKReqContainerHandle handle);
-
-extern HgfsKReqHandle HgfsKReq_AllocateRequest(HgfsKReqContainerHandle handle, int *ret);
-extern void HgfsKReq_ReleaseRequest(HgfsKReqContainerHandle container,
- HgfsKReqHandle oldRequest);
-extern int HgfsKReq_SubmitRequest(HgfsKReqHandle req);
-extern HgfsKReqState HgfsKReq_GetState(HgfsKReqHandle req);
-
-extern uint32_t HgfsKReq_GetId(HgfsKReqHandle req);
-extern char * HgfsKReq_GetPayload(HgfsKReqHandle req);
-extern char * HgfsKReq_GetPayload_V3(HgfsKReqHandle req);
-extern char * HgfsKRep_GetPayload_V3(HgfsKReqHandle req);
-extern size_t HgfsKReq_GetPayloadSize(HgfsKReqHandle req);
-extern void HgfsKReq_SetPayloadSize(HgfsKReqHandle req,
- size_t newSize);
-
-
-#endif /* _REQUEST_H_ */
-
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/requestInt.h b/open-vm-tools/modules/freebsd/vmhgfs/requestInt.h
deleted file mode 100644
index 72745935..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/requestInt.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * requestInt.h --
- *
- * Internal declarations for the HgfsRequest module. Filesystem code
- * should not include this file.
- */
-
-#ifndef _requestInt_H_
-#define _requestInt_H_
-
-#define INCLUDE_ALLOW_MODULE
-#include "includeCheck.h"
-
-#if defined __FreeBSD__
-# include <sys/libkern.h> // common string, memcpy, etc userland routines
-# include <vm/uma.h> // for the UMA (slab) allocator
-#elif defined __APPLE__
-# include <string.h>
-#endif
-
-
-#include "vm_assert.h"
-
-#include "os.h"
-#include "request.h"
-#include "debug.h"
-
-#if defined __APPLE__
- #include "hgfsTransport.h"
- #define HGFS_REQUEST_PREFIX_LENGTH MAX(HGFS_CLIENT_CMD_LEN, sizeof (HgfsVmciTransportStatus))
-#else
- #define HGFS_REQUEST_PREFIX_LENGTH HGFS_CLIENT_CMD_LEN
-#endif
-
-
-/*
- * Data types
- */
-struct HgfsTransportChannel;
-
-
-/*
- * In-kernel representation of an Hgfs request. These objects are kept on zero,
- * one, or two lists at any time.
- *
- * (Ideal) Lifecycle of an Hgfs request:
- * - File system calls HgfsKReq_AllocateRequest to allocate a request. The
- * new request's reference count is initialized to one, and it is placed
- * in the filesystem's requests container.
- * - File system calls HgfsKReq_SubmitRequest to submit the request for
- * processing via the backdoor. At this point, request is inserted on a
- * global work item list and its reference count is bumped.
- * - Worker thread removes request from the work item list. Reference count is
- * unchanged as the reference is simply transferred from the work item list to
- * the worker thread itself.
- * - When the worker thread receives a reply, it updates the request's state,
- * copies in the reply data, and decrements the reference count.
- *
- * At any point, the file system may abort a request with
- * HgfsKReq_ReleaseRequest. Doing so will involve decrementing the object's
- * reference count, since the file system is giving up its reference. Whoever
- * reduces the reference count to zero is responsible for freeing it.
- *
- * Special case -- Forced unmount of a file system:
- *
- * If the user forcibly unmounts the file system, the following work is done.
- * - For each request object associated with a file system
- * - If the item is on the work item list, it is removed from that list. The
- * canceling thread is then responsible for decrementing the object's
- * reference count.
- * - The request's state is set to HGFS_REQ_ERROR, and a wakeup signal is
- * sent to the stateCv. (If the file system had not yet submitted the
- * request, it will immediately return as a failure at submission time.)
- * - Without anything left to do with this request, the cancellation thread
- * drops the reference count, and if it reaches zero, frees the object.
- */
-typedef struct HgfsKReqObject {
- DblLnkLst_Links fsNode; // Link between object and its parent file system.
- DblLnkLst_Links pendingNode; // Link between object and pending request list.
- DblLnkLst_Links sentNode; // Link between object and sent request list.
-
- unsigned int refcnt; // Object reference count
- HgfsKReqState state; // Indicates state of request
- OS_MUTEX_T *stateLock; // Protects state: ...
- OS_CV_T stateCv; // Condition variable to wait for and signal
- // presence of reply. Used with the stateLock
- // above.
-
- uint32_t id; // The unique identifier of this request.
- // Typically just incremented sequentially
- // from zero.
- size_t payloadSize; // Total size of payload
- void *ioBuf; // Pointer to memory descriptor.
- // Used for MacOS over VMCI.
-
- /* On which channel was the request allocated/sent ?. */
- struct HgfsTransportChannel *channel;
- /*
- * The file system is concerned only with the payload portion of an Hgfs
- * request packet, but the RPC message opens with the command string "f ".
- *
- * Strangely, the HgfsBd_Dispatch routine takes a pointer to the payload, but indexes
- * -backwards- from that pointer to get to the RPC command. (This was actually done
- * because we wanted to vary the command - async vs. sync - on the fly without
- * performing another allocation. So the buffer is sized for any command plus the
- * packet, and the command is varied by the transport layer.) So, anyway, effectively
- * all of __rpc_packet will be sent across the backdoor, but the file system will only
- * muck with _payload.
- *
- * VMCI:
- * Mac OS X is capable of using VMCI in which case _command will have
- * HgfsVmciTransportStatus.
- *
- */
- struct {
- char _command[HGFS_REQUEST_PREFIX_LENGTH];
- char _payload[HGFS_PACKET_MAX]; // Contains both the request and
- // its reply.
- } __rpc_packet;
-} HgfsKReqObject;
-
-#define command __rpc_packet._command
-#define payload __rpc_packet._payload
-
-/*
- * Opaque container for a file system's request objects. File system operates
- * only on a typedef'd handle. (See request.h.)
- */
-typedef struct HgfsKReqContainer {
- OS_MUTEX_T *listLock;
- DblLnkLst_Links list;
-} HgfsKReqContainer;
-
-/*
- * Current state & instruction for the HgfsKReq worker thread.
- */
-typedef struct HgfsKReqWState {
- Bool running; // Is worker running?
- Bool exit; // Set this to TRUE at module unload time.
-} HgfsKReqWState;
-
-
-/*
- * Module internal variables
- */
-
-/* Workitem list anchor */
-extern DblLnkLst_Links hgfsKReqWorkItemList;
-
-/* Workitem list lock. */
-extern OS_MUTEX_T *hgfsKReqWorkItemLock;
-
-extern OS_CV_T hgfsKReqWorkItemCv;
-
-/* UMA zone (slab) for allocating HgfsKReqs. */
-extern OS_ZONE_T *hgfsKReqZone;
-
-/* Process structure for the worker thread */
-extern OS_THREAD_T hgfsKReqWorkerThread;
-extern HgfsKReqWState hgfsKReqWorkerState;
-
-
-/*
- * Function prototypes
- */
-
-extern void HgfsKReqWorker(void *arg);
-
-
-#endif // ifndef _requestInt_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/state.c b/open-vm-tools/modules/freebsd/vmhgfs/state.c
deleted file mode 100644
index e2e8e5db..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/state.c
+++ /dev/null
@@ -1,1780 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * state.c --
- *
- * Vnode and HgfsFile state manipulation routines.
- */
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/fcntl.h>
-
-#if defined __FreeBSD__
-# include <sys/libkern.h>
-# include <sys/malloc.h>
-# include "sha1.h"
-# include "compat_freebsd.h"
-#define vnode_get(vnode) vget(vnode, LK_SHARED, curthread)
-#define vnode_rele(vnode) vrele(vnode)
-#define vnode_ref(vnode) vref(vnode)
-#elif defined __APPLE__
-# include <string.h>
-/*
- * The Mac OS kernel includes the same exact SHA1 routines as those
- * provided by bora/lib/misc. Use the kernel ones under Mac OS.
- */
-# include <libkern/crypto/sha1.h>
-#endif
-
-#include "hgfs_kernel.h"
-#include "state.h"
-#include "debug.h"
-#include "os.h"
-
-/*
- * Macros
- */
-
-#define HGFS_FILE_HT_HEAD(ht, index) (ht->hashTable[index]).next
-#define HGFS_FILE_HT_BUCKET(ht, index) (&ht->hashTable[index])
-
-#define HGFS_IS_ROOT_FILE(sip, file) (HGFS_VP_TO_FP(sip->rootVnode) == file)
-#define LCK_MTX_ASSERT(mutex)
-
-#if defined __APPLE__
-# define SHA1_HASH_LEN SHA_DIGEST_LENGTH
-
-#if defined VMX86_DEVEL
-#undef LCK_MTX_ASSERT
-#define LCK_MTX_ASSERT(mutex) lck_mtx_assert(mutex, LCK_MTX_ASSERT_OWNED)
-#endif
-
-#endif
-
-/*
- * Local functions (prototypes)
- */
-
-static int HgfsVnodeGetInt(struct vnode **vpp,
- struct vnode *dvp,
- struct HgfsSuperInfo *sip,
- struct mount *vfsp,
- const char *fileName,
- HgfsFileType fileType,
- HgfsFileHashTable *htp,
- Bool rootVnode,
- Bool createFile,
- int permissions,
- off_t fileSize);
-
-/* Allocation/initialization/free of open file state */
-static HgfsFile *HgfsAllocFile(const char *fileName, HgfsFileType fileType,
- struct vnode *dvp, HgfsFileHashTable *htp,
- int permissions, off_t fileSize);
-
-/* Acquiring/releasing file state */
-static HgfsFile *HgfsInsertFile(const char *fileName,
- HgfsFile *fp,
- HgfsFileHashTable *htp);
-static void HgfsReleaseFile(HgfsFile *fp, HgfsFileHashTable *htp);
-static void HgfsFileVnodeLock(HgfsFile *fp,
- HgfsVnodeLockType type);
-static void HgfsFileVnodeUnlock(HgfsFile *fp,
- HgfsVnodeLockType type);
-static int HgfsInitFile(HgfsFile *fp, struct vnode *dvp, const char *fileName,
- HgfsFileType fileType, int permissions, off_t fileSize);
-static void HgfsFreeFile(HgfsFile *fp);
-
-/* Adding/finding/removing file state from hash table */
-static void HgfsAddFile(HgfsFile *fp, HgfsFileHashTable *htp);
-static HgfsFile *HgfsFindFile(const char *fileName, HgfsFileHashTable *htp);
-
-/* Other utility functions */
-static unsigned int HgfsFileNameHash(const char *fileName);
-static void HgfsNodeIdHash(const char *fileName, uint32_t fileNameLength,
- ino_t *outHash);
-static Bool HgfsIsModeCompatible(HgfsMode requestedMode, HgfsMode existingMode);
-/*
- * Global functions
- */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVnodeLock --
- *
- * Locks the HgfsFile associated with the vnode (vp). The type specifies if
- * we are locking for reads or writes. We only lock the HgfsFile on Mac OS
- * because FreeBSD vnodes are locked when handed to the VFS layer and there
- * is a 1:1 mapping between vnodes and HgfsFile objects so no extra locking
- * is required.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsVnodeLock(struct vnode *vp, // IN: Vnode to lock
- HgfsVnodeLockType type) // IN: Reader or Writer lock?
-{
- HgfsFile *fp;
-
- ASSERT(type == HGFS_READER_LOCK || type == HGFS_WRITER_LOCK);
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%p,%d,%p)\n", vp, type, fp);
-
- HgfsFileVnodeLock(fp, type);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVnodeUnlock --
- *
- * Unlocks the HgfsFile associated with the vnode (vp). Results are
- * undefined the type of lock specified is different than the one that the
- * vnode was locked with originally.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsVnodeUnlock(struct vnode *vp, // IN: Vnode to unlock
- HgfsVnodeLockType type) // IN: Reader or Writer lock?
-{
- HgfsFile *fp;
-
- ASSERT(type == HGFS_READER_LOCK || type == HGFS_WRITER_LOCK);
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%p,%d,%p)\n", vp, type, fp);
-
- HgfsFileVnodeUnlock(fp, type);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVnodeGet --
- *
- * Creates a vnode for the provided filename.
- *
- * This will always allocate a vnode and HgfsFile. If a HgfsFile
- * already exists for this filename then that is used, if a HgfsFile doesn't
- * exist, one is created.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure. The new
- * vnode is returned locked.
- *
- * Side effects:
- * If the HgfsFile already exists and createFile is TRUE then the EEXIST error
- * is returned. Otherwise if the HgfsFile already exists its reference count
- * is incremented.
- * If HgfsFile with the given name does not exist then HgfsFile is created.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsVnodeGet(struct vnode **vpp, // OUT: Filled with address of created vnode
- struct vnode *dvp, // IN: Parent directory vnode
- HgfsSuperInfo *sip, // IN: Superinfo
- struct mount *vfsp, // IN: Filesystem structure
- const char *fileName, // IN: Name of this file
- HgfsFileType fileType, // IN: Type of file
- HgfsFileHashTable *htp, // IN: File hash table
- Bool createFile, // IN: Creating a new file or open existing?
- int permissions, // IN: Permissions for the created file
- off_t fileSize) // IN: File size if the vnode is VREG
-{
- return HgfsVnodeGetInt(vpp, dvp, sip, vfsp, fileName, fileType, htp, FALSE,
- createFile, permissions, fileSize);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVnodeGetRoot --
- *
- * Creates a root vnode. This should only be called by the VFS mount
- * function when the filesystem is first being mounted.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure. The new
- * vnode is returned locked on FreeBSD.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsVnodeGetRoot(struct vnode **vpp, // OUT: Filled with address of created vnode
- HgfsSuperInfo *sip, // IN: Superinfo
- struct mount *vfsp, // IN: Filesystem structure
- const char *fileName, // IN: Name of this file
- HgfsFileType fileType, // IN: Type of file
- HgfsFileHashTable *htp) // IN: File hash table
-{
- return HgfsVnodeGetInt(vpp, NULL, sip, vfsp, fileName, fileType, htp, TRUE,
- FALSE, 0, 0);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsReleaseVnodeContext --
- *
- * Releases context for the provided vnode.
- *
- * This will free the context information associated vnode.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- *
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsReleaseVnodeContext(struct vnode *vp, // IN: Vnode to release
- HgfsFileHashTable *htp) // IN: Hash table pointer
-{
- HgfsFile *fp;
-
- ASSERT(vp);
- ASSERT(htp);
-
- DEBUG(VM_DEBUG_ENTRY, "Entering HgfsVnodePut\n");
-
- /* Get our private open-file state. */
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- /* We need to release private HGFS information asosiated with the vnode. */
- HgfsReleaseFile(fp, htp);
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsNodeIdGet --
- *
- * Gets the node id for the provided file. This will only calculate the
- * node id again if a per-file state structure doesn't yet exist for this
- * file. (This situation exists on a readdir since dentries are filled in
- * rather than creating vnodes.)
- *
- * The Hgfs protocol does not provide us with unique identifiers for files
- * since it must support filesystems that do not have the concept of inode
- * numbers. Therefore, we must maintain a mapping from filename to node id/
- * inode numbers. This is done in a stateless manner by calculating the
- * SHA-1 hash of the filename. All points in the Hgfs code that need a node
- * id/inode number obtain it by either calling this function or directly
- * referencing the saved node id value in the vnode, if one is available.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsNodeIdGet(HgfsFileHashTable *htp, // IN: File hash table
- const char *fileName, // IN: Filename to get node id for
- uint32_t fileNameLength, // IN: Length of filename
- ino_t *outNodeId) // OUT: Destination for nodeid
-{
- HgfsFile *fp;
-
- ASSERT(htp);
- ASSERT(fileName);
- ASSERT(outNodeId);
-
- os_mutex_lock(htp->mutex);
-
- fp = HgfsFindFile(fileName, htp);
- if (fp) {
- *outNodeId = fp->nodeId;
- } else {
- HgfsNodeIdHash(fileName, fileNameLength, outNodeId);
- }
-
- os_mutex_unlock(htp->mutex);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsInitFileHashTable --
- *
- * Initializes the hash table used to track per-file state.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsInitFileHashTable(HgfsFileHashTable *htp) // IN: Hash table to initialize
-{
- int i;
-
- ASSERT(htp);
-
- htp->mutex = os_mutex_alloc_init("HgfsHashChain");
- if (!htp->mutex) {
- return HGFS_ERR;
- }
-
- for (i = 0; i < ARRAYSIZE(htp->hashTable); i++) {
- DblLnkLst_Init(&htp->hashTable[i]);
- }
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDestroyFileHashTable --
- *
- * Cleanup the hash table used to track per-file state.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsDestroyFileHashTable(HgfsFileHashTable *htp)
-{
- ASSERT(htp);
- os_mutex_free(htp->mutex);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileHashTableIsEmpty --
- *
- * Determines whether the hash table is in an acceptable state to unmount
- * the file system.
- *
- * Note that this is not strictly empty: if the only file in the table is
- * the root of the filesystem and its reference count is 1, this is
- * considered empty since this is part of the operation of unmounting the
- * filesystem.
- *
- * Results:
- * Returns TRUE if the hash table is empty and false otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-Bool
-HgfsFileHashTableIsEmpty(HgfsSuperInfo *sip, // IN: Superinfo
- HgfsFileHashTable *htp) // IN: File hash table
-{
- int i;
-
- ASSERT(sip);
- ASSERT(htp);
-
- os_mutex_lock(htp->mutex);
-
- /* Traverse each bucket. */
- for (i = 0; i < ARRAYSIZE(htp->hashTable); i++) {
- DblLnkLst_Links *currNode = HGFS_FILE_HT_HEAD(htp, i);
-
- /* Visit each file in this bucket */
- while (currNode != HGFS_FILE_HT_BUCKET(htp, i)) {
- HgfsFile *currFile = DblLnkLst_Container(currNode, HgfsFile, listNode);
-
- /*
- * Here we special case the root of our filesystem. In a correct
- * unmount, the root vnode of the filesystem will have an entry in the
- * hash table and will have a reference count of 1. We check if the
- * current entry is the root file, and if so, make sure its vnode's
- * reference count is not > 1. Note that we are not mapping from file
- * to vnode here (which is not possible), we are using the root vnode
- * stored in the superinfo structure. This is the only vnode that
- * should have multiple references associated with it because whenever
- * someone calls HgfsRoot(), we return that vnode.
- */
- if (HGFS_IS_ROOT_FILE(sip, currFile)) {
- HGFS_VP_VI_LOCK(sip->rootVnode);
- if (!HGFS_VP_ISINUSE(sip->rootVnode, 1)) {
- HGFS_VP_VI_UNLOCK(sip->rootVnode);
-
- /* This file is okay; skip to the next one. */
- currNode = currNode->next;
- continue;
- }
-
- DEBUG(VM_DEBUG_FAIL, "HgfsFileHashTableIsEmpty: %s is in use.\n",
- currFile->fileName);
-
- HGFS_VP_VI_UNLOCK(sip->rootVnode);
- /* Fall through to failure case */
- }
-
- /* Fail if a file is found. */
- os_mutex_unlock(htp->mutex);
- DEBUG(VM_DEBUG_FAIL, "HgfsFileHashTableIsEmpty: %s still in use.\n",
- currFile->fileName);
- return FALSE;
- }
- }
-
- os_mutex_unlock(htp->mutex);
-
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsCheckAndReferenceHandle --
- *
- * Determines whether one of vnode's open file handles is currently set.
- * If the handle is set the function increments its reference count.
- * The function must be called while holding handleLock from the correspondent
- * HgfsFile structure.
- *
- * Results:
- * Returns 0 if the handle is set and had been referenced,
- * EACCES if the handle is set but has an incompatible open mode,
- * ENOENT if no handle is set for the vnode
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsCheckAndReferenceHandle(struct vnode *vp, // IN: Vnode to check handle of
- int requestedOpenMode, // IN: Requested open mode
- HgfsOpenType openType) // IN: Requested open type
-{
- HgfsFile *fp;
- int ret = 0;
-
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- if (0 == fp->handleRefCount && 0 == fp->intHandleRefCount) {
- ret = ENOENT;
- DEBUG(VM_DEBUG_LOG, "No handle: mode %d type %d\n", requestedOpenMode, openType);
- goto exit;
- }
-
- if (!HgfsIsModeCompatible(requestedOpenMode, fp->mode)) {
- ret = EACCES;
- DEBUG(VM_DEBUG_LOG, "Incompatible modes: %d %d\n", requestedOpenMode, fp->mode);
- goto exit;
- }
-
- DEBUG(VM_DEBUG_LOG, "Compatible handle: type %d mapped %d count %d\n",
- openType, fp->mmapped, fp->handleRefCount);
-
- /*
- * Do nothing for subsequent mmap/read reference requests.
- * For mmap the OS layer invokes mnomap only once
- * for multiple mmap calls.
- * For read we only need to reference the first real need to open, i.e. ENOENT
- * is returned when there isn't a compatible handle.
- */
- if (OPENREQ_MMAP == openType && fp->mmapped) {
- DEBUG(VM_DEBUG_LOG, "Mmapped: already referenced %d %d\n", requestedOpenMode, fp->mode);
- goto exit;
- }
-
- if (OPENREQ_READ == openType) {
- DEBUG(VM_DEBUG_LOG, "Open for Read: already referenced %d %d\n", requestedOpenMode, fp->mode);
- goto exit;
- }
-
- /*
- * Reference the handle for the open.
- * For the regular open and memory map calls we increment the normal
- * count, for all others (e.g. create) it is an internal increment.
- */
- if (OPENREQ_OPEN != openType && OPENREQ_MMAP != openType) {
- fp->intHandleRefCount++;
- DEBUG(VM_DEBUG_LOG, "Internal Handle Ref Cnt %d\n", fp->intHandleRefCount);
- } else {
- fp->handleRefCount++;
- DEBUG(VM_DEBUG_LOG, "Handle Ref Cnt %d\n", fp->handleRefCount);
- }
-
- if (!(fp->mmapped) && OPENREQ_MMAP == openType) {
- fp->mmapped = TRUE;
- }
-
-exit:
- return ret;
- }
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSetOpenFileHandle --
- *
- * Sets the file handle for the provided vnode if it has reference count
- * equal to zero. The reference count of the handle must be increased when
- * the handle is set. This is done with HgfsCheckAndReferenceHandle.
- * Caller must hold handleLock when invoking the function.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The handle may not be set again until it is cleared.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsSetOpenFileHandle(struct vnode *vp, // IN: Vnode to set handle for
- HgfsHandle handle, // IN: Value of handle
- HgfsMode openMode, // IN: Mode assosiated with the handle
- HgfsOpenType openType) // IN: type of open for VNOP_ call
-{
- HgfsFile *fp;
-
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- fp->handle = handle;
- fp->mode = openMode;
- fp->handleRefCount = 1;
- if (OPENREQ_OPEN == openType) {
- fp->handleRefCount = 1;
- } else {
- fp->intHandleRefCount = 1;
- }
- DEBUG(VM_DEBUG_STATE, "File %s handle %d ref Cnt %d Int Ref Cnt %d\n",
- HGFS_VP_TO_FILENAME(vp), fp->handle, fp->handleRefCount, fp->intHandleRefCount);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsGetOpenFileHandle --
- *
- * Gets the file handle for the provided vnode.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure. On success,
- * the value of the vnode's handle is placed in outHandle.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsGetOpenFileHandle(struct vnode *vp, // IN: Vnode to get handle for
- HgfsHandle *outHandle) // OUT: Filled with value of handle
-{
- HgfsFile *fp;
- int ret = 0;
-
- ASSERT(vp);
- ASSERT(outHandle);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- os_rw_lock_lock_shared(fp->handleLock);
-
- if (fp->handleRefCount == 0) {
- ret = HGFS_ERR;
- } else {
- *outHandle = fp->handle;
- }
-
- os_rw_lock_unlock_shared(fp->handleLock);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsReleaseOpenFileHandle --
- *
- * Decrements the reference count of one of the handles for the provided
- * vnode. If the reference count becomes zero, then the handle is cleared and
- * the original handle is retruned to the caller.
- *
- * Results:
- * Returns new handle reference count.
- * When the returned value is 0 returns the file handle which need to be closed
- * on the host.
- * Returns special value -1 if the handle had not been open.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsReleaseOpenFileHandle(struct vnode *vp, // IN: correspondent vnode
- HgfsOpenType openType, // IN: open type to release
- HgfsHandle *handleToClose) // OUT: Host handle to close
-{
- int ret = -1;
- HgfsFile *fp;
-
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- os_rw_lock_lock_exclusive(fp->handleLock);
-
- /* Make sure the reference count is not going negative! */
- ASSERT(fp->handleRefCount >= 0 || fp->intHandleRefCount > 0);
-
- if (fp->handleRefCount > 0 || fp->intHandleRefCount > 0) {
- if (fp->handleRefCount > 0) {
- --fp->handleRefCount;
- }
- /*
- * We don't issue explicit closes for internal opens (read/create), so
- * always decrement the internal count here.
- */
- if (fp->intHandleRefCount > 0) {
- --fp->intHandleRefCount;
- }
- /* Return the real not internal count. */
- ret = fp->handleRefCount;
- /* If unmapping clear our flag. */
- if (OPENREQ_MMAP == openType) {
- fp->mmapped = FALSE;
- }
-
- /* If the reference count has gone to zero, clear the handle. */
- if (ret == 0) {
- DEBUG(VM_DEBUG_LOG, "Last open closing handle %d\n", fp->handle);
- *handleToClose = fp->handle;
- fp->handle = 0;
- fp->intHandleRefCount = 0;
- } else {
- DEBUG(VM_DEBUG_LOG, "ReleaseOpenFileHandle: refCount: %d intRefCount %d\n",
- fp->handleRefCount, fp->intHandleRefCount);
- }
- }
- os_rw_lock_unlock_exclusive(fp->handleLock);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsLookupExistingVnode --
- *
- * Locates existing vnode in the hash table that matches given file name.
- * If a vnode that corresponds the given name does not exists then the function
- * returns ENOENT.
- * If the vnode exists the function behavior depends on failIfExist parameter.
- * When failIfExist is true then the function return EEXIST, otherwise
- * function references the vnode, assigns vnode pointer to vpp and return 0.
- *
- * Results:
- *
- * Returns 0 if existing vnode is found and its address is returned in vpp or
- * an error code otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsLookupExistingVnode(const char* fileName,
- HgfsFileHashTable *htp,
- Bool failIfExist,
- struct vnode **vpp)
-{
- HgfsFile* existingFp;
- int err = ENOENT;
- os_mutex_lock(htp->mutex);
- /* First verify if a vnode for the filename is already allocated. */
- existingFp = HgfsFindFile(fileName, htp);
- if (existingFp != NULL) {
- DEBUG(VM_DEBUG_LOG, "Found existing vnode for %s\n", fileName);
- if (failIfExist) {
- err = EEXIST;
- } else {
- err = vnode_get(existingFp->vnodep);
- if (err == 0) {
- *vpp = existingFp->vnodep;
- } else {
- /* vnode exists but unusable, remove HGFS context assosiated with it. */
- DEBUG(VM_DEBUG_FAIL, "Removing HgfsFile assosiated with an unusable vnode\n");
- DblLnkLst_Unlink1(&existingFp->listNode);
- err = ENOENT;
- }
- }
- }
- os_mutex_unlock(htp->mutex);
- return err;
-}
-
-/*
- * Local functions (definitions)
- */
-
-/* Internal versions of public functions to allow bypassing htp locking */
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVnodeGetInt --
- *
- * Creates a vnode for the provided filename.
- *
- * If a HgfsFile already exists for this filename then it is used and the associated
- * vnode is referenced and returned.
- * if a HgfsFile doesn't exist, a new vnode and HgfsFile structure is created.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure. The new
- * vnode is returned locked.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-#if defined __FreeBSD__
-static int
-HgfsVnodeGetInt(struct vnode **vpp, // OUT: Filled with address of created vnode
- struct vnode *dvp, // IN: Parent directory vnode
- HgfsSuperInfo *sip, // IN: Superinfo
- struct mount *vfsp, // IN: Filesystem structure
- const char *fileName, // IN: Name of this file
- HgfsFileType fileType, // IN: Tyoe of file
- HgfsFileHashTable *htp, // IN: File hash
- Bool rootVnode, // IN: Is this a root vnode?
- Bool fileCreate, // IN: Is it a new file creation?
- int permissions, // IN: Permissions for new files
- off_t fileSize) // IN: Size of the file
-{
- struct vnode *vp;
- int ret;
-
- HgfsFile *fp;
- HgfsFile *existingFp;
-
- ASSERT(vpp);
- ASSERT(sip);
- ASSERT(vfsp);
- ASSERT(fileName);
- ASSERT(htp);
- ASSERT(dvp != NULL || rootVnode);
-
- /* First verify if a vnode for the filename is already allocated. */
- ret = HgfsLookupExistingVnode(fileName, htp, fileCreate, vpp);
- if (ret != ENOENT) {
- return ret;
- }
-
- /*
- * Here we need to construct the vnode for the kernel as well as our
- * internal file system state. Our internal state described by
- * HgfsFile structure which is kept per-file. There is no state information assosiated
- * with file descriptor. The reason is that when OS invokes vnode methods
- * it does not provide information about file descriptor that was used to initiate the
- * IO. We have a one-to-one mapping between vnodes and HgfsFiles.
- */
- if ((ret = getnewvnode(HGFS_FS_NAME, vfsp, &HgfsVnodeOps, &vp)) != 0) {
- return ret;
- }
-
- /*
- * Return a locked vnode to the caller.
- */
- ret = compat_lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, curthread);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Fatal: could not acquire lock on vnode\n");
- goto destroyVnode;
- }
-
- /*
- * Now we'll initialize the vnode. We need to set the file type, vnode
- * operations, flags, filesystem pointer, reference count, and device.
- * After that we'll create our private structures and hang them from the
- * vnode's v_data pointer.
- */
- switch (fileType) {
- case HGFS_FILE_TYPE_REGULAR:
- vp->v_type = VREG;
- break;
-
- case HGFS_FILE_TYPE_DIRECTORY:
- vp->v_type = VDIR;
- break;
-
- case HGFS_FILE_TYPE_SYMLINK:
- vp->v_type = VLNK;
- break;
-
- default:
- /* Hgfs only supports directories and regular files */
- ret = EPERM;
- goto destroyOut;
- }
-
- /* We now allocate our private open file structure. */
- fp = (void *)HgfsAllocFile(fileName, fileType, dvp, htp, permissions, fileSize);
- if (fp == NULL) {
- ret = ENOMEM;
- goto destroyOut;
- }
-
- fp->vnodep = vp;
- vp->v_data = fp;
- /* If this is going to be the root vnode, we have to mark it as such. */
- if (rootVnode) {
- vp->v_vflag |= VV_ROOT;
- }
-
- existingFp = HgfsInsertFile(fileName, fp, htp);
-
- if (existingFp != NULL) { // Race occured, another thread inserted a node ahead of us
- if (fileCreate) {
- ret = EEXIST;
- goto destroyOut;
- }
- compat_lockmgr(vp->v_vnlock, LK_RELEASE, NULL, curthread);
- vput(vp);
- vp = existingFp->vnodep;
- /*
- * Return a locked vnode to the caller.
- */
- ret = compat_lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL, curthread);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Fatal: could not acquire lock on vnode\n");
- goto destroyVnode;
- }
- HgfsFreeFile(fp);
- }
-
- /* Fill in the provided address with the new vnode. */
- *vpp = vp;
-
- /* Return success */
- return 0;
-
- /* Cleanup points for errors. */
-destroyOut:
- compat_lockmgr(vp->v_vnlock, LK_RELEASE, NULL, curthread);
-destroyVnode:
- vput(vp);
- return ret;
-}
-
-#elif defined __APPLE__
-static int
-HgfsVnodeGetInt(struct vnode **vpp, // OUT
- struct vnode *dvp, // IN
- HgfsSuperInfo *sip, // IN
- struct mount *vfsp, // IN
- const char *fileName, // IN
- HgfsFileType fileType, // IN
- HgfsFileHashTable *htp, // IN
- Bool rootVnode, // IN
- Bool fileCreate, // IN
- int permissions, // IN
- off_t fileSize) // IN
-{
- struct vnode *vp;
- struct vnode_fsparam params;
- int ret;
- HgfsFile *fp = NULL;
- HgfsFile *existingFp;
-
- ASSERT(vpp);
- ASSERT(sip);
- ASSERT(vfsp);
- ASSERT(fileName);
- ASSERT(htp);
-
- /* First verify if a vnode for the filename is already allocated. */
- ret = HgfsLookupExistingVnode(fileName, htp, fileCreate, vpp);
- if (ret != ENOENT) {
- return ret;
- }
-
- params.vnfs_mp = vfsp;
- params.vnfs_str = "hgfs";
- params.vnfs_dvp = dvp;
- params.vnfs_fsnode = NULL;
- params.vnfs_vops = HgfsVnodeOps;
- params.vnfs_marksystem = FALSE;
- params.vnfs_rdev = 0;
- params.vnfs_filesize = fileSize;
- params.vnfs_cnp = NULL;
- /* Do not let Mac OS cache vnodes for us. */
- params.vnfs_flags = VNFS_NOCACHE | VNFS_CANTCACHE;
-
- if (rootVnode) {
- params.vnfs_markroot = TRUE;
- } else {
- params.vnfs_markroot = FALSE;
- }
-
- /*
- * Now we'll initialize the vnode. We need to set the file type, vnode
- * operations, flags, filesystem pointer, reference count, and device.
- * After that we'll create our private structures and hang them from the
- * vnode's v_data pointer.
- */
- switch (fileType) {
- case HGFS_FILE_TYPE_REGULAR:
- params.vnfs_vtype = VREG;
- break;
-
- case HGFS_FILE_TYPE_DIRECTORY:
- params.vnfs_vtype = VDIR;
- break;
-
- case HGFS_FILE_TYPE_SYMLINK:
- params.vnfs_vtype = VLNK;
- break;
-
- default:
- /* Hgfs only supports directories and regular files */
- ret = EINVAL;
- goto out;
- }
-
- fp = HgfsAllocFile(fileName, fileType, dvp, htp, permissions, fileSize);
-
- params.vnfs_fsnode = (void *)fp;
- if (params.vnfs_fsnode == NULL) {
- ret = ENOMEM;
- goto out;
- }
-
- ret = vnode_create(VNCREATE_FLAVOR, sizeof(params), &params, &vp);
- if (ret != 0) {
- DEBUG(VM_DEBUG_FAIL, "Failed to create vnode");
- goto out;
- }
-
- fp->vnodep = vp;
-
- existingFp = HgfsInsertFile(fileName, fp, htp);
-
- if (existingFp != NULL) { // Race occured, another thread inserted a node ahead of us
- vnode_put(vp);
- if (fileCreate) {
- ret = EEXIST;
- goto out;
- }
- vp = existingFp->vnodep;
- HgfsFreeFile(fp);
- } else {
- /* Get a soft FS reference to the vnode. This tells the system that the vnode
- * has data associated with it. It is considered a weak reference though, in that
- * it does not prevent the system from reusing the vnode.
- */
- vnode_addfsref(vp);
- }
-
- /* Fill in the provided address with the new vnode. */
- *vpp = vp;
-
- /* Return success */
- return 0;
-
-out:
- if (fp) {
- HgfsFreeFile(fp);
- }
- return ret;
-}
-#else
- NOT_IMPLEMENTED();
-#endif
-
-/* Vnode read/write lock of open file state */
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileVnodeLockInit --
- *
- * Allocates and initializes the file node's vnode lock.
- * NOTE: only lock the node on Mac OS because FreeBSD vnodes are locked when
- * handed to the VFS layer.
- *
- * Results:
- * TRUE if successful or FreeBSD, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-HgfsFileVnodeLockInit(HgfsFile *fp) // IN: file state for vnode lock
-{
- Bool result = TRUE;
-
-#if defined __APPLE__
- fp->rwVnodeLock = os_rw_lock_alloc_init("hgfs_rw_file_lock");
- if (NULL == fp->rwVnodeLock) {
- result = FALSE;
- }
- DEBUG(VM_DEBUG_LOG, "fp = %p, rw vnode lock = %p\n", fp, fp->rwVnodeLock);
-#endif
-
- return result;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileVnodeLockFree --
- *
- * Destroys and releases the file node's vnode lock.
- * NOTE: only lock the node on Mac OS because FreeBSD vnodes are locked when
- * handed to the VFS layer.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsFileVnodeLockFree(HgfsFile *fp) // IN: file state for vnode lock
-{
-#if defined __APPLE__
- DEBUG(VM_DEBUG_LOG, "Destroying fp = %p, rw vnode lock = %p\n", fp, fp->rwVnodeLock);
- if (NULL != fp->rwVnodeLock) {
- os_rw_lock_free(fp->rwVnodeLock);
- }
-#endif
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileVnodeLock --
- *
- * Locks the file node's vnode lock. The type specifies if
- * we are locking for reads or writes. We only lock the HgfsFile on Mac OS
- * because FreeBSD vnodes are locked when handed to the VFS layer and there
- * is a 1:1 mapping between vnodes and HgfsFile objects so no extra locking
- * is required.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsFileVnodeLock(HgfsFile *fp, // IN: file state for vnode lock
- HgfsVnodeLockType type) // IN: Reader or Writer lock?
-{
-#if defined __APPLE__
- DEBUG(VM_DEBUG_ENTRY, "Enter(%p,%p,%d)\n",
- fp, fp->rwVnodeLock, type);
-
- if (type == HGFS_READER_LOCK) {
- os_rw_lock_lock_shared(fp->rwVnodeLock);
- } else {
- os_rw_lock_lock_exclusive(fp->rwVnodeLock);
- }
-#endif
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileVnodeUnlock --
- *
- * Unlocks the file node's vnode lock. Results are
- * undefined the type of lock specified is different than the one that the
- * vnode was locked with originally.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsFileVnodeUnlock(HgfsFile *fp, // IN: file node to lock
- HgfsVnodeLockType type) // IN: Reader or Writer lock?
-{
-#if defined __APPLE__
- DEBUG(VM_DEBUG_ENTRY, "Enter(%p,%p,%d)\n",
- fp, fp->rwVnodeLock, type);
-
- if (type == HGFS_READER_LOCK) {
- os_rw_lock_unlock_shared(fp->rwVnodeLock);
- } else {
- os_rw_lock_unlock_exclusive(fp->rwVnodeLock);
- }
-#endif
-}
-
-
-/* Allocation/initialization/free of open file state */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsAllocFile --
- *
- * Allocates and initializes a file structure.
- *
- * Results:
- * Returns a pointer to the open file on success, NULL on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static HgfsFile *
-HgfsAllocFile(const char *fileName, // IN: Name of file
- HgfsFileType fileType, // IN: Type of file
- struct vnode *dvp, // IN: Parent directory vnode
- HgfsFileHashTable *htp, // IN: Hash table
- int permissions, // IN: permissions for creating new files
- off_t fileSize) // IN: file size
-{
- HgfsFile *fp;
- fp = os_malloc(sizeof *fp, M_ZERO | M_WAITOK);
-
- if (fp != NULL) {
- DEBUG(VM_DEBUG_INFO, "HgfsGetFile: allocated HgfsFile for %s.\n", fileName);
-
- if (HgfsInitFile(fp, dvp, fileName, fileType, permissions, fileSize) != 0) {
- DEBUG(VM_DEBUG_FAIL, "Failed to initialize HgfsFile");
- os_free(fp, sizeof(*fp));
- fp = NULL;
- }
- } else {
- DEBUG(VM_DEBUG_FAIL, "Failed to allocate memory");
- }
- return fp;
-}
-
-/* Acquiring/releasing file state */
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsInsertFile --
- *
- * Inserts a HgfsFile object into the hash table if the table does not
- * contain an object with the same name.
- * If an object with the same name already exists in the hash table
- * then does nothing and just returns pointer to the existing object.
- *
- * Results:
- * Returns a pointer to the file if there is a name collision, NULL otherwise.
- *
- * Side effects:
- * If there is a name collision adds reference to vnode IOrefcount.
- *
- *----------------------------------------------------------------------------
- */
-
-static HgfsFile *
-HgfsInsertFile(const char *fileName, // IN: Filename to get file for
- HgfsFile *fp, // IN: HgfsFile object to insert
- HgfsFileHashTable *htp) // IN: Hash table to look in
-{
- HgfsFile *existingFp = NULL;
-
- ASSERT(fileName);
- ASSERT(htp);
-
- /*
- * We try to find the file in the hash table. If it exists we increment its
- * reference count and return it.
- */
- os_mutex_lock(htp->mutex);
-
- existingFp = HgfsFindFile(fileName, htp);
- if (existingFp) { // HgfsFile with this name already exists
- int ret = vnode_get(existingFp->vnodep);
- if (ret != 0) {
- /*
- * It is not clear why vnode_get may fail while there is HgfsFile in
- * our hash table. Most likely it will never happen.
- * However if this ever occur the safest approach is to remove
- * the HgfsFile structure from the hash table but do dont free it.
- * It should be freed later on when the vnode is recycled.
- */
- DblLnkLst_Unlink1(&existingFp->listNode);
- existingFp = NULL;
- }
- }
- if (existingFp == NULL) {
- HgfsAddFile(fp, htp);
- }
-
- os_mutex_unlock(htp->mutex);
- return existingFp;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsReleaseFile --
- *
- * Removes HgfsFile structure from the hash table and releases it.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsReleaseFile(HgfsFile *fp, // IN: File to release
- HgfsFileHashTable *htp) // IN: Hash table to look in/remove from
-{
- ASSERT(fp);
- ASSERT(htp);
-
- DEBUG(VM_DEBUG_INFO, "HgfsReleaseFile: freeing HgfsFile for %s.\n",
- fp->fileName);
- /* Take this file off its list */
- os_mutex_lock(htp->mutex);
- DblLnkLst_Unlink1(&fp->listNode);
- os_mutex_unlock(htp->mutex);
-
- HgfsFreeFile(fp);
-}
-
-
-/* Allocation/initialization/free of file state */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsInitFile --
- *
- * Initializes a file structure.
- *
- * This sets the filename of the file and initializes other structure
- * elements.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsInitFile(HgfsFile *fp, // IN: File to initialize
- struct vnode *dvp, // IN: Paretn directory vnode
- const char *fileName, // IN: Name of file
- HgfsFileType fileType, // IN: Type of file
- int permissions, // IN: Permissions for new files
- off_t fileSize) // IN: File size
-{
- int len;
-
- ASSERT(fp);
- ASSERT(fileName);
-
- /* Make sure the filename will fit. */
- len = strlen(fileName);
- if (len > sizeof fp->fileName - 1) {
- return HGFS_ERR;
- }
-
- fp->fileNameLength = len;
- memcpy(fp->fileName, fileName, len + 1);
- fp->fileName[fp->fileNameLength] = '\0';
-
- /*
- * We save the file type so we can recreate a vnode for the HgfsFile without
- * sending a request to the Hgfs Server.
- */
- fp->permissions = permissions;
-
- /* Initialize the links to place this file in our hash table. */
- DblLnkLst_Init(&fp->listNode);
-
- /*
- * Fill in the node id. This serves as the inode number in directory
- * entries and the node id in vnode attributes.
- */
- HgfsNodeIdHash(fp->fileName, fp->fileNameLength, &fp->nodeId);
-
- fp->mode = 0;
- fp->modeIsSet = FALSE;
-
- fp->handleRefCount = 0;
- fp->intHandleRefCount = 0;
- fp->handle = 0;
- fp->mmapped = FALSE;
- fp->fileSize = fileSize;
-
- fp->handleLock = os_rw_lock_alloc_init("hgfs_rw_handle_lock");
- if (!fp->handleLock) {
- goto destroyOut;
- }
-
- fp->modeMutex = os_mutex_alloc_init("hgfs_mtx_mode");
- if (!fp->modeMutex) {
- goto destroyOut;
- }
-
- if (!HgfsFileVnodeLockInit(fp)) {
- goto destroyOut;
- }
-
- fp->parent = dvp;
- if (dvp != NULL) {
- vnode_ref(dvp);
- }
-
- /* Success */
- return 0;
-
-destroyOut:
- ASSERT(fp);
-
- if (fp->handleLock) {
- os_rw_lock_free(fp->handleLock);
- }
-
- if (fp->modeMutex) {
- os_mutex_free(fp->modeMutex);
- }
-
- HgfsFileVnodeLockFree(fp);
-
- os_free(fp, sizeof *fp);
- return HGFS_ERR;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFreeFile --
- *
- * Preforms necessary cleanup and frees the memory allocated for HgfsFile.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsFreeFile(HgfsFile *fp) // IN: HgfsFile structure to free
-{
- ASSERT(fp);
- os_rw_lock_free(fp->handleLock);
- os_mutex_free(fp->modeMutex);
- HgfsFileVnodeLockFree(fp);
- if (fp->parent != NULL) {
- vnode_rele(fp->parent);
- }
- os_free(fp, sizeof *fp);
-}
-
-
-/* Adding/finding/removing file state from hash table */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsAddFile --
- *
- * Adds the file to the hash table.
- *
- * This function must be called with the hash table lock held. This is done
- * so adding the file in the hash table can be made with any other
- * operations (such as previously finding out that this file wasn't in the
- * hash table).
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsAddFile(HgfsFile *fp, // IN: File to add
- HgfsFileHashTable *htp) // IN: Hash table to add to
-{
- unsigned int index;
-
- ASSERT(fp);
- ASSERT(htp);
-
- LCK_MTX_ASSERT(htp->mutex);
- index = HgfsFileNameHash(fp->fileName);
-
- /* Add this file to the end of the bucket's list */
- DblLnkLst_LinkLast(HGFS_FILE_HT_HEAD(htp, index), &fp->listNode);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFindFile --
- *
- * Looks for a filename in the hash table.
- *
- * This function must be called with the hash table lock held. This is done
- * so finding the file in the hash table and using it (after this function
- * returns) can be atomic.
- *
- * Results:
- * Returns a pointer to the file if found, NULL otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static HgfsFile *
-HgfsFindFile(const char *fileName, // IN: Filename to look for
- HgfsFileHashTable *htp) // IN: Hash table to look in
-{
- HgfsFile *found = NULL;
- DblLnkLst_Links *currNode;
- unsigned int index;
-
- ASSERT(fileName);
- ASSERT(htp);
- LCK_MTX_ASSERT(htp->mutex);
-
- /* Determine which bucket. */
- index = HgfsFileNameHash(fileName);
-
- /* Traverse the bucket's list. */
- for (currNode = HGFS_FILE_HT_HEAD(htp, index);
- currNode != HGFS_FILE_HT_BUCKET(htp, index);
- currNode = currNode->next) {
- HgfsFile *curr;
- curr = DblLnkLst_Container(currNode, HgfsFile, listNode);
-
- if (strcmp(curr->fileName, fileName) == 0) {
- /* We found the file we want. */
- found = curr;
- break;
- }
- }
-
- /* Return file if found. */
- return found;
-}
-
-
-/* Other utility functions */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileNameHash --
- *
- * Hashes the filename to get an index into the hash table. This is known
- * as the PJW string hash function and it was taken from "Mastering
- * Algorithms in C".
- *
- * Results:
- * Returns an index between 0 and HGFS_HT_NR_BUCKETS.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static unsigned int
-HgfsFileNameHash(const char *fileName) // IN: Filename to hash
-{
- unsigned int val = 0;
-
- ASSERT(fileName);
-
- while (*fileName != '\0') {
- unsigned int tmp;
-
- val = (val << 4) + (*fileName);
- if ((tmp = (val & 0xf0000000))) {
- val = val ^ (tmp >> 24);
- val = val ^ tmp;
- }
-
- fileName++;
- }
-
- return val % HGFS_HT_NR_BUCKETS;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsNodeIdHash --
- *
- * Hashes the provided filename to generate a node id.
- *
- * Results:
- * None. The value of the hash is filled into outHash.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static void
-HgfsNodeIdHash(const char *fileName, // IN: Filename to hash
- uint32_t fileNameLength, // IN: Length of the filename
- ino_t *outHash) // OUT: Location to write hash to
-{
- SHA1_CTX hashContext;
- unsigned char digest[SHA1_HASH_LEN];
- int i;
-
- ASSERT(fileName);
- ASSERT(outHash);
-
- /* Make sure we start at a consistent state. */
- memset(&hashContext, 0, sizeof hashContext);
- memset(digest, 0, sizeof digest);
- memset(outHash, 0, sizeof *outHash);
-
- /* Generate a SHA1 hash of the filename */
- SHA1Init(&hashContext);
- SHA1Update(&hashContext, (unsigned const char *)fileName, fileNameLength);
- SHA1Final(digest, &hashContext);
-
- /*
- * Fold the digest into the allowable size of our hash.
- *
- * For each group of bytes the same size as our output hash, xor the
- * contents of the digest together. If there are less than that many bytes
- * left in the digest, xor each byte that's left.
- */
- for(i = 0; i < sizeof digest; i += sizeof *outHash) {
- int bytesLeft = sizeof digest - i;
-
- /* Do a byte-by-byte xor if there aren't enough bytes left in the digest */
- if (bytesLeft < sizeof *outHash) {
- int j;
-
- for (j = 0; j < bytesLeft; j++) {
- uint8 *outByte = (uint8 *)outHash + j;
- uint8 *inByte = (uint8 *)((uint32_t *)(digest + i)) + j;
- *outByte ^= *inByte;
- }
- break;
- }
-
- /* Block xor */
- *outHash ^= *((uint32_t *)(digest + i));
- }
-
- /*
- * Clear the most significant byte so that user space apps depending on
- * a node id/inode number that's only 32 bits won't break. (For example,
- * gedit's call to stat(2) returns EOVERFLOW if we don't do this.)
- */
-#if 0
-# ifndef HGFS_BREAK_32BIT_USER_APPS
- *((uint32_t *)outHash) ^= *((uint32_t *)outHash + 1);
- *((uint32_t *)outHash + 1) = 0;
-# endif
-#endif
-
- DEBUG(VM_DEBUG_INFO, "Hash of: %s (%d) is %u\n", fileName, fileNameLength, *outHash);
-
- return;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsIsModeCompatible --
- *
- * Verifies if the requested open mode for the file is compatible
- * with already assigned open mode.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-HgfsIsModeCompatible(HgfsMode requestedMode, // IN: Requested open mode
- HgfsMode existingMode) // IN: Existing open mode
-{
- DEBUG(VM_DEBUG_LOG, "Compare mode %d with %d.\n", requestedMode, existingMode);
- return (existingMode == HGFS_OPEN_MODE_READ_WRITE ||
- requestedMode == existingMode);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSetFileSize --
- *
- * Notifies virtual memory system that file size has changed.
- * Required for memory mapped files to work properly.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-void
-HgfsSetFileSize(struct vnode *vp, // IN: vnode which file size has changed
- off_t newSize) // IN: new value for file size
-{
- HgfsFile *fp;
-
- ASSERT(vp);
- fp = HGFS_VP_TO_FP(vp);
- if (fp->fileSize != newSize) {
- fp->fileSize = newSize;
- os_SetSize(vp, newSize);
- }
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/state.h b/open-vm-tools/modules/freebsd/vmhgfs/state.h
deleted file mode 100644
index 7b91b53d..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/state.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * state.h --
- *
- * Public functions, types, and macros for Hgfs state that is attached to
- * vnodes.
- */
-
-#ifndef _STATE_H_
-#define _STATE_H_
-
-/*
- * Includes
- */
-
-#include <sys/param.h> /* MAXPATHLEN */
-#include <sys/lock.h>
-#include <sys/vnode.h> /* struct vnode */
-
-#include "hgfsProto.h"
-#include "dbllnklst.h"
-#include "os.h"
-
-/*
- * Macros
- */
-
-/* Number of buckets for the HgfsInode hash table */
-#define HGFS_HT_NR_BUCKETS 5
-
-/* Conversion between different state structures */
-#if defined __FreeBSD__
-# define HGFS_VP_TO_FP(vp) \
- ((HgfsFile *)(vp)->v_data)
-#elif defined __APPLE__
-# define HGFS_VP_TO_FP(vp) \
- ((HgfsFile *)vnode_fsnode(vp))
-#endif
-
-#define HGFS_FP_TO_VP(fp) \
- (fp)->vnodep
-
-#define HGFS_VP_TO_FILENAME(vp) \
- HGFS_VP_TO_FP(vp)->fileName
-
-#define HGFS_VP_TO_FILENAME_LENGTH(vp) \
- HGFS_VP_TO_FP(vp)->fileNameLength
-
-#define HGFS_VP_TO_NODEID(vp) \
- HGFS_VP_TO_FP(vp)->nodeId
-
-#define HGFS_VP_TO_RWLOCK(vp) \
- HGFS_VP_TO_FP(vp)->rwlock
-
-#define HGFS_VP_TO_RWLOCKP(vp) \
- &(HGFS_VP_TO_RWLOCK(vp))
-
-#define HGFS_VP_TO_PERMISSIONS(vp) \
- HGFS_VP_TO_FP(vp)->permissions
-
-#define HGFS_VP_TO_MMAPPED(vp) \
- HGFS_VP_TO_FP(vp)->mmapped
-
-#define HGFS_VP_TO_FILESIZE(vp) \
- HGFS_VP_TO_FP(vp)->fileSize
-
-
-/*
- * Types
- */
-
-typedef uint32_t HgfsMode;
-
-typedef enum HgfsVnodeLockType {
- HGFS_WRITER_LOCK = 0,
- HGFS_READER_LOCK = 1
-} HgfsVnodeLockType;
-
-typedef enum HgfsOpenType {
- OPENREQ_OPEN, /* A referenced handle in response to a vnode_open. */
- OPENREQ_CREATE, /* A referenced handle in response to a vnode_create. */
- OPENREQ_READ, /* A referenced handle in response to a vnode_read. */
- OPENREQ_MMAP, /* A referenced handle in response to a vnode_mmap. */
-} HgfsOpenType;
-
-/*
- * State kept per shared file from the host.
- *
- * All fields are read-only after initialization except reference count, which
- * is protected by the mutex.
- */
-typedef struct HgfsFile {
- /* Link to place this state on the file state hash table */
- DblLnkLst_Links listNode;
- /*
- * Full path of file within the filesystem (that is, taking /mnt/hgfs as /).
- * These are built from / in HgfsMount() and appending names as provided to
- * HgfsLookup(). Saving the length in HgfsIget() saves having to calculate
- * it in each HgfsMakeFullName().
- */
- char fileName[MAXPATHLEN + 1];
- uint32_t fileNameLength;
- ino_t nodeId;
-
- /*
- * A pointer back to the vnode this HgfsFile is for.
- */
- struct vnode *vnodep;
-
- /*
- * A pointer back to the parent directory vnode.
- */
- struct vnode *parent;
-
- /*
- * Mode (permissions) specified for this file to be created with. This is necessary
- * because create is called with the mode then open is called without it.
- * We save this value in create and access it in open.
- * This field is set during initialization of HGFS and is never changed.
- */
- int permissions;
-
- /* Mode that was used to open the handle on the host */
- HgfsMode mode;
- Bool modeIsSet;
- OS_MUTEX_T *modeMutex;
-
- /*
- * Handle provided by reply to a request. If the reference count is > 0, the
- * the handle is valid.
- */
- uint32_t handleRefCount;
- HgfsHandle handle;
- OS_RWLOCK_T *handleLock;
- /*
- * Locked along with the above, the additional reference which is the
- * internal references for opening which occurs alongside the actual open.
- */
- uint32_t intHandleRefCount;
-
- /*
- * Indicates that memory mapping has been established for the file.
- * Used with the reference counting above.
- */
- Bool mmapped;
-
- /*
- * One big difference between the Mac OS and FreeBSD VFS layers is that the
- * XNU kernel does not lock a vnode before it calls our VFS functions. As a
- * result, we have to provide our RwLock which is locked in macos/vnops.c
- * before any common functions are called.
- */
-#if defined __APPLE__
- OS_RWLOCK_T *rwVnodeLock;
-#endif
- /*
- * File size. HGFS must tell memory management system when file size is changed.
- * It implies that HGFS has to know if a write request writes data beyond EOF thus
- * it has to maintain local copy of file size that is kept in sync with the size
- * reported to memory manager/pager.
- */
- off_t fileSize;
-} HgfsFile;
-
-/* The hash table for file state. */
-typedef struct HgfsFileHashTable {
- OS_MUTEX_T *mutex;
- DblLnkLst_Links hashTable[HGFS_HT_NR_BUCKETS];
-} HgfsFileHashTable;
-
-/* Forward declaration to prevent circular dependency between this and hgfsbsd.h. */
-struct HgfsSuperInfo;
-
-void HgfsVnodeLock(struct vnode *vp, HgfsVnodeLockType type);
-void HgfsVnodeUnlock(struct vnode *vp, HgfsVnodeLockType type);
-
-int HgfsVnodeGet(struct vnode **vpp, struct vnode *dp, struct HgfsSuperInfo *sip,
- struct mount *vfsp, const char *fileName, HgfsFileType fileType,
- HgfsFileHashTable *htp, Bool createFile, int permissions,
- off_t fileSize);
-int HgfsVnodeGetRoot(struct vnode **vpp, struct HgfsSuperInfo *sip, struct mount *vfsp,
- const char *fileName, HgfsFileType fileType, HgfsFileHashTable *htp);
-int HgfsReleaseVnodeContext(struct vnode *vp, HgfsFileHashTable *htp);
-void HgfsNodeIdGet(HgfsFileHashTable *ht, const char *fileName,
- uint32_t fileNameLength, ino_t *outNodeId);
-int HgfsInitFileHashTable(HgfsFileHashTable *htp);
-void HgfsDestroyFileHashTable(HgfsFileHashTable *htp);
-Bool HgfsFileHashTableIsEmpty(struct HgfsSuperInfo *sip, HgfsFileHashTable *htp);
-
-/* Handle get/set/clear functions */
-void HgfsSetOpenFileHandle(struct vnode *vp, HgfsHandle handle,
- HgfsMode openMode, HgfsOpenType openType);
-int HgfsGetOpenFileHandle(struct vnode *vp, HgfsHandle *outHandle);
-int HgfsReleaseOpenFileHandle(struct vnode *vp, HgfsOpenType openType, HgfsHandle *handleToClose);
-int HgfsCheckAndReferenceHandle(struct vnode *vp, int requestedOpenMode, HgfsOpenType openType);
-int HgfsHandleIncrementRefCount(struct vnode *vp);
-void HgfsSetFileSize(struct vnode *vp, off_t newSize);
-
-#endif /* _STATE_H_ */
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/transport.c b/open-vm-tools/modules/freebsd/vmhgfs/transport.c
deleted file mode 100644
index 5eb86b4e..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/transport.c
+++ /dev/null
@@ -1,389 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * transport.c --
- *
- * Functions that prepare HGFS packages and send them to the host.
- * Implementations are shared between both Mac OS and FreeBSD.
- */
-
-#include <sys/param.h> // for everything
-#include <sys/vnode.h> // for struct vnode
-#include <sys/dirent.h> // for struct dirent
-
-#include "fsutil.h"
-#include "debug.h"
-#include "transport.h"
-#include "cpName.h"
-#include "os.h"
-
-#define HGFS_FILE_OPEN_MASK (HGFS_OPEN_VALID_MODE | \
- HGFS_OPEN_VALID_FLAGS | \
- HGFS_OPEN_VALID_SPECIAL_PERMS | \
- HGFS_OPEN_VALID_OWNER_PERMS | \
- HGFS_OPEN_VALID_GROUP_PERMS | \
- HGFS_OPEN_VALID_OTHER_PERMS | \
- HGFS_OPEN_VALID_FILE_NAME)
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSendOpenDirRequest --
- *
- * Sends a SEARCH_OPEN request to the Hgfs server.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsSendOpenDirRequest(HgfsSuperInfo *sip, // IN: Superinfo pointer
- char *fullPath, // IN: Full path for the file
- uint32 fullPathLen, // IN: Length of the full path
- HgfsHandle *handle) // OUT: HGFS handle for the opened file
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestSearchOpenV3 *request;
- HgfsReplySearchOpenV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- uint32 reqBufferSize;
- int ret;
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- return ret;
- }
-
- /* Set the correct header values */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestSearchOpenV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SEARCH_OPEN_V3);
-
- request->dirName.flags = 0;
- request->dirName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
- request->dirName.fid = HGFS_INVALID_HANDLE;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1,
- request->dirName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- return -ret;
- }
-
- request->dirName.length = ret;
- reqSize += ret;
-
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- /* Submit the request to the Hgfs server */
- ret = HgfsSubmitRequest(sip, req);
- if (ret == 0) {
-
- /* Our reply is in the request packet */
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplySearchOpenV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret == 0) {
- *handle = reply->search;
- } else {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- }
-
- DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id);
- DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status);
- DEBUG(VM_DEBUG_COMM, " handle: %d\n", reply->search);
-
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- return ret;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSendOpenRequest --
- *
- * Sends an OPEN request to the Hgfs server to open an existing file.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsSendOpenRequest(HgfsSuperInfo *sip, // IN: Superinfo pointer
- int openMode, // IN: HGFS mode of open
- int openFlags, // IN: HGFS open flags
- int permissions, // IN: Permissions of open (only when creating)
- char *fullPath, // IN: Full path for the file
- uint32 fullPathLen, // IN: Length of the full path
- HgfsHandle *handle) // OUT: HGFS handle for the opened file
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestOpenV3 *request;
- HgfsReplyOpenV3 *reply;
- int ret;
- uint32 reqSize;
- uint32 repSize;
- uint32 reqBufferSize;
-
- DEBUG(VM_DEBUG_LOG, "Trace enter.\n");
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- DEBUG(VM_DEBUG_FAIL, "HgfsKReq_AllocateRequest failed.\n");
- return ret;
- }
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestOpenV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_OPEN_V3);
-
- request->mask = HGFS_FILE_OPEN_MASK;
- request->reserved1 = 0;
- request->reserved2 = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
- request->mode = openMode;
- request->flags = openFlags;
- DEBUG(VM_DEBUG_COMM, "open flags are %x\n", request->flags);
-
- request->specialPerms = (permissions & (S_ISUID | S_ISGID | S_ISVTX)) >>
- HGFS_ATTR_SPECIAL_PERM_SHIFT;
- request->ownerPerms = (permissions & S_IRWXU) >> HGFS_ATTR_OWNER_PERM_SHIFT;
- request->groupPerms = (permissions & S_IRWXG) >> HGFS_ATTR_GROUP_PERM_SHIFT;
- request->otherPerms = permissions & S_IRWXO;
- DEBUG(VM_DEBUG_COMM, "permissions are %o\n", permissions);
-
- request->fileName.flags = 0;
- request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
- request->fileName.fid = HGFS_INVALID_HANDLE;
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1,
- request->fileName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
- ret = -ret;
- goto out;
- }
- request->fileName.length = ret;
- reqSize += ret;
-
- /* Packet size includes the request and its payload. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* HgfsSubmitRequest will destroy the request if necessary. */
- DEBUG(VM_DEBUG_FAIL, "could not submit request.\n");
- req = NULL; // Request has been deallocated by SubmitRequest
- } else {
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplyOpenV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
- ret = HgfsGetStatus(req, repSize);
- if (ret == 0) {
- *handle = reply->file;
- }
- }
-out:
- if (req != NULL) {
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- return ret;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsCloseServerDirHandle --
- *
- * Prepares close handle request and sends it to the HGFS server
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsCloseServerDirHandle(HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle handle) // IN: Handle to close
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestSearchCloseV3 *request;
- HgfsReplySearchCloseV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- int ret;
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- return ret;
- }
-
- /*
- * Prepare the request structure. Of note here is that the request is
- * always the same size so we just set the packetSize to that.
- */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestSearchCloseV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SEARCH_CLOSE_V3);
-
- request->search = handle;
- request->reserved = 0;
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
-
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- /* Submit the request to the Hgfs server */
- ret = HgfsSubmitRequest(sip, req);
- if (ret == 0) {
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
- DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id);
- DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- if (ret != EPROTO) {
- ret = EFAULT;
- }
- }
-
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsCloseServerFileHandle --
- *
- * Prepares close handle request and sends it to the HGFS server
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsCloseServerFileHandle(HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle handle) // IN: Handle to close
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestCloseV3 *request;
- HgfsReplyCloseV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- int ret;
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- return ret;
- }
-
- /*
- * Prepare the request structure. Of note here is that the request is
- * always the same size so we just set the packetSize to that.
- */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestCloseV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_CLOSE_V3);
-
- request->file = handle;
- request->reserved = 0;
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
-
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- /* Submit the request to the Hgfs server */
- ret = HgfsSubmitRequest(sip, req);
- if (ret == 0) {
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
- DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id);
- DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- if (ret != EPROTO) {
- ret = EFAULT;
- }
- }
-
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- return ret;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/transport.h b/open-vm-tools/modules/freebsd/vmhgfs/transport.h
deleted file mode 100644
index 31ac7ba8..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/transport.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * transport.h --
- *
- * Communication with HGFS server.
- */
-
-#ifndef _HGFS_TRANSPORT_COMMON_H_
-#define _HGFS_TRANSPORT_COMMON_H_
-
-#include "hgfs_kernel.h"
-
-/* Internal transport functions used by both FreeBSD and Mac OS */
-int HgfsSendOpenRequest(HgfsSuperInfo *sip, int openMode, int openFlags,
- int permissions, char *fullPath,
- uint32 fullPathLen, HgfsHandle *handle);
-int HgfsSendOpenDirRequest(HgfsSuperInfo *sip, char *fullPath,
- uint32 fullPathLen, HgfsHandle *handle);
-int HgfsCloseServerDirHandle(HgfsSuperInfo *sip, HgfsHandle handleToClose);
-int HgfsCloseServerFileHandle(HgfsSuperInfo *sip, HgfsHandle handleToClose);
-
-#endif // _HGFS_TRANSPORT_COMMON_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/vfsops.c b/open-vm-tools/modules/freebsd/vmhgfs/vfsops.c
deleted file mode 100644
index a0fa8f1d..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/vfsops.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * vfsops.c --
- *
- * VFS operations for the FreeBSD Hgfs client.
- */
-
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#if __FreeBSD_version >= 700000
-#include <sys/priv.h>
-#endif
-
-#include "hgfs_kernel.h"
-#include "request.h"
-#include "debug.h"
-#include "hgfsDevLinux.h"
-#include "os.h"
-#include "compat_freebsd.h"
-#include "vfsopscommon.h"
-
-/*
- * Local functions (prototypes)
- */
-
-static vfs_mount_t HgfsVfsMount;
-static vfs_unmount_t HgfsVfsUnmount;
-static vfs_root_t HgfsVfsRoot;
-static vfs_statfs_t HgfsVfsStatfs;
-static vfs_init_t HgfsVfsInit;
-static vfs_uninit_t HgfsVfsUninit;
-
-
-/*
- * Global data
- */
-
-/*
- * Hgfs VFS operations vector
- */
-static struct vfsops HgfsVfsOps = {
- .vfs_mount = HgfsVfsMount,
- .vfs_unmount = HgfsVfsUnmount,
- .vfs_root = HgfsVfsRoot,
- .vfs_quotactl = vfs_stdquotactl,
- .vfs_statfs = HgfsVfsStatfs,
- .vfs_sync = vfs_stdsync,
- .vfs_vget = vfs_stdvget,
- .vfs_fhtovp = vfs_stdfhtovp,
- .vfs_checkexp = vfs_stdcheckexp,
-#if __FreeBSD_version < 700000
- .vfs_vptofh = vfs_stdvptofh,
-#endif
- .vfs_init = HgfsVfsInit,
- .vfs_uninit = HgfsVfsUninit,
- .vfs_extattrctl = vfs_stdextattrctl,
- .vfs_sysctl = vfs_stdsysctl,
-};
-
-/*
- * Kernel module glue to execute init/uninit at load/unload.
- */
-VFS_SET(HgfsVfsOps, vmhgfs, 0);
-
-
-/*
- * Local functions (definitions)
- */
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVfsMount
- *
- * "The VFS_MOUNT() macro mounts a file system into the system's
- * namespace or updates the attributes of an already mounted file
- * system." (VFS_MOUNT(9).)
- *
- * Results:
- * Zero on success, an appropriate system error on failure.
- *
- * Side effects:
- * Done.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVfsMount(struct mount *mp, // IN: structure representing the file system
- struct thread *td) // IN: thread which is mounting the file system
-{
- HgfsSuperInfo *sip;
- struct vnode *vp;
- int ret = 0;
- char *target;
- int error;
- int size;
- Bool *uidSet = NULL;
- int *uid = NULL;
- Bool *gidSet = NULL;
- int *gid = NULL;
-
- /*
- * - Examine/validate mount flags from userland.
- * - Grab mount options from userland, validate. (Paths, etc.)
- * - Allocate HgfsSuperInfo, root vnode; bind the two.
- * - Update mnt_flag/mnt_kern_flags (ex: MPSAFE?)
- * - vfs_getnewfsid
- * - vfs_mountedfrom
- */
-
- /*
- * We do not support any of the user's mount options, so fail any mount
- * attempt with a non-zero mnt_flag. (It'd be quite a shock to find out
- * that a share successfully mounted read-only is really writeable!)
- */
- if (mp->mnt_flag != 0) {
- return EOPNOTSUPP;
- }
-
- /*
- * Since Hgfs requires the caller to be root, only allow mount attempts made
- * by the superuser.
- */
- if ((ret = suser(td)) != 0) {
- return ret;
- }
-
- /*
- * Allocate a new HgfsSuperInfo structure. This is the super structure
- * maintained for each file system. (With M_WAITOK, this call cannot fail.)
- */
- sip = os_malloc(sizeof *sip, M_WAITOK | M_ZERO);
- mp->mnt_data = sip;
-
- error = HgfsInitFileHashTable(&sip->fileHashTable);
- if (error) {
- goto out;
- }
-
- /*
- * Allocate the root vnode, then record it and the file system information
- * in our superinfo.
- */
- error = HgfsVnodeGetRoot(&vp, sip, mp, "/",
- HGFS_FILE_TYPE_DIRECTORY, &sip->fileHashTable);
- if (error) {
- HgfsDestroyFileHashTable(&sip->fileHashTable);
- goto out;
- }
-
- sip->vfsp = mp;
- sip->rootVnode = vp;
-
- /* We're finished with the root vnode, so unlock it. */
- COMPAT_VOP_UNLOCK(vp, 0, td);
-
- /*
- * Initialize this file system's Hgfs requests container.
- */
- sip->reqs = HgfsKReq_AllocateContainer();
-
- /*
- * Since this implementation supports fine-grained locking, inform the kernel
- * that we're MPSAFE. (This is in the context of protecting its own data
- * structures, not oplocks/leases with the VM's host.)
- */
- MNT_ILOCK(mp);
- mp->mnt_kern_flag |= MNTK_MPSAFE;
- MNT_IUNLOCK(mp);
-
- /* Get a new unique filesystem ID */
- vfs_getnewfsid(mp);
-
- error = vfs_getopt(mp->mnt_optnew, "target", (void **)&target, &size);
- if (error || target[size - 1] != '\0') {
- target = "host:hgfs";
- }
-
- /* Get uidSet */
- error = vfs_getopt(mp->mnt_optnew, "uidSet", (void**)&uidSet, &size);
-
- if (!error && size == sizeof(Bool) && uidSet) {
- sip->uidSet = *uidSet;
- } else {
- sip->uidSet = FALSE;
- }
-
- /* Get uid */
- error = vfs_getopt(mp->mnt_optnew, "uid", (void**)&uid, &size);
-
- if (!error && size == sizeof(int) && uid) {
- sip->uid = *uid;
- } else {
- sip->uidSet = FALSE;
- }
-
- /* Get gidSet */
- error = vfs_getopt(mp->mnt_optnew, "gidSet", (void**)&gidSet, &size);
-
- if (!error && size == sizeof(Bool) && gidSet) {
- sip->gidSet = *gidSet;
- } else {
- sip->gidSet = FALSE;
- }
-
- /* Get gid */
- error = vfs_getopt(mp->mnt_optnew, "gid", (void**)&gid, &size);
-
- if (!error && size == sizeof(int) && gid) {
- sip->gid = *gid;
- } else {
- sip->gidSet = FALSE;
- }
-
- vfs_mountedfrom(mp, target);
-
- /*
- * Fill in the statfs structure. Note that even if HgfsStatfsInt
- * fails, we shall just log the error and move on, since it is
- * not a critical operation.
- */
- error = HgfsStatfsInt(vp, &mp->mnt_stat);
- if (error) {
- DEBUG(VM_DEBUG_FAIL, "HgfsStatfsInt failed with ret = %d\n", ret);
- error = 0;
- }
-
- DEBUG(VM_DEBUG_LOAD, "Exit\n");
-
-out:
- if (error) {
- os_free(sip, sizeof *sip);
- }
-
- return error;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVfsUnmount --
- *
- * "VFS_UNMOUNT -- unmount a file system", VFS_UNMOUNT(9).
- *
- * Results:
- * Zero if filesystem unmounted, otherwise errno.
- *
- * Side effects:
- * This call may fail if the filesystem is busy & MNT_FORCE not set.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVfsUnmount(struct mount *mp, int mntflags, struct thread *td)
-{
- HgfsSuperInfo *sip;
- int ret = 0;
- int flags = 0;
-
- sip = (HgfsSuperInfo *)mp->mnt_data;
-
- ASSERT(sip);
-
- /*
- * If there are pending requests & we're not being forced out, tell the user
- * that we're still busy.
- */
- if (((mntflags & MNT_FORCE) == 0) &&
- ((HgfsKReq_ContainerIsEmpty(sip->reqs) == FALSE) ||
- (HgfsFileHashTableIsEmpty(sip, &sip->fileHashTable) == FALSE))) {
- return EBUSY;
- }
-
- /*
- * If the user wants us out, cancel all pending Hgfs requests and fail all
- * existing vnode operations.
- */
- if (mntflags & MNT_FORCE) {
- HgfsKReq_CancelRequests(sip->reqs);
- flags |= FORCECLOSE;
- }
-
- /*
- * Vflush will wait until all pending vnode operations are complete.
- */
- ret = vflush(mp, 1, flags, td);
- if (ret != 0) {
- return ret;
- }
-
- HgfsDestroyFileHashTable(&sip->fileHashTable);
-
- /*
- * Now we can throw away our superinfo. Let's reclaim everything allocated
- * during HgfsVfsMount.
- */
- HgfsKReq_FreeContainer(sip->reqs);
-
- mp->mnt_data = NULL;
- os_free(sip, sizeof *sip);
-
- DEBUG(VM_DEBUG_LOAD, "Exit\n");
-
- return 0;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVfsStatvs --
- *
- * "VFS_STATFS(9) - return file system status."
- *
- * Results:
- * Zero on success and non-zero error code on failure.
- *
- * Side effects:
- * Caller's statfs structure is populated.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVfsStatfs(struct mount *mp, struct statfs *sbp, struct thread *td)
-{
- int ret = 0;
- struct vnode *vp;
-
- /* We always want HGFS_BLOCKSIZE to be a power of two */
- ASSERT_ON_COMPILE(HGFS_IS_POWER_OF_TWO(HGFS_BLOCKSIZE));
-
- /*
- * This fills in file system ID and the type number that
- * we got from a call to vfs_getnewfsid() in HgfsVfsMount()
- */
- bcopy(&mp->mnt_stat, sbp, sizeof mp->mnt_stat);
-
- ret = HgfsVfsRoot(mp, LK_SHARED, &vp, td);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "HgfsVfsRoot failed\n");
- return ret;
- }
-
- ret = HgfsStatfsInt(vp, sbp);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "HgfsStatfsInt failed with ret = %d\n", ret);
- goto out;
- }
-
-out:
- /* Drop the reference and shared lock that we acquired in HgfsVfsRoot */
- vput(vp);
- return ret;
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVfsRoot --
- *
- * Retrieves the root Vnode of the specified filesystem.
- *
- * Results:
- * Zero if successful, non-zero otherwise.
- *
- * Side effects:
- * Sets *vpp.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVfsRoot(struct mount *mp, // IN: Filesystem structure
- int flags, // IN: Flags to vget
- struct vnode **vpp, // OUT: Address of root vnode
- struct thread *td) // IN: Thread structure
-{
- HgfsSuperInfo *sip = (HgfsSuperInfo *)mp->mnt_data;
- int ret = 0;
-
- *vpp = NULL;
-
- ret = vget(sip->rootVnode, flags, td);
- if (ret == 0) {
- *vpp = sip->rootVnode;
- }
-
- return ret;
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVfsInit --
- *
- * Initializes the Hgfs filesystem implementation
- *
- * Results:
- * Zero if successful, an errno-type value otherwise.
- *
- * Side effects:
- * Initializes the hgfs request processing system.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVfsInit(struct vfsconf *vfsconf)
-{
- int ret = 0;
-
- /* Initialize the os memory allocation and thread synchronization subsystem. */
- if ((ret = os_init()) != 0) {
- return ret;
- }
-
- ret = HgfsKReq_SysInit();
-
- DEBUG(VM_DEBUG_LOAD, "Hgfs filesystem loaded");
-
- return ret;
-}
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsVfsUninit --
- *
- * Tears down the Hgfs filesystem module state
- *
- * Results:
- * Zero if successful, an errno-type value otherwise.
- *
- * Side effects:
- * Can no longer use any hgfs file systems.
- *
- *-----------------------------------------------------------------------------
- */
-
-static int
-HgfsVfsUninit(struct vfsconf *vfsconf)
-{
- int ret = 0;
-
- ret = HgfsKReq_SysFini();
- os_cleanup();
-
- DEBUG(VM_DEBUG_LOAD, "Hgfs filesystem unloaded");
- return ret;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/vfsopscommon.c b/open-vm-tools/modules/freebsd/vmhgfs/vfsopscommon.c
deleted file mode 100644
index 5ab39057..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/vfsopscommon.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * vnopscommon.h --
- *
- * Common VFS vfsop implementations that are shared between both Mac OS and FreeBSD.
- */
-
-#include <sys/param.h> // for everything
-#include <sys/vnode.h> // for struct vnode
-
-#include "fsutil.h"
-#include "state.h"
-#include "debug.h"
-#include "request.h"
-#include "vnopscommon.h"
-#include "vfsopscommon.h"
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsStatfsInt --
- *
- * Hgfs statfs method. Called by HgfsVfsStatfs on FreeBSD and
- * HgfsVfsGetattr on Mac OS.
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsStatfsInt(struct vnode *vp, // IN: vnode
- HgfsStatfs *stat) // IN: statfs structure to fill in
-{
- HgfsSuperInfo *sip;
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestQueryVolumeV3 *request;
- HgfsReplyQueryVolumeV3 *reply;
- uint32 reqSize;
- uint32 reqBufferSize;
- uint32 repSize;
- char *fullPath = NULL;
- uint32 fullPathLen;
- int ret = 0;
-
- /* Get pointer to the superinfo. */
- sip = HGFS_VP_TO_SIP(vp);
- if (!sip) {
- DEBUG(VM_DEBUG_FAIL, "couldn't acquire superinfo\n");
- return ENOTSUP;
- }
-
- /* Prepare the request */
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- return ret;
- }
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestQueryVolumeV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- /* Initialize the request header */
- requestHeader->id = HgfsKReq_GetId(req);
- requestHeader->op = HGFS_OP_QUERY_VOLUME_INFO_V3;
-
- request->fileName.flags = 0;
- request->fileName.fid = HGFS_INVALID_HANDLE;
- request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- fullPath = HGFS_VP_TO_FILENAME(vp);
- fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp);
-
- ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1,
- request->fileName.name,
- reqBufferSize);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
- ret = -ret;
- goto destroyOut;
- }
- request->fileName.length = ret;
- reqSize += ret;
-
- /* The request size includes header, request and file length */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- ret = HgfsSubmitRequest(sip, req);
-
- if (ret) {
- /* HgfsSubmitRequest() destroys the request if necessary */
-
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplyQueryVolumeV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "reply was invalid");
- goto destroyOut;
- }
-
- ret = HgfsStatusToBSD(replyHeader->status);
-
- if (ret) {
- goto destroyOut;
- }
-
- stat->f_bsize = HGFS_BLOCKSIZE;
- stat->f_iosize = HGFS_BLOCKSIZE;
- stat->f_blocks = HGFS_CONVERT_TO_BLOCKS(reply->totalBytes);
- stat->f_bfree = HGFS_CONVERT_TO_BLOCKS(reply->freeBytes);
- stat->f_bavail = stat->f_bfree;
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- return ret;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/vnops.c b/open-vm-tools/modules/freebsd/vmhgfs/vnops.c
deleted file mode 100644
index 1b424ec1..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/vnops.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * vnops.c --
- *
- * Vnode operations for FreeBSD HGFS client.
- */
-
-#include <sys/param.h> // for everything
-#include <sys/vnode.h> // for struct vnode
-#include <sys/mount.h> // for struct mount
-#include <sys/namei.h> // for name lookup goodness
-#include <sys/libkern.h> // for string & other functions
-#include <sys/fcntl.h> // for in-kernel file access flags (FREAD, etc)
-#include <sys/stat.h> // for file flag bitmasks (S_IRWXU, etc)
-#include <sys/uio.h> // for uiomove
-#include <sys/dirent.h> // for struct dirent
-
-#include "cpName.h"
-
-#include "hgfsUtil.h"
-
-#include "hgfs_kernel.h"
-#include "request.h"
-#include "state.h"
-#include "debug.h"
-#include "fsutil.h"
-#include "vnopscommon.h"
-
-
-/*
- * Local functions (prototypes)
- */
-
-static vop_lookup_t HgfsVopLookup;
-static vop_create_t HgfsVopCreate;
-static vop_open_t HgfsVopOpen;
-static vop_close_t HgfsVopClose;
-static vop_access_t HgfsVopAccess;
-static vop_getattr_t HgfsVopGetattr;
-static vop_setattr_t HgfsVopSetattr;
-static vop_read_t HgfsVopRead;
-static vop_write_t HgfsVopWrite;
-static vop_remove_t HgfsVopRemove;
-static vop_rename_t HgfsVopRename;
-static vop_mkdir_t HgfsVopMkdir;
-static vop_rmdir_t HgfsVopRmdir;
-static vop_readdir_t HgfsVopReaddir;
-static vop_inactive_t HgfsVopInactive;
-static vop_reclaim_t HgfsVopReclaim;
-static vop_print_t HgfsVopPrint;
-static vop_readlink_t HgfsVopReadlink;
-static vop_symlink_t HgfsVopSymlink;
-
-/*
- * Global data
- */
-
-/*
- * HGFS vnode operations vector
- */
-struct vop_vector HgfsVnodeOps = {
- .vop_default = &default_vnodeops,
- .vop_lookup = HgfsVopLookup,
- .vop_create = HgfsVopCreate,
- .vop_open = HgfsVopOpen,
- .vop_close = HgfsVopClose,
- .vop_access = HgfsVopAccess,
- .vop_getattr = HgfsVopGetattr,
- .vop_setattr = HgfsVopSetattr,
- .vop_read = HgfsVopRead,
- .vop_write = HgfsVopWrite,
- .vop_remove = HgfsVopRemove,
- .vop_rename = HgfsVopRename,
- .vop_mkdir = HgfsVopMkdir,
- .vop_rmdir = HgfsVopRmdir,
- .vop_readdir = HgfsVopReaddir,
- .vop_inactive = HgfsVopInactive,
- .vop_reclaim = HgfsVopReclaim,
- .vop_print = HgfsVopPrint,
- .vop_readlink = HgfsVopReadlink,
- .vop_symlink = HgfsVopSymlink,
-};
-
-
-/*
- * Local functions (definitions)
- */
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopLookup --
- *
- * Looks in the provided directory for the specified filename by calling
- * HgfsLookupInt.
- *
- * Results:
- * Returns zero on success and ENOENT if the file cannot be found
- * If file is found, a vnode representing the file is returned in vpp.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopLookup(struct vop_lookup_args *ap)
-/*
-struct vop_lookup_args {
- struct vnode *dvp; // IN : locked vnode of search directory
- struct vnode **vpp; // IN/OUT: addr to store located (locked) vnode
- struct componentname *cnp; // IN : pathname component to search for
-};
- */
-{
- struct vnode *dvp = ap->a_dvp;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
-
- return HgfsLookupInt(dvp, vpp, cnp);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopCreate --
- *
- * This entry point is invoked when a user calls open(2) with the O_CREAT
- * flag specified. We simply call HgfsCreateInt which does the file
- * creation work in a FreeBSD / Mac OS independent way.
- *
- * Results:
- * Returns zero on success and an appropriate error code on error.
- *
- * Side effects:
- * If the file doesn't exist, a vnode will be created.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopCreate(struct vop_create_args *ap)
-/*
-struct vop_create {
- struct vnode *dvp; // IN : locked directory vnode
- struct vnode **vp; // OUT: location to place resultant locked vnode
- struct componentname *cnp; // IN : pathname component created
- struct vattr *vap; // IN : attributes to create new object with
- */
-{
- struct vnode *dvp = ap->a_dvp;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
- struct vattr *vap = ap->a_vap;
-
- return HgfsCreateInt(dvp, vpp, cnp, vap->va_mode);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopOpen --
- *
- * Invoked when open(2) is called on a file in our filesystem. Sends an
- * OPEN request to the Hgfs server with the filename of this vnode.
- *
- * "Opens a file referenced by the supplied vnode. The open() system call
- * has already done a vop_lookup() on the path name, which returned a vnode
- * pointer and then calls to vop_open(). This function typically does very
- * little since most of the real work was performed by vop_lookup()."
- * (Solaris Internals, p537)
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * The HgfsOpenFile for this file is given a handle that can be used on
- * future read and write requests.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopOpen(struct vop_open_args *ap)
-/*
-struct vop_open_args {
- struct vnode *vp; // IN: vnode of file to open
- int mode; // IN: access mode requested by calling process
- struct ucred *cred; // IN: calling process's user's credentials
- struct thread *td; // IN: thread accessing file
- int fdidx; // IN: file descriptor number
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- int mode = ap->a_mode;
-
- return HgfsOpenInt(vp, mode, OPENREQ_OPEN);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopClose --
- *
- * Invoked when a user calls close(2) on a file in our filesystem.
- *
- * Calls HgfsCloseInt which handles the close in a FreeBSD / Mac OS
- * independent way.
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopClose(struct vop_close_args *ap)
-/*
-struct vop_close_args {
- struct vnode *vp; // IN: vnode of object to close [exclusive lock held]
- int fflag; // IN: F* flags (FWRITE, etc) on object
- struct ucred *cred; // IN: calling process's user's credentials
- struct thread *td; // IN: thread accessing file
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- int fflag = ap->a_fflag;
- struct vnode *rootVnode;
- int ret = 0;
-
- /*
- * According to the FreeBSD manpage, VOP_CLOSE can be called with or
- * without a lock held on vp. However, in the FreeBSD 6.2 source code,
- * the only place that VOP_CLOSE is called without a lock held is in
- * kern/vfs_subr.c::vgone1 and only if the vnode is not already doomed with the
- * VI_DOOMED flag. In addition, the VFS layer will not acquire a vnode lock
- * on a doomed vnode (kern/vfs_vnops.c::vn_lock). This means that there is no need
- * to do any locking here as this function will always be called in a serial manner.
- */
-
- /*
- * A problem exists where vflush (on unmount) calls close on the root vnode without
- * first having calling open.
- * Here is the problematic sequence of events:
- * 1. HgfsVfsUnmount calls vflush with 1 v_usecount ref on the rootVnode (the one from mount).
- * 2. vflush calls vgone on the root vnode because rootrefs (in FreeBSD vflush code)
- * is > 0.
- * 3. vgone calls VOP_CLOSE because the root vnode has a v_usecount == 1.
- * The problem is that there was never an open to match the close. This means that when
- * HgfsCloseInt tries decrement the handle reference count, it will go negative (in addition
- * to sending a bad close to the hgfs server). To handle this situation, look for this
- * specific case (which only happens on FreeBSD) and do not call HgfsCloseInt.
- */
-
- rootVnode = HGFS_VP_TO_SIP(vp)->rootVnode;
- if ((rootVnode == vp) && (rootVnode->v_usecount == 1)) {
- DEBUG(VM_DEBUG_LOG, "Skipping final close on rootVnode\n");
- goto out;
- }
-
- ret = HgfsCloseInt(vp, fflag);
-
-out:
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopAccess --
- *
- * This function is invoked when the user calls access(2) on a file in our
- * filesystem. It checks to ensure the user has the specified type of
- * access to the file.
- *
- * We send a GET_ATTRIBUTE request by calling HgfsGetattr() to get the mode
- * (permissions) for the provided vnode.
- *
- * Results:
- * Returns 0 if access is allowed and a non-zero error code otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopAccess(struct vop_access_args *ap)
-/*
-struct vop_access_args {
- struct vnode *vp; // IN: vnode of file to check
- int mode; // IN: type of access required (mask of VREAD|VWRITE|VEXEC)
- struct ucred *cred; // IN: calling process's user's credentials
- struct thread *td; // IN: thread accessing file
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- int mode = ap->a_mode;
- HgfsAccessMode accessMode = 0;
- Bool isDir = vp->v_type == VDIR;
- if (mode & VREAD) {
- accessMode |= isDir ? HGFS_MODE_LIST_DIRECTORY : HGFS_MODE_READ_DATA;
- accessMode |= HGFS_MODE_READ_ATTRIBUTES;
- }
- if (mode & VWRITE) {
- if (isDir) {
- accessMode |= HGFS_MODE_ADD_FILE | HGFS_MODE_ADD_SUBDIRECTORY |
- HGFS_MODE_DELETE | HGFS_MODE_DELETE_CHILD |
- HGFS_MODE_WRITE_ATTRIBUTES;
- } else {
- accessMode |= HGFS_MODE_WRITE_DATA | HGFS_MODE_ADD_SUBDIRECTORY |
- HGFS_MODE_DELETE | HGFS_MODE_WRITE_ATTRIBUTES;
- }
- }
- if (mode & VAPPEND) {
- accessMode |= isDir ? HGFS_MODE_ADD_SUBDIRECTORY : HGFS_MODE_APPEND_DATA;
- }
- if (mode & VEXEC) {
- accessMode |= isDir ? HGFS_MODE_TRAVERSE_DIRECTORY : HGFS_MODE_GENERIC_EXECUTE;
- }
-
- return HgfsAccessInt(vp, accessMode);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopGetattr --
- *
- * "Gets the attributes for the supplied vnode." (Solaris Internals, p536)
- *
- * Results:
- * Zero if successful, an errno-type value otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopGetattr(struct vop_getattr_args *ap)
-/*
-struct vop_getattr_args {
- struct vnode *vp; // IN : vnode of file
- struct vattr *vap; // OUT: attribute container
- struct ucred *cred; // IN : calling process's user's credentials
- struct thread *td; // IN : thread accessing file
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
-
- return HgfsGetattrInt(vp, vap);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopSetattr --
- *
- * Maps the FreeBSD attributes to Hgfs attributes (by calling
- * HgfsSetattrCopy()) and sends a set attribute request to the Hgfs server.
- *
- * "Sets the attributes for the supplied vnode." (Solaris Internals, p537)
- *
- * Results:
- * Returns 0 on success and a non-zero error code on error.
- *
- * Side effects:
- * The file on the host will have new attributes.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopSetattr(struct vop_setattr_args *ap)
-/*
-struct vop_setattr_args {
- struct vnode *vp; // IN: vnode of file
- struct vattr *vap; // IN: attribute container
- struct ucred *cred; // IN: calling process's user's credentials
- struct thread *td; // IN: thread accessing file
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
-
- return HgfsSetattrInt(vp, vap);
-
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopRead --
- *
- * Invoked when a user calls read(2) on a file in our filesystem.
- *
- * Results:
- * Returns zero on success and an error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopRead(struct vop_read_args *ap)
-/*
-struct vop_read_args {
- struct vnode *vp; // IN : the vnode of the file
- struct uio *uio; // INOUT: location of data to be read
- int ioflag; // IN : hints & other directives
- struct ucread *cred; // IN : caller's credentials
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uiop = ap->a_uio;
-
- return HgfsReadInt(vp, uiop, FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopWrite --
- *
- * This is invoked when a user calls write(2) on a file in our filesystem.
- *
- *
- * Results:
- * Returns 0 on success and error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopWrite(struct vop_write_args *ap)
-/*
-struct vop_write_args {
- struct vnode *vp; // IN :
- struct uio *uio; // INOUT:
- int ioflag; // IN :
- struct ucred *cred; // IN :
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uiop = ap->a_uio;
- int ioflag = ap->a_ioflag;
-
- return HgfsWriteInt(vp, uiop, ioflag, FALSE);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopRemove --
- *
- * Composes the full pathname of this file and sends a DELETE_FILE request
- * by calling HgfsDelete().
- *
- * "Removes the file for the supplied vnode." (Solaris Internals, p537)
- *
- * Results:
- * Returns 0 on success or a non-zero error code on error.
- *
- * Side effects:
- * If successful, the file specified will be deleted from the host's
- * filesystem.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopRemove(struct vop_remove_args *ap)
-/*
-struct vop_remove_args {
- struct vnode *dvp; // IN: parent directory
- struct vnode *vp; // IN: vnode to remove
- struct componentname *cnp; // IN: file's pathname information
-*/
-{
- struct vnode *vp = ap->a_vp;
-
- return HgfsRemoveInt(vp);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopRename --
- *
- * Renames the provided source name in the source directory with the
- * destination name in the destination directory. A RENAME request is sent
- * to the Hgfs server.
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopRename(struct vop_rename_args *ap)
-/*
-struct vop_rename_args {
- struct vnode *fdvp; // IN: "from" parent directory
- struct vnode *fvp; // IN: "from" file
- struct componentname *fcnp: // IN: "from" pathname info
- struct vnode *tdvp; // IN: "to" parent directory
- struct vnode *tvp; // IN: "to" file (if it exists)
- struct componentname *tcnp: // IN: "to" pathname info
-};
-*/
-{
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tdvp = ap->a_tdvp;
- struct vnode *tvp = ap->a_tvp;
- struct componentname *tcnp = ap->a_tcnp;
-
-
- int ret;
-
- /*
- * Note that fvp and fdvp are not locked when called by the VFS layer. However,
- * this does not matter for the HgfsRenameInt implementaiton which does not use
- * the handle or mode from the HgfsOpenFile (the two things that can change in an
- * HgfsOpenFile struct). So while a normal VFS implementation would lock at least fvp
- * here, this one does not.
- */
- ret = HgfsRenameInt(fvp, tdvp, tvp, tcnp);
-
- vrele(fdvp);
- vrele(fvp);
-
- vput(tdvp);
- if (tvp) {
- vput(tvp);
- }
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsMkdir --
- *
- * Calls HgfsMkdirInt which does all of the directory creation work in a
- * FreeBSD / Mac OS independent way.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * If successful, a directory is created on the host's filesystem.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopMkdir(struct vop_mkdir_args *ap)
-/*
-struct vop_mkdir_args {
- struct vnode *dvp; // IN : directory vnode
- struct vnode **vpp; // OUT: pointer to new directory vnode
- struct componentname *cnp; // IN : pathname component created
- struct vattr *vap; // IN : attributes to create directory with
-};
-*/
-{
- struct vnode *dvp = ap->a_dvp;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
- struct vattr *vap = ap->a_vap;
-
- return HgfsMkdirInt(dvp, vpp, cnp, vap->va_mode);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopRmdir --
- *
- * Removes the specified name from the provided vnode by calling
- * HgfsRmdirInt.
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopRmdir(struct vop_rmdir_args *ap)
-/*
-struct vop_rmdir_args {
- struct vnode *dvp; // IN: parent directory vnode
- struct vnode *vp; // IN: directory to remove
- struct componentname *cnp; // IN: pathname information
-};
-*/
-{
- struct vnode *dvp = ap->a_dvp;
- struct vnode *vp = ap->a_vp;
- struct componentname *cnp = ap->a_cnp;
-
- return HgfsRmdirInt(dvp, vp, cnp);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopReaddir --
- *
- * Reads as many entries from the directory as will fit in to the provided
- * buffer. Each directory entry is read by calling HgfsGetNextDirEntry().
- *
- * The funciton simply calls HgfsReaddirInt to do all of the common
- * FreeBSD and Solaris work.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopReaddir(struct vop_readdir_args *ap)
-/*
-struct vop_readdir_args {
- struct vnode *vp; // IN : directory to read from
- struct uio *uio; // INOUT: where to read contents
- struct ucred *cred; // IN : caller's credentials
- int *eofflag; // INOUT: end of file status
- int *ncookies; // OUT : used by NFS server only; ignored
- u_long **cookies; // INOUT: used by NFS server only; ignored
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uiop = ap->a_uio;
- int *eofp = ap->a_eofflag;
-
- return HgfsReaddirInt(vp, uiop, eofp);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopInactive --
- *
- * Called when vnode's use count reaches zero.
- *
- * Results:
- * Unconditionally zero.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopInactive(struct vop_inactive_args *ap)
-/*
-struct vop_inactive_args {
- struct vnode *vp; // IN: vnode to inactive
- struct thread *td; // IN: caller's thread context
-};
-*/
-{
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopReclaim --
- *
- * Dissociates vnode from the underlying filesystem.
- *
- * Results:
- * Zero on success, or an appropriate system error otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopReclaim(struct vop_reclaim_args *ap)
-/*
-struct vop_reclaim_args {
- struct vnode *vp; // IN: vnode to reclaim
- struct thread *td; // IN: caller's thread context
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
-
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
-
- HgfsReleaseVnodeContext(vp, &sip->fileHashTable);
- vp->v_data = NULL;
-
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopPrint --
- *
- * This function is needed to fill in the HgfsVnodeOps structure.
- * Right now it does nothing.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopPrint(struct vop_print_args *ap)
-{
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopReadlink --
- *
- * Invoked when a user calls readlink(2) on a file in our filesystem.
- *
- * Results:
- * Returns zero on success and an error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopReadlink(struct vop_readlink_args *ap)
-/*
-struct vop_readlink_args {
- vnode *vp; // IN : vnode of file
- struct uio *uio; // OUT: location to copy symlink name.
- struct ucred *cred; // IN : caller's credentials
-};
-*/
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uiop = ap->a_uio;
-
- return HgfsReadlinkInt(vp, uiop);
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopSymlink --
- *
- * Invoked when a user calls symlink(2) to create a symbolic link.
- *
- * Results:
- * Returns zero on success and an error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsVopSymlink(struct vop_symlink_args *ap)
-/*
-struct vop_symlink_args {
- vnode *dvp; // IN : vnode of directory
- vnode **vp; // OUT: location to place resultant vnode
- struct componentname *cnp; // IN : symlink pathname info
- struct vatttr *vap; // IN : attributes to create new object with
- char *target; // IN : Target name
-};
-*/
-{
- struct vnode **vp = ap->a_vpp;
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- char *target = ap->a_target;
-
- return HgfsSymlinkInt(dvp, vp, cnp, target);
-}
-
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.c b/open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.c
deleted file mode 100644
index 5857ed74..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.c
+++ /dev/null
@@ -1,3274 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * vnopscommon.c --
- *
- * Common VFS vnop implementations that are shared between both Mac OS and FreeBSD.
- */
-
-#include <sys/param.h> // for everything
-#include <sys/vnode.h> // for struct vnode
-#include <sys/dirent.h> // for struct dirent
-
-#include "fsutil.h"
-#include "debug.h"
-#include "vnopscommon.h"
-#include "transport.h"
-#include "cpName.h"
-#include "os.h"
-
-/* Local function prototypes */
-int HgfsGetNextDirEntry(HgfsSuperInfo *sip, HgfsHandle handle,
- uint32_t offset, char *nameOut, size_t nameSize,
- HgfsFileType *type, Bool *done);
-int HgfsDirOpen(HgfsSuperInfo *sip, struct vnode *vp, HgfsOpenType openType);
-int HgfsFileOpen(HgfsSuperInfo *sip, struct vnode *vp,
- int flag, int permissions, HgfsOpenType openType);
-int HgfsDirClose(HgfsSuperInfo *sip, struct vnode *vp);
-int HgfsFileClose(HgfsSuperInfo *sip, struct vnode *vp, int flag);
-int HgfsDoRead(HgfsSuperInfo *sip, HgfsHandle handle, uint64_t offset,
- uint32_t size, struct uio *uiop);
-int HgfsDoWrite(HgfsSuperInfo *sip, HgfsHandle handle, int ioflag,
- uint64_t offset, uint32_t size, struct uio *uiop);
-int HgfsDelete(HgfsSuperInfo *sip, const char *filename, HgfsOp op);
-static int HgfsDoGetattrInt(const char *path, const HgfsHandle handle, HgfsSuperInfo *sip,
- HgfsAttrV2 *hgfsAttrV2);
-static int HgfsDoGetattrByName(const char *path, HgfsSuperInfo *sip, HgfsAttrV2 *hgfsAttrV2);
-int HgfsReadlinkInt(struct vnode *vp, struct uio *uiop);
-static int HgfsQueryAttrInt(const char *path, HgfsHandle handle, HgfsSuperInfo *sip,
- HgfsKReqHandle req);
-static int HgfsRenewHandle(struct vnode *vp, HgfsSuperInfo *sip, HgfsHandle *handle);
-static int HgfsRefreshDirHandle(struct vnode *vp, HgfsSuperInfo *sip, HgfsHandle *handle);
-static int HgfsGetNewHandle(struct vnode *vp, HgfsSuperInfo *sip, HgfsFile *fp,
- HgfsHandle *handle);
-
-
-#if 0
-static int HgfsDoGetattrByHandle(HgfsHandle handle, HgfsSuperInfo *sip, HgfsAttrV2 *hgfsAttrV2);
-#endif
-
-#define HGFS_CREATE_DIR_MASK (HGFS_CREATE_DIR_VALID_FILE_NAME | \
- HGFS_CREATE_DIR_VALID_SPECIAL_PERMS | \
- HGFS_CREATE_DIR_VALID_OWNER_PERMS | \
- HGFS_CREATE_DIR_VALID_GROUP_PERMS | \
- HGFS_CREATE_DIR_VALID_OTHER_PERMS)
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsRenameInt --
- *
- * Renames the provided source name in the source directory with the
- * destination name in the destination directory. A RENAME request is sent
- * to the Hgfs server.
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsRenameInt(struct vnode *fvp, // IN: "from" file
- struct vnode *tdvp, // IN: "to" parent directory
- struct vnode *tvp, // IN: "to" file
- struct componentname *tcnp) // IN: "to" pathname info
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(fvp);
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsRequestRenameV3 *request;
- HgfsReplyRenameV3 *reply;
- HgfsFileNameV3 *newNameP;
- char *srcFullPath = NULL; // will point to fvp's filename; don't free
- char *dstFullPath = NULL; // allocated from M_TEMP; free when done.
- uint32 srcFullPathLen;
- uint32 dstFullPathLen;
- uint32 reqBufferSize;
- uint32 reqSize;
- uint32 repSize;
- int ret;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s -> %.*s/%.*s).\n",
- HGFS_VP_TO_FILENAME_LENGTH(fvp), HGFS_VP_TO_FILENAME(fvp),
- HGFS_VP_TO_FILENAME_LENGTH(tdvp), HGFS_VP_TO_FILENAME(tdvp),
- (int)tcnp->cn_namelen, tcnp->cn_nameptr);
-
- /* No cross-device renaming. */
- if (HGFS_VP_TO_MP(fvp) != HGFS_VP_TO_MP(tdvp)) {
- ret = EXDEV;
- goto out;
- }
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- goto out;
- }
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestRenameV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- /* Initialize the request header */
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_RENAME_V3);
- request->hints = 0;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_PACKET_MAX - (reqSize - 2);
-
- /* Make the full path of the source. */
- srcFullPath = HGFS_VP_TO_FILENAME(fvp);
- srcFullPathLen = HGFS_VP_TO_FILENAME_LENGTH(fvp);
-
- /* Make the full path of the destination. */
- dstFullPath = os_malloc(MAXPATHLEN, M_WAITOK);
- if (!dstFullPath) {
- ret = ENOMEM;
- goto destroyOut;
- }
-
- ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(tdvp),
- HGFS_VP_TO_FILENAME_LENGTH(tdvp),
- tcnp->cn_nameptr,
- tcnp->cn_namelen,
- dstFullPath,
- MAXPATHLEN);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "could not construct full path of dest.\n");
- ret = ENAMETOOLONG;
- goto destroyOut;
- }
- dstFullPathLen = ret;
-
- /* Ensure both names will fit in one request. */
- if ((reqSize + srcFullPathLen + dstFullPathLen) > HGFS_PACKET_MAX) {
- DEBUG(VM_DEBUG_FAIL, "names too big for one request.\n");
- ret = EPROTO;
- goto destroyOut;
- }
-
- request->oldName.flags = 0;
- request->oldName.fid = HGFS_INVALID_HANDLE;
- request->oldName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(srcFullPath, srcFullPathLen + 1,
- request->oldName.name, reqBufferSize);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Couldn't encode to wire format\n");
- ret = -ret;
- goto destroyOut;
- }
- request->oldName.length = ret;
- reqSize += ret;
- reqBufferSize -= ret;
-
- /*
- * The new name is placed directly after the old name in the packet and we
- * access it through this pointer.
- */
- newNameP = (HgfsFileNameV3 *)((char *)&request->oldName +
- sizeof request->oldName +
- request->oldName.length);
- newNameP->flags = 0;
- newNameP->fid = HGFS_INVALID_HANDLE;
- newNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
-
- ret = HgfsNameToWireEncoding(dstFullPath, dstFullPathLen + 1,
- newNameP->name, reqBufferSize);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Couldn't encode to wire format.\n");
- ret = -ret;
- goto destroyOut;
- }
- newNameP->length = ret;
- reqSize += ret;
-
- /* The request's size includes the header, request and both filenames. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* HgfsSubmitRequest() destroys the request if necessary. */
- goto out;
- }
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- goto destroyOut;
- }
-
- /* Successfully renamed file on the server. */
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-
-out:
- if (dstFullPath != NULL) {
- os_free(dstFullPath, MAXPATHLEN);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%d).\n", ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsReaddirInt --
- *
- * Reads as many entries from the directory as will fit in to the provided
- * buffer. Each directory entry is read by calling HgfsGetNextDirEntry().
- *
- * "The vop_readdir() method reads chunks of the directory into a uio
- * structure. Each chunk can contain as many entries as will fit within
- * the size supplied by the uio structure. The uio_resid structure member
- * shows the size of the getdents request in bytes, which is divided by the
- * size of the directory entry made by the vop_readdir() method to
- * calculate how many directory entries to return." (Solaris Internals,
- * p555)
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsReaddirInt(struct vnode *vp, // IN : Directory vnode to get entries from.
- struct uio *uiop, // IN/OUT: Buffer to place dirents in.
- int *eofp) // IN/OUT: Have all entries been read?
-{
-
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsHandle handle;
- uint64_t offset;
- Bool done;
- char *fullName = NULL; /* Hashed to generate inode number */
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* uio_offset is a signed quantity. */
- if (HGFS_UIOP_TO_OFFSET(uiop) < 0) {
- DEBUG(VM_DEBUG_FAIL, "fed negative offset.\n");
- ret = EINVAL;
- goto out;
- }
-
- /*
- * In order to fill the user's buffer with directory entries, we must
- * iterate on HGFS_OP_SEARCH_READ requests until either the user's buffer is
- * full or there are no more entries. Each call to HgfsGetNextDirEntry()
- * fills in the name and attribute structure for the next entry. We then
- * escape that name and place it in a kernel buffer that's the same size as
- * the user's buffer. Once there are no more entries or no more room in the
- * buffer, we copy it to user space.
- */
-
- /*
- * We need to get the handle for this open directory to send to the Hgfs
- * server in our requests.
- */
- ret = HgfsGetOpenFileHandle(vp, &handle);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "could not get handle.\n");
- ret = EINVAL;
- goto out;
- }
-
- if (HGFS_UIOP_TO_OFFSET(uiop) == 0) {
- ret = HgfsRefreshDirHandle(vp, sip, &handle);
- }
-
- /*
- * Allocate 1K (MAXPATHLEN) buffer for inode number generation.
- */
- fullName = os_malloc(MAXPATHLEN, M_WAITOK);
- if (!fullName) {
- ret = ENOMEM;
- goto out;
- }
-
- /*
- * Loop until one of the following conditions is met:
- * o An error occurs while reading a directory entry
- * o There are no more directory entries to read
- * o The buffer is full and cannot hold the next entry
- *
- * We request dentries from the Hgfs server based on their index in the
- * directory. The offset value is initialized to the value specified in
- * the user's io request and is incremented each time through the loop.
- *
- * dirp is incremented by the record length each time through the loop and
- * is used to determine where in the kernel buffer we write to.
- */
- for (offset = HGFS_UIOP_TO_OFFSET(uiop), done = 0; /* Nothing */ ; offset++) {
- struct dirent dirent, *dirp = &dirent;
- char nameBuf[sizeof dirp->d_name];
- HgfsFileType fileType = HGFS_FILE_TYPE_REGULAR;
-
- DEBUG(VM_DEBUG_COMM,
- "HgfsReaddir: getting directory entry at offset %"FMT64"u.\n", offset);
-
- DEBUG(VM_DEBUG_HANDLE, "** handle=%d, file=%s\n",
- handle, HGFS_VP_TO_FILENAME(vp));
-
- bzero(dirp, sizeof *dirp);
-
- ret = HgfsGetNextDirEntry(sip, handle, offset, nameBuf, sizeof nameBuf,
- &fileType, &done);
- /* If the filename was too long, we skip to the next entry ... */
- if (ret == EOVERFLOW) {
- continue;
- } else if (ret == EBADF) {
- /*
- * If we got invalid handle from the server, this was because user
- * enabled/disabled the shared folders. We should get a new handle
- * from the server, now.
- */
- ret = HgfsRenewHandle(vp, sip, &handle);
- if (ret == 0) {
- /*
- * Now we have valid handle, let's try again from the same
- * offset.
- */
- offset--;
- continue;
- } else {
- ret = EBADF;
- goto out;
- }
- } else if (ret) {
- if (ret != EPROTO) {
- ret = EINVAL;
- }
- DEBUG(VM_DEBUG_FAIL, "failure occurred in HgfsGetNextDirEntry\n");
- goto out;
- /*
- * ... and if there are no more entries, we set the end of file pointer
- * and break out of the loop.
- */
- } else if (done == TRUE) {
- DEBUG(VM_DEBUG_COMM, "Done reading directory entries.\n");
- if (eofp != NULL) {
- *eofp = TRUE;
- }
- break;
- }
- /*
- * Convert an input string to utf8 decomposed form and then escape its
- * buffer.
- */
- ret = HgfsNameFromWireEncoding(nameBuf, strlen(nameBuf), dirp->d_name,
- sizeof dirp->d_name);
- /*
- * If the name didn't fit in the buffer or illegal utf8 characters
- * were encountered, skip to the next entry.
- */
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "HgfsNameFromWireEncoding failed.\n");
- continue;
- }
-
- /* Fill in the directory entry. */
- dirp->d_namlen = ret;
- dirp->d_reclen = sizeof(*dirp); // NB: d_namlen must be set first!
- dirp->d_type =
- (fileType == HGFS_FILE_TYPE_REGULAR) ? DT_REG :
- (fileType == HGFS_FILE_TYPE_DIRECTORY) ? DT_DIR :
- DT_UNKNOWN;
-
- /*
- * Make sure there is enough room in the buffer for the entire directory
- * entry. If not, we just break out of the loop and copy what we have an set
- * the return value to be 0.
- */
- if (dirp->d_reclen > HGFS_UIOP_TO_RESID(uiop)) {
- DEBUG(VM_DEBUG_INFO, "ran out of room in the buffer.\n");
- ret = 0;
- break;
- }
-
-
- ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(vp), // Directorie's name
- HGFS_VP_TO_FILENAME_LENGTH(vp), // Length
- dirp->d_name, // Name of file
- dirp->d_namlen, // Length of filename
- fullName, // Destination buffer
- MAXPATHLEN); // Size of this buffer
-
- /* Skip this entry if the full path was too long. */
- if (ret < 0) {
- continue;
- }
-
- /*
- * Place the node id, which serves the purpose of inode number, for this
- * filename directory entry. As long as we are using a dirent64, this is
- * okay since ino_t is also a u_longlong_t.
- */
- HgfsNodeIdGet(&sip->fileHashTable, fullName, (uint32_t)ret,
- &dirp->d_fileno);
-
- /* Copy out this directory entry. */
- ret = uiomove((caddr_t)dirp, dirp->d_reclen, uiop);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "uiomove failed.\n");
- goto out;
- }
- }
-
- /*
- * uiomove(9) will have incremented the uio offset by the number of bytes
- * written. We reset it here to the fs-specific offset in our directory so
- * the next time we are called it is correct. (Note, this does not break
- * anything and /is/ how this field is intended to be used.)
- */
- HGFS_UIOP_SET_OFFSET(uiop, offset);
-
- DEBUG(VM_DEBUG_EXIT, "done (ret=%d, *eofp=%d).\n", ret, *eofp);
-out:
- if (fullName != NULL) {
- os_free(fullName, MAXPATHLEN);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsGetattrInt --
- *
- * "Gets the attributes for the supplied vnode." (Solaris Internals, p536)
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsGetattrInt(struct vnode *vp, // IN : vnode of the file
- HgfsVnodeAttr *vap) // OUT: attributes container
-{
-
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsAttrV2 hgfsAttrV2;
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* XXX It would be nice to do a GetattrByHandle when possible here. */
- ret = HgfsDoGetattrByName(HGFS_VP_TO_FILENAME(vp), sip, &hgfsAttrV2);
-
- if (!ret) {
- /*
- * HgfsDoGetattr obtained attributes from the hgfs server so
- * map the attributes into BSD attributes.
- */
-
- HgfsAttrToBSD(vp, &hgfsAttrV2, vap);
- }
-
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSetattrInt --
- *
- * Maps the Mac OS/FreeBsd attributes to Hgfs attributes (by calling
- * HgfsSetattrCopy()) and sends a set attribute request to the Hgfs server.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on error.
- *
- * Side effects:
- * The file on the host will have new attributes.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsSetattrInt(struct vnode *vp, // IN : vnode of the file
- HgfsVnodeAttr *vap) // IN : attributes container
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsRequestSetattrV3 *request;
- HgfsReplySetattrV3 *reply;
- uint32 reqSize;
- uint32 reqBufferSize;
- uint32 repSize;
- char *fullPath = NULL;
- uint32 fullPathLen;
- int ret;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
- ASSERT(vp);
- ASSERT(vap);
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- goto out;
- }
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestSetattrV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SETATTR_V3);
-
- request->reserved = 0;
-
- /*
- * Fill the attributes and hint fields of the request. If no updates are
- * needed then we will just return success without sending the request.
- */
- if (HgfsSetattrCopy(vap, &request->attr, &request->hints) == FALSE) {
- DEBUG(VM_DEBUG_COMM, "don't need to update attributes.\n");
- ret = 0;
- goto destroyOut;
- }
-
- fullPath = HGFS_VP_TO_FILENAME(vp);
- fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp);
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(fullPath, fullPathLen + 1,
- request->fileName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
- ret = -ret;
- goto destroyOut;
- }
-
- request->fileName.fid = HGFS_INVALID_HANDLE;
- request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
- request->fileName.flags = 0;
- request->fileName.length = ret;
-
- reqSize += ret;
-
- /* The request's size includes the header, request and filename. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- if (!request->attr.mask) {
- /* they were trying to set filerev or vaflags, which we ignore */
- ret = 0;
- goto destroyOut;
- }
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* HgfsSubmitRequest() destroys the request if necessary. */
- goto out;
- }
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- if (ret == EPROTO) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- }
- goto destroyOut;
- } else {
- if (HGFS_VATTR_SIZE_IS_ACTIVE(vap, HGFS_VA_DATA_SIZE)) {
- HgfsSetFileSize(vp, vap->HGFS_VA_DATA_SIZE);
- }
- }
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsVopRmdir --
- *
- * Removes the specified name from the provided vnode. Sends a DELETE
- * request by calling HgfsDelete() with the filename and correct opcode to
- * indicate deletion of a directory.
- *
- * "Removes the directory pointed to by the supplied vnode." (Solaris
- * Internals, p537)
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsRmdirInt(struct vnode *dvp, // IN: parent directory
- struct vnode *vp, // IN: directory to remove
- struct componentname *cnp) // IN: Only used for debugging
-{
- int ret = 0;
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- ret = HgfsDelete(sip, HGFS_VP_TO_FILENAME(vp), HGFS_OP_DELETE_DIR_V3);
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
-
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsRemoveInt --
- *
- * Composes the full pathname of this file and sends a DELETE_FILE request
- * by calling HgfsDelete().
- *
- * Results:
- * Returns 0 on success or a non-zero error code on error.
- *
- * Side effects:
- * If successful, the file specified will be deleted from the host's
- * filesystem.
- *
- *----------------------------------------------------------------------------
- */
-
-int HgfsRemoveInt(struct vnode *vp) // IN: Vnode to delete
-{
-
- int ret = 0;
-
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* Removing directories is a no-no; save that for VNOP_RMDIR. */
- if (HGFS_VP_TO_VTYPE(vp) == VDIR) {
- DEBUG(VM_DEBUG_FAIL, "HgfsRemove(). on dir ret EPERM\n");
- ret = EPERM;
- goto out;
- }
-
- os_FlushRange(vp, 0, HGFS_VP_TO_FILESIZE(vp));
- os_SetSize(vp, 0);
-
- /* We can now send the delete request. */
- ret = HgfsDelete(sip, HGFS_VP_TO_FILENAME(vp), HGFS_OP_DELETE_FILE_V3);
-
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsCloseInt --
- *
- * Called by HgfsVnopClose under Mac OS or HgfsVopClose under FreeBSD to
- * close a file.
- *
- * "Closes the file given by the supplied vnode. When this is the last
- * close, some filesystems use vnop_close() to initiate a writeback of
- * outstanding dirty pages by checking the reference cound in the vnode."
- * (Solaris Internals, p536)
- *
- * Results:
- * Always returns 0 success.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsCloseInt(struct vnode *vp, // IN: Vnode to close.
- int mode) // IN: Mode of vnode being closed.
-{
- int ret = 0;
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- mode);
-
- /*
- * If we are closing a directory we need to send a SEARCH_CLOSE request,
- * but if we are closing a regular file we need to send a CLOSE request.
- * Other file types are not supported by the Hgfs protocol.
- */
-
- switch (HGFS_VP_TO_VTYPE(vp)) {
- case VDIR:
- ret = HgfsDirClose(sip, vp);
- break;
-
- case VREG:
- ret = HgfsFileClose(sip, vp, mode);
- break;
-
- default:
- DEBUG(VM_DEBUG_FAIL, "unsupported filetype %d.\n",
- HGFS_VP_TO_VTYPE(vp));
- ret = EINVAL;
- break;
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d -> 0)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsOpenInt --
- *
- * Invoked when open(2) is called on a file in our filesystem. Sends an
- * OPEN request to the Hgfs server with the filename of this vnode.
- *
- * "Opens a file referenced by the supplied vnode. The open() system call
- * has already done a vnop_lookup() on the path name, which returned a vnode
- * pointer and then calls to vnop_open(). This function typically does very
- * little since most of the real work was performed by vnop_lookup()."
- * (Solaris Internals, p537)
- *
- * Results:
- * Returns 0 on success and an error code on error.
- *
- * Side effects:
- * If the HgfsFile for this file does not already have a handle, it is
- * given one that can be used for future read and write requests.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsOpenInt(struct vnode *vp, // IN: Vnode to open.
- int mode, // IN: Mode of vnode being opened.
- HgfsOpenType openType) // IN: TRUE if called outside of VNOP_OPEN.
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %d, %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- mode, openType);
-
- switch(HGFS_VP_TO_VTYPE(vp)) {
- case VDIR:
- DEBUG(VM_DEBUG_LOG, "opening a directory\n");
- ret = HgfsDirOpen(sip, vp, openType);
- break;
-
- case VREG:
- /*
- * If HgfsCreate() was called prior to this then is would set permissions
- * in HgfsFile that we need to pass to HgfsFileOpen.
- * If HgfsCreate has not been called then file already exists and permissions
- * are ignored by HgfsFileOpen.
- */
- DEBUG(VM_DEBUG_LOG, "opening a file with flag %x\n", mode);
- ret = HgfsFileOpen(sip, vp, mode, HGFS_VP_TO_PERMISSIONS(vp), openType);
- break;
-
- default:
- DEBUG(VM_DEBUG_FAIL,
- "HgfsOpen: unrecognized file of type %d.\n", HGFS_VP_TO_VTYPE(vp));
- ret = EINVAL;
- break;
- }
-
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp), ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsLookupInt --
- *
- * Looks in the provided directory for the specified filename. If we cannot
- * determine the vnode locally (i.e, the vnode is not the root vnode of the
- * filesystem provided by dvp or in our hashtable), we send a getattr
- * request to the server and allocate a vnode and internal filesystem state
- * for this file.
- *
- * Results:
- * Returns zero on success and ENOENT if the file cannot be found
- * If file is found, a vnode representing the file is returned in vpp.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsLookupInt(struct vnode *dvp, // IN : directory vnode
- struct vnode **vpp, // OUT: ptr to vnode if it exists
- struct componentname *cnp) // IN : pathname to component
-{
- HgfsAttrV2 attrV2;
- HgfsSuperInfo *sip;
- char *path = NULL;
- int ret = 0;
- int len = 0;
-
- ASSERT(dvp);
- ASSERT(vpp);
- ASSERT(cnp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %.*s).\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr);
-
- if (cnp->cn_flags & ISDOTDOT) {
- HgfsFile *fp = HGFS_VP_TO_FP(dvp);
- ASSERT(fp);
- if (fp->parent == NULL) {
- return EIO; // dvp is root directory
- } else {
-#if defined __FreeBSD__
- vref(fp->parent);
-#else
- vnode_get(fp->parent);
-#endif
- *vpp = fp->parent;
- return 0;
- }
- }
- if (cnp->cn_namelen == 1 && *cnp->cn_nameptr == '.') {
-#if defined __FreeBSD__
- vref(dvp);
-#else
- vnode_get(dvp);
-#endif
- *vpp = dvp;
- return 0;
- }
-
- /*
- * Get pointer to the superinfo. If the device is not attached,
- * hgfsInstance will not be valid and we immediately return an error.
- */
- sip = HGFS_VP_TO_SIP(dvp);
- if (!sip) {
- DEBUG(VM_DEBUG_FAIL, "couldn't acquire superinfo.\n");
- return ENOTSUP;
- }
-
- /* Snag a pathname buffer */
- path = os_malloc(MAXPATHLEN, M_WAITOK);
- if (!path) {
- return ENOMEM;
- }
-
- /* Construct the full path for this lookup. */
- len = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Path to this file
- HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of path
- cnp->cn_nameptr, // File's name
- cnp->cn_namelen, // Filename length
- path, // Destination buffer
- MAXPATHLEN); // Size of dest buffer
- if (len < 0) {
- DEBUG(VM_DEBUG_FAIL, "LookupInt length is less than zero\n");
- ret = EINVAL;
- goto out;
- }
-
- DEBUG(VM_DEBUG_LOAD, "full path is \"%s\"\n", path);
-
- /* See if the lookup is really for the root vnode. */
- if (strcmp(path, "/") == 0) {
- DEBUG(VM_DEBUG_INFO, "returning the root vnode.\n");
- *vpp = sip->rootVnode;
- /*
- * If we are returning the root vnode, then we need to get a reference
- * to it. Under Mac OS this gets an I/O Count.
- */
- HGFS_VPP_GET_IOCOUNT(vpp);
- goto out;
- };
-
- /* Send a Getattr request to the Hgfs server. */
- ret = HgfsDoGetattrByName(path, sip, &attrV2);
-
- /*
- * If this is the final pathname component & the user is attempt a CREATE
- * or RENAME, just return without a leaf vnode. (This differs from
- * Solaris where ENOENT would be returned in all cases.)
- */
- if (ret == ENOENT) {
- if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
- cnp->cn_flags & ISLASTCN) {
- ret = EJUSTRETURN;
- DEBUG(VM_DEBUG_FAIL, "GetattrByName error %d for \"%s\".\n", ret, path);
- goto out;
- }
- }
-
- /* Got an error from HgfsDoGetattrByName, return it to the caller. */
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "GetattrByName error %d for \"%s\".\n", ret, path);
- goto out;
- }
-
- ret = HgfsVnodeGet(vpp, // Location to write vnode's address
- dvp, // Parent vnode
- sip, // Superinfo
- HGFS_VP_TO_MP(dvp), // VFS for our filesystem
- path, // Full name of the file
- attrV2.type, // Type of file
- &sip->fileHashTable, // File hash table
- FALSE, // Not a new file creation
- 0, // No permissions - not a new file
- attrV2.size); // File size
-
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "couldn't create vnode for \"%s\".\n", path);
- goto out;
- }
-
- /*
- * Either we will have a cache hit or called HgfsVnodeGet. Both of these
- * paths guarantees that *vpp will be set to a vnode.
- */
- ASSERT(*vpp);
-
- DEBUG(VM_DEBUG_LOAD, "assigned vnode %p to %s\n", *vpp, path);
-
- ret = 0; /* Return success */
-
-out:
- if (path != NULL) {
- os_free(path, MAXPATHLEN);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s, %.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsCreateInt --
- *
- * Called by either HgfsVnopCreate under Mac OS or HgfsVopCreate under
- * FreeBSD when the user is trying to create a file by calling open() with
- * the O_CREAT flag specified.
- *
- * The kernel calls the open entry point which calls (HgfsOpenInt()) after
- * calling this function, so here all we do is consruct the vnode and
- * save the filename and permission bits for the file to be created within
- * our filesystem internal state.
- *
- * Results:
- * Returns zero on success and an appropriate error code on error.
- *
- * Side effects:
- * If the file doesn't exist, a vnode will be created.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsCreateInt(struct vnode *dvp, // IN : Directory vnode
- struct vnode **vpp, // OUT: Pointer to new vnode
- struct componentname *cnp, // IN : Location to create new vnode
- int mode) // IN : Mode of vnode being created.
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp);
- char *fullname = NULL; // allocated from M_TEMP; free when done.
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr);
-
- if (*vpp != NULL) {
- DEBUG(VM_DEBUG_FAIL, "vpp (%p) not null\n", vpp);
- ret = EEXIST;
- goto out;
- }
-
- /* If we have gotten to this point then we know that we need to create a
- * new vnode. The actual file will be created on the HGFS server in the
- * HgfsOpenInt call should happen right after this call.
- */
- fullname = os_malloc(MAXPATHLEN, M_WAITOK);
- if (!fullname) {
- ret = ENOMEM;
- goto out;
- }
-
- ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Name of directory to create in
- HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name
- cnp->cn_nameptr, // Name of file to create
- cnp->cn_namelen, // Length of new filename
- fullname, // Buffer to write full name
- MAXPATHLEN); // Size of this buffer
-
- if (ret >= 0) {
- /* Create the vnode for this file. */
- ret = HgfsVnodeGet(vpp, dvp, sip, HGFS_VP_TO_MP(dvp), fullname,
- HGFS_FILE_TYPE_REGULAR, &sip->fileHashTable, TRUE,
- mode, 0);
- /* HgfsVnodeGet() guarantees this. */
- ASSERT(ret != 0 || *vpp);
- /*
- * NOTE: This is a temporary workaround.
- * This condition may occur because we look up vnodes by file name in the
- * vnode cache.
- * There is a race condition when file is already deleted but still referenced -
- * thus vnode still exist. If a new file with the same name is created I
- * can neither use the vnode of the deleted file nor insert a new vnode with
- * the same name - thus I fail the request. This behavior is not correct and will
- * be fixed after further restructuring if the source code.
- */
- if (ret == EEXIST) {
- ret = EIO;
- }
- } else {
- DEBUG(VM_DEBUG_FAIL, "couldn't create full path name.\n");
- ret = ENAMETOOLONG;
- }
-
-out:
- if (fullname != NULL) {
- os_free(fullname, MAXPATHLEN);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsReadInt --
- *
- * Called by HgfsVnopRead under Mac OS or HgfsVopRead under FreeBSD to read
- * a file.
- *
- * We call HgfsDoRead() to fill the user's buffer until the request is met
- * or the file has no more data. This is done since we can only transfer
- * HGFS_IO_MAX bytes in any one request.
- *
- * "Reads the range supplied for the given vnode. vop_read() typically
- * maps the requested range of a file into kernel memory and then uses
- * vop_getpage() to do the real work." (Solaris Internals, p537)
- *
- * Results:
- * Returns zero on success and an error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsReadInt(struct vnode *vp, // IN : Vnode to read from
- struct uio *uiop, // IN/OUT: Buffer to write data into.
- Bool pagingIo) // IN: True if the read is a result of a page fault
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsHandle handle;
- uint64_t offset;
- int ret;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* We can't read from directories, that's what readdir() is for. */
- if (HGFS_VP_TO_VTYPE(vp) != VREG) {
- DEBUG(VM_DEBUG_FAIL, "Can only read regular files.\n");
- ret = (HGFS_VP_TO_VTYPE(vp) == VDIR) ? EISDIR : EPERM;
- DEBUG(VM_DEBUG_FAIL, "Read not a reg file type %d ret %d.\n", HGFS_VP_TO_VTYPE(vp), ret);
- return ret;
- }
-
- /* off_t is a signed quantity */
- if (HGFS_UIOP_TO_OFFSET(uiop) < 0) {
- DEBUG(VM_DEBUG_FAIL, "given negative offset.\n");
- return EINVAL;
- }
-
- /* This is where the user wants to start reading from in the file. */
- offset = HGFS_UIOP_TO_OFFSET(uiop);
-
- /*
- * We need to get the handle for the requests sent to the Hgfs server. Note
- * that this is guaranteed to not change until a close(2) is called on this
- * vnode, so it's safe and correct to acquire it outside the loop below.
- */
- ret = HgfsGetOpenFileHandle(vp, &handle);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "could not get handle.\n");
- return EINVAL;
- }
-
- /* Flush mmaped data to maintain data coherence between mmap and read. */
- if (!pagingIo) {
- ret = os_FlushRange(vp, offset, HGFS_UIOP_TO_RESID(uiop));
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "could not flush data.\n");
- return EINVAL;
- }
- }
-
- /*
- * Here we loop around HgfsDoRead with requests less than or equal to
- * HGFS_IO_MAX until one of the following conditions is met:
- * (1) All the requested data has been read
- * (2) The file has no more data
- * (3) An error occurred
- *
- * Since HgfsDoRead() calls uiomove(9), we know condition (1) is met when
- * the uio structure's uio_resid is decremented to zero. If HgfsDoRead()
- * returns 0 we know condition (2) was met, and if it returns less than 0 we
- * know condtion (3) was met.
- */
- do {
- uint32_t size;
-
- /* Request at most HGFS_IO_MAX bytes */
- size = (HGFS_UIOP_TO_RESID(uiop) > HGFS_IO_MAX) ? HGFS_IO_MAX :
- HGFS_UIOP_TO_RESID(uiop);
-
- DEBUG(VM_DEBUG_INFO, "offset=%"FMT64"d, uio_offset=%"FMT64"d\n",
- offset, HGFS_UIOP_TO_OFFSET(uiop));
- DEBUG(VM_DEBUG_HANDLE, "** handle=%d, file=%s to read %u\n",
- handle, HGFS_VP_TO_FILENAME(vp), size);
-
- if (size == 0) {
- /* For a zero byte length read we return success. */
- DEBUG(VM_DEBUG_EXIT, "size of 0 ret -> 0.\n");
- return 0;
- }
-
- /* Send one read request. */
- ret = HgfsDoRead(sip, handle, offset, size, uiop);
- if (ret == 0) {
- /* On end of file we return success */
- DEBUG(VM_DEBUG_EXIT, "end of file reached.\n");
- return 0;
- } else if (ret == -EBADF) { // Stale host handle
- ret = HgfsRenewHandle(vp, sip, &handle);
- if (ret == 0) {
- ret = HgfsDoRead(sip, handle, offset, size, uiop);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Failed to read from a fresh handle.\n");
- return -ret;
- }
- } else {
- DEBUG(VM_DEBUG_FAIL, "Failed to get a fresh handle.\n");
- return EBADF;
- }
- } else if (ret < 0) {
- /*
- * HgfsDoRead() returns the negative of an appropriate error code to
- * differentiate between success and error cases. We flip the sign
- * and return the appropriate error code. See the HgfsDoRead()
- * function header for a fuller explanation.
- */
- DEBUG(VM_DEBUG_FAIL, "HgfsDoRead() failed, error %d.\n", ret);
- return -ret;
- }
-
- /* Bump the offset past where we have already read. */
- offset += ret;
- } while (HGFS_UIOP_TO_RESID(uiop));
-
- /* We fulfilled the user's read request, so return success. */
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> 0)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
- return 0;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsWriteInt --
- *
- * Called by HgfsVnopWrite under Mac OS or HgfsVopWrite under FreeBSD.
- *
- * We call HgfsDoWrite() once with requests less than or equal to
- * HGFS_IO_MAX bytes until the user's write request has completed.
- *
- * Results:
- * Returns 0 on success and error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsWriteInt(struct vnode *vp, // IN : the vnode of the file
- struct uio *uiop, // IN/OUT: location of data to be written
- int ioflag, // IN : hints & other directives
- Bool pagingIo) // IN: True if the write is originated by memory manager
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsHandle handle;
- uint64_t offset;
- int ret = 0;
- int error = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* Skip write requests for 0 bytes. */
- if (HGFS_UIOP_TO_RESID(uiop) == 0) {
- DEBUG(VM_DEBUG_INFO, "write of 0 bytes requested.\n");
- error = 0;
- goto out;
- }
-
- DEBUG(VM_DEBUG_INFO, "file is %s\n", HGFS_VP_TO_FILENAME(vp));
-
- /* Off_t is a signed type. */
- if (HGFS_UIOP_TO_OFFSET(uiop) < 0) {
- DEBUG(VM_DEBUG_FAIL, "given negative offset.\n");
- error = EINVAL;
- goto out;
- }
-
- /* This is where the user will begin writing into the file. */
- offset = HGFS_UIOP_TO_OFFSET(uiop);
-
- /* Get the handle we need to supply the Hgfs server. */
- ret = HgfsGetOpenFileHandle(vp, &handle);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "could not get handle.\n");
- error = EINVAL;
- goto out;
- }
-
- /* Flush mmaped data to maintain data coherence between mmap and read. */
- if (!pagingIo && (ioflag & IO_APPEND) == 0) {
- ret = os_FlushRange(vp, offset, HGFS_UIOP_TO_RESID(uiop));
- }
-
- /*
- * We loop around calls to HgfsDoWrite() until either (1) we have written all
- * of our data or (2) an error has occurred. HGFS_UIOP_TO_RESID(uiop) is decremented
- * by uiomove(9F) inside HgfsDoWrite(), so condition (1) is met when it
- * reaches zero. Condition (2) occurs when HgfsDoWrite() returns less than
- * zero.
- */
- do {
- uint32_t size;
-
- DEBUG(VM_DEBUG_INFO, "** offset=%"FMT64"d, uio_offset=%"FMT64"d\n",
- offset, HGFS_UIOP_TO_OFFSET(uiop));
- DEBUG(VM_DEBUG_HANDLE, "** handle=%d, file=%s\n",
- handle, HGFS_VP_TO_FILENAME(vp));
-
- /* Write at most HGFS_IO_MAX bytes. */
- size = (HGFS_UIOP_TO_RESID(uiop) > HGFS_IO_MAX) ? HGFS_IO_MAX : HGFS_UIOP_TO_RESID(uiop);
-
- /* Send one write request. */
- ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop);
- if (ret == -EBADF) { // Stale host handle
- ret = HgfsRenewHandle(vp, sip, &handle);
- if (ret == 0) {
- ret = HgfsDoWrite(sip, handle, ioflag, offset, size, uiop);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Failed to write to a fresh handle.\n");
- error = -ret;
- break;
- }
- } else {
- DEBUG(VM_DEBUG_FAIL, "Failed to get a fresh handle, error %d.\n", ret);
- error = EBADF;
- break;
- }
- } else if (ret < 0) {
- /*
- * As in HgfsRead(), we need to flip the sign. See the comment in the
- * function header of HgfsDoWrite() for a more complete explanation.
- */
- DEBUG(VM_DEBUG_INFO, "HgfsDoWrite failed, returning %d\n", -ret);
- error = -ret;
- break;
- }
-
- /* Increment the offest by the amount already written. */
- offset += ret;
-
- } while (HGFS_UIOP_TO_RESID(uiop));
-
- /* Need to notify memory manager if written data extended the file. */
- if (!pagingIo && (offset > HGFS_VP_TO_FILESIZE(vp))) {
- if ((ioflag & IO_APPEND) == 0) {
- os_SetSize(vp, offset);
- } else {
- off_t oldSize = HGFS_VP_TO_FILESIZE(vp);
- off_t writtenData = offset - HGFS_UIOP_TO_OFFSET(uiop);
- os_SetSize(vp, oldSize + writtenData);
- }
- }
-
-out:
- /* We have completed the user's write request, so return. */
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp), error);
-
- return error;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsMkdirInt --
- *
- * Makes a directory named dirname in the directory specified by the dvp
- * vnode by sending a CREATE_DIR request, then allocates a vnode for this
- * new directory and writes its address into vpp.
- *
- * Results:
- * Returns 0 on success and a non-zero error code on failure.
- *
- * Side effects:
- * If successful, a directory is created on the host's filesystem.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsMkdirInt(struct vnode *dvp, // IN : directory vnode
- struct vnode **vpp, // OUT: pointer to new directory vnode
- struct componentname *cnp, // IN : pathname to component
- int mode) // IN : mode to create dir
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp);
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsRequestCreateDirV3 *request;
- HgfsReplyCreateDirV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- uint32 reqBufferSize;
- char *fullName = NULL; // allocated from M_TEMP; free when done.
- uint32 fullNameLen;
- int ret;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s,%d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr, mode);
-
- /*
- * We need to construct the full path of the directory to create then send
- * a CREATE_DIR request. If successful we will create a vnode and fill in
- * vpp with a pointer to it.
- *
- * Note that unlike in HgfsCreate(), *vpp is always NULL.
- */
-
- /* Construct the complete path of the directory to create. */
- fullName = os_malloc(MAXPATHLEN, M_WAITOK);
- if (!fullName) {
- ret = ENOMEM;
- goto out;
- }
-
- ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Parent directory
- HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name
- cnp->cn_nameptr, // Name of file to create
- cnp->cn_namelen, // Length of filename
- fullName, // Buffer to write full name
- MAXPATHLEN); // Size of this buffer
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "couldn't create full path name.\n");
- ret = ENAMETOOLONG;
- goto out;
- }
- fullNameLen = ret;
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- goto out;
- }
-
- /* Initialize the request's contents. */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestCreateDirV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_CREATE_DIR_V3);
-
- request->fileAttr = 0;
- request->mask = HGFS_CREATE_DIR_MASK;
- request->specialPerms = (mode & (S_ISUID | S_ISGID | S_ISVTX)) >>
- HGFS_ATTR_SPECIAL_PERM_SHIFT;
- request->ownerPerms = (mode & S_IRWXU) >> HGFS_ATTR_OWNER_PERM_SHIFT;
- request->groupPerms = (mode & S_IRWXG) >> HGFS_ATTR_GROUP_PERM_SHIFT;
- request->otherPerms = mode & S_IRWXO;
- request->fileName.flags = 0;
- request->fileName.fid = HGFS_INVALID_HANDLE;
- request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(fullName, fullNameLen + 1,
- request->fileName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL,"Could not encode to wire format");
- ret = -ret;
- goto destroyOut;
- }
-
- request->fileName.length = ret;
- reqSize += ret;
-
- /* Set the size of this request. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- /* Send the request to guestd. */
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* Request is destroyed in HgfsSubmitRequest() if necessary. */
- goto out;
- }
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- goto destroyOut;
- }
-
- ret = HgfsVnodeGet(vpp, dvp, sip, HGFS_VP_TO_MP(dvp), fullName,
- HGFS_FILE_TYPE_DIRECTORY, &sip->fileHashTable, TRUE,
- mode, 0);
- if (ret) {
- ret = EIO;
- DEBUG(VM_DEBUG_FAIL, "Error encountered creating vnode ret = %d\n", ret);
- goto destroyOut;
- }
-
- ASSERT(*vpp);
- ret = 0;
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- if (fullName != NULL) {
- os_free(fullName, MAXPATHLEN);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDirOpen --
- *
- * Invoked when HgfsOpen() is called with a vnode of type VDIR.
- *
- * Sends a SEARCH_OPEN request to the Hgfs server.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsDirOpen(HgfsSuperInfo *sip, // IN: Superinfo pointer
- struct vnode *vp, // IN: Vnode of directory to open
- HgfsOpenType openType) // IN: type of VNOP_OPEN.
-{
- char *fullPath;
- uint32 fullPathLen;
- int ret;
- HgfsFile *fp;
- HgfsHandle handle;
-
- ASSERT(sip);
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- openType);
-
- /*
- * If the directory is already opened then we are done.
- * There is no different open modes for directories thus the handle is compatible.
- */
- os_rw_lock_lock_exclusive(fp->handleLock);
- ret = HgfsCheckAndReferenceHandle(vp, 0, openType);
- if (ret == ENOENT) { // Handle is not set, need to get one from the host
-
- if (HGFS_IS_ROOT_VNODE(sip, vp)) {
- fullPath = "";
- fullPathLen = 0;
- } else {
- fullPath = HGFS_VP_TO_FILENAME(vp);
- fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp);
- }
-
- ret = HgfsSendOpenDirRequest(sip, fullPath, fullPathLen, &handle);
- if (ret == 0) {
- /*
- * We successfully received a reply, so we need to save the handle in
- * this file's HgfsOpenFile and return success.
- */
- HgfsSetOpenFileHandle(vp, handle, HGFS_OPEN_MODE_READ_ONLY, openType);
- }
- }
- os_rw_lock_unlock_exclusive(fp->handleLock);
-
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsRequestHostFileHandle --
- *
- * Sends a open request to the server to get a file handle.
- * If client needs a readonly handle the function first asks for
- * read-write handle since this handle may be shared between multiple
- * file descriptors. If getting read-write handle fails the function
- * sends another request for readonly handle.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsRequestHostFileHandle(HgfsSuperInfo *sip, // IN: Superinfo pointer
- struct vnode *vp, // IN: Vnode of file to open
- int *openMode, // IN OUT: open mode
- int openFlags, // IN: flags for the open request
- int permissions, // IN: Permissions for new files
- HgfsHandle *handle) // OUT: file handle
-{
- char *fullPath;
- uint32 fullPathLen;
- int ret;
-
- fullPath = HGFS_VP_TO_FILENAME(vp);
- fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s, %d, %d, %o)\n", fullPathLen, fullPath,
- *openMode, openFlags, permissions);
-
- /* First see if we can get the most permissive read/write open mode */
- ret = HgfsSendOpenRequest(sip, HGFS_OPEN_MODE_READ_WRITE, openFlags,
- permissions, fullPath, fullPathLen, handle);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Open failed %d, re-submitting original mode = %d.\n",
- ret, *openMode);
- if (ret == EACCES && HGFS_OPEN_MODE_READ_WRITE != *openMode) {
- /*
- * Failed to open in read/write open mode because of denied access.
- * It means file's permissions do not allow opening for read/write.
- * However caller does not need this mode and may be satisfied with
- * less permissive mode.
- * Try exact open mode now.
- */
- DEBUG(VM_DEBUG_FAIL, "RW mode failed, re-submitting original mode = %d.\n",
- *openMode);
- ret = HgfsSendOpenRequest(sip, *openMode, openFlags,
- permissions, fullPath, fullPathLen, handle);
- }
- } else {
- *openMode = HGFS_OPEN_MODE_READ_WRITE;
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", fullPathLen, fullPath, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileOpen --
- *
- * Invoked when HgfsOpen() is called with a vnode of type VREG. Sends
- * a OPEN request to the Hgfs server.
- *
- * Note that this function doesn't need to handle creations since the
- * HgfsCreate() entry point is called by the kernel for that.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsFileOpen(HgfsSuperInfo *sip, // IN: Superinfo pointer
- struct vnode *vp, // IN: Vnode of file to open
- int flag, // IN: Flags of open
- int permissions, // IN: Permissions of open (only when creating)
- HgfsOpenType openType) // IN: initiator type for the open
-{
- int ret;
- int openMode;
- int openFlags;
- HgfsHandle handle;
- HgfsFile *fp;
-
- ASSERT(sip);
- ASSERT(vp);
-
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d,%d,%o)\n",
- HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- flag, openType, permissions);
-
- /*
- * Check if the user is trying to create a new share. This check was
- * mainly implemented to address the issue with Mac OS. When the user
- * attempts to create a file in the root folder, the server returns ENOENT
- * error code. However, Mac OS specifically checks for this case. If Mac OS asks for
- * the creation of a new file and if it gets ENOENT as a return error code,
- * then it assumes that the error was because of some race condition and tries it
- * again. Thus, returning ENOENT to the Mac OS puts the guest kernel into infinite
- * loop. In order to resolve this issue, before passing on the request to the
- * server, we validate if user is attempting to create a new share. If yes,
- * we return EACCES as the error code.
- */
- if (HgfsAttemptToCreateShare(HGFS_VP_TO_FILENAME(vp), flag)) {
- DEBUG (VM_DEBUG_LOG, "An attempt to create a new share was made.\n");
- ret = EACCES;
- goto out;
- }
-
- /* Convert FreeBSD modes to Hgfs modes */
- openMode = HgfsGetOpenMode((uint32_t)flag);
- if (openMode < 0) {
- DEBUG(VM_DEBUG_FAIL, "HgfsGetOpenMode failed.\n");
- ret = EINVAL;
- goto out;
- }
- DEBUG(VM_DEBUG_COMM, "open mode is %x\n", openMode);
-
- /* Convert FreeBSD flags to Hgfs flags */
- openFlags = HgfsGetOpenFlags((uint32_t)flag);
- if (openFlags < 0) {
- DEBUG(VM_DEBUG_FAIL, "HgfsGetOpenFlags failed.\n");
- ret = EINVAL;
- goto out;
- }
-
- os_rw_lock_lock_exclusive(fp->handleLock);
- /*
- * If the file is already opened, verify that it is opened in a compatible mode.
- * If it is true then add reference to vnode and grant the access, otherwise
- * deny the access.
- */
- ret = HgfsCheckAndReferenceHandle(vp, openMode, openType);
- if (ret == ENOENT) { // Handle is not set, need to get one from the host
- ret = HgfsRequestHostFileHandle(sip, vp, &openMode, openFlags,
- permissions, &handle);
- /*
- * We successfully received a reply, so we need to save the handle in
- * this file's HgfsOpenFile and return success.
- */
- if (ret == 0) {
- HgfsSetOpenFileHandle(vp, handle, openMode, openType);
- }
- }
-
- os_rw_lock_unlock_exclusive(fp->handleLock);
-
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsRefreshDirHandle --
- *
- * Refresh the directory HgfsHandle for the vnode.
- * Needed when original handle become stale because the directory contents
- * have changed either in the VM or on the remote server.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsRefreshDirHandle(struct vnode *vp, // IN: Vnode of file to open
- HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle *handle) // IN/OUT: handle to close and reopen
-{
- int ret = 0;
- HgfsFile *fp;
-
- ASSERT(vp);
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- os_rw_lock_lock_exclusive(fp->handleLock);
-
- ASSERT(HGFS_VP_TO_VTYPE(vp) == VDIR);
-
- if (fp->handle != *handle) {
- /* Handle has been refreshed in another thread. */
- *handle = fp->handle;
- } else {
- /* Close the existing handle and open a new one from the host. */
- HgfsCloseServerDirHandle(sip, *handle);
- ret = HgfsGetNewHandle(vp, sip, fp, handle);
- }
-
- os_rw_lock_unlock_exclusive(fp->handleLock);
-
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsRenewHandle --
- *
- * Renew the HgfsHandle for the vnode. Needed when original handle
- * become stale because HGFS has been disabled and re-enabled or VM
- * has been suspened and then resumed.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsRenewHandle(struct vnode *vp, // IN: Vnode of file to open
- HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle *handle) // IN/OUT: Pointer to the stale handle
-{
- int result = 0;
- HgfsFile *fp;
-
- ASSERT(vp);
- fp = HGFS_VP_TO_FP(vp);
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- os_rw_lock_lock_exclusive(fp->handleLock);
-
- if (fp->handle != *handle) {
- /* Handle has been refreshed in another thread. */
- *handle = fp->handle;
- } else {
- result = HgfsGetNewHandle(vp, sip, fp, handle);
- }
- os_rw_lock_unlock_exclusive(fp->handleLock);
-
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- result);
- return result;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsGetNewHandle --
- *
- * Get a new HgfsHandle for the vnode. Needed when original handle
- * become stale because HGFS has been disabled and re-enabled or VM
- * has been suspened and then resumed, or folder contents have changed.
- *
- * NOTE: file lock must be acquired when calling this function.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsGetNewHandle(struct vnode *vp, // IN: Vnode of file to open
- HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsFile *fp, // IN/OUT: file node pointer
- HgfsHandle *handle) // IN OUT: Pointer to the stale handle
-{
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* Retrieve a new handle from the host. */
- if (HGFS_VP_TO_VTYPE(vp) == VREG) {
- ret = HgfsRequestHostFileHandle(sip, vp, (int *)&fp->mode,
- HGFS_OPEN, 0, handle);
- } else if (HGFS_VP_TO_VTYPE(vp) == VDIR) {
- char *fullPath = HGFS_VP_TO_FILENAME(vp);
- uint32 fullPathLen = HGFS_VP_TO_FILENAME_LENGTH(vp);
-
- ret = HgfsSendOpenDirRequest(sip, fullPath, fullPathLen, handle);
- } else {
- goto out;
- }
-
- if (ret == 0) {
- fp->handle = *handle;
- }
-
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDirClose --
- *
- * Invoked when HgfsClose() is called with a vnode of type VDIR.
- *
- * Sends an SEARCH_CLOSE request to the Hgfs server.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsDirClose(HgfsSuperInfo *sip, // IN: Superinfo pointer
- struct vnode *vp) // IN: Vnode of directory to close
-{
- int ret = 0;
- HgfsHandle handleToClose;
-
- ASSERT(sip);
- ASSERT(vp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /*
- * Check to see if we should close the file handle on the host ( which happen when
- * the reference count of the current handle become 0.
- */
- if (HgfsReleaseOpenFileHandle(vp, OPENREQ_OPEN, &handleToClose) == 0) {
- ret = HgfsCloseServerDirHandle(sip, handleToClose);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsFileClose --
- *
- * Invoked when HgfsClose() is called with a vnode of type VREG.
- *
- * Sends a CLOSE request to the Hgfs server.
- *
- * Results:
- * Returns zero on success and an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsFileClose(HgfsSuperInfo *sip, // IN: Superinfo pointer
- struct vnode *vp, // IN: Vnode of file to close
- int flags) // IN: The mode flags for the close
-{
- int ret = 0;
- HgfsHandle handleToClose;
-
- ASSERT(sip);
- ASSERT(vp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- flags);
-
- /*
- * Check to see if we should close the file handle on the host ( which happen when
- * the reference count of the current handle become 0.
- */
- if (HgfsReleaseOpenFileHandle(vp, OPENREQ_OPEN, &handleToClose) == 0) {
- ret = HgfsCloseServerFileHandle(sip, handleToClose);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDoRead --
- *
- * Sends a single READ request to the Hgfs server and writes the contents
- * into the user's buffer if successful.
- *
- * This function is called repeatedly by HgfsRead() with requests of size
- * less than or equal to HGFS_IO_MAX.
- *
- * Note that we return the negative of an appropriate error code in this
- * function so we can differentiate between success and failure. On success
- * we need to return the number of bytes read, but FreeBSD's error codes are
- * positive so we negate them before returning. If callers want to return
- * these error codes to the Kernel, they will need to flip their sign.
- *
- * Results:
- * Returns number of bytes read on success and a negative value on error.
- *
- * Side effects:
- * On success, size bytes are written into the user's buffer.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsDoRead(HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle handle, // IN: Server's handle to read from
- uint64_t offset, // IN: File offset to read at
- uint32_t size, // IN: Number of bytes to read
- struct uio *uiop) // IN: Defines user's read request
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestReadV3 *request;
- HgfsReplyReadV3 *reply;
- uint32 reqSize;
- int ret;
-
- ASSERT(sip);
- ASSERT(uiop);
- ASSERT(size <= HGFS_IO_MAX); // HgfsRead() should guarantee this
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%u,%"FMT64"u,%u)\n", handle, offset, size);
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- ret = -ret;
- goto out;
- }
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestReadV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_READ_V3);
-
- /* Indicate which file, where in the file, and how much to read. */
- request->file = handle;
- request->offset = offset;
- request->requiredSize = size;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
-
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /*
- * We need to flip the sign of the return value to indicate error; see
- * the comment in the function header. HgfsSubmitRequest() handles
- * destroying the request if necessary, so we don't here.
- */
- DEBUG(VM_DEBUG_FAIL, " hgfssubmitrequest failed\n");
- ret = -ret;
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplyReadV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
-
- ret = HgfsGetStatus(req, sizeof *replyHeader);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- if (ret != EPROTO && ret != EBADF) {
- ret = EACCES;
- }
- ret = -ret;
- goto destroyOut;
- }
-
- /*
- * Now perform checks on the actualSize. There are three cases:
- * o actualSize is less than or equal to size, which indicates success
- * o actualSize is zero, which indicates the end of the file (and success)
- * o actualSize is greater than size, which indicates a server error
- */
- if (reply->actualSize <= size) {
- /* If we didn't get any data, we don't need to copy to the user. */
- if (reply->actualSize == 0) {
- goto success;
- }
-
- /* Perform the copy to the user */
- ret = uiomove(reply->payload, reply->actualSize, uiop);
- if (ret) {
- ret = -EIO;
- goto destroyOut;
- }
-
- /* We successfully copied the payload to the user's buffer */
- goto success;
-
- } else {
- /* We got too much data: server error. */
- DEBUG(VM_DEBUG_FAIL, "received too much data in payload.\n");
- ret = -EPROTO;
- goto destroyOut;
- }
-
-success:
- ret = reply->actualSize;
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDoWrite --
- *
- * Sends a single WRITE request to the Hgfs server with the contents of
- * the user's buffer.
- *
- * This function is called repeatedly by HgfsWrite() with requests of size
- * less than or equal to HGFS_IO_MAX.
- *
- * Note that we return the negative of an appropriate error code in this
- * function so we can differentiate between success and failure. On success
- * we need to return the number of bytes written, but FreeBSD's error codes are
- * positive so we negate them before returning. If callers want to return
- * these error codes to the kernel, they will need to flip their sign.
- *
- * Results:
- * Returns number of bytes written on success and a negative value on error.
- *
- * Side effects:
- * On success, size bytes are written to the file specified by the handle.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsDoWrite(HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle handle, // IN: Handle representing file to write to
- int ioflag, // IN: Flags for write
- uint64_t offset, // IN: Where in the file to begin writing
- uint32_t size, // IN: How much data to write
- struct uio *uiop) // IN: Describes user's write request
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestWriteV3 *request;
- HgfsReplyWriteV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- int ret;
-
- ASSERT(sip);
- ASSERT(uiop);
- ASSERT(size <= HGFS_IO_MAX); // HgfsWrite() guarantees this
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%u,%d,%"FMT64"u,%u)\n", handle, ioflag, offset, size);
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- ret = -ret;
- goto out;
- }
-
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestWriteV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_WRITE_V3);
-
- request->file = handle;
- request->flags = 0;
- request->offset = offset;
- request->requiredSize = size;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
-
- if (ioflag & IO_APPEND) {
- DEBUG(VM_DEBUG_COMM, "writing in append mode.\n");
- request->flags |= HGFS_WRITE_APPEND;
- }
-
- DEBUG(VM_DEBUG_COMM, "requesting write of %d bytes.\n", size);
-
- /* Copy the data the user wants to write into the payload. */
- ret = uiomove(request->payload, request->requiredSize, uiop);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL,
- "HgfsDoWrite: uiomove(9F) failed copying data from user.\n");
- ret = -EIO;
- goto destroyOut;
- }
-
- /* We subtract one so request's 'char payload[1]' member isn't double counted. */
- HgfsKReq_SetPayloadSize(req, reqSize + request->requiredSize - 1);
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /*
- * As in HgfsDoRead(), we need to flip the sign of the error code
- * returned by HgfsSubmitRequest().
- */
- DEBUG(VM_DEBUG_FAIL, "HgfsSubmitRequest failed.\n");
- ret = -ret;
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
-
- ret = HgfsGetStatus(req, sizeof *replyHeader);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- if (ret != EPROTO && ret != EBADF) {
- ret = EACCES;
- }
- ret = -ret;
- goto destroyOut;
- }
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- if (HgfsKReq_GetPayloadSize(req) != repSize) {
- DEBUG(VM_DEBUG_FAIL,
- "Error: invalid size of reply on successful reply.\n");
- ret = -EPROTO;
- goto destroyOut;
- }
-
- reply = (HgfsReplyWriteV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
-
- /* The write was completed successfully, so return the amount written. */
- ret = reply->actualSize;
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDelete --
- *
- * Sends a request to delete a file or directory.
- *
- * Results:
- * Returns 0 on success or an error code on error.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsDelete(HgfsSuperInfo *sip, // IN: Superinfo
- const char *filename, // IN: Full name of file to remove
- HgfsOp op) // IN: Hgfs operation this delete is for
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestDeleteV3 *request;
- HgfsReplyDeleteV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- uint32 reqBufferSize;
- int ret;
-
- ASSERT(sip);
- ASSERT(filename);
- ASSERT((op == HGFS_OP_DELETE_FILE_V3) || (op == HGFS_OP_DELETE_DIR_V3));
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%s,%d)\n", filename, op);
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- goto out;
- }
-
- /* Initialize the request's contents. */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestDeleteV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, op);
- request->hints = 0;
- request->fileName.fid = HGFS_INVALID_HANDLE;
- request->fileName.flags = 0;
- request->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(filename, strlen(filename) + 1,
- request->fileName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
- ret = -ret;
- goto destroyOut;
- }
-
- request->fileName.length = ret;
- reqSize += ret;
-
- /* Set the size of our request. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- DEBUG(VM_DEBUG_COMM, "deleting \"%s\"\n", filename);
-
- /* Submit our request to guestd. */
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* HgfsSubmitRequest() handles destroying the request if necessary. */
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
-
- ret = HgfsGetStatus(req, repSize);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- goto destroyOut;
- }
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%s -> %d)\n", filename, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsGetNextDirEntry --
- *
- * Writes the name of the directory entry matching the handle and offset to
- * nameOut. Also records the entry's type (file, directory) in type. This
- * requires sending a SEARCH_READ request.
- *
- * Results:
- * Returns zero on success and an error code on error. The done value is
- * set if there are no more directory entries.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsGetNextDirEntry(HgfsSuperInfo *sip, // IN: Superinfo pointer
- HgfsHandle handle, // IN: Handle for request
- uint32_t offset, // IN: Offset
- char *nameOut, // OUT: Location to write name
- size_t nameSize, // IN : Size of nameOut
- HgfsFileType *type, // OUT: Entry's type
- Bool *done) // OUT: Whether there are any more
-{
- HgfsKReqHandle req;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestSearchReadV3 *request;
- HgfsReplySearchReadV3 *reply;
- HgfsDirEntry *dirent;
- uint32 reqSize;
- uint32 repSize;
- int ret;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%u,%u)\n", handle, offset);
-
- ASSERT(sip);
- ASSERT(nameOut);
- ASSERT(done);
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- DEBUG(VM_DEBUG_FAIL, "couldn't get req.\n");
- goto out;
- }
-
- /*
- * Fill out the search read request that will return a single directory
- * entry for the provided handle at the given offset.
- */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestSearchReadV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_SEARCH_READ_V3);
-
- request->search = handle;
- request->offset = offset;
- request->flags = 0;
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* HgfsSubmitRequest will destroy the request if necessary. */
- DEBUG(VM_DEBUG_FAIL, "HgfsSubmitRequest failed.\n");
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
-
- ret = HgfsGetStatus(req, sizeof *replyHeader);
- if (ret) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- goto destroyOut;
- }
-
- DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n",
- replyHeader->id);
- DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status);
-
- reply = (HgfsReplySearchReadV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
- reply->count = 1;
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply) + sizeof *dirent;
- dirent = (HgfsDirEntry *)reply->payload;
-
- /* Make sure we got an entire reply (excluding filename) */
- if (HgfsKReq_GetPayloadSize(req) < repSize) {
- DEBUG(VM_DEBUG_FAIL, "server didn't provide entire reply.\n");
- ret = EFAULT;
- goto destroyOut;
- }
-
- /* See if there are no more filenames to read */
- if (dirent->fileName.length <= 0) {
- DEBUG(VM_DEBUG_LOG, "no more directory entries.\n");
- *done = TRUE;
- ret = 0; /* return success */
- goto destroyOut;
- }
-
- /* Make sure filename isn't too long */
- if ((dirent->fileName.length >= nameSize) ||
- (dirent->fileName.length > HGFS_PAYLOAD_MAX(repSize)) ) {
- DEBUG(VM_DEBUG_FAIL, "filename is too long.\n");
- ret = EOVERFLOW;
- goto destroyOut;
- }
-
- /*
- * Everything is all right, copy filename to caller's buffer. Note that even though
- * the hgfs SearchRead reply holds lots of information about the file's attributes,
- * FreeBSD directory entries do not currently need any of that information except the
- * file type.
- */
- memcpy(nameOut, dirent->fileName.name, dirent->fileName.length);
- nameOut[dirent->fileName.length] = '\0';
- *type = dirent->attr.type;
- ret = 0;
-
-destroyOut:
- HgfsKReq_ReleaseRequest(sip->reqs, req);
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsReadlinkInt --
- *
- * Reads a symbolic link target.
- *
- * Results:
- * Either 0 on success or a BSD error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsReadlinkInt(struct vnode *vp, // IN : File vnode
- struct uio *uiop) // OUT: Attributes from hgfs server
-{
- HgfsKReqHandle req = NULL;
- int ret = 0;
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsReplyGetattrV3 *reply;
- HgfsReply *replyHeader;
- uint32 outLength;
- char* outBuffer = NULL;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp));
-
- /* This operation is valid only for symbolic links. */
- if (HGFS_VP_TO_VTYPE(vp) != VLNK) {
- DEBUG(VM_DEBUG_FAIL, "Must be a symbolic link.\n");
- ret = EINVAL;
- goto out;
- }
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- goto out;
- }
-
- ret = HgfsQueryAttrInt(HGFS_VP_TO_FILENAME(vp), 0, sip, req);
- if (ret != 0) {
- DEBUG(VM_DEBUG_FAIL, "Error %d reading symlink name.\n", ret);
- goto out;
- }
-
- outLength = HGFS_UIOP_TO_RESID(uiop);
- outBuffer = os_malloc(outLength, M_WAITOK);
- if (outBuffer != NULL) {
- DEBUG(VM_DEBUG_FAIL, "No memory for symlink name.\n");
- ret = ENOMEM;
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplyGetattrV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
- if (reply->symlinkTarget.name[reply->symlinkTarget.length - 1] == '\0') {
- ret = EINVAL; // Not a well formed name
- goto out;
- }
-
- ret = HgfsNameFromWireEncoding(reply->symlinkTarget.name,
- reply->symlinkTarget.length,
- outBuffer, outLength);
- if (ret < 0) {
- ret = -ret; // HgfsNameFromWireEncoding returns negative error code
- DEBUG(VM_DEBUG_FAIL, "Error converting link wire format length is %d, name is %s\n",
- reply->symlinkTarget.length, reply->symlinkTarget.name);
- goto out;
- }
-
- ret = uiomove(outBuffer, MIN(ret, outLength), uiop);
- if (ret != 0) {
- DEBUG(VM_DEBUG_FAIL, "Failed %d copying into user buffer.\n", ret);
- }
-
-out:
- if (outBuffer != NULL) {
- os_free(outBuffer, outLength);
- }
- if (req != NULL) {
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d\n", HGFS_VP_TO_FILENAME_LENGTH(vp), HGFS_VP_TO_FILENAME(vp),
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsSymlnikInt --
- *
- * Creates symbolic link on the host.
- *
- * Results:
- * Either 0 on success or a BSD error code on failure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsSymlinkInt(struct vnode *dvp, // IN : directory vnode
- struct vnode **vpp, // OUT: pointer to new symlink vnode
- struct componentname *cnp, // IN : pathname to component
- char *targetName) // IN : Symbolic link target
-{
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(dvp);
- HgfsKReqHandle req = NULL;
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestSymlinkCreateV3 *request;
- HgfsReplySymlinkCreateV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- uint32 reqBufferSize;
- int ret;
- char *fullName = NULL;
- uint32 fullNameLen;
- HgfsFileNameV3 *fileNameP;
- int nameOffset;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s/%.*s,%s)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr,
- targetName);
-
- fullName = os_malloc(MAXPATHLEN, M_WAITOK);
- if (!fullName) {
- ret = ENOMEM;
- goto out;
- }
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- goto out;
- }
-
- ret = HgfsMakeFullName(HGFS_VP_TO_FILENAME(dvp), // Parent directory
- HGFS_VP_TO_FILENAME_LENGTH(dvp), // Length of name
- cnp->cn_nameptr, // Name of file to create
- cnp->cn_namelen, // Length of filename
- fullName, // Buffer to write full name
- MAXPATHLEN); // Size of this buffer
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "couldn't create full path name.\n");
- ret = ENAMETOOLONG;
- goto out;
- }
- fullNameLen = ret;
-
- /* Initialize the request's contents. */
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestSymlinkCreateV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_CREATE_SYMLINK_V3);
-
- request->reserved = 0;
-
- request->symlinkName.flags = 0;
- request->symlinkName.fid = HGFS_INVALID_HANDLE;
- request->symlinkName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(fullName, fullNameLen + 1,
- request->symlinkName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL,"Could not encode file name to wire format");
- ret = -ret;
- goto out;
- }
- request->symlinkName.length = ret;
- reqSize += ret;
-
- fileNameP = (HgfsFileNameV3 *)((char*)&request->symlinkName +
- sizeof request->symlinkName +
- request->symlinkName.length);
- fileNameP->flags = 0;
- fileNameP->fid = HGFS_INVALID_HANDLE;
- fileNameP->caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
-
- /*
- * Currently we have different name formats for file names and for symbolic
- * link targets. Flie names are always absolute and on-wire representation does
- * not include leading path separator. HgfsNameToWireEncoding removes
- * leading path separator from the name. However symbolic link targets may be
- * either absolute or relative. To distinguish between them the leading path separator
- * must be preserved for absolute symbolic link target.
- * In the long term we should fix the protocol and have only one name
- * format which is suitable for all names.
- * The following code compensates for this problem before there is such
- * universal name representation.
- */
- if (*targetName == '/') {
- fileNameP->length = 1;
- reqSize += 1;
- *fileNameP->name = '\0';
- targetName++;
- } else {
- fileNameP->length = 0;
- }
- /*
- * Convert symbolic link target to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- nameOffset = fileNameP->name - (char*)requestHeader;
- ret = HgfsNameToWireEncoding(targetName, strlen(targetName) + 1,
- fileNameP->name + fileNameP->length,
- HGFS_PACKET_MAX - nameOffset -
- fileNameP->length);
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL,"Could not encode file name to wire format");
- ret = -ret;
- goto out;
- }
- fileNameP->length += ret;
-
- reqSize += ret;
-
- /* Set the size of this request. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* Request is destroyed in HgfsSubmitRequest() if necessary. */
- req = NULL;
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplySymlinkCreateV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply);
- ret = HgfsGetStatus(req, repSize);
- if (ret == 0) {
- ret = HgfsVnodeGet(vpp, dvp, sip, HGFS_VP_TO_MP(dvp), fullName,
- HGFS_FILE_TYPE_SYMLINK, &sip->fileHashTable, TRUE, 0, 0);
- if (ret) {
- ret = EIO;
- }
- } else {
- DEBUG(VM_DEBUG_FAIL, "Error encountered with ret = %d\n", ret);
- }
-
- ASSERT(ret != 0 || *vpp != NULL);
-
-out:
- if (req) {
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- if (fullName != NULL) {
- os_free(fullName, MAXPATHLEN);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s/%.*s -> %d)\n",
- HGFS_VP_TO_FILENAME_LENGTH(dvp), HGFS_VP_TO_FILENAME(dvp),
- (int)cnp->cn_namelen, cnp->cn_nameptr,
- ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDoGetattrByName --
- *
- * Send a name getattr request to the hgfs server and put the result in
- * hgfsAttr.
- *
- * Results:
- * Either 0 on success or a BSD error code on failure. The hgfsAttr field
- * is only filled out on success.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsDoGetattrByName(const char *path, // IN : Path to get attributes for
- HgfsSuperInfo *sip, // IN : SuperInfo block of hgfs mount.
- HgfsAttrV2 *hgfsAttrV2) // OUT: Attributes from hgfs server
-{
- int ret;
- DEBUG(VM_DEBUG_ENTRY, "Enter(%s)\n", path);
- ret = HgfsDoGetattrInt(path, 0, sip, hgfsAttrV2);
- DEBUG(VM_DEBUG_EXIT, "Exit(%s -> %d)\n", path, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDoGetattrByName --
- *
- * Send a handle getattr request to the hgfs server and put the result in
- * hgfsAttr.
- *
- * Results:
- * Either 0 on success or a BSD error code on failure. The hgfsAttr field
- * is only filled out on success.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-#if 0
-static int
-HgfsDoGetattrByHandle(HgfsHandle handle, // IN : Hgfs handle for attr request
- HgfsSuperInfo *sip, // IN : SuperInfo block for hgfs mount
- HgfsAttrV2 *hgfsAttrV2) // OUT: Attributes from hgfs server
-{
- int ret;
- DEBUG(VM_DEBUG_ENTRY, "Enter(%u)\n", handle);
- ret = HgfsDoGetattrInt(NULL, handle, sip, hgfsAttrV2);
- DEBUG(VM_DEBUG_EXIT, "Exit(%u -> %d)\n", handle, ret);
-}
-#endif
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsDoGetattrInt --
- *
- * Internal function that actually sends a getattr request to the hgfs
- * server and puts the results in hgfsAttrV2. This function should only
- * be called by HgfsDoGetattrByName or HgfsDoGetattrByHandle and will do
- * a getattr by filename if path is non-NULL. Otherwise it does a getattr by
- * handle.
- *
- *
- * Results:
- * Either 0 on success or a BSD error code on failure. The hgfsAttr field
- * is only filled out on success.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsDoGetattrInt(const char *path, // IN : Path to get attributes for
- HgfsHandle handle, // IN : Handle to get attribues for
- HgfsSuperInfo *sip, // IN : SuperInfo block for hgfs mount
- HgfsAttrV2 *hgfsAttrV2) // OUT: Attributes from hgfs server
-{
- HgfsKReqHandle req;
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%s,%u)\n", (path != NULL ? path : "null"), handle);
- ASSERT(hgfsAttrV2);
-
- req = HgfsKReq_AllocateRequest(sip->reqs, &ret);
- if (!req) {
- return ret;
- }
-
- ret = HgfsQueryAttrInt(path, handle, sip, req);
- if (ret == 0) {
- HgfsReplyGetattrV3 *reply;
- HgfsReply *replyHeader;
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
- reply = (HgfsReplyGetattrV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
-
- /* Fill out hgfsAttrV2 with the results from the server. */
- memcpy(hgfsAttrV2, &reply->attr, sizeof *hgfsAttrV2);
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%s,%u -> %d)\n", (path != NULL ? path : "null"), handle, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsQueryAttrInt --
- *
- * Internal function that actually sends a getattr request to the hgfs
- * server and puts the results in hgfsAttrV2. This function does
- * a getattr by filename if path is non-NULL. Otherwise it does a getattr by
- * handle.
- *
- *
- * Results:
- * Either 0 on success or a BSD error code on failure. When function
- * succeeds a valid hgfs request is returned and it must be de-allocaed
- * by the caller.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static int
-HgfsQueryAttrInt(const char *path, // IN : Path to get attributes for
- HgfsHandle handle, // IN : Handle to get attribues for
- HgfsSuperInfo *sip, // IN : SuperInfo block for hgfs mount
- HgfsKReqHandle req) // IN/OUT: preacllocated hgfs request
-{
- HgfsRequest *requestHeader;
- HgfsReply *replyHeader;
- HgfsRequestGetattrV3 *request;
- HgfsReplyGetattrV3 *reply;
- uint32 reqSize;
- uint32 repSize;
- uint32 reqBufferSize;
- int ret = 0;
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%s,%u)\n", (path != NULL ? path : "null"), handle);
- requestHeader = (HgfsRequest *)HgfsKReq_GetPayload(req);
- request = (HgfsRequestGetattrV3 *)HGFS_REQ_GET_PAYLOAD_V3(requestHeader);
-
- HGFS_INIT_REQUEST_HDR(requestHeader, req, HGFS_OP_GETATTR_V3);
- request->reserved = 0;
-
- reqSize = HGFS_REQ_PAYLOAD_SIZE_V3(request);
- reqBufferSize = HGFS_NAME_BUFFER_SIZET(HGFS_PACKET_MAX, reqSize);
-
- /*
- * Per the calling conventions of this function, if the path is NULL then
- * this is a Getattr by handle.
- */
- if (path == NULL) {
- request->hints = HGFS_ATTR_HINT_USE_FILE_DESC;
- request->fileName.fid = handle;
- request->fileName.flags = HGFS_FILE_NAME_USE_FILE_DESC;
- request->fileName.caseType = HGFS_FILE_NAME_DEFAULT_CASE;
- request->fileName.length = 0;
-
- } else {
- /* Do a Getattr by path. */
- request->hints = 0;
- request->fileName.caseType = HGFS_FILE_NAME_CASE_SENSITIVE;
- request->fileName.fid = HGFS_INVALID_HANDLE;
- request->fileName.flags = 0;
-
- /*
- * Convert an input string to utf8 precomposed form, convert it to
- * the cross platform name format and finally unescape any illegal
- * filesystem characters.
- */
- ret = HgfsNameToWireEncoding(path, strlen(path) + 1,
- request->fileName.name,
- reqBufferSize);
-
- if (ret < 0) {
- DEBUG(VM_DEBUG_FAIL, "Could not encode to wire format");
- ret = -ret;
- goto destroyOut;
- }
- request->fileName.length = ret;
- reqSize += ret;
- }
-
- /* Packet size includes the header, request and its payload. */
- HgfsKReq_SetPayloadSize(req, reqSize);
-
- DEBUG(VM_DEBUG_COMM, "sending getattr request for ID %d\n",
- requestHeader->id);
- DEBUG(VM_DEBUG_COMM, " fileName.length: %d\n", request->fileName.length);
- DEBUG(VM_DEBUG_COMM, " fileName.name: \"%s\"\n", request->fileName.name);
-
- /*
- * Submit the request and wait for the reply. HgfsSubmitRequest handles
- * destroying the request on both error and interrupt cases.
- */
- ret = HgfsSubmitRequest(sip, req);
- if (ret) {
- /* HgfsSubmitRequest destroys the request if necessary */
- goto out;
- }
-
- replyHeader = (HgfsReply *)HgfsKReq_GetPayload(req);
-
- ret = HgfsGetStatus(req, sizeof *replyHeader);
- if (ret) {
- if (ret == EPROTO) {
- DEBUG(VM_DEBUG_FAIL, "Error encountered for ID = %d\n"
- "with status %d.\n", replyHeader->id, replyHeader->status);
- }
- goto destroyOut;
- }
-
- reply = (HgfsReplyGetattrV3 *)HGFS_REP_GET_PAYLOAD_V3(replyHeader);
-
- DEBUG(VM_DEBUG_COMM, "received reply for ID %d\n", replyHeader->id);
- DEBUG(VM_DEBUG_COMM, " status: %d (see hgfsProto.h)\n", replyHeader->status);
- DEBUG(VM_DEBUG_COMM, " file type: %d\n", reply->attr.type);
- DEBUG(VM_DEBUG_COMM, " file size: %llu\n", (long long unsigned)reply->attr.size);
- DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.ownerPerms);
- DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.groupPerms);
- DEBUG(VM_DEBUG_COMM, " permissions: %o\n", reply->attr.otherPerms);
- DEBUG(VM_DEBUG_COMM, " hostFileId: %llu\n", (long long unsigned)reply->attr.hostFileId);
-
- repSize = HGFS_REP_PAYLOAD_SIZE_V3(reply) + reply->symlinkTarget.length;
-
- /* The GetAttr succeeded, ensure packet contains correct amount of data. */
- if (HgfsKReq_GetPayloadSize(req) != repSize) {
- DEBUG(VM_DEBUG_COMM, "HgfsLookup: invalid packet size received for \"%s\".\n",
- path);
- ret = EFAULT;
- goto destroyOut;
- }
-
-destroyOut:
- if (ret != 0) {
- HgfsKReq_ReleaseRequest(sip->reqs, req);
- }
-
-out:
- DEBUG(VM_DEBUG_EXIT, "Exit(%s,%u -> %d)\n", (path != NULL ? path : "null"), handle, ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * IsModeCompatible --
- *
- * Checks if the requested mode is compatible with permissions.
- *
- * Results:
- * Returns TRUE if the mode is compatible, FALSE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-static Bool
-IsModeCompatible(HgfsAccessMode mode, // IN: Requested open mode
- uint32 permissions) // IN: Effective user permissions
-{
- if ((permissions & HGFS_PERM_READ) == 0) {
- if ((mode & (HGFS_MODE_GENERIC_READ |
- HGFS_MODE_READ_DATA |
- HGFS_MODE_LIST_DIRECTORY |
- HGFS_MODE_READ_ATTRIBUTES |
- HGFS_MODE_READ_EXTATTRIBUTES |
- HGFS_MODE_READ_SECURITY)) != 0) {
- return FALSE;
- }
- }
-
- if ((permissions & HGFS_PERM_WRITE) == 0) {
- if ((mode & (HGFS_MODE_GENERIC_WRITE |
- HGFS_MODE_WRITE_DATA |
- HGFS_MODE_APPEND_DATA |
- HGFS_MODE_DELETE |
- HGFS_MODE_ADD_SUBDIRECTORY |
- HGFS_MODE_DELETE_CHILD |
- HGFS_MODE_WRITE_ATTRIBUTES |
- HGFS_MODE_WRITE_EXTATTRIBUTES |
- HGFS_MODE_WRITE_SECURITY |
- HGFS_MODE_TAKE_OWNERSHIP |
- HGFS_MODE_ADD_FILE)) != 0) {
- return FALSE;
- }
- }
-
- if ((permissions & HGFS_PERM_EXEC) == 0) {
- if ((mode & (HGFS_MODE_GENERIC_EXECUTE |
- HGFS_MODE_TRAVERSE_DIRECTORY)) != 0) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsAccessInt --
- *
- * Check to ensure the user has the specified type of access to the file.
- *
- * Results:
- * Returns 0 if access is allowed and a non-zero error code otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsAccessInt(struct vnode *vp, // IN: Vnode to check access for
- HgfsAccessMode mode) // IN: Access mode requested.
-{
- int ret = 0;
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
- HgfsAttrV2 hgfsAttrV2;
-
- DEBUG(VM_DEBUG_ENTRY, "HgfsAccessInt(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp), mode);
-
- ret = HgfsDoGetattrByName(HGFS_VP_TO_FILENAME(vp), sip, &hgfsAttrV2);
- if (ret == 0) {
- uint32 effectivePermissions;
- if (hgfsAttrV2.mask & HGFS_ATTR_VALID_EFFECTIVE_PERMS) {
- effectivePermissions = hgfsAttrV2.effectivePerms;
- } else {
- /*
- * If the server did not return actual effective permissions then
- * need to calculate ourselves. However we should avoid unnecessary denial of
- * access so perform optimistic permissions calculation.
- * It is safe since host enforces necessary restrictions regardless of
- * the client's decisions.
- */
- effectivePermissions =
- hgfsAttrV2.ownerPerms | hgfsAttrV2.groupPerms | hgfsAttrV2.otherPerms;
- }
- if (!IsModeCompatible(mode, effectivePermissions)) {
- ret = EACCES;
- DEBUG(VM_DEBUG_FAIL, "HgfsAccessInt denied access: %s (%d, %d)\n",
- HGFS_VP_TO_FILENAME(vp), mode, effectivePermissions);
- }
- } else {
- DEBUG(VM_DEBUG_FAIL, "HgfsAccessInt failed getting attrib: %s (%d)\n",
- HGFS_VP_TO_FILENAME(vp), ret);
- }
-
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp), ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsMmapInt --
- *
- * HgfsMmapInt is invoked invoked from HgfsVnopMmap to verify parameters
- * and mark vnode as mmapped if necessary.
- *
- * Results:
- * Zero on success or non-zero error code otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsMmapInt(struct vnode *vp,
- int accessMode)
-{
- int ret;
- HgfsFile *fp;
-
- ASSERT(vp);
- fp = HGFS_VP_TO_FP(vp);
-
- ASSERT(fp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s,%d)\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp), accessMode);
-
- /*
- * If the directory is already opened then we are done.
- * There is no different open modes for directories thus the handle is compatible.
- */
- os_rw_lock_lock_exclusive(fp->handleLock);
-
- ret = HgfsCheckAndReferenceHandle(vp, accessMode, OPENREQ_MMAP);
- os_rw_lock_unlock_exclusive(fp->handleLock);
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d).\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp), ret);
- return ret;
-}
-
-
-/*
- *----------------------------------------------------------------------------
- *
- * HgfsMnomapInt --
- *
- * HgfsMnomapInt is invoked invoked from HgfsVnopNomap to tear down memory
- * mapping and dereference file handle.
- *
- * Results:
- * Zero on success or non-zero error code otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------------
- */
-
-int
-HgfsMnomapInt(struct vnode *vp)
-{
- int ret = 0;
- HgfsHandle handleToClose;
- HgfsSuperInfo *sip = HGFS_VP_TO_SIP(vp);
-
- ASSERT(vp);
-
- DEBUG(VM_DEBUG_ENTRY, "Enter(%.*s)\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp));
-
- /*
- * Check to see if we should close the file handle on the host, which happen when
- * the reference count of the current handle become 0.
- */
- if (HgfsReleaseOpenFileHandle(vp, OPENREQ_MMAP, &handleToClose) == 0) {
- ret = HgfsCloseServerFileHandle(sip, handleToClose);
- }
- DEBUG(VM_DEBUG_EXIT, "Exit(%.*s -> %d).\n", HGFS_VP_TO_FILENAME_LENGTH(vp),
- HGFS_VP_TO_FILENAME(vp), ret);
- return ret;
-}
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.h b/open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.h
deleted file mode 100644
index 43bcdbde..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/vnopscommon.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*********************************************************
- * Copyright (C) 2008 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
- *
- *********************************************************/
-
-/*
- * vnopscommon.h --
- *
- * Common VFS vnop implementations that are shared between both Mac OS and FreeBSD.
- */
-
-#ifndef _HGFS_VNOPS_COMMON_H_
-#define _HGFS_VNOPS_COMMON_H_
-
-#include "hgfs_kernel.h"
-
-/*
- * Macros
- */
-
-/* Access uio struct information in a Mac OS / FreeBSD independent manner. */
-#if defined __FreeBSD__
-#define HGFS_UIOP_TO_RESID(uiop) \
- ((uiop)->uio_resid)
-#define HGFS_UIOP_TO_OFFSET(uiop) \
- ((uiop)->uio_offset)
-#define HGFS_UIOP_SET_OFFSET(uiop, offset) \
- ((uiop)->uio_offset = (offset))
-#elif defined __APPLE__
-#define HGFS_UIOP_TO_RESID(uiop) \
- (uio_resid(uiop))
-#define HGFS_UIOP_TO_OFFSET(uiop) \
- (uio_offset(uiop))
-#define HGFS_UIOP_SET_OFFSET(uiop, offset) \
- (uio_setoffset(uiop, offset))
-#endif
-
-/* Access vnode struct information in a Mac OS / FreeBSD independent manner. */
-#if defined __FreeBSD__
-#define HGFS_VP_TO_VTYPE(vp) \
- (vp->v_type)
-#define HGFS_VPP_GET_IOCOUNT(vpp) \
- (vref(*vpp))
-#elif defined __APPLE__
-#define HGFS_VP_TO_VTYPE(vp) \
- (vnode_vtype(vp))
-#define HGFS_VPP_GET_IOCOUNT(vpp) \
- (vnode_get(*vpp))
-#endif
-
-/* Internal Vnops functions used by both FreeBSD and Mac OS */
-int HgfsReaddirInt(struct vnode *vp, struct uio *uiop, int *eofp);
-int HgfsSetattrInt(struct vnode *vp, HgfsVnodeAttr *vap);
-int HgfsGetattrInt(struct vnode *vp, HgfsVnodeAttr *vap);
-int HgfsRmdirInt(struct vnode *dvp, struct vnode *vp,
- struct componentname *cnp);
-int HgfsRemoveInt(struct vnode *vp);
-int HgfsCloseInt(struct vnode *vp, int mode);
-int HgfsOpenInt(struct vnode *vp, int fflag, HgfsOpenType openType);
-int HgfsLookupInt(struct vnode *dvp, struct vnode **vpp,
- struct componentname *cnp);
-int HgfsCreateInt(struct vnode *dvp, struct vnode **vpp,
- struct componentname *cnp, int mode);
-int HgfsReadInt(struct vnode *vp, struct uio *uiop, Bool pagingIo);
-int HgfsReadlinkInt(struct vnode *vp, struct uio *uiop);
-int HgfsWriteInt(struct vnode *vp, struct uio *uiop,
- int ioflag, Bool pagingIo);
-int HgfsMkdirInt(struct vnode *dvp, struct vnode **vpp,
- struct componentname *cnp, int mode);
-int HgfsRenameInt(struct vnode *fvp,
- struct vnode *tdvp, struct vnode *tvp,
- struct componentname *tcnp);
-int HgfsAccessInt(struct vnode *vp, HgfsAccessMode mode);
-int HgfsSymlinkInt(struct vnode *dvp,
- struct vnode **vpp,
- struct componentname *cnp,
- char *targetName);
-int HgfsMmapInt(struct vnode *vp, int accessMode);
-int HgfsMnomapInt(struct vnode *vp);
-
-#endif // _HGFS_VNOPS_COMMON_H_
diff --git a/open-vm-tools/modules/freebsd/vmhgfs/worker.c b/open-vm-tools/modules/freebsd/vmhgfs/worker.c
deleted file mode 100644
index 0a9537b7..00000000
--- a/open-vm-tools/modules/freebsd/vmhgfs/worker.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*********************************************************
- * Copyright (C) 2007 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
- *
- *********************************************************/
-
-/*
- * worker.c --
- *
- * Worker thread to process issue Guest -> Host Hgfs requests.
- */
-
-#if defined __FreeBSD__
-# include <sys/libkern.h>
-#endif
-
-#include "hgfs_kernel.h"
-#include "request.h"
-#include "requestInt.h"
-#include "os.h"
-#include "channel.h"
-
-
-/*
- * Local data
- */
-
-/*
- * Process structure filled in when the worker thread is created.
- */
-OS_THREAD_T hgfsKReqWorkerThread;
-
-/*
- * See requestInt.h.
- */
-HgfsKReqWState hgfsKReqWorkerState;
-HgfsTransportChannel *gHgfsChannel = NULL;
-OS_MUTEX_T *gHgfsChannelLock = NULL;
-
-
-/*
- * Global (module) functions
- */
-
-/*
- *----------------------------------------------------------------------
- *
- * HgfsTransportSetupNewChannel --
- *
- * Find a new workable channel.
- *
- * Results:
- * TRUE on success, otherwise FALSE.
- *
- * Side effects:
- * None
- *
- *----------------------------------------------------------------------
- */
-
-Bool
-HgfsSetupNewChannel(void)
-{
- Bool ret;
-
- os_mutex_lock(gHgfsChannelLock);
-
- if (gHgfsChannel && gHgfsChannel->status == HGFS_CHANNEL_CONNECTED) {
- ret = TRUE;
- goto exit;
- }
-
- gHgfsChannel = HgfsGetVmciChannel();
- if (gHgfsChannel) {
- if ((ret = gHgfsChannel->ops.open(gHgfsChannel))) {
- goto exit;
- }
- }
-
- /* Every client using this code is expected to have backdoor enabled. */
- gHgfsChannel = HgfsGetBdChannel();
- ret = gHgfsChannel->ops.open(gHgfsChannel);
-
-exit:
- if (ret) {
- gHgfsChannel->status = HGFS_CHANNEL_CONNECTED;
- DEBUG(VM_DEBUG_ALWAYS, "Channel: %s\n", gHgfsChannel->name);
- } else {
- gHgfsChannel->status = HGFS_CHANNEL_NOTCONNECTED;
- }
-
- os_mutex_unlock(gHgfsChannelLock);
-
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * HgfsKReqWorker --
- *
- * Main routine for Hgfs client worker thread. This thread is responsible
- * for all Hgfs communication with the host via the backdoor.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-HgfsKReqWorker(void *arg)
-{
- DblLnkLst_Links *currNode, *nextNode;
- HgfsKReqWState *ws = (HgfsKReqWState *)arg;
- HgfsKReqObject *req;
- int ret = 0;
- HgfsTransportChannel *channel;
-
- ws->running = TRUE;
-
- gHgfsChannelLock = os_mutex_alloc_init(HGFS_FS_NAME "_channellck");
- if (!gHgfsChannelLock) {
- goto exit;
- }
-
- ret = HgfsSetupNewChannel();
- if (!ret) {
- DEBUG(VM_DEBUG_INFO, "VMware hgfs: %s: ohoh no channel yet.\n", __func__);
- }
-
- for (;;) {
- /*
- * This loop spends most of its time sleeping until signalled by another
- * thread. We expect to be signalled only if either there is work to do
- * or if the module is being unloaded.
- */
-
- os_mutex_lock(hgfsKReqWorkItemLock);
-
- while (!ws->exit && !DblLnkLst_IsLinked(&hgfsKReqWorkItemList)) {
- os_cv_wait(&hgfsKReqWorkItemCv, hgfsKReqWorkItemLock);
- }
-
- if (ws->exit) {
- /* Note that the list lock is still held. */
- break;
- }
-
- /*
- * We have work to do! Hooray! Start by locking the request and pulling
- * it from the work item list. (The list's reference is transferred to
- * us, so we'll decrement the request's reference count when we're
- * finished with it.)
- *
- * With the request locked, make a decision based on the request's state.
- * Typically a request will be in the SUBMITTED state, but if its owner
- * aborted an operation or the file system cancelled it, it may be listed
- * as ABANDONED. If either of the latter are true, then we don't bother
- * with any further processing.
- *
- * Because we're not sure how long the backdoor operation will take, we
- * yield the request's state lock before calling HgfsBd_Dispatch. Upon
- * return, we must test the state again (see above re: cancellation),
- * and then we finally update the state & signal any waiters.
- */
-
- currNode = hgfsKReqWorkItemList.next;
- DblLnkLst_Unlink1(currNode);
- req = DblLnkLst_Container(currNode, HgfsKReqObject, pendingNode);
-
- os_mutex_lock(req->stateLock);
-
- channel = req->channel;
- switch (req->state) {
- case HGFS_REQ_SUBMITTED:
- if (channel->status != HGFS_CHANNEL_CONNECTED) {
- req->state = HGFS_REQ_ERROR;
- os_cv_signal(&req->stateCv);
- os_mutex_unlock(req->stateLock);
- os_mutex_unlock(hgfsKReqWorkItemLock);
- goto done;
- }
- break;
- case HGFS_REQ_ABANDONED:
- case HGFS_REQ_ERROR:
- os_mutex_unlock(req->stateLock);
- os_mutex_unlock(hgfsKReqWorkItemLock);
- goto done;
- default:
- panic("Request object (%p) in unknown state: %u", req, req->state);
- }
- os_mutex_unlock(req->stateLock);
-
- /*
- * We're done with the work item list for now. Unlock it and let the file
- * system add requests while we're busy.
- */
- os_mutex_unlock(hgfsKReqWorkItemLock);
-
- ret = channel->ops.send(gHgfsChannel, req);
-
- if (ret != 0) {
- /*
- * If the channel was previously open, make sure it's dead and gone
- * now. We do this because subsequent requests deserve a chance to
- * reopen it.
- */
- os_mutex_lock(gHgfsChannelLock);
- gHgfsChannel->ops.close(gHgfsChannel);
- os_mutex_unlock(gHgfsChannelLock);
- }
-
-done:
-
- /*
- * If transport wants to process request async then it should have
- * taken reference for itself. If not we free it.
- */
- if (os_add_atomic(&req->refcnt, -1) == 1) {
- os_zone_free(hgfsKReqZone, req);
- }
- }
-
- /*
- * NB: The work item lock is still held.
- *
- * XXX There may be some request on the sentList. what should we do about them ?
- */
-
- /*
- * We're signaled to exit. Remove any items from the pending request list
- * before exiting.
- */
- DblLnkLst_ForEachSafe(currNode, nextNode, &hgfsKReqWorkItemList) {
- req = DblLnkLst_Container(currNode, HgfsKReqObject, pendingNode);
- DblLnkLst_Unlink1(currNode);
- os_mutex_lock(req->stateLock);
- req->state = HGFS_REQ_ERROR;
- os_cv_signal(&req->stateCv);
- os_mutex_unlock(req->stateLock);
-
- /*
- * If we held the final reference to a request, free it.
- */
- if (os_add_atomic(&req->refcnt, -1) == 1) {
- os_zone_free(hgfsKReqZone, req);
- }
- }
-
- os_mutex_unlock(hgfsKReqWorkItemLock);
-
- ws->running = FALSE;
-
- if (gHgfsChannel && gHgfsChannel->status == HGFS_CHANNEL_CONNECTED) {
- gHgfsChannel->ops.close(gHgfsChannel);
- }
-
- if (gHgfsChannelLock) {
- os_mutex_free(gHgfsChannelLock);
- }
-exit:
- os_thread_exit(0);
-}
diff --git a/open-vm-tools/modules/freebsd/vmmemctl/os.c b/open-vm-tools/modules/freebsd/vmmemctl/os.c
index caee2a66..1342edab 100644
--- a/open-vm-tools/modules/freebsd/vmmemctl/os.c
+++ b/open-vm-tools/modules/freebsd/vmmemctl/os.c
@@ -295,7 +295,12 @@ OS_ReservedPageGetHandle(PA64 pa) // IN
Mapping
OS_MapPageHandle(PageHandle handle) // IN
{
+#if __FreeBSD_version < 1000000
vm_offset_t res = kmem_alloc_nofault(kernel_map, PAGE_SIZE);
+#else
+ vm_offset_t res = kva_alloc(PAGE_SIZE);
+#endif
+
vm_page_t page = (vm_page_t)handle;
if (!res) {
@@ -352,7 +357,11 @@ void
OS_UnmapPage(Mapping mapping) // IN
{
pmap_qremove((vm_offset_t)mapping, 1);
+#if __FreeBSD_version < 1000000
kmem_free(kernel_map, (vm_offset_t)mapping, PAGE_SIZE);
+#else
+ kva_free((vm_offset_t)mapping, PAGE_SIZE);
+#endif
}
@@ -363,20 +372,28 @@ os_pmap_alloc(os_pmap *p) // IN
p->size = (cnt.v_page_count + 7) / 8;
/*
- * expand to nearest word boundary
- * XXX: bitmap can be greater than total number of pages in system
+ * expand to nearest word boundary
+ * XXX: bitmap can be greater than total number of pages in system
*/
- p->size = (p->size + sizeof(unsigned long) - 1) &
+ p->size = (p->size + sizeof(unsigned long) - 1) &
~(sizeof(unsigned long) - 1);
+#if __FreeBSD_version < 1000000
p->bitmap = (unsigned long *)kmem_alloc(kernel_map, p->size);
+#else
+ p->bitmap = (unsigned long *)kmem_malloc(kernel_arena, p->size, M_WAITOK | M_ZERO);
+#endif
}
static void
os_pmap_free(os_pmap *p) // IN
{
+#if __FreeBSD_version < 1000000
kmem_free(kernel_map, (vm_offset_t)p->bitmap, p->size);
+#else
+ kmem_free(kernel_arena, (vm_offset_t)p->bitmap, p->size);
+#endif
p->size = 0;
p->bitmap = NULL;
}
diff --git a/open-vm-tools/modules/freebsd/vmxnet/net_compat.h b/open-vm-tools/modules/freebsd/vmxnet/net_compat.h
index 78c38507..c36ca745 100644
--- a/open-vm-tools/modules/freebsd/vmxnet/net_compat.h
+++ b/open-vm-tools/modules/freebsd/vmxnet/net_compat.h
@@ -170,9 +170,12 @@
#if __FreeBSD_version < 505000
# define VXN_IF_ADDR_LOCK(_ifp)
# define VXN_IF_ADDR_UNLOCK(_ifp)
-#else
+#elif __FreeBSD_version < 1000000
# define VXN_IF_ADDR_LOCK(_ifp) IF_ADDR_LOCK((_ifp))
# define VXN_IF_ADDR_UNLOCK(_ifp) IF_ADDR_UNLOCK((_ifp))
+#else
+# define VXN_IF_ADDR_LOCK(_ifp) if_maddr_rlock((_ifp))
+# define VXN_IF_ADDR_UNLOCK(_ifp) if_maddr_runlock((_ifp))
#endif
#endif /* _VXN_NET_COMPAT_H_ */
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/freebsd/vmhgfs/vmci.c b/open-vm-tools/modules/linux/shared/autoconf/dcount.c
index b5fd216d..c78968d0 100644
--- a/open-vm-tools/modules/freebsd/vmhgfs/vmci.c
+++ b/open-vm-tools/modules/linux/shared/autoconf/dcount.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2010 VMware, Inc. All rights reserved.
+ * 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
@@ -16,33 +16,28 @@
*
*********************************************************/
-/*
- * vmci.c --
- *
- * VMCI transport channel for the HGFS client is not currently implemented.
- */
-#include "channel.h"
+#include "compat_version.h"
+#include "compat_autoconf.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
+#include <linux/dcache.h>
/*
- *----------------------------------------------------------------------
- *
- * HgfsGetVmciChannel --
- *
- * Get Vmci channel.
+ * After 3.11.0, the dentry d_count field was removed. Red Hat
+ * backported this behavior into a 3.10.0 kernel.
*
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
+ * This test will fail on a kernel with such a patch.
*/
-
-HgfsTransportChannel*
-HgfsGetVmciChannel(void) // IN:
+void test(void)
{
- return NULL;
-}
+ 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/freebsd/vmhgfs/vfsopscommon.h b/open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c
index ad3cd052..818aee32 100644
--- a/open-vm-tools/modules/freebsd/vmhgfs/vfsopscommon.h
+++ b/open-vm-tools/modules/linux/shared/autoconf/file_operations_flush.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2008 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
@@ -17,32 +17,30 @@
*********************************************************/
/*
- * vfsopscommon.h --
+ * 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.
*
- * Common VFS vfsop implementations that are shared between both Mac OS and FreeBSD.
+ * This test will fail on a kernel with such a patch.
*/
-#ifndef _HGFS_VFSOPS_COMMON_H_
-#define _HGFS_VFSOPS_COMMON_H_
+#include "compat_version.h"
+#include "compat_autoconf.h"
-#include <sys/mount.h>
-#include <sys/vnode.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+#error This compile test intentionally fails on 2.6.18 and newer kernels.
+#else
-/*
- * Macros
- */
-
-#define HGFS_CONVERT_TO_BLOCKS(bytes) (bytes / HGFS_BLOCKSIZE)
-#define HGFS_IS_POWER_OF_TWO(val) (val && !(val & (val - 1)))
-
-#if defined __FreeBSD__
- typedef struct statfs HgfsStatfs;
-#elif defined __APPLE__
- typedef struct vfsstatfs HgfsStatfs;
-#endif
+#include <linux/fs.h>
+static int TestFlush(struct file *file);
+{
+ return 0;
+}
-int
-HgfsStatfsInt(struct vnode *vp, HgfsStatfs *stat);
+struct file_operations testFO = {
+ .flush = TestFlush,
+};
-#endif // _HGFS_VFSOPS_COMMON_H_
+#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_ */
diff --git a/open-vm-tools/modules/shared/vmblock/block.c b/open-vm-tools/modules/shared/vmblock/block.c
index 72e4af98..d81a44d2 100644
--- a/open-vm-tools/modules/shared/vmblock/block.c
+++ b/open-vm-tools/modules/shared/vmblock/block.c
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmblock/block.h b/open-vm-tools/modules/shared/vmblock/block.h
index 7171e59d..29e21183 100644
--- a/open-vm-tools/modules/shared/vmblock/block.h
+++ b/open-vm-tools/modules/shared/vmblock/block.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmblock/stubs.c b/open-vm-tools/modules/shared/vmblock/stubs.c
index cc284da4..cc158bc2 100644
--- a/open-vm-tools/modules/shared/vmblock/stubs.c
+++ b/open-vm-tools/modules/shared/vmblock/stubs.c
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.c b/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.c
index 3189af91..3ea87736 100644
--- a/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.c
+++ b/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.c
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.h b/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.h
index f2289802..5e26ebe8 100644
--- a/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.h
+++ b/open-vm-tools/modules/shared/vmmemctl/backdoor_balloon.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/balloonInt.h b/open-vm-tools/modules/shared/vmmemctl/balloonInt.h
index 684af098..5c472124 100644
--- a/open-vm-tools/modules/shared/vmmemctl/balloonInt.h
+++ b/open-vm-tools/modules/shared/vmmemctl/balloonInt.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/balloon_def.h b/open-vm-tools/modules/shared/vmmemctl/balloon_def.h
index ef870cda..0ba139cf 100644
--- a/open-vm-tools/modules/shared/vmmemctl/balloon_def.h
+++ b/open-vm-tools/modules/shared/vmmemctl/balloon_def.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/dbllnklst.h b/open-vm-tools/modules/shared/vmmemctl/dbllnklst.h
index c996f1a5..95745826 100644
--- a/open-vm-tools/modules/shared/vmmemctl/dbllnklst.h
+++ b/open-vm-tools/modules/shared/vmmemctl/dbllnklst.h
@@ -1,5 +1,5 @@
/*********************************************************
- * 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 Lesser General Public License as published
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/kernelStubs.h b/open-vm-tools/modules/shared/vmmemctl/kernelStubs.h
index 2fecd043..d0a53ad7 100644
--- a/open-vm-tools/modules/shared/vmmemctl/kernelStubs.h
+++ b/open-vm-tools/modules/shared/vmmemctl/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 Lesser General Public License as published
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -69,6 +66,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"
@@ -78,12 +90,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
@@ -107,6 +139,7 @@
# include <sys/types.h>
# include <sys/varargs.h>
#endif
+#include "kernelStubsSal.h"
/*
* Function Prototypes
@@ -126,19 +159,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) { */
@@ -169,23 +224,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/shared/vmmemctl/os.h b/open-vm-tools/modules/shared/vmmemctl/os.h
index e8f1d48b..e02bc67f 100644
--- a/open-vm-tools/modules/shared/vmmemctl/os.h
+++ b/open-vm-tools/modules/shared/vmmemctl/os.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/vmballoon.c b/open-vm-tools/modules/shared/vmmemctl/vmballoon.c
index 70add0d1..0590f99e 100644
--- a/open-vm-tools/modules/shared/vmmemctl/vmballoon.c
+++ b/open-vm-tools/modules/shared/vmmemctl/vmballoon.c
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmmemctl/vmballoon.h b/open-vm-tools/modules/shared/vmmemctl/vmballoon.h
index 295b1b7b..b8193b0a 100644
--- a/open-vm-tools/modules/shared/vmmemctl/vmballoon.h
+++ b/open-vm-tools/modules/shared/vmmemctl/vmballoon.h
@@ -26,9 +26,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of VMware Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission of VMware Inc.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
diff --git a/open-vm-tools/modules/shared/vmxnet/eth_public.h b/open-vm-tools/modules/shared/vmxnet/eth_public.h
index f606c9f8..6a75f245 100644
--- a/open-vm-tools/modules/shared/vmxnet/eth_public.h
+++ b/open-vm-tools/modules/shared/vmxnet/eth_public.h
@@ -47,6 +47,8 @@
#define INCLUDE_ALLOW_USERLEVEL
#include "includeCheck.h"
+#include "vm_basic_defs.h"
+
#define ETH_LADRF_LEN 2
#define ETH_ADDR_LENGTH 6
diff --git a/open-vm-tools/modules/shared/vmxnet/vmnet_def.h b/open-vm-tools/modules/shared/vmxnet/vmnet_def.h
index d9b75c7a..73252067 100644
--- a/open-vm-tools/modules/shared/vmxnet/vmnet_def.h
+++ b/open-vm-tools/modules/shared/vmxnet/vmnet_def.h
@@ -57,57 +57,62 @@
* (eg VLAN support is in the virtual switch) so even vlance
* can use them
*/
-#define VMNET_CAP_SG CONST64U(0x0001) /* Can do scatter-gather transmits. */
-#define VMNET_CAP_IP4_CSUM CONST64U(0x0002) /* Can checksum only TCP/UDP over IPv4. */
-#define VMNET_CAP_HW_CSUM CONST64U(0x0004) /* Can checksum all packets. */
-#define VMNET_CAP_HIGH_DMA CONST64U(0x0008) /* Can DMA to high memory. */
-#define VMNET_CAP_TOE CONST64U(0x0010) /* Supports TCP/IP offload. */
-#define VMNET_CAP_TSO CONST64U(0x0020) /* Supports TCP Segmentation offload */
-#define VMNET_CAP_SW_TSO CONST64U(0x0040) /* Supports SW TCP Segmentation */
-#define VMNET_CAP_VMXNET_APROM CONST64U(0x0080) /* Vmxnet APROM support */
-#define VMNET_CAP_HW_TX_VLAN CONST64U(0x0100) /* Can we do VLAN tagging in HW */
-#define VMNET_CAP_HW_RX_VLAN CONST64U(0x0200) /* Can we do VLAN untagging in HW */
-#define VMNET_CAP_SW_VLAN CONST64U(0x0400) /* Can we do VLAN tagging/untagging in SW */
-#define VMNET_CAP_WAKE_PCKT_RCV CONST64U(0x0800) /* Can wake on network packet recv? */
-#define VMNET_CAP_ENABLE_INT_INLINE CONST64U(0x1000) /* Enable Interrupt Inline */
-#define VMNET_CAP_ENABLE_HEADER_COPY CONST64U(0x2000) /* copy header for vmkernel */
-#define VMNET_CAP_TX_CHAIN CONST64U(0x4000) /* Guest can use multiple tx entries for a pkt */
-#define VMNET_CAP_RX_CHAIN CONST64U(0x8000) /* a pkt can span multiple rx entries */
-#define VMNET_CAP_LPD CONST64U(0x10000) /* large pkt delivery */
-#define VMNET_CAP_BPF CONST64U(0x20000) /* BPF Support in VMXNET Virtual Hardware */
-#define VMNET_CAP_SG_SPAN_PAGES CONST64U(0x40000) /* Can do scatter-gather span multiple pages transmits. */
-#define VMNET_CAP_IP6_CSUM CONST64U(0x80000) /* Can do IPv6 csum offload. */
-#define VMNET_CAP_TSO6 CONST64U(0x100000) /* Can do TSO segmentation offload for IPv6 pkts. */
-#define VMNET_CAP_TSO256k CONST64U(0x200000) /* Can do TSO segmentation offload for pkts up to 256kB. */
-#define VMNET_CAP_UPT CONST64U(0x400000) /* Support UPT */
-#define VMNET_CAP_RDONLY_INETHDRS CONST64U(0x800000) /* Modifies inet headers for TSO/CSUm */
-#define VMNET_CAP_ENCAP CONST64U(0x1000000) /* NPA not used, so redefining for ENCAP support */
-#define VMNET_CAP_DCB CONST64U(0x2000000) /* Support DCB */
-#define VMNET_CAP_OFFLOAD_8OFFSET CONST64U(0x4000000) /* supports 8bit parameterized offsets */
-#define VMNET_CAP_OFFLOAD_16OFFSET CONST64U(0x8000000) /* supports 16bit parameterized offsets */
-#define VMNET_CAP_IP6_CSUM_EXT_HDRS CONST64U(0x10000000) /* support csum of ip6 ext hdrs */
-#define VMNET_CAP_TSO6_EXT_HDRS CONST64U(0x20000000) /* support TSO for ip6 ext hdrs */
-#define VMNET_CAP_SCHED CONST64U(0x40000000) /* compliant with network scheduling */
-#define VMNET_CAP_SRIOV CONST64U(0x80000000) /* Supports SR-IOV */
+#define VMNET_CAP_SG CONST64U(0x0001) /* Can do scatter-gather transmits. */
+#define VMNET_CAP_IP4_CSUM CONST64U(0x0002) /* Can checksum only TCP/UDP over IPv4. */
+#define VMNET_CAP_HW_CSUM CONST64U(0x0004) /* Can checksum all packets. */
+#define VMNET_CAP_HIGH_DMA CONST64U(0x0008) /* Can DMA to high memory. */
+#define VMNET_CAP_TOE CONST64U(0x0010) /* Supports TCP/IP offload. */
+#define VMNET_CAP_TSO CONST64U(0x0020) /* Supports TCP Segmentation offload */
+#define VMNET_CAP_SW_TSO CONST64U(0x0040) /* Supports SW TCP Segmentation */
+#define VMNET_CAP_VMXNET_APROM CONST64U(0x0080) /* Vmxnet APROM support */
+#define VMNET_CAP_HW_TX_VLAN CONST64U(0x0100) /* Can we do VLAN tagging in HW */
+#define VMNET_CAP_HW_RX_VLAN CONST64U(0x0200) /* Can we do VLAN untagging in HW */
+#define VMNET_CAP_SW_VLAN CONST64U(0x0400) /* Can we do VLAN tagging/untagging in SW */
+#define VMNET_CAP_WAKE_PCKT_RCV CONST64U(0x0800) /* Can wake on network packet recv? */
+#define VMNET_CAP_ENABLE_INT_INLINE CONST64U(0x1000) /* Enable Interrupt Inline */
+#define VMNET_CAP_ENABLE_HEADER_COPY CONST64U(0x2000) /* copy header for vmkernel */
+#define VMNET_CAP_TX_CHAIN CONST64U(0x4000) /* Guest can use multiple tx entries for a pkt */
+#define VMNET_CAP_RX_CHAIN CONST64U(0x8000) /* a pkt can span multiple rx entries */
+#define VMNET_CAP_LPD CONST64U(0x10000) /* large pkt delivery */
+#define VMNET_CAP_BPF CONST64U(0x20000) /* BPF Support in VMXNET Virtual Hardware */
+#define VMNET_CAP_SG_SPAN_PAGES CONST64U(0x40000) /* Can do scatter-gather span multiple pages transmits. */
+#define VMNET_CAP_IP6_CSUM CONST64U(0x80000) /* Can do IPv6 csum offload. */
+#define VMNET_CAP_TSO6 CONST64U(0x100000) /* Can do TSO segmentation offload for IPv6 pkts. */
+#define VMNET_CAP_TSO256k CONST64U(0x200000) /* Can do TSO segmentation offload for pkts up to 256kB. */
+#define VMNET_CAP_UPT CONST64U(0x400000) /* Support UPT */
+#define VMNET_CAP_RDONLY_INETHDRS CONST64U(0x800000) /* Modifies inet headers for TSO/CSUm */
+#define VMNET_CAP_ENCAP CONST64U(0x1000000) /* NPA not used, so redefining for ENCAP support */
+#define VMNET_CAP_DCB CONST64U(0x2000000) /* Support DCB */
+#define VMNET_CAP_OFFSET_BASED_OFFLOAD CONST64U(0x4000000) /* Support offload based offload */
+#define VMNET_CAP_GENEVE_OFFLOAD CONST64U(0x8000000) /* Support Geneve encapsulation offload */
+#define VMNET_CAP_IP6_CSUM_EXT_HDRS CONST64U(0x10000000) /* support csum of ip6 ext hdrs */
+#define VMNET_CAP_TSO6_EXT_HDRS CONST64U(0x20000000) /* support TSO for ip6 ext hdrs */
+#define VMNET_CAP_SCHED CONST64U(0x40000000) /* compliant with network scheduling */
+#define VMNET_CAP_SRIOV CONST64U(0x80000000) /* Supports SR-IOV */
-#define VMNET_CAP_SG_TX VMNET_CAP_SG
-#define VMNET_CAP_SG_RX CONST64U(0x200000000) /* Scatter-gather receive capability */
-#define VMNET_CAP_PRIV_STATS CONST64U(0x400000000) /* Driver supports accessing private stats */
-#define VMNET_CAP_LINK_STATUS_SET CONST64U(0x800000000) /* Driver supports changing link status */
-#define VMNET_CAP_MAC_ADDR_SET CONST64U(0x1000000000) /* Driver supports changing the interface MAC address */
-#define VMNET_CAP_COALESCE_PARAMS CONST64U(0x2000000000) /* Driver supports changing interrupt coalescing parameters */
-#define VMNET_CAP_VLAN_FILTER CONST64U(0x4000000000) /* VLAN Filtering capability */
-#define VMNET_CAP_WAKE_ON_LAN CONST64U(0x8000000000) /* Wake-On-LAN capability */
-#define VMNET_CAP_NETWORK_DUMP CONST64U(0x10000000000) /* Network core dumping capability */
-#define VMNET_CAP_MULTI_QUEUE CONST64U(0x20000000000) /* Multiple queue capability */
-#define VMNET_CAP_EEPROM CONST64U(0x40000000000) /* EEPROM dump capability */
-#define VMNET_CAP_REGDUMP CONST64U(0x80000000000) /* Register dump capability */
-#define VMNET_CAP_SELF_TEST CONST64U(0x100000000000) /* Self-test capability */
-#define VMNET_CAP_PAUSE_PARAMS CONST64U(0x200000000000) /* Pause frame parameter adjusting */
-#define VMNET_CAP_RESTART_NEG CONST64U(0x400000000000) /* Ability to restart negotiation of link speed/duplexity */
-#define VMNET_CAP_LRO CONST64U(0x800000000000) /* Hardware supported LRO */
-#define VMNET_CAP_OFFLOAD_ALIGN_ANY CONST64U(0x1000000000000) /* Nic requires no header alignment */
-#define VMNET_CAP_GENERIC_OFFLOAD CONST64U(0x2000000000000) /* Generic hardware offloading (eg. vxlan encap offload and offset based offload) */
-#define VMNET_CAP_LEGACY CONST64U(0x8000000000000000) /* Uplink is compatible with vmklinux drivers */
+#define VMNET_CAP_SG_TX VMNET_CAP_SG
+#define VMNET_CAP_SG_RX CONST64U(0x200000000) /* Scatter-gather receive capability */
+#define VMNET_CAP_PRIV_STATS CONST64U(0x400000000) /* Driver supports accessing private stats */
+#define VMNET_CAP_LINK_STATUS_SET CONST64U(0x800000000) /* Driver supports changing link status */
+#define VMNET_CAP_MAC_ADDR_SET CONST64U(0x1000000000) /* Driver supports changing the interface MAC address */
+#define VMNET_CAP_COALESCE_PARAMS CONST64U(0x2000000000) /* Driver supports changing interrupt coalescing parameters */
+#define VMNET_CAP_VLAN_FILTER CONST64U(0x4000000000) /* VLAN Filtering capability */
+#define VMNET_CAP_WAKE_ON_LAN CONST64U(0x8000000000) /* Wake-On-LAN capability */
+#define VMNET_CAP_NETWORK_DUMP CONST64U(0x10000000000) /* Network core dumping capability */
+#define VMNET_CAP_MULTI_QUEUE CONST64U(0x20000000000) /* Multiple queue capability */
+#define VMNET_CAP_EEPROM CONST64U(0x40000000000) /* EEPROM dump capability */
+#define VMNET_CAP_REGDUMP CONST64U(0x80000000000) /* Register dump capability */
+#define VMNET_CAP_SELF_TEST CONST64U(0x100000000000) /* Self-test capability */
+#define VMNET_CAP_PAUSE_PARAMS CONST64U(0x200000000000) /* Pause frame parameter adjusting */
+#define VMNET_CAP_RESTART_NEG CONST64U(0x400000000000) /* Ability to restart negotiation of link speed/duplexity */
+#define VMNET_CAP_LRO CONST64U(0x800000000000) /* Hardware supported LRO */
+#define VMNET_CAP_OFFLOAD_ALIGN_ANY CONST64U(0x1000000000000) /* Nic requires no header alignment */
+#define VMNET_CAP_GENERIC_OFFLOAD CONST64U(0x2000000000000) /* Generic hardware offloading (eg. vxlan encap offload and offset based offload) */
+#define VMNET_CAP_CABLE_TYPE CONST64U(0x4000000000000) /* Uplink supports getting and setting cable type. */
+#define VMNET_CAP_PHY_ADDRESS CONST64U(0x8000000000000) /* Uplink supports getting and setting PHY address. */
+#define VMNET_CAP_TRANSCEIVER_TYPE CONST64U(0x10000000000000) /* Uplink supports getting and setting transceiver type. */
+#define VMNET_CAP_MESSAGE_LEVEL CONST64U(0x20000000000000) /* Uplink supports getting and setting message level. */
+#define VMNET_CAP_RING_PARAMS CONST64U(0x40000000000000) /* Support getting/setting RX/TX ring size parameters */
+#define VMNET_CAP_LEGACY CONST64U(0x8000000000000000) /* Uplink is compatible with vmklinux drivers */
#endif // _VMNET_DEF_H_
diff --git a/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h b/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h
index eb9af751..b79ecdb4 100644
--- a/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h
+++ b/open-vm-tools/modules/shared/vmxnet/vmxnet3_defs.h
@@ -347,6 +347,18 @@ struct Vmxnet3_RxCompDesc {
#include "vmware_pack_end.h"
Vmxnet3_RxCompDesc;
+typedef
+#include "vmware_pack_begin.h"
+struct Vmxnet3_RxCompDescExt {
+ __le32 dword1;
+ uint8 segCnt; /* Number of aggregated packets */
+ uint8 dupAckCnt; /* Number of duplicate Acks */
+ __le16 tsDelta; /* TCP timestamp difference */
+ __le32 dword2[2];
+}
+#include "vmware_pack_end.h"
+Vmxnet3_RxCompDescExt;
+
/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
#define VMXNET3_RCD_TUC_SHIFT 16
#define VMXNET3_RCD_IPC_SHIFT 19
@@ -367,17 +379,20 @@ Vmxnet3_RxCompDesc;
/* a union for accessing all cmd/completion descriptors */
typedef union Vmxnet3_GenericDesc {
- __le64 qword[2];
- __le32 dword[4];
- __le16 word[8];
- Vmxnet3_TxDesc txd;
- Vmxnet3_RxDesc rxd;
- Vmxnet3_TxCompDesc tcd;
- Vmxnet3_RxCompDesc rcd;
+ __le64 qword[2];
+ __le32 dword[4];
+ __le16 word[8];
+ Vmxnet3_TxDesc txd;
+ Vmxnet3_RxDesc rxd;
+ Vmxnet3_TxCompDesc tcd;
+ Vmxnet3_RxCompDesc rcd;
+ Vmxnet3_RxCompDescExt rcdExt;
} Vmxnet3_GenericDesc;
#define VMXNET3_INIT_GEN 1
+#define VMXNET3_INVALID_QUEUEID -1
+
/* Max size of a single tx buffer */
#define VMXNET3_MAX_TX_BUF_SIZE (1 << 14)
@@ -405,6 +420,7 @@ typedef union Vmxnet3_GenericDesc {
#define VMXNET3_TX_RING_MAX_SIZE 4096
#define VMXNET3_TC_RING_MAX_SIZE 4096
#define VMXNET3_RX_RING_MAX_SIZE 4096
+#define VMXNET3_RX_RING2_MAX_SIZE 2048
#define VMXNET3_RC_RING_MAX_SIZE 8192
/* a list of reasons for queue stop */
diff --git a/open-vm-tools/modules/solaris/vmhgfs/Makefile b/open-vm-tools/modules/solaris/vmhgfs/Makefile
index ef086918..1979d435 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/Makefile
+++ b/open-vm-tools/modules/solaris/vmhgfs/Makefile
@@ -1,6 +1,6 @@
#!/usr/bin/make -f
##########################################################
-# Copyright (C) 2008 VMware, Inc. All rights reserved.
+# Copyright (C) 2008-2015 VMware, Inc. All rights reserved.
#
# The contents of this file are subject to the terms of the Common
# Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/debug.c b/open-vm-tools/modules/solaris/vmhgfs/debug.c
index b82476fd..25039e08 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/debug.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/debug.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/debug.h b/open-vm-tools/modules/solaris/vmhgfs/debug.h
index 657eff0f..44096ae4 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/debug.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/debug.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/filesystem.c b/open-vm-tools/modules/solaris/vmhgfs/filesystem.c
index 7f4d9994..187be2c9 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/filesystem.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/filesystem.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/filesystem.h b/open-vm-tools/modules/solaris/vmhgfs/filesystem.h
index 3773eb6c..709fc218 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/filesystem.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/filesystem.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.c b/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.c
index 8d302abd..4b52814b 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
@@ -25,6 +25,7 @@
#include "request.h"
#include "hgfsBdGlue.h"
#include "hgfsBd.h"
+#include "vm_basic_defs.h"
#include "vm_assert.h"
#include "debug.h"
diff --git a/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.h b/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.h
index b39bc504..eb27ec21 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/hgfsBdGlue.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/hgfsSolaris.h b/open-vm-tools/modules/solaris/vmhgfs/hgfsSolaris.h
index 5a1f8871..506d9a23 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/hgfsSolaris.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/hgfsSolaris.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
@@ -62,6 +62,7 @@
#ifdef _KERNEL
#include "dbllnklst.h"
+#include "vm_basic_defs.h"
#include "vm_assert.h"
#endif /* _KERNEL */
diff --git a/open-vm-tools/modules/solaris/vmhgfs/hgfsState.c b/open-vm-tools/modules/solaris/vmhgfs/hgfsState.c
index 56a00471..77c2ff0b 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/hgfsState.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/hgfsState.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
@@ -32,8 +32,9 @@
#include "hgfsState.h"
#include "debug.h"
-#include "vm_assert.h"
#include "vm_basic_types.h"
+#include "vm_basic_defs.h"
+#include "vm_assert.h"
#include "sha1.h" /* SHA-1 for Node ID calculation */
diff --git a/open-vm-tools/modules/solaris/vmhgfs/hgfsState.h b/open-vm-tools/modules/solaris/vmhgfs/hgfsState.h
index bfaa4423..9fc349a4 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/hgfsState.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/hgfsState.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/kernelStubs.h b/open-vm-tools/modules/solaris/vmhgfs/kernelStubs.h
index f6e83166..1f8fef07 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/kernelStubs.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/kernelStubs.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2006 VMware, Inc. All rights reserved.
+ * Copyright (C) 2006-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
@@ -25,6 +25,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"
@@ -34,12 +49,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
@@ -63,6 +98,7 @@
# include <sys/types.h>
# include <sys/varargs.h>
#endif
+#include "kernelStubsSal.h"
/*
* Function Prototypes
@@ -82,19 +118,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) { */
@@ -125,23 +183,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/solaris/vmhgfs/kernelStubsSolaris.c b/open-vm-tools/modules/solaris/vmhgfs/kernelStubsSolaris.c
index 75ae9b9f..947ff8e2 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/kernelStubsSolaris.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/kernelStubsSolaris.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/module.c b/open-vm-tools/modules/solaris/vmhgfs/module.c
index 62cef6b6..07bd7570 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/module.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/module.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/module.h b/open-vm-tools/modules/solaris/vmhgfs/module.h
index 1dab9d6d..164c2bf6 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/module.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/module.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/request.c b/open-vm-tools/modules/solaris/vmhgfs/request.c
index 644a437d..293e71be 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/request.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/request.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/request.h b/open-vm-tools/modules/solaris/vmhgfs/request.h
index 6d081bc7..d735e680 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/request.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/request.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/vnode.c b/open-vm-tools/modules/solaris/vmhgfs/vnode.c
index 88548c11..b746403a 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/vnode.c
+++ b/open-vm-tools/modules/solaris/vmhgfs/vnode.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmhgfs/vnode.h b/open-vm-tools/modules/solaris/vmhgfs/vnode.h
index e1a1551a..a9265ac1 100644
--- a/open-vm-tools/modules/solaris/vmhgfs/vnode.h
+++ b/open-vm-tools/modules/solaris/vmhgfs/vnode.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2004 VMware, Inc. All rights reserved.
+ * Copyright (C) 2004-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmmemctl/kernelStubsSolaris.c b/open-vm-tools/modules/solaris/vmmemctl/kernelStubsSolaris.c
index 75ae9b9f..947ff8e2 100644
--- a/open-vm-tools/modules/solaris/vmmemctl/kernelStubsSolaris.c
+++ b/open-vm-tools/modules/solaris/vmmemctl/kernelStubsSolaris.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2009 VMware, Inc. All rights reserved.
+ * Copyright (C) 2009-2015 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
diff --git a/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_main.c b/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_main.c
index 8b9a07f2..a2675e80 100644
--- a/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_main.c
+++ b/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_main.c
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2014 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
@@ -36,9 +36,30 @@ static int vmxnet3_multicst(void *, boolean_t, const uint8_t *);
static int vmxnet3_unicst(void *, const uint8_t *);
static boolean_t vmxnet3_getcapab(void *, mac_capab_t, void *);
+#ifdef SOL11
+static int vmxnet3_get_prop(void *,
+ const char *,
+ mac_prop_id_t,
+ uint_t,
+ void *);
+static int vmxnet3_set_prop(void *,
+ const char *,
+ mac_prop_id_t,
+ uint_t,
+ const void *);
+static void vmxnet3_prop_info(void *,
+ const char *,
+ mac_prop_id_t,
+ mac_prop_info_handle_t);
+#endif
+
/* MAC callbacks */
static mac_callbacks_t vmxnet3_mac_callbacks = {
+#ifdef SOL11
+ .mc_callbacks = MC_GETCAPAB | MC_IOCTL | MC_GETPROP | MC_SETPROP | MC_PROPINFO,
+#else
.mc_callbacks = MC_GETCAPAB | MC_IOCTL,
+#endif
.mc_getstat = vmxnet3_getstat,
.mc_start = vmxnet3_start,
.mc_stop = vmxnet3_stop,
@@ -46,6 +67,11 @@ static mac_callbacks_t vmxnet3_mac_callbacks = {
.mc_multicst = vmxnet3_multicst,
.mc_unicst = vmxnet3_unicst,
.mc_tx = vmxnet3_tx,
+#ifdef SOL11
+ .mc_getprop = vmxnet3_get_prop,
+ .mc_setprop = vmxnet3_set_prop,
+ .mc_propinfo = vmxnet3_prop_info,
+#endif
#ifndef OPEN_SOLARIS
#ifndef SOL11
.mc_resources = NULL,
@@ -977,12 +1003,15 @@ vmxnet3_change_mtu(vmxnet3_softc_t *dp, uint32_t new_mtu)
VMXNET3_WARN(dp, "New MTU not in valid range [%d, %d].\n",
VMXNET3_MIN_MTU, VMXNET3_MAX_MTU);
return EINVAL;
- } else if (new_mtu > ETHERMTU && !dp->allow_jumbo) {
+ }
+#if defined(SOL9) || defined (SOL10) || defined (OPEN_SOLARIS)
+ if (new_mtu > ETHERMTU && !dp->allow_jumbo) {
VMXNET3_WARN(dp, "MTU cannot be greater than %d because accept-jumbo "
"is not enabled.\n", ETHERMTU);
return EINVAL;
}
+#endif
if (dp->devEnabled) {
do_reset = 1;
@@ -991,7 +1020,8 @@ vmxnet3_change_mtu(vmxnet3_softc_t *dp, uint32_t new_mtu)
}
dp->cur_mtu = new_mtu;
-#if defined (SOL11) || defined (OPEN_SOLARIS)
+
+#ifdef OPEN_SOLARIS
mac_maxsdu_update(dp->mac, new_mtu);
#endif
@@ -1159,6 +1189,80 @@ vmxnet3_getcapab(void *data, mac_capab_t capab, void *arg)
return ret;
}
+#ifdef SOL11
+static int
+vmxnet3_get_prop(void *data,
+ const char *prop_name,
+ mac_prop_id_t prop_id,
+ uint_t prop_val_size,
+ void *prop_val)
+{
+ vmxnet3_softc_t *dp = data;
+ int ret = 0;
+
+ switch (prop_id) {
+ case MAC_PROP_MTU: {
+ ASSERT(prop_val_size >= sizeof (uint32_t));
+ bcopy(&dp->cur_mtu, prop_val, sizeof (uint32_t));
+ break;
+ }
+ default: {
+ VMXNET3_WARN(dp, "vmxnet3_get_prop property %d not supported", prop_id);
+ ret = ENOTSUP;
+ }
+ }
+ return (0);
+}
+
+
+static int
+vmxnet3_set_prop(void *data,
+ const char *prop_name,
+ mac_prop_id_t prop_id,
+ uint_t prop_val_size,
+ const void *prop_val)
+{
+ vmxnet3_softc_t *dp = data;
+ int ret;
+
+ switch (prop_id) {
+ case MAC_PROP_MTU: {
+ uint32_t new_mtu;
+ ASSERT(prop_val_size >= sizeof (uint32_t));
+ bcopy(prop_val, &new_mtu, sizeof (new_mtu));
+ ret = vmxnet3_change_mtu(dp, new_mtu);
+ break;
+ }
+ default: {
+ VMXNET3_WARN(dp, "vmxnet3_set_prop property %d not supported", prop_id);
+ ret = ENOTSUP;
+ }
+ }
+
+ return ret;
+}
+
+
+static void
+vmxnet3_prop_info(void *data,
+ const char *prop_name,
+ mac_prop_id_t prop_id,
+ mac_prop_info_handle_t prop_handle)
+{
+ vmxnet3_softc_t *dp = data;
+
+ switch (prop_id) {
+ case MAC_PROP_MTU: {
+ mac_prop_info_set_range_uint32(prop_handle, VMXNET3_MIN_MTU, VMXNET3_MAX_MTU);
+ break;
+ }
+ default: {
+ VMXNET3_WARN(dp, "vmxnet3_prop_info: property %d not supported", prop_id);
+ }
+ }
+}
+#endif
+
/*
*---------------------------------------------------------------------------
@@ -1636,7 +1740,7 @@ vmxnet3_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
* Structures used by the Solaris module loader
*/
-#define VMXNET3_IDENT "VMware EtherAdapter v3 b" BUILD_NUMBER_NUMERIC_STRING
+#define VMXNET3_IDENT "VMware EtherAdapter v3 " VMXNET3_DRIVER_VERSION_STRING
COMPAT_DDI_DEFINE_STREAM_OPS(vmxnet3_dev_ops,
nulldev,
diff --git a/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_solaris.h b/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_solaris.h
index bf812b3a..368b96d7 100644
--- a/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_solaris.h
+++ b/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_solaris.h
@@ -1,5 +1,5 @@
/*********************************************************
- * Copyright (C) 2007 VMware, Inc. All rights reserved.
+ * Copyright (C) 2007-2014 VMware, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common
* Development and Distribution License (the "License") version 1.0
@@ -178,6 +178,7 @@ void vmxnet3_rxqueue_fini(vmxnet3_softc_t *dp, vmxnet3_rxqueue_t *rxq);
extern ddi_device_acc_attr_t vmxnet3_dev_attr;
#define VMXNET3_MODNAME "vmxnet3s"
+#define VMXNET3_DRIVER_VERSION_STRING "1.1.0.0"
/* Logging stuff */
#define VMXNET3_LOG(Level, Device, Format, Args...) \
diff --git a/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_tx.c b/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_tx.c
index 586c4ec6..9b2af6a0 100644
--- a/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_tx.c
+++ b/open-vm-tools/modules/solaris/vmxnet3/vmxnet3_tx.c
@@ -103,14 +103,16 @@ vmxnet3_tx_prepare_offload(vmxnet3_softc_t *dp,
mblk_t *mp)
{
int ret = 0;
- uint32_t start, stuff, value, flags;
+ uint32_t start, stuff, value, flags, lso_flag, mss;
ol->om = VMXNET3_OM_NONE;
ol->hlen = 0;
ol->msscof = 0;
hcksum_retrieve(mp, NULL, NULL, &start, &stuff, NULL, &value, &flags);
- if (flags) {
+ mac_lso_get(mp, &mss, &lso_flag);
+
+ if (flags || lso_flag) {
struct ether_vlan_header *eth = (void *) mp->b_rptr;
uint8_t ethLen;
@@ -123,12 +125,7 @@ vmxnet3_tx_prepare_offload(vmxnet3_softc_t *dp,
VMXNET3_DEBUG(dp, 4, "flags=0x%x, ethLen=%u, start=%u, stuff=%u, value=%u\n",
flags, ethLen, start, stuff, value);
- if (flags & HCK_PARTIALCKSUM) {
- ol->om = VMXNET3_OM_CSUM;
- ol->hlen = start + ethLen;
- ol->msscof = stuff + ethLen;
- }
- if (flags & HW_LSO) {
+ if (lso_flag & HW_LSO) {
mblk_t *mblk = mp;
uint8_t *ip, *tcp;
uint8_t ipLen, tcpLen;
@@ -157,13 +154,17 @@ vmxnet3_tx_prepare_offload(vmxnet3_softc_t *dp,
ol->om = VMXNET3_OM_TSO;
ol->hlen = ethLen + ipLen + tcpLen;
- /* OpenSolaris fills 'value' with the MSS but Solaris doesn't. */
- ol->msscof = DB_LSOMSS(mp);
+ ol->msscof = mss;
if (mblk != mp) {
ret = ol->hlen;
}
+ } else if (flags & HCK_PARTIALCKSUM) {
+ ol->om = VMXNET3_OM_CSUM;
+ ol->hlen = start + ethLen;
+ ol->msscof = stuff + ethLen;
}
+
}
return ret;