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