/** * Unmount VBoxVFS. * * @param mp Mount data provided by VFS layer. * @param fFlags Unmounting flags. * @param pContext kAuth context needed in order to authentificate mount operation. * * @return 0 on success or BSD error code otherwise. */ static int vboxvfs_unmount(struct mount *mp, int fFlags, vfs_context_t pContext) { NOREF(pContext); vboxvfs_mount_t *pMount; int rc = EBUSY; int fFlush = (fFlags & MNT_FORCE) ? FORCECLOSE : 0; PDEBUG("Attempting to %s unmount a shared folder", (fFlags & MNT_FORCE) ? "forcibly" : "normally"); AssertReturn(mp, EINVAL); pMount = (vboxvfs_mount_t *)vfs_fsprivate(mp); AssertReturn(pMount, EINVAL); AssertReturn(pMount->pRootVnode, EINVAL); /* Check if we can do unmount at the moment */ if (!vnode_isinuse(pMount->pRootVnode, 1)) { /* Flush child vnodes first */ rc = vflush(mp, pMount->pRootVnode, fFlush); if (rc == 0) { /* Flush root vnode */ rc = vflush(mp, NULL, fFlush); if (rc == 0) { vfs_setfsprivate(mp, NULL); rc = VbglR0SfUnmapFolder(&g_vboxSFClient, &pMount->pMap); if (RT_SUCCESS(rc)) { vboxvfs_destroy_internal_data(&pMount); PDEBUG("A shared folder has been successfully unmounted"); return 0; } PDEBUG("Unable to unmount shared folder"); rc = EPROTO; } else PDEBUG("Unable to flush filesystem before unmount, some data might be lost"); } else PDEBUG("Unable to flush child vnodes"); } else PDEBUG("Root vnode is in use, can't unmount"); vnode_put(pMount->pRootVnode); return rc; }
/* unmap the share and free global info [sf_g] */ static void sf_glob_free(struct sf_glob_info *sf_g) { int rc; TRACE(); rc = VbglR0SfUnmapFolder(&client_handle, &sf_g->map); if (RT_FAILURE(rc)) LogFunc(("VbglR0SfUnmapFolder failed rc=%d\n", rc)); if (sf_g->nls) unload_nls(sf_g->nls); kfree(sf_g); }
NTSTATUS VBoxMRxFinalizeNetRoot(IN PMRX_NET_ROOT pNetRoot, IN PBOOLEAN ForceDisconnect) { PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(pNetRoot); RT_NOREF(pNetRoot, ForceDisconnect); Log(("VBOXSF: MRxFinalizeNetRoot: NET_ROOT %p\n", pNetRoot)); if (pNetRootExtension->phgcmClient) { int vboxRC = VbglR0SfUnmapFolder(pNetRootExtension->phgcmClient, &pNetRootExtension->map); if (vboxRC != VINF_SUCCESS) Log(("VBOXSF: MRxFinalizeVNetRoot: VbglR0SfUnmapFolder failed with %d\n", vboxRC)); pNetRootExtension->phgcmClient = NULL; } return STATUS_SUCCESS; }
static int vboxvfs_unmount(struct mount *mp, int mntflags, struct thread *td) { struct sf_glob_info *pShFlGlobalInfo = VFSMP2SFGLOBINFO(mp); int rc; int flags = 0; rc = VbglR0SfUnmapFolder(&g_vboxSFClient, &pShFlGlobalInfo->map); if (RT_FAILURE(rc)) printf("Failed to unmap shared folder\n"); if (mntflags & MNT_FORCE) flags |= FORCECLOSE; /* There is 1 extra root vnode reference (vnode_root). */ rc = vflush(mp, 1, flags, td); if (rc) return rc; RTMemFree(pShFlGlobalInfo); mp->mnt_data = NULL; return 0; }