Differential D25496 Diff 73810 emulators/virtualbox-ose/files/patch-src_VBox_Additions_freebsd_vboxvfs_vboxvfs__vfsops.c
Changeset View
Changeset View
Standalone View
Standalone View
emulators/virtualbox-ose/files/patch-src_VBox_Additions_freebsd_vboxvfs_vboxvfs__vfsops.c
--- src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c.orig 2017-04-28 16:59:22.000000000 +0200 | --- src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c.orig 2020-05-13 19:37:06 UTC | ||||
+++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c 2017-07-12 19:24:26.109029000 +0200 | +++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vfsops.c | ||||
@@ -1,10 +1,5 @@ | @@ -1,8 +1,3 @@ | ||||
-/* $Id: vboxvfs_vfsops.c $ */ | -/* $Id: vboxvfs_vfsops.c $ */ | ||||
-/** @file | -/** @file | ||||
- * Description. | - * Description. | ||||
- */ | - */ | ||||
- | - | ||||
/* | /* | ||||
* Copyright (C) 2008-2017 Oracle Corporation | * Copyright (C) 2008-2017 Oracle Corporation | ||||
* | * | ||||
* This file is part of VirtualBox Open Source Edition (OSE), as | |||||
* available from http://www.virtualbox.org. This file is free software; | |||||
@@ -14,245 +9,479 @@ | @@ -14,245 +9,479 @@ | ||||
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the | ||||
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. | ||||
*/ | */ | ||||
- | - | ||||
-#include "vboxvfs.h" | -#include "vboxvfs.h" | ||||
+#include <sys/types.h> | +#include <sys/types.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
Show All 11 Lines | |||||
+#include <sys/fcntl.h> | +#include <sys/fcntl.h> | ||||
+#include <sys/priv.h> | +#include <sys/priv.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
+#include <sys/sbuf.h> | +#include <sys/sbuf.h> | ||||
-#include <iprt/mem.h> | -#include <iprt/mem.h> | ||||
- | |||||
-#define VFSMP2SFGLOBINFO(mp) ((struct sf_glob_info *)mp->mnt_data) | |||||
- | |||||
-static int vboxvfs_version = VBOXVFS_VERSION; | |||||
+#include <geom/geom.h> | +#include <geom/geom.h> | ||||
+#include <geom/geom_vfs.h> | +#include <geom/geom_vfs.h> | ||||
+#include "vboxvfs.h" | |||||
+ | |||||
#define VFSMP2SFGLOBINFO(mp) ((struct sf_glob_info *)mp->mnt_data) | |||||
-static int vboxvfs_version = VBOXVFS_VERSION; | |||||
+#ifdef MALLOC_DECLARE | |||||
+MALLOC_DEFINE(M_VBOXVFS, "vboxvfs", "VBOX VFS"); | |||||
+#endif | |||||
-SYSCTL_NODE(_vfs, OID_AUTO, vboxvfs, CTLFLAG_RW, 0, "VirtualBox shared filesystem"); | -SYSCTL_NODE(_vfs, OID_AUTO, vboxvfs, CTLFLAG_RW, 0, "VirtualBox shared filesystem"); | ||||
-SYSCTL_INT(_vfs_vboxvfs, OID_AUTO, version, CTLFLAG_RD, &vboxvfs_version, 0, ""); | -SYSCTL_INT(_vfs_vboxvfs, OID_AUTO, version, CTLFLAG_RD, &vboxvfs_version, 0, ""); | ||||
+#include "vboxvfs.h" | +static sfp_connection_t *sfprov = NULL; | ||||
-/* global connection to the host service. */ | -/* global connection to the host service. */ | ||||
-static VBGLSFCLIENT g_vboxSFClient; | -static VBGLSFCLIENT g_vboxSFClient; | ||||
+#define VFSMP2SFGLOBINFO(mp) ((struct sf_glob_info *)mp->mnt_data) | +static int vboxfs_version = VBOXVFS_VERSION; | ||||
+u_int vboxvfs_debug = 1; | |||||
-static vfs_init_t vboxvfs_init; | -static vfs_init_t vboxvfs_init; | ||||
-static vfs_uninit_t vboxvfs_uninit; | -static vfs_uninit_t vboxvfs_uninit; | ||||
-static vfs_cmount_t vboxvfs_cmount; | -static vfs_cmount_t vboxvfs_cmount; | ||||
-static vfs_mount_t vboxvfs_mount; | -static vfs_mount_t vboxvfs_mount; | ||||
-static vfs_root_t vboxvfs_root; | -static vfs_root_t vboxvfs_root; | ||||
-static vfs_quotactl_t vboxvfs_quotactl; | -static vfs_quotactl_t vboxvfs_quotactl; | ||||
-static vfs_statfs_t vboxvfs_statfs; | -static vfs_statfs_t vboxvfs_statfs; | ||||
-static vfs_unmount_t vboxvfs_unmount; | -static vfs_unmount_t vboxvfs_unmount; | ||||
- | +SYSCTL_NODE(_vfs, OID_AUTO, vboxfs, CTLFLAG_RW, 0, "VirtualBox shared filesystem"); | ||||
+SYSCTL_INT(_vfs_vboxfs, OID_AUTO, version, CTLFLAG_RD, &vboxfs_version, 0, ""); | |||||
+SYSCTL_UINT(_vfs_vboxfs, OID_AUTO, debug, CTLFLAG_RW, &vboxvfs_debug, 0, "Debug level"); | |||||
-static struct vfsops vboxvfs_vfsops = { | -static struct vfsops vboxvfs_vfsops = { | ||||
- .vfs_init = vboxvfs_init, | - .vfs_init = vboxvfs_init, | ||||
- .vfs_cmount = vboxvfs_cmount, | - .vfs_cmount = vboxvfs_cmount, | ||||
- .vfs_mount = vboxvfs_mount, | - .vfs_mount = vboxvfs_mount, | ||||
- .vfs_quotactl = vboxvfs_quotactl, | - .vfs_quotactl = vboxvfs_quotactl, | ||||
- .vfs_root = vboxvfs_root, | - .vfs_root = vboxvfs_root, | ||||
- .vfs_statfs = vboxvfs_statfs, | - .vfs_statfs = vboxvfs_statfs, | ||||
- .vfs_sync = vfs_stdsync, | - .vfs_sync = vfs_stdsync, | ||||
- .vfs_uninit = vboxvfs_uninit, | - .vfs_uninit = vboxvfs_uninit, | ||||
- .vfs_unmount = vboxvfs_unmount, | - .vfs_unmount = vboxvfs_unmount, | ||||
+#ifdef MALLOC_DECLARE | |||||
+MALLOC_DEFINE(M_VBOXVFS, "vboxvfs", "VBOX VFS"); | |||||
+#endif | |||||
+ | |||||
+static sfp_connection_t *sfprov = NULL; | |||||
+ | |||||
+static int vboxfs_version = VBOXVFS_VERSION; | |||||
+u_int vboxvfs_debug = 1; | |||||
+ | |||||
+SYSCTL_NODE(_vfs, OID_AUTO, vboxfs, CTLFLAG_RW, 0, "VirtualBox shared filesystem"); | |||||
+SYSCTL_INT(_vfs_vboxfs, OID_AUTO, version, CTLFLAG_RD, &vboxfs_version, 0, ""); | |||||
+SYSCTL_UINT(_vfs_vboxfs, OID_AUTO, debug, CTLFLAG_RW, &vboxvfs_debug, 0, "Debug level"); | |||||
+ | |||||
+static vfs_init_t vboxfs_init; | +static vfs_init_t vboxfs_init; | ||||
+static vfs_uninit_t vboxfs_uninit; | +static vfs_uninit_t vboxfs_uninit; | ||||
+static vfs_cmount_t vboxfs_cmount; | +static vfs_cmount_t vboxfs_cmount; | ||||
+static vfs_mount_t vboxfs_mount; | +static vfs_mount_t vboxfs_mount; | ||||
+static vfs_root_t vboxfs_root; | +static vfs_root_t vboxfs_root; | ||||
+static vfs_quotactl_t vboxfs_quotactl; | +static vfs_quotactl_t vboxfs_quotactl; | ||||
+static vfs_statfs_t vboxfs_statfs; | +static vfs_statfs_t vboxfs_statfs; | ||||
+static vfs_unmount_t vboxfs_unmount; | +static vfs_unmount_t vboxfs_unmount; | ||||
Show All 40 Lines | |||||
+ */ | + */ | ||||
+int | +int | ||||
+vboxfs_alloc_node(struct mount *mp, struct vboxfs_mnt *vsfmp, const char *fullpath, | +vboxfs_alloc_node(struct mount *mp, struct vboxfs_mnt *vsfmp, const char *fullpath, | ||||
+ enum vtype type, uid_t uid, gid_t gid, mode_t mode, struct vboxfs_node *parent, | + enum vtype type, uid_t uid, gid_t gid, mode_t mode, struct vboxfs_node *parent, | ||||
+ struct vboxfs_node **node) | + struct vboxfs_node **node) | ||||
{ | { | ||||
- struct vboxvfs_mount_info args; | - struct vboxvfs_mount_info args; | ||||
- int rc = 0; | - int rc = 0; | ||||
- | |||||
- printf("%s: Enter\n", __FUNCTION__); | |||||
- | |||||
- rc = copyin(data, &args, sizeof(struct vboxvfs_mount_info)); | |||||
- if (rc) | |||||
- return rc; | |||||
+ struct vboxfs_node *nnode; | + struct vboxfs_node *nnode; | ||||
- ma = mount_argf(ma, "uid", "%d", args.uid); | - printf("%s: Enter\n", __FUNCTION__); | ||||
- ma = mount_argf(ma, "gid", "%d", args.gid); | |||||
- ma = mount_arg(ma, "from", args.name, -1); | |||||
+ if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) { | + if ((mp->mnt_kern_flag & MNTK_UNMOUNT) != 0) { | ||||
+ /* | + /* | ||||
+ * When a new tmpfs node is created for fully | + * When a new tmpfs node is created for fully | ||||
+ * constructed mount point, there must be a parent | + * constructed mount point, there must be a parent | ||||
+ * node, which vnode is locked exclusively. As | + * node, which vnode is locked exclusively. As | ||||
+ * consequence, if the unmount is executing in | + * consequence, if the unmount is executing in | ||||
+ * parallel, vflush() cannot reclaim the parent vnode. | + * parallel, vflush() cannot reclaim the parent vnode. | ||||
+ * Due to this, the check for MNTK_UNMOUNT flag is not | + * Due to this, the check for MNTK_UNMOUNT flag is not | ||||
+ * racy: if we did not see MNTK_UNMOUNT flag, then tmp | + * racy: if we did not see MNTK_UNMOUNT flag, then tmp | ||||
+ * cannot be destroyed until node construction is | + * cannot be destroyed until node construction is | ||||
+ * finished and the parent vnode unlocked. | + * finished and the parent vnode unlocked. | ||||
+ * | + * | ||||
+ * Tmpfs does not need to instantiate new nodes during | + * Tmpfs does not need to instantiate new nodes during | ||||
+ * unmount. | + * unmount. | ||||
+ */ | + */ | ||||
+ return (EBUSY); | + return (EBUSY); | ||||
+ } | + } | ||||
+ | |||||
- rc = copyin(data, &args, sizeof(struct vboxvfs_mount_info)); | |||||
- if (rc) | |||||
- return rc; | |||||
+ nnode = (struct vboxfs_node *)uma_zalloc_arg( | + nnode = (struct vboxfs_node *)uma_zalloc_arg( | ||||
+ vsfmp->sf_node_pool, vsfmp, M_WAITOK); | + vsfmp->sf_node_pool, vsfmp, M_WAITOK); | ||||
+ | |||||
- ma = mount_argf(ma, "uid", "%d", args.uid); | |||||
- ma = mount_argf(ma, "gid", "%d", args.gid); | |||||
- ma = mount_arg(ma, "from", args.name, -1); | |||||
+ /* Generic initialization. */ | + /* Generic initialization. */ | ||||
+ nnode->sf_type = type; | + nnode->sf_type = type; | ||||
+ nnode->sf_ino = vsfmp->sf_ino++; | + nnode->sf_ino = vsfmp->sf_ino++; | ||||
+ nnode->sf_path = strdup(fullpath, M_VBOXVFS); | + nnode->sf_path = strdup(fullpath, M_VBOXVFS); | ||||
+ nnode->sf_parent = parent; | + nnode->sf_parent = parent; | ||||
+ nnode->vboxfsmp = vsfmp; | + nnode->vboxfsmp = vsfmp; | ||||
+ | |||||
- rc = kernel_mount(ma, flags); | |||||
+ /* Type-specific initialization. */ | + /* Type-specific initialization. */ | ||||
+ switch (nnode->sf_type) { | + switch (nnode->sf_type) { | ||||
+ case VBLK: | + case VBLK: | ||||
+ case VCHR: | + case VCHR: | ||||
+ case VDIR: | + case VDIR: | ||||
+ case VFIFO: | + case VFIFO: | ||||
+ case VSOCK: | + case VSOCK: | ||||
+ case VLNK: | + case VLNK: | ||||
+ case VREG: | + case VREG: | ||||
+ break; | + break; | ||||
+ | |||||
- printf("%s: Leave rc=%d\n", __FUNCTION__, rc); | |||||
+ default: | + default: | ||||
+ panic("vboxfs_alloc_node: type %p %d", nnode, (int)nnode->sf_type); | + panic("vboxfs_alloc_node: type %p %d", nnode, (int)nnode->sf_type); | ||||
+ } | + } | ||||
- rc = kernel_mount(ma, flags); | |||||
- | |||||
- printf("%s: Leave rc=%d\n", __FUNCTION__, rc); | |||||
- | |||||
- return rc; | - return rc; | ||||
+ *node = nnode; | + *node = nnode; | ||||
+ return 0; | + return 0; | ||||
} | } | ||||
-static const char *vboxvfs_opts[] = { | -static const char *vboxvfs_opts[] = { | ||||
- "uid", "gid", "from", "fstype", "fspath", "errmsg", NULL | - "uid", "gid", "from", "fstype", "fspath", "errmsg", NULL | ||||
-}; | -}; | ||||
- | - | ||||
-static int vboxvfs_mount(struct mount *mp, struct thread *td) | -static int vboxvfs_mount(struct mount *mp, struct thread *td) | ||||
+void | +void | ||||
+vboxfs_free_node(struct vboxfs_mnt *vboxfs, struct vboxfs_node *node) | +vboxfs_free_node(struct vboxfs_mnt *vboxfs, struct vboxfs_node *node) | ||||
{ | { | ||||
- int rc; | - int rc; | ||||
- char *pszShare; | - char *pszShare; | ||||
- int cbShare, cbOption; | - int cbShare, cbOption; | ||||
- int uid = 0, gid = 0; | - int uid = 0, gid = 0; | ||||
- struct sf_glob_info *pShFlGlobalInfo; | - struct sf_glob_info *pShFlGlobalInfo; | ||||
- SHFLSTRING *pShFlShareName = NULL; | - SHFLSTRING *pShFlShareName = NULL; | ||||
- int cbShFlShareName; | - int cbShFlShareName; | ||||
- | |||||
- printf("%s: Enter\n", __FUNCTION__); | |||||
- | |||||
- if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS)) | |||||
- return EOPNOTSUPP; | |||||
- | |||||
- if (vfs_filteropt(mp->mnt_optnew, vboxvfs_opts)) | |||||
- { | |||||
- vfs_mount_error(mp, "%s", "Invalid option"); | |||||
- return EINVAL; | |||||
- } | |||||
- | |||||
- rc = vfs_getopt(mp->mnt_optnew, "from", (void **)&pszShare, &cbShare); | |||||
- if (rc || pszShare[cbShare-1] != '\0' || cbShare > 0xfffe) | |||||
- return EINVAL; | |||||
- | |||||
- rc = vfs_getopt(mp->mnt_optnew, "gid", (void **)&gid, &cbOption); | |||||
- if ((rc != ENOENT) && (rc || cbOption != sizeof(gid))) | |||||
- return EINVAL; | |||||
- | |||||
- rc = vfs_getopt(mp->mnt_optnew, "uid", (void **)&uid, &cbOption); | |||||
- if ((rc != ENOENT) && (rc || cbOption != sizeof(uid))) | |||||
- return EINVAL; | |||||
- pShFlGlobalInfo = RTMemAllocZ(sizeof(struct sf_glob_info)); | - printf("%s: Enter\n", __FUNCTION__); | ||||
- if (!pShFlGlobalInfo) | |||||
- return ENOMEM; | |||||
+#ifdef INVARIANTS | +#ifdef INVARIANTS | ||||
+ TMPFS_NODE_LOCK(node); | + TMPFS_NODE_LOCK(node); | ||||
+ MPASS(node->sf_vnode == NULL); | + MPASS(node->sf_vnode == NULL); | ||||
+ MPASS((node->sf_vpstate & TMPFS_VNODE_ALLOCATING) == 0); | + MPASS((node->sf_vpstate & TMPFS_VNODE_ALLOCATING) == 0); | ||||
+ TMPFS_NODE_UNLOCK(node); | + TMPFS_NODE_UNLOCK(node); | ||||
+#endif | +#endif | ||||
+ if (node->sf_path) | + if (node->sf_path) | ||||
+ free(node->sf_path, M_VBOXVFS); | + free(node->sf_path, M_VBOXVFS); | ||||
- cbShFlShareName = offsetof (SHFLSTRING, String.utf8) + cbShare + 1; | - if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS)) | ||||
- pShFlShareName = RTMemAllocZ(cbShFlShareName); | - return EOPNOTSUPP; | ||||
- if (!pShFlShareName) | |||||
- return VERR_NO_MEMORY; | |||||
+ uma_zfree(vboxfs->sf_node_pool, node); | + uma_zfree(vboxfs->sf_node_pool, node); | ||||
+} | +} | ||||
- pShFlShareName->u16Length = cbShare; | - if (vfs_filteropt(mp->mnt_optnew, vboxvfs_opts)) | ||||
- pShFlShareName->u16Size = cbShare + 1; | - { | ||||
- memcpy (pShFlShareName->String.utf8, pszShare, cbShare + 1); | - vfs_mount_error(mp, "%s", "Invalid option"); | ||||
- return EINVAL; | |||||
- } | |||||
+static int | +static int | ||||
+vboxfs_cmount(struct mntarg *ma, void *data, uint64_t flags) | +vboxfs_cmount(struct mntarg *ma, void *data, uint64_t flags) | ||||
+{ | +{ | ||||
+ struct vboxfs_mount_info args; | + struct vboxfs_mount_info args; | ||||
+ int error = 0; | + int error = 0; | ||||
- rc = VbglR0SfMapFolder (&g_vboxSFClient, pShFlShareName, &pShFlGlobalInfo->map); | - rc = vfs_getopt(mp->mnt_optnew, "from", (void **)&pszShare, &cbShare); | ||||
- RTMemFree(pShFlShareName); | - if (rc || pszShare[cbShare-1] != '\0' || cbShare > 0xfffe) | ||||
- return EINVAL; | |||||
+ if (data == NULL) | + if (data == NULL) | ||||
+ return (EINVAL); | + return (EINVAL); | ||||
+ error = copyin(data, &args, sizeof(struct vboxfs_mount_info)); | + error = copyin(data, &args, sizeof(struct vboxfs_mount_info)); | ||||
+ if (error) | + if (error) | ||||
+ return (error); | + return (error); | ||||
+ | |||||
- rc = vfs_getopt(mp->mnt_optnew, "gid", (void **)&gid, &cbOption); | |||||
- if ((rc != ENOENT) && (rc || cbOption != sizeof(gid))) | |||||
- return EINVAL; | |||||
+ ma = mount_argf(ma, "uid", "%d", args.uid); | + ma = mount_argf(ma, "uid", "%d", args.uid); | ||||
+ ma = mount_argf(ma, "gid", "%d", args.gid); | + ma = mount_argf(ma, "gid", "%d", args.gid); | ||||
+ ma = mount_argf(ma, "file_mode", "%d", args.fmode); | + ma = mount_argf(ma, "file_mode", "%d", args.fmode); | ||||
+ ma = mount_argf(ma, "dir_mode", "%d", args.dmode); | + ma = mount_argf(ma, "dir_mode", "%d", args.dmode); | ||||
+ ma = mount_arg(ma, "from", args.name, -1); | + ma = mount_arg(ma, "from", args.name, -1); | ||||
- if (RT_FAILURE (rc)) | - rc = vfs_getopt(mp->mnt_optnew, "uid", (void **)&uid, &cbOption); | ||||
- { | - if ((rc != ENOENT) && (rc || cbOption != sizeof(uid))) | ||||
- RTMemFree(pShFlGlobalInfo); | - return EINVAL; | ||||
- printf("VbglR0SfMapFolder failed rc=%d\n", rc); | |||||
- return EPROTO; | |||||
- } | |||||
+ return (kernel_mount(ma, flags)); | + return (kernel_mount(ma, flags)); | ||||
+} | +} | ||||
- pShFlGlobalInfo->uid = uid; | - pShFlGlobalInfo = RTMemAllocZ(sizeof(struct sf_glob_info)); | ||||
- pShFlGlobalInfo->gid = gid; | - if (!pShFlGlobalInfo) | ||||
- return ENOMEM; | |||||
+static const char *vboxfs_opts[] = { | +static const char *vboxfs_opts[] = { | ||||
+ "fstype", | + "fstype", | ||||
+ "fspath", | + "fspath", | ||||
+ "from", | + "from", | ||||
+ "uid", | + "uid", | ||||
+ "gid", | + "gid", | ||||
+ "file_mode", | + "file_mode", | ||||
+ "dir_mode", | + "dir_mode", | ||||
+ "errmsg", | + "errmsg", | ||||
+ NULL | + NULL | ||||
+}; | +}; | ||||
- mp->mnt_data = pShFlGlobalInfo; | - cbShFlShareName = offsetof (SHFLSTRING, String.utf8) + cbShare + 1; | ||||
- pShFlShareName = RTMemAllocZ(cbShFlShareName); | |||||
- if (!pShFlShareName) | |||||
- return VERR_NO_MEMORY; | |||||
+#define VBOX_INTOPT(optname, val, base) do { \ | +#define VBOX_INTOPT(optname, val, base) do { \ | ||||
+ char *ep, *optarg = NULL; \ | + char *ep, *optarg = NULL; \ | ||||
+ if (vfs_getopt(opts, optname, (void **)&optarg, NULL) == 0) { \ | + if (vfs_getopt(opts, optname, (void **)&optarg, NULL) == 0) { \ | ||||
+ if (optarg != NULL && *optarg == '\0') \ | + if (optarg != NULL && *optarg == '\0') \ | ||||
+ optarg = NULL; \ | + optarg = NULL; \ | ||||
+ if (optarg != NULL) \ | + if (optarg != NULL) \ | ||||
+ val = strtoul(optarg, &ep, base); \ | + val = strtoul(optarg, &ep, base); \ | ||||
+ if (optarg == NULL || *ep != '\0') { \ | + if (optarg == NULL || *ep != '\0') { \ | ||||
+ struct sbuf *sb = sbuf_new_auto(); \ | + struct sbuf *sb = sbuf_new_auto(); \ | ||||
+ sbuf_printf(sb, "Invalid %s: \"%s\"", optname, \ | + sbuf_printf(sb, "Invalid %s: \"%s\"", optname, \ | ||||
+ optarg); \ | + optarg); \ | ||||
+ sbuf_finish(sb); \ | + sbuf_finish(sb); \ | ||||
+ vfs_mount_error(mp, sbuf_data(sb)); \ | + vfs_mount_error(mp, sbuf_data(sb)); \ | ||||
+ sbuf_delete(sb); \ | + sbuf_delete(sb); \ | ||||
+ return (EINVAL); \ | + return (EINVAL); \ | ||||
+ } \ | + } \ | ||||
+ } \ | + } \ | ||||
+} while (0) | +} while (0) | ||||
- /** @todo root vnode. */ | - pShFlShareName->u16Length = cbShare; | ||||
- pShFlShareName->u16Size = cbShare + 1; | |||||
- memcpy (pShFlShareName->String.utf8, pszShare, cbShare + 1); | |||||
+static int | +static int | ||||
+vboxfs_node_ctor(void *mem, int size, void *arg, int flags) | +vboxfs_node_ctor(void *mem, int size, void *arg, int flags) | ||||
+{ | +{ | ||||
+ struct vboxfs_node *node = (struct vboxfs_node *)mem; | + struct vboxfs_node *node = (struct vboxfs_node *)mem; | ||||
- vfs_getnewfsid(mp); | - rc = VbglR0SfMapFolder (&g_vboxSFClient, pShFlShareName, &pShFlGlobalInfo->map); | ||||
- vfs_mountedfrom(mp, pszShare); | - RTMemFree(pShFlShareName); | ||||
+ node->sf_vnode = NULL; | + node->sf_vnode = NULL; | ||||
+ node->sf_vpstate = 0; | + node->sf_vpstate = 0; | ||||
- printf("%s: Leave rc=0\n", __FUNCTION__); | - if (RT_FAILURE (rc)) | ||||
- { | |||||
- RTMemFree(pShFlGlobalInfo); | |||||
- printf("VbglR0SfMapFolder failed rc=%d\n", rc); | |||||
- return EPROTO; | |||||
- } | |||||
+ return (0); | + return (0); | ||||
+} | +} | ||||
- return 0; | - pShFlGlobalInfo->uid = uid; | ||||
- pShFlGlobalInfo->gid = gid; | |||||
+static void | +static void | ||||
+vboxfs_node_dtor(void *mem, int size, void *arg) | +vboxfs_node_dtor(void *mem, int size, void *arg) | ||||
+{ | +{ | ||||
+ struct vboxfs_node *node = (struct vboxfs_node *)mem; | + struct vboxfs_node *node = (struct vboxfs_node *)mem; | ||||
+ node->sf_type = VNON; | + node->sf_type = VNON; | ||||
} | +} | ||||
-static int vboxvfs_unmount(struct mount *mp, int mntflags, struct thread *td) | - mp->mnt_data = pShFlGlobalInfo; | ||||
+static int | +static int | ||||
+vboxfs_node_init(void *mem, int size, int flags) | +vboxfs_node_init(void *mem, int size, int flags) | ||||
{ | +{ | ||||
- struct sf_glob_info *pShFlGlobalInfo = VFSMP2SFGLOBINFO(mp); | |||||
- int rc; | |||||
- int flags = 0; | |||||
+ struct vboxfs_node *node = (struct vboxfs_node *)mem; | + struct vboxfs_node *node = (struct vboxfs_node *)mem; | ||||
+ node->sf_ino = 0; | + node->sf_ino = 0; | ||||
- rc = VbglR0SfUnmapFolder(&g_vboxSFClient, &pShFlGlobalInfo->map); | - /** @todo root vnode. */ | ||||
- if (RT_FAILURE(rc)) | |||||
- printf("Failed to unmap shared folder\n"); | |||||
+ mtx_init(&node->sf_interlock, "tmpfs node interlock", NULL, MTX_DEF); | + mtx_init(&node->sf_interlock, "tmpfs node interlock", NULL, MTX_DEF); | ||||
- if (mntflags & MNT_FORCE) | - vfs_getnewfsid(mp); | ||||
- flags |= FORCECLOSE; | - vfs_mountedfrom(mp, pszShare); | ||||
+ return (0); | + return (0); | ||||
+} | +} | ||||
- /* There is 1 extra root vnode reference (vnode_root). */ | - printf("%s: Leave rc=0\n", __FUNCTION__); | ||||
- rc = vflush(mp, 1, flags, td); | |||||
- if (rc) | |||||
- return rc; | |||||
+static void | +static void | ||||
+vboxfs_node_fini(void *mem, int size) | +vboxfs_node_fini(void *mem, int size) | ||||
+{ | +{ | ||||
+ struct vboxfs_node *node = (struct vboxfs_node *)mem; | + struct vboxfs_node *node = (struct vboxfs_node *)mem; | ||||
- return 0; | |||||
+ mtx_destroy(&node->sf_interlock); | + mtx_destroy(&node->sf_interlock); | ||||
+} | } | ||||
- RTMemFree(pShFlGlobalInfo); | -static int vboxvfs_unmount(struct mount *mp, int mntflags, struct thread *td) | ||||
- mp->mnt_data = NULL; | |||||
+static int | +static int | ||||
+vboxfs_mount(struct mount *mp) | +vboxfs_mount(struct mount *mp) | ||||
+{ | { | ||||
- struct sf_glob_info *pShFlGlobalInfo = VFSMP2SFGLOBINFO(mp); | |||||
- int rc; | |||||
- int flags = 0; | |||||
+ struct vboxfs_mnt *vboxfsmp = NULL; | + struct vboxfs_mnt *vboxfsmp = NULL; | ||||
+ struct vfsoptlist *opts = mp->mnt_optnew; | + struct vfsoptlist *opts = mp->mnt_optnew; | ||||
+ sfp_mount_t *handle = NULL; | + sfp_mount_t *handle = NULL; | ||||
+ int readonly = 0; | + int readonly = 0; | ||||
+ sffs_fsinfo_t fsinfo; | + sffs_fsinfo_t fsinfo; | ||||
+ int error, share_len; | + int error, share_len; | ||||
+ char *share_name; | + char *share_name; | ||||
+ mode_t file_mode = 0, dir_mode = 0; | + mode_t file_mode = 0, dir_mode = 0; | ||||
+ uid_t uid = 0; | + uid_t uid = 0; | ||||
+ gid_t gid = 0; | + gid_t gid = 0; | ||||
+ struct vboxfs_node *root; | + struct vboxfs_node *root; | ||||
+ | |||||
- rc = VbglR0SfUnmapFolder(&g_vboxSFClient, &pShFlGlobalInfo->map); | |||||
- if (RT_FAILURE(rc)) | |||||
- printf("Failed to unmap shared folder\n"); | |||||
+ if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS)) | + if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS)) | ||||
+ return (EOPNOTSUPP); | + return (EOPNOTSUPP); | ||||
+ | |||||
- if (mntflags & MNT_FORCE) | |||||
- flags |= FORCECLOSE; | |||||
+ if (vfs_filteropt(opts, vboxfs_opts)) { | + if (vfs_filteropt(opts, vboxfs_opts)) { | ||||
+ vfs_mount_error(mp, "%s", "Invalid option"); | + vfs_mount_error(mp, "%s", "Invalid option"); | ||||
+ return (EINVAL); | + return (EINVAL); | ||||
+ } | + } | ||||
+ | |||||
- /* There is 1 extra root vnode reference (vnode_root). */ | |||||
- rc = vflush(mp, 1, flags, td); | |||||
- if (rc) | |||||
- return rc; | |||||
+ VBOX_INTOPT("uid", uid, 10); | + VBOX_INTOPT("uid", uid, 10); | ||||
+ VBOX_INTOPT("gid", gid, 10); | + VBOX_INTOPT("gid", gid, 10); | ||||
+ VBOX_INTOPT("file_mode", file_mode, 8); | + VBOX_INTOPT("file_mode", file_mode, 8); | ||||
+ VBOX_INTOPT("dir_mode", dir_mode, 8); | + VBOX_INTOPT("dir_mode", dir_mode, 8); | ||||
+ VBOX_INTOPT("ro", readonly, 10); | + VBOX_INTOPT("ro", readonly, 10); | ||||
+ | |||||
+ error = vfs_getopt(opts, "from", (void **)&share_name, &share_len); | + error = vfs_getopt(opts, "from", (void **)&share_name, &share_len); | ||||
+ if (error != 0 || share_len == 0) { | + if (error != 0 || share_len == 0) { | ||||
+ vfs_mount_error(mp, "Invalid from"); | + vfs_mount_error(mp, "Invalid from"); | ||||
+ return (EINVAL); | + return (EINVAL); | ||||
+ } | + } | ||||
+ | |||||
- RTMemFree(pShFlGlobalInfo); | |||||
- mp->mnt_data = NULL; | |||||
+ vboxfsmp = malloc(sizeof(struct vboxfs_mnt), M_VBOXVFS, M_WAITOK | M_ZERO); | + vboxfsmp = malloc(sizeof(struct vboxfs_mnt), M_VBOXVFS, M_WAITOK | M_ZERO); | ||||
+ vboxfsmp->sf_uid = uid; | + vboxfsmp->sf_uid = uid; | ||||
+ vboxfsmp->sf_gid = gid; | + vboxfsmp->sf_gid = gid; | ||||
+ vboxfsmp->sf_fmode = file_mode & (S_IRWXU | S_IRWXG | S_IRWXO); | + vboxfsmp->sf_fmode = file_mode & (S_IRWXU | S_IRWXG | S_IRWXO); | ||||
+ vboxfsmp->sf_dmode = dir_mode & (S_IRWXU | S_IRWXG | S_IRWXO); | + vboxfsmp->sf_dmode = dir_mode & (S_IRWXU | S_IRWXG | S_IRWXO); | ||||
+ vboxfsmp->sf_ino = 3; | + vboxfsmp->sf_ino = 3; | ||||
+ vboxfsmp->sf_stat_ttl = 200; | + vboxfsmp->sf_stat_ttl = 200; | ||||
+ | |||||
- return 0; | |||||
+ /* Invoke Hypervisor mount interface before proceeding */ | + /* Invoke Hypervisor mount interface before proceeding */ | ||||
+ error = sfprov_mount(share_name, &handle); | + error = sfprov_mount(share_name, &handle); | ||||
+ if (error) | + if (error) | ||||
+ return (error); | + return (error); | ||||
+ | + | ||||
+ /* Determine whether the filesystem must be read-only. */ | + /* Determine whether the filesystem must be read-only. */ | ||||
+ error = sfprov_get_fsinfo(handle, &fsinfo); | + error = sfprov_get_fsinfo(handle, &fsinfo); | ||||
+ if (error != 0) { | + if (error != 0) { | ||||
Show All 36 Lines | |||||
+#if __FreeBSD_version >= 1000021 | +#if __FreeBSD_version >= 1000021 | ||||
+ mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED; | + mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED; | ||||
+#else | +#else | ||||
+ mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED | | + mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED | | ||||
+ MNTK_EXTENDED_SHARED; | + MNTK_EXTENDED_SHARED; | ||||
+#endif | +#endif | ||||
+ MNT_IUNLOCK(mp); | + MNT_IUNLOCK(mp); | ||||
+ vfs_mountedfrom(mp, share_name); | + vfs_mountedfrom(mp, share_name); | ||||
+ | |||||
- return 0; | |||||
+ return (0); | + return (0); | ||||
} | } | ||||
-static int vboxvfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) | -static int vboxvfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) | ||||
+/* | +/* | ||||
+ * Unmount a shared folder. | + * Unmount a shared folder. | ||||
+ * | + * | ||||
+ * vboxfs_unmount umounts the mounted file system. It return 0 | + * vboxfs_unmount umounts the mounted file system. It return 0 | ||||
+ * on sucess and any relevant errno on failure. | + * on sucess and any relevant errno on failure. | ||||
+ */ | + */ | ||||
+static int | +static int | ||||
+vboxfs_unmount(struct mount *mp, int mntflags) | +vboxfs_unmount(struct mount *mp, int mntflags) | ||||
{ | { | ||||
- int rc = 0; | - int rc = 0; | ||||
- struct sf_glob_info *pShFlGlobalInfo = VFSMP2SFGLOBINFO(mp); | - struct sf_glob_info *pShFlGlobalInfo = VFSMP2SFGLOBINFO(mp); | ||||
- struct vnode *vp; | - struct vnode *vp; | ||||
+ struct vboxfs_mnt *vboxfsmp; | + struct vboxfs_mnt *vboxfsmp; | ||||
+ struct thread *td; | + struct thread *td; | ||||
+ int error; | + int error; | ||||
+ int flags; | + int flags; | ||||
+ | |||||
- printf("%s: Enter\n", __FUNCTION__); | |||||
+ vboxfsmp = VFSTOVBOXFS(mp); | + vboxfsmp = VFSTOVBOXFS(mp); | ||||
+ td = curthread; | + td = curthread; | ||||
+ flags = 0; | + flags = 0; | ||||
+ if (mntflags & MNT_FORCE) | + if (mntflags & MNT_FORCE) | ||||
+ flags |= FORCECLOSE; | + flags |= FORCECLOSE; | ||||
+ | |||||
- vp = pShFlGlobalInfo->vnode_root; | |||||
- VREF(vp); | |||||
+ error = vflush(mp, 0, flags, td); | + error = vflush(mp, 0, flags, td); | ||||
+ if (error) | + if (error) | ||||
+ return (error); | + return (error); | ||||
+ | |||||
- vn_lock(vp, flags | LK_RETRY, td); | |||||
- *vpp = vp; | |||||
+ /* Invoke Hypervisor unmount interface before proceeding */ | + /* Invoke Hypervisor unmount interface before proceeding */ | ||||
+ error = sfprov_unmount(vboxfsmp->sf_handle); | + error = sfprov_unmount(vboxfsmp->sf_handle); | ||||
+ if (error != 0) { | + if (error != 0) { | ||||
+ /* TBD anything here? */ | + /* TBD anything here? */ | ||||
+ } | + } | ||||
+ | |||||
- printf("%s: Leave\n", __FUNCTION__); | |||||
+ uma_zdestroy(vboxfsmp->sf_node_pool); | + uma_zdestroy(vboxfsmp->sf_node_pool); | ||||
+ | |||||
- return rc; | |||||
+ free(vboxfsmp, M_VBOXVFS); | + free(vboxfsmp, M_VBOXVFS); | ||||
+ MNT_ILOCK(mp); | + MNT_ILOCK(mp); | ||||
+ mp->mnt_data = NULL; | + mp->mnt_data = NULL; | ||||
+ mp->mnt_flag &= ~MNT_LOCAL; | + mp->mnt_flag &= ~MNT_LOCAL; | ||||
+ MNT_IUNLOCK(mp); | + MNT_IUNLOCK(mp); | ||||
+ | |||||
- printf("%s: Enter\n", __FUNCTION__); | |||||
- | |||||
- vp = pShFlGlobalInfo->vnode_root; | |||||
- VREF(vp); | |||||
+ return (0); | + return (0); | ||||
+} | } | ||||
- vn_lock(vp, flags | LK_RETRY, td); | -static int vboxvfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, struct thread *td) | ||||
- *vpp = vp; | |||||
+static int | +static int | ||||
+vboxfs_root(struct mount *mp, int flags, struct vnode **vpp) | +vboxfs_root(struct mount *mp, int flags, struct vnode **vpp) | ||||
+{ | { | ||||
- return EOPNOTSUPP; | |||||
+ int error; | + int error; | ||||
+ error = vboxfs_alloc_vp(mp, VFSTOVBOXFS(mp)->sf_root, flags, vpp); | + error = vboxfs_alloc_vp(mp, VFSTOVBOXFS(mp)->sf_root, flags, vpp); | ||||
+ | |||||
- printf("%s: Leave\n", __FUNCTION__); | |||||
+ if (!error) | + if (!error) | ||||
+ (*vpp)->v_vflag |= VV_ROOT; | + (*vpp)->v_vflag |= VV_ROOT; | ||||
+ | |||||
- return rc; | |||||
+ return error; | + return error; | ||||
} | } | ||||
-static int vboxvfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, struct thread *td) | -int vboxvfs_init(struct vfsconf *vfsp) | ||||
+/* | +/* | ||||
+ * Do operation associated with quotas, not supported | + * Do operation associated with quotas, not supported | ||||
+ */ | + */ | ||||
+static int | +static int | ||||
+vboxfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg) | +vboxfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg) | ||||
{ | { | ||||
- return EOPNOTSUPP; | - int rc; | ||||
+ return (EOPNOTSUPP); | + return (EOPNOTSUPP); | ||||
} | +} | ||||
-int vboxvfs_init(struct vfsconf *vfsp) | - /* Initialize the R0 guest library. */ | ||||
- rc = VbglR0SfInit(); | |||||
- if (RT_FAILURE(rc)) | |||||
- return ENXIO; | |||||
+/* | +/* | ||||
+ * Initialize the filesystem globals. | + * Initialize the filesystem globals. | ||||
+ */ | + */ | ||||
+static int | +static int | ||||
+vboxfs_init(struct vfsconf *vfsp) | +vboxfs_init(struct vfsconf *vfsp) | ||||
{ | +{ | ||||
- int rc; | |||||
+ int error; | + int error; | ||||
- /* Initialize the R0 guest library. */ | |||||
- rc = VbglR0SfInit(); | |||||
- if (RT_FAILURE(rc)) | |||||
- return ENXIO; | |||||
+ DROP_GIANT(); | |||||
- /* Connect to the host service. */ | - /* Connect to the host service. */ | ||||
- rc = VbglR0SfConnect(&g_vboxSFClient); | - rc = VbglR0SfConnect(&g_vboxSFClient); | ||||
- if (RT_FAILURE(rc)) | - if (RT_FAILURE(rc)) | ||||
- { | - { | ||||
- printf("Failed to get connection to host! rc=%d\n", rc); | - printf("Failed to get connection to host! rc=%d\n", rc); | ||||
- VbglR0SfTerm(); | - VbglR0SfTerm(); | ||||
- return ENXIO; | - return ENXIO; | ||||
- } | - } | ||||
+ sfprov = sfprov_connect(SFPROV_VERSION); | + DROP_GIANT(); | ||||
+ if (sfprov == NULL) { | |||||
+ printf("%s: couldn't connect to sf provider", __func__); | |||||
+ return (ENODEV); | |||||
+ } | |||||
+ | |||||
+ error = sfprov_set_show_symlinks(); | |||||
+ if (error != 0) | |||||
+ printf("%s: host unable to show symlinks, error=%d\n", | |||||
+ __func__, error); | |||||
- rc = VbglR0SfSetUtf8(&g_vboxSFClient); | - rc = VbglR0SfSetUtf8(&g_vboxSFClient); | ||||
- if (RT_FAILURE (rc)) | - if (RT_FAILURE (rc)) | ||||
- { | - { | ||||
- printf("VbglR0SfSetUtf8 failed, rc=%d\n", rc); | - printf("VbglR0SfSetUtf8 failed, rc=%d\n", rc); | ||||
- VbglR0SfDisconnect(&g_vboxSFClient); | - VbglR0SfDisconnect(&g_vboxSFClient); | ||||
- VbglR0SfTerm(); | - VbglR0SfTerm(); | ||||
- return EPROTO; | - return EPROTO; | ||||
- } | - } | ||||
- | + sfprov = sfprov_connect(SFPROV_VERSION); | ||||
+ if (sfprov == NULL) { | |||||
+ printf("%s: couldn't connect to sf provider", __func__); | |||||
+ return (ENODEV); | |||||
+ } | |||||
- printf("Successfully loaded shared folder module\n"); | - printf("Successfully loaded shared folder module\n"); | ||||
- | + error = sfprov_set_show_symlinks(); | ||||
+ if (error != 0) | |||||
+ printf("%s: host unable to show symlinks, error=%d\n", | |||||
+ __func__, error); | |||||
- return 0; | - return 0; | ||||
+ PICKUP_GIANT(); | + PICKUP_GIANT(); | ||||
+ return (0); | + return (0); | ||||
} | } | ||||
-int vboxvfs_uninit(struct vfsconf *vfsp) | -int vboxvfs_uninit(struct vfsconf *vfsp) | ||||
+/* | +/* | ||||
+ * Undo the work of vboxfs_init(). | + * Undo the work of vboxfs_init(). | ||||
▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines |