vboxvfs_vfsops.c revision 34d1c9a81582b1acc9831732458231fcd8ddf2a5
/* $Id$ */
/** @file
* VirtualBox File System Driver for Solaris Guests. VFS operations.
*/
/*
* Copyright (C) 2008 Sun Microsystems, Inc.
*
* Sun Microsystems, Inc. confidential
* All rights reserved
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include "vboxvfs.h"
#if defined(DEBUG_ramshankar) && !defined(LOG_ENABLED)
# define LOG_ENABLED
# define LOG_TO_BACKDOOR
#endif
#if defined(DEBUG_ramshankar)
#endif
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
/** Mount Options */
#define MNTOPT_VBOXVFS_UID "uid"
#define MNTOPT_VBOXVFS_GID "gid"
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
static int vboxvfs_CheckMountPerm(vfs_t *pVFS, struct mounta *pMount, vnode_t *pVNodeSpec, cred_t *pCred);
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* mntopts_t: mount options table array
*/
static mntopt_t g_VBoxVFSMountOptions[] =
{
/* Option Name Cancel Opt. Default Arg Flags Data */
};
/**
* mntopts_t: mount options table prototype
*/
static mntopts_t g_VBoxVFSMountTableProt =
{
sizeof(g_VBoxVFSMountOptions) / sizeof(mntopt_t),
};
/**
* vfsdef_t: driver specific mount options
*/
static vfsdef_t g_VBoxVFSDef =
{
};
/**
* modlfs: loadable file system
*/
static struct modlfs g_VBoxVFSLoadMod =
{
&mod_fsops, /* extern from kernel */
};
/**
*/
static struct modlinkage g_VBoxVFSModLinkage =
{
MODREV_1, /* loadable module system revision */
NULL /* terminate array of linkage structures */
};
/*******************************************************************************
* Global Variables *
*******************************************************************************/
/** Opaque pointer to list of states. */
static void *g_pVBoxVFSState;
/** GCC C++ hack. */
unsigned __gxx_personality_v0 = 0xdecea5ed;
/** Global connection to the client. */
/** Global VFS Operations pointer. */
/** The file system type identifier. */
static int g_VBoxVFSType;
/**
* Kernel entry points
*/
int _init(void)
{
return mod_install(&g_VBoxVFSModLinkage);;
}
int _fini(void)
{
if (rc)
return rc;
/* Blow away the operation vectors*/
}
{
}
{
int rc;
/* Initialize the R0 guest library. */
if (VBOX_SUCCESS(rc))
{
/* Connect to the host service. */
if (VBOX_SUCCESS(rc))
{
/* Use UTF-8 encoding. */
if (VBOX_SUCCESS(rc))
{
/* Fill up VFS user entry points. */
static const fs_operation_def_t s_VBoxVFS_vfsops_template[] =
{
};
if (!rc)
{
/* Set VNode operations. */
if (!rc)
{
return 0;
}
else
}
else
}
else
{
}
}
else
{
}
vboxUninit();
}
else
{
}
return rc;
}
{
int rc = 0;
int Uid = 0;
int Gid = 0;
size_t cbShflShareName = 0;
/* Check user credentials for mounting in the specified target. */
if (rc)
{
return EPERM;
}
/* We can mount to only directories. */
return ENOTDIR;
/* We don't support remounting. */
return ENOTSUP;
{
return EBUSY;
}
/* From what I understood the options are already parsed at a higher level */
{
return EINVAL;
}
/* Get UID argument (optional). */
if (rc < 0)
{
return EINVAL;
}
/* Get GID argument (optional). */
if (rc < 0)
{
return EINVAL;
}
/* Get special (sharename). */
if (!rc)
{
/* Get the vnode for the special file for storing the device identifier and path. */
if (!rc)
{
/* Check if user has permission to use the special file for mounting. */
if (!rc)
{
}
else
}
else
}
else
{
}
if (!rc)
return rc;
/* Get VNode of the special file being mounted. */
{
/* Open the vnode for mounting. */
if (rc)
{
}
}
else
{
}
if (!rc)
{
return rc;
}
/* Allocate the global info. structure. */
if (pVBoxVFSGlobalInfo)
{
if (pShflShareName)
{
if (VBOX_SUCCESS(rc))
rc = 0;
else
{
}
}
else
{
LogRel((DEVICE_NAME ":VBoxVFS_Mount: RTMemAllocZ failed to alloc %d bytes for ShFlShareName.\n", cbShflShareName));
}
}
else
{
LogRel((DEVICE_NAME ":VBoxVFS_Mount: RTMemAlloc failed to alloc %d bytes for global struct.\n", sizeof(*pVBoxVFSGlobalInfo)));
}
/* Undo work on failure. */
if (rc)
goto mntError1;
/* Initialize the per-filesystem mutex */
/* Allocate root vboxvfs_vnode_t object */
if (pVNodeRoot)
{
/* Initialize vnode protection mutex */
/* Allocate root path */
if (pVNodeRoot->pPath)
{
/* Initialize root path */
/* Stat root node info from host */
if (!rc)
{
/* Initialize the root vboxvfs_node_t object */
/* Success! */
return 0;
}
else
}
else
{
}
}
else
{
}
/* Undo work in reverse. */
/* Just release the mount location. */
VOP_CLOSE(pVNodeDev, (pVFS->vfs_flag & VFS_RDONLY) ? FREAD : FREAD | FWRITE, 1, (offset_t)0, pCred, NULL);
return rc;
}
{
int rc;
/* Check if user can unmount. */
if (rc)
{
return EPERM;
}
/* @todo -XXX - Not sure of supporting force unmounts. What this means is that a failed force mount could bring down
* the entire system as hanging about vnode releases would no longer be valid after unloading ourselves...
*/
/* @todo implement ref-counting of active vnodes & check for busy state here. */
/* @todo mutex protection needed here */
if (VBOX_FAILURE(rc))
return 0;
}
{
return 0;
}
{
int rc;
cbBuffer = sizeof(VolumeInfo);
rc = vboxCallFSInfo(&g_VBoxVFSClient, &pVBoxVFSGlobalInfo->Map, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME, &cbBuffer,
if (VBOX_FAILURE(rc))
return RTErrConvertToErrno(rc);
pStat->f_ffree = 1000; /* don't return 0 here since the guest may think that it is not possible to create any more files */
return 0;
}
{
/* -- TODO -- */
return 0;
}
{
vboxUninit();
}
static int vboxvfs_CheckMountPerm(vfs_t *pVFS, struct mounta *pMount, vnode_t *pVNodeSpec, cred_t *pCred)
{
/* Check if user has the rights to mount the special file. */
int rc;
return ENOTBLK;
{
}
if (!rc)
return rc;
}
{
int rc;
long Val;
if (rc)
{
if ( !rc
{
return 0;
}
return -1;
}
return 1;
}