socsvn commit: r255111 - soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files
oleksandr at FreeBSD.org
oleksandr at FreeBSD.org
Wed Jul 24 13:01:54 UTC 2013
Author: oleksandr
Date: Wed Jul 24 13:01:54 2013
New Revision: 255111
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255111
Log:
Implemented access, open and close function for vboxvfs_vnops
Modified:
soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files/patch-src-VBox-Additions-freebsd.kmk
Modified: soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files/patch-src-VBox-Additions-freebsd.kmk
==============================================================================
--- soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files/patch-src-VBox-Additions-freebsd.kmk Wed Jul 24 11:32:58 2013 (r255110)
+++ soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files/patch-src-VBox-Additions-freebsd.kmk Wed Jul 24 13:01:54 2013 (r255111)
@@ -12,7 +12,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
-@@ -33,7 +32,28 @@
+@@ -33,7 +32,29 @@
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -21,6 +21,7 @@
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/kernel.h>
++#include <sys/types.h>
+#include <sys/malloc.h>
+#include <sys/stat.h>
+#include <sys/bio.h>
@@ -41,7 +42,7 @@
/*
* Prototypes for VBOXVFS vnode operations
*/
-@@ -56,6 +76,7 @@
+@@ -56,6 +77,7 @@
static vop_symlink_t vboxvfs_symlink;
static vop_readdir_t vboxvfs_readdir;
static vop_strategy_t vboxvfs_strategy;
@@ -49,7 +50,7 @@
static vop_print_t vboxvfs_print;
static vop_pathconf_t vboxvfs_pathconf;
static vop_advlock_t vboxvfs_advlock;
-@@ -65,177 +86,633 @@
+@@ -65,177 +87,755 @@
static vop_inactive_t vboxvfs_inactive;
static vop_putpages_t vboxvfs_putpages;
static vop_reclaim_t vboxvfs_reclaim;
@@ -118,19 +119,68 @@
+ .vop_symlink = vboxvfs_symlink,
+ .vop_write = vboxvfs_write,
};
++/*
++ * uid and gid in sffs determine owner and group for all files.
++ */
++#if 0
++static int
++sfnode_access(sfnode_t *node, mode_t mode, cred_t *cr)
++{
++ sffs_data_t *sffs = node->sf_sffs;
++ mode_t m;
++ int shift = 0;
++ int error;
++ vnode_t *vp;
++ ASSERT(MUTEX_HELD(&sffs_lock));
++
++ /*
++ * get the mode from the cache or provider
++ */
++ if (sfnode_stat_cached(node))
++ error = 0;
++ else
++ error = sfnode_update_stat_cache(node);
++ m = (error == 0) ? node->sf_stat.sf_mode : 0;
++
++ /*
++ * mask off the permissions based on uid/gid
++ */
++ if (crgetuid(cr) != sffs->sf_uid) {
++ shift += 3;
++ if (groupmember(sffs->sf_gid, cr) == 0)
++ shift += 3;
++ }
++ mode &= ~(m << shift);
++
++ if (mode == 0) {
++ error = 0;
++ } else {
++ vp = sfnode_get_vnode(node);
++ error = secpolicy_vnode_access(cr, vp, sffs->sf_uid, mode);
++ VN_RELE(vp);
++ }
++ return (error);
++}
++#endif
static int vboxvfs_access(struct vop_access_args *ap)
{
- return 0;
+#if 0
-+ struct vnode *vp;
-+ accmode_t accmode;
++ sfnode_t *node = VN2SFN(vp->a_vp);
++ int error;
+
-+ vp = ap->a_vp;
-+ accmode = ap->a_accmode;
++ mutex_enter(&sffs_lock);
++ error = sfnode_access(node, mode, cr);
++ mutex_exit(&sffs_lock);
+
-+ if (accmode & VWRITE) {
-+ switch (vp->v_type) {
++ return (error);
++#endif
++ struct vnode *vp = ap->a_vp;
++ accmode_t accmode = ap->a_accmode;
++
++ if ((accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
++ switch (vp->v_type) {
+ case VDIR:
+ case VLNK:
+ case VREG:
@@ -139,36 +189,109 @@
+ default:
+ break;
+ }
-+ }
-+
++ }
+ return (vaccess(vp->v_type, 0444, 0, 0,
+ accmode, ap->a_cred, NULL));
-+#endif
-+ return (0);
}
++/*
++ * Clears the (cached) directory listing for the node.
++ */
++static void
++vfsnode_clear_dir_list(struct vboxvfs_node *np)
++{
++ while (np->sf_dir_list != NULL) {
++ sffs_dirents_t *next = np->sf_dir_list->sf_next;
++ free(np->sf_dir_list, M_VBOXVFS);
++ np->sf_dir_list = next;
++ }
++}
++
++/*
++ * Open the provider file associated with a vnode. Holding the file open is
++ * the only way we have of trying to have a vnode continue to refer to the
++ * same host file in the host in light of the possibility of host side renames.
++ */
++static void
++vfsnode_open(struct vboxvfs_node *np)
++{
++ int error;
++ sfp_file_t *fp;
++
++ if (np->sf_file != NULL)
++ return;
++ error = sfprov_open(np->vboxvfsmp->sf_handle, np->sf_path, &fp);
++ if (error == 0)
++ np->sf_file = fp;
++}
++
static int vboxvfs_open(struct vop_open_args *ap)
{
- return 0;
-+#if 0
-+ struct vboxvfs_node *np = VTON(ap->a_vp);
++ struct vnode *vp = ap->a_vp;
++ struct vboxvfs_node *np;
++ int error = 0;
+ off_t fsize;
+
++ np = VTOVBOXFS(vp);
++ vfsnode_open(np);
++ if (np->sf_file == NULL)
++ error = EINVAL;
++
+ fsize = np->vboxvfsmp->size;
+ vnode_create_vobject(ap->a_vp, fsize, ap->a_td);
-+#endif
-+ return (0);
++
++ return (error);
}
++#if 0
++static uint64_t
++sfnode_cur_time_usec(void)
++{
++ clock_t now = drv_hztousec(ddi_get_lbolt());
++ return now;
++}
++static int
++sfnode_stat_cached(sfnode_t *node)
++{
++ return (sfnode_cur_time_usec() - node->sf_stat_time) <
++ node->sf_sffs->sf_stat_ttl * 1000L;
++}
++#endif
++static void
++vfsnode_invalidate_stat_cache(struct vboxvfs_node *np)
++{
++ np->sf_stat_time = 0;
++}
++
static int vboxvfs_close(struct vop_close_args *ap)
{
- return 0;
-+#if 0
-+ int rc;
-+
-+ rc = vboxCallClose(&vbox_client, &fp->map, fp->handle);
-+ kmem_free(fp, sizeof(sfp_file_t));
-+#endif
++
++ struct vnode *vp = ap->a_vp;
++ struct vboxvfs_node *np;
++
++ np = VTOVBOXFS(vp);
++
++ /*
++ * Free the directory entries for the node. We do this on this call
++ * here because the directory node may not become inactive for a long
++ * time after the readdir is over. Case in point, if somebody cd's into
++ * the directory then it won't become inactive until they cd away again.
++ * In such a case we would end up with the directory listing not getting
++ * updated (i.e. the result of 'ls' always being the same) until they
++ * change the working directory.
++ */
++ vfsnode_clear_dir_list(np);
++
++ vfsnode_invalidate_stat_cache(np);
++
++ if (np->sf_file != NULL)
++ {
++ (void)sfprov_close(np->sf_file);
++ np->sf_file = NULL;
++ }
++
+ return (0);
}
@@ -744,7 +867,7 @@
===================================================================
--- src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h (revision 4)
+++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h (working copy)
-@@ -21,24 +21,130 @@
+@@ -21,46 +21,193 @@
#define VBOXVFS_VFSNAME "vboxvfs"
#define VBOXVFS_VERSION 1
@@ -761,8 +884,8 @@
- int ttl;
-};
+/** Helper macros */
-+#define VFSTOVBOXFS(mp) ((vboxvfs_mnt_t *)((mp)->mnt_data))
-+#define VTON(vp) ((vboxvfs_node *)((vp)->v_data))
++#define VFSTOVBOXFS(mp) ((struct vboxvfs_mnt *)((mp)->mnt_data))
++#define VTOVBOXFS(vp) ((struct vboxvfs_node *)(vp)->v_data)
+MALLOC_DECLARE(M_VBOXVFS);
+
@@ -788,7 +911,6 @@
+#include "../../../../../include/iprt/time.h"
+#include "../../../../../include/iprt/types.h"
+#include "../../../../../include/iprt/uni.h"
-+#include "../../common/VBoxGuestLib/SysHlp.h"
+#include "../../../../../include/iprt/nocrt/limits.h"
+#include "../../../../../include/iprt/alloc.h"
+#include "../../../../../include/iprt/asm.h"
@@ -816,22 +938,81 @@
#include <sys/mount.h>
-#include <sys/vnode.h>
+#include <sys/vnode.h>
++#include <sys/_timespec.h>
-struct vboxvfsmount {
+- uid_t uid;
+- gid_t gid;
+- mode_t file_mode;
+- mode_t dir_mode;
+- struct mount *mp;
+- struct ucred *owner;
+- u_int flags;
+- long nextino;
+- int caseopt;
+- int didrele;
+/*
+ * representation of an active mount point
+ */
+struct sfp_mount {
+ VBSFMAP map;
+ };
+
+-/* structs - stolen from the linux shared module code */
++/*
++ * Mount / Unmount a shared folder.
++ *
++ * sfprov_mount() takes as input the connection pointer and the name of
++ * the shared folder. On success, it returns zero and supplies an
++ * sfp_mount_t handle. On failure it returns any relevant errno value.
++ *
++ * sfprov_unmount() unmounts the mounted file system. It returns 0 on
++ * success and any relevant errno on failure.
++ */
++typedef struct sfp_mount sfp_mount_t;
++
++struct sfp_file {
++ SHFLHANDLE handle;
++ VBSFMAP map; /* need this again for the close operation */
+};
+
-+typedef struct sfp_mount sfp_mount_t;
++typedef struct sfp_file sfp_file_t;
++
++/*
++ * File operations: open/close/read/write/etc.
++ *
++ * open/create can return any relevant errno, however ENOENT
++ * generally means that the host file didn't exist.
++ */
++typedef struct sffs_stat {
++ mode_t sf_mode;
++ off_t sf_size;
++ off_t sf_alloc;
++ struct timespec sf_atime;
++ struct timespec sf_mtime;
++ struct timespec sf_ctime;
++} sffs_stat_t;
+
++/*
++ * Read directory entries.
++ */
++/*
++ * a singly linked list of buffers, each containing an array of stat's+dirent's.
++ * sf_len is length of the sf_entries array, in bytes.
++ */
++typedef struct sffs_dirents {
++ struct sffs_dirents *sf_next;
++ unsigned long long int sf_len;
++ struct sffs_dirent {
++ sffs_stat_t sf_stat;
++ struct dirent sf_entry; /* this is variable length */
++ } sf_entries[1];
++} sffs_dirents_t;
+
+/*
+ * Shared Folders filesystem per-mount data structure.
+ */
-+typedef struct vboxvfs_mnt {
++struct vboxvfs_mnt {
+ struct mount *sf_vfsp; /* filesystem's vfs struct */
+ struct vnode *sf_rootnode; /* of vnode of the root directory */
+ uid_t sf_uid; /* owner of all shared folders */
@@ -846,7 +1027,30 @@
+ char *sf_mntpath; /* name of mount point */
+ sfp_mount_t *sf_handle;
+ uint64_t sf_ino; /* per FS ino generator */
-+} vboxvfs_mnt_t;
++ off_t size;
++};
++
++/*
++ * vboxvfs_node is the file system dependent vnode data for vboxsf.
++ * vboxvfs_node's also track all files ever accessed, both open and closed.
++ * It duplicates some of the information in vnode, since it holds
++ * information for files that may have been completely closed.
++ *
++ */
++struct vboxvfs_node {
++ struct vboxvfs_mnt *vboxvfsmp; /* containing mounted file system */
++ char *sf_path; /* full pathname to file or dir */
++ uint64_t sf_ino; /* assigned unique ID number */
++ struct vnode *sf_vnode; /* vnode if active */
++ sfp_file_t *sf_file; /* non NULL if open */
++ struct vboxvfs_node *sf_parent; /* parent sfnode of this one */
++ uint16_t sf_children; /* number of children sfnodes */
++ uint8_t sf_type; /* VDIR or VREG */
++ uint8_t sf_is_stale; /* this is stale and should be purged */
++ sffs_stat_t sf_stat; /* cached file attrs for this node */
++ uint64_t sf_stat_time; /* last-modified time of sf_stat */
++ sffs_dirents_t *sf_dir_list; /* list of entries for this directory */
++};
+
+struct vboxvfs_mount_info {
+ char name[MAX_HOST_NAME];
@@ -856,43 +1060,6 @@
+ int ttl;
+};
+
-+#if 0
-+struct vboxvfs_mnt
-+{
-+ VBSFMAP map;
-+ int im_flags;
-+ struct mount *im_mountp;
-+ struct g_consumer *im_cp;
-+ struct bufobj *im_bo;
-+ struct cdev *im_dev;
-+ struct vnode *im_devvp;
-+ off_t size;
-+ int bsize;
-+ int bshift;
-+ int bmask;
-+ int use_devvp;
-+};
-+#endif
-+
-+/** VNode for VBoxVFS */
-+typedef struct vboxvfs_node
-+{
-+ struct vnode *i_vnode;
-+ struct vboxvfs_mnt *vboxvfsmp;
-+ ino_t hash_id;
-+} vboxvfs_vnode_t;
-+#if 0
-+struct vboxvfs_mount {
- uid_t uid;
- gid_t gid;
- mode_t file_mode;
-@@ -50,17 +156,27 @@
- int caseopt;
- int didrele;
- };
--
--/* structs - stolen from the linux shared module code */
-+#endif
struct sf_glob_info {
- VBSFMAP map;
+ VBSFMAP map;
@@ -910,17 +1077,104 @@
+/** Per-file system mount instance data. */
+typedef struct vboxvfs_globinfo
+{
-+ VBSFMAP Map;
-+ int Ttl;
-+ int Uid;
-+ int Gid;
-+ struct mount *pVFS;
-+ vboxvfs_vnode_t *pVNodeRoot;
++ VBSFMAP Map;
++ int Ttl;
++ int Uid;
++ int Gid;
++ struct mount *pVFS;
++ struct vboxvfs_node *pVNodeRoot;
+} vboxvfs_globinfo_t;
+
struct sf_inode_info {
SHFLSTRING *path;
int force_restat;
+@@ -86,6 +233,86 @@
+ SHFLHANDLE handle;
+ };
+
++/*
++ * Initialization and termination.
++ * sfprov_connect() is called once before any other interfaces and returns
++ * a handle used in further calls. The argument should be SFPROV_VERSION
++ * from above. On failure it returns a NULL pointer.
++ *
++ * sfprov_disconnect() must only be called after all sf file systems have been
++ * unmounted.
++ */
++typedef struct sfp_connection sfp_connection_t;
++
++extern sfp_connection_t *sfprov_connect(int);
++extern void sfprov_disconnect(sfp_connection_t *);
++extern int sfprov_mount(sfp_connection_t *, char *, sfp_mount_t **);
++extern int sfprov_unmount(sfp_mount_t *);
++
++/*
++ * query information about a mounted file system
++ */
++typedef struct sffs_fsinfo {
++ uint64_t blksize;
++ uint64_t blksused;
++ uint64_t blksavail;
++ uint32_t maxnamesize;
++ uint32_t readonly;
++} sffs_fsinfo_t;
++
++extern int sfprov_get_fsinfo(sfp_mount_t *, sffs_fsinfo_t *);
++
++extern int sfprov_create(sfp_mount_t *, char *path, mode_t mode,
++ sfp_file_t **fp, sffs_stat_t *stat);
++extern int sfprov_open(sfp_mount_t *, char *path, sfp_file_t **fp);
++extern int sfprov_close(sfp_file_t *fp);
++extern int sfprov_read(sfp_file_t *, char * buffer, uint64_t offset,
++ uint32_t *numbytes);
++extern int sfprov_write(sfp_file_t *, char * buffer, uint64_t offset,
++ uint32_t *numbytes);
++extern int sfprov_fsync(sfp_file_t *fp);
++
++
++/*
++ * get/set information about a file (or directory) using pathname
++ */
++extern int sfprov_get_mode(sfp_mount_t *, char *, mode_t *);
++extern int sfprov_get_size(sfp_mount_t *, char *, uint64_t *);
++extern int sfprov_get_atime(sfp_mount_t *, char *, struct timespec *);
++extern int sfprov_get_mtime(sfp_mount_t *, char *, struct timespec *);
++extern int sfprov_get_ctime(sfp_mount_t *, char *, struct timespec *);
++extern int sfprov_get_attr(sfp_mount_t *, char *, sffs_stat_t *);
++extern int sfprov_set_attr(sfp_mount_t *, char *, u_int, mode_t,
++ struct timespec, struct timespec, struct timespec);
++extern int sfprov_set_size(sfp_mount_t *, char *, uint64_t);
++
++
++/*
++ * File/Directory operations
++ */
++extern int sfprov_trunc(sfp_mount_t *, char *);
++extern int sfprov_remove(sfp_mount_t *, char *path, u_int is_link);
++extern int sfprov_mkdir(sfp_mount_t *, char *path, mode_t mode,
++ sfp_file_t **fp, sffs_stat_t *stat);
++extern int sfprov_rmdir(sfp_mount_t *, char *path);
++extern int sfprov_rename(sfp_mount_t *, char *from, char *to, u_int is_dir);
++
++
++/*
++ * Symbolic link operations
++ */
++extern int sfprov_set_show_symlinks(void);
++extern int sfprov_readlink(sfp_mount_t *, char *path, char *target,
++ size_t tgt_size);
++extern int sfprov_symlink(sfp_mount_t *, char *linkname, char *target,
++ sffs_stat_t *stat);
++
++#define SFFS_DIRENTS_SIZE 8192
++#define SFFS_DIRENTS_OFF (offsetof(sffs_dirents_t, sf_entries[0]))
++
++/*extern int sfprov_readdir(sfp_mount_t *mnt, char *path,
++ sffs_dirents_t **dirents); */
++
+ #endif /* KERNEL */
+
+ #endif /* !___VBOXVFS_H___ */
Index: src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk
===================================================================
--- src/VBox/Additions/freebsd/vboxvfs/Makefile.kmk (revision 4)
@@ -961,13 +1215,12 @@
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/vnode.h>
-@@ -29,8 +29,35 @@
+@@ -29,10 +29,40 @@
#include <sys/malloc.h>
#include <sys/module.h>
-#include <iprt/mem.h>
+#include "vboxvfs.h"
-+#include "vboxvfs_prov.h"
+#if 0
+#include <sys/types.h>
+#include <sys/param.h>
@@ -997,8 +1250,14 @@
+
#define VFSMP2SFGLOBINFO(mp) ((struct sf_glob_info *)mp->mnt_data)
++#ifdef MALLOC_DECLARE
++MALLOC_DEFINE(M_VBOXVFS, "vboxvfs", "VBOX VFS");
++#endif
++
static int vboxvfs_version = VBOXVFS_VERSION;
-@@ -51,15 +78,15 @@
+
+ SYSCTL_NODE(_vfs, OID_AUTO, vboxvfs, CTLFLAG_RW, 0, "VirtualBox shared filesystem");
+@@ -51,15 +81,15 @@
static vfs_unmount_t vboxvfs_unmount;
static struct vfsops vboxvfs_vfsops = {
@@ -1023,7 +1282,7 @@
};
-@@ -66,193 +93,238 @@
+@@ -66,193 +96,238 @@
VFS_SET(vboxvfs_vfsops, vboxvfs, VFCF_NETWORK);
MODULE_DEPEND(vboxvfs, vboxguest, 1, 1, 1);
@@ -1358,7 +1617,7 @@
+int vboxvfs_statfs(struct mount *mp, struct statfs *sbp)
{
- return 0;
-+ vboxvfs_mnt_t *vboxvfsmp;
++ struct vboxvfs_mnt *vboxvfsmp;
+ sffs_fsinfo_t fsinfo;
+// dev32_t d32;
+ int error;
@@ -1390,7 +1649,7 @@
===================================================================
--- src/VBox/Additions/freebsd/vboxvfs/vboxvfs_prov.c (revision 0)
+++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs_prov.c (working copy)
-@@ -0,0 +1,1021 @@
+@@ -0,0 +1,1011 @@
+/** @file
+ * VirtualBox File System for FreeBSD Guests, provider implementation.
+ * Portions contributed by: Ronald.
@@ -1429,15 +1688,10 @@
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/dirent.h>
-+#include <vboxvfs.h>
-+#include "vboxvfs_prov.h"
++#include "vboxvfs.h"
+
+#define SFPROV_VERSION 1
+
-+#ifdef MALLOC_DECLARE
-+MALLOC_DEFINE(M_VBOXVFS, "vboxvfs", "VBOX VFS");
-+#endif
-+
+static VBSFCLIENT vbox_client;
+
+static int sfprov_vbox2errno(int rc)
@@ -1689,11 +1943,6 @@
+ * open/create can return any relevant errno, however ENOENT
+ * generally means that the host file didn't exist.
+ */
-+struct sfp_file {
-+ SHFLHANDLE handle;
-+ VBSFMAP map; /* need this again for the close operation */
-+};
-+
+int
+sfprov_create(
+ sfp_mount_t *mnt,
@@ -2416,7 +2665,7 @@
===================================================================
--- src/VBox/Additions/freebsd/vboxvfs/vboxvfs_prov.h (revision 0)
+++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs_prov.h (working copy)
-@@ -0,0 +1,152 @@
+@@ -0,0 +1,154 @@
+/* $Id: vboxfs_prov.h $ */
+/** @file
+ * VirtualBox File System for FreeBSD Guests, provider header.
@@ -2469,6 +2718,7 @@
+extern sfp_connection_t *sfprov_connect(int);
+extern void sfprov_disconnect(sfp_connection_t *);
+extern int sfprov_mount(sfp_connection_t *, char *, sfp_mount_t **);
++
+extern int sfprov_unmount(sfp_mount_t *);
+
+/*
@@ -2498,6 +2748,7 @@
+ struct timespec sf_mtime;
+ struct timespec sf_ctime;
+} sffs_stat_t;
++
+typedef struct sfp_file sfp_file_t;
+
+extern int sfprov_create(sfp_mount_t *, char *path, mode_t mode,
More information about the svn-soc-all
mailing list