Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Jul 2013 21:22:45 GMT
From:      oleksandr@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r255173 - soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files
Message-ID:  <201307252122.r6PLMj6Y036807@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oleksandr
Date: Thu Jul 25 21:22:45 2013
New Revision: 255173
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255173

Log:
  Implemented initial version of vboxvfs_read and vboxvfs_readdir, now correctly working yet

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	Thu Jul 25 20:53:15 2013	(r255172)
+++ soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files/patch-src-VBox-Additions-freebsd.kmk	Thu Jul 25 21:22:45 2013	(r255173)
@@ -452,7 +452,7 @@
 ===================================================================
 --- src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h	(revision 4)
 +++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs.h	(working copy)
-@@ -21,46 +21,193 @@
+@@ -21,46 +21,200 @@
  #define VBOXVFS_VFSNAME "vboxvfs"
  #define VBOXVFS_VERSION 1
  
@@ -536,6 +536,10 @@
 -    long            nextino;
 -    int             caseopt;
 -    int             didrele;
++#define DIRENT_RECLEN(namelen)        \
++        ((offsetof(dirent, d_name[0]) + 1 + (namelen) + 7) & ~ 7)
++#define DIRENT_NAMELEN(reclen)        \
++        ((reclen) - (offsetof(dirent, d_name[0])))
 +/*
 + * representation of an active mount point
 + */
@@ -587,7 +591,7 @@
 + */
 +typedef struct sffs_dirents {
 +        struct sffs_dirents     *sf_next;
-+        unsigned long long int  sf_len;
++        long long sf_len;
 +        struct sffs_dirent {
 +                sffs_stat_t     sf_stat;
 +                struct dirent    sf_entry;      /* this is variable length */
@@ -599,7 +603,7 @@
 + */
 +struct vboxvfs_mnt {
 +        struct mount    *sf_vfsp;       /* filesystem's vfs struct */
-+        struct vnode    *sf_rootnode;   /* of vnode of the root directory */
++        struct vnode    *sf_devvp;   	/* of vnode of the root directory */
 +        uid_t           sf_uid;         /* owner of all shared folders */
 +        gid_t           sf_gid;         /* group of all shared folders */
 +        mode_t          sf_dmode;    	/* mode of all directories */
@@ -613,6 +617,9 @@
 +        sfp_mount_t     *sf_handle;
 +        uint64_t        sf_ino;         /* per FS ino generator */
 +	off_t		size;
++	int		bshift;
++	int		bmask;
++	struct bufobj	*sf_bo;
 +};
 +
 +/*
@@ -673,7 +680,7 @@
  struct sf_inode_info {
      SHFLSTRING *path;
      int force_restat;
-@@ -86,6 +233,86 @@
+@@ -86,6 +240,86 @@
      SHFLHANDLE handle;
  };
  
@@ -754,8 +761,8 @@
 +#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); */
++extern int sfprov_readdir(sfp_mount_t *mnt, char *path,
++        sffs_dirents_t **dirents); 
 +
  #endif  /* KERNEL */
  
@@ -764,7 +771,7 @@
 ===================================================================
 --- src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c	(revision 4)
 +++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs_vnops.c	(working copy)
-@@ -14,26 +14,28 @@
+@@ -14,27 +14,35 @@
   * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
   * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
   */
@@ -801,9 +808,16 @@
 +#include "vboxvfs.h"
 +
  /*
++ * For now we'll use an I/O buffer that doesn't page fault for VirtualBox
++ * to transfer data into.
++ */
++char *vboxvfs_buffer;
++
++/*
   * Prototypes for VBOXVFS vnode operations
   */
-@@ -56,6 +58,7 @@
+ static vop_create_t     vboxvfs_create;
+@@ -56,6 +64,7 @@
  static vop_symlink_t    vboxvfs_symlink;
  static vop_readdir_t    vboxvfs_readdir;
  static vop_strategy_t   vboxvfs_strategy;
@@ -811,10 +825,12 @@
  static vop_print_t      vboxvfs_print;
  static vop_pathconf_t   vboxvfs_pathconf;
  static vop_advlock_t    vboxvfs_advlock;
-@@ -65,177 +68,894 @@
+@@ -64,178 +73,1040 @@
+ static vop_getpages_t   vboxvfs_getpages;
  static vop_inactive_t   vboxvfs_inactive;
  static vop_putpages_t   vboxvfs_putpages;
- static vop_reclaim_t    vboxvfs_reclaim;
+-static vop_reclaim_t    vboxvfs_reclaim;
++static vop_reclaim_t   	vboxvfs_reclaim;
 +static vop_vptofh_t 	vboxvfs_vptofh;
  
  struct vop_vector vboxvfs_vnodeops = {
@@ -984,6 +1000,34 @@
 +                np->sf_file = fp;
 +}
 +
++/*
++ * get a new vnode reference for an sfnode
++ */
++#if 0
++struct vnode *
++vfsnode_get_vnode(struct vboxvfs_node *node)
++{
++        struct vnode *vp;
++
++        if (node->sf_vnode != NULL) {
++                vref(node->sf_vnode);
++        } else {
++                vp = vn_alloc(KM_SLEEP);
++        printf("  %s gets vnode 0x%p\n", node->sf_path, vp);
++                vp->v_type = node->sf_type;
++                vp->v_vfsp = node->sf_sffs->sf_vfsp;
++                vn_setops(vp, sffs_ops);
++                vp->v_flag = VNOSWAP;
++#ifndef VBOXVFS_WITH_MMAP
++                vp->v_flag |= VNOMAP;
++#endif
++                vn_exists(vp);
++                vp->v_data = node;
++                node->sf_vnode = vp;
++        }
++        return (node->sf_vnode);
++}
++#endif
  static int vboxvfs_open(struct vop_open_args *ap)
  {
 -    return 0;
@@ -1275,64 +1319,63 @@
 +        return (error);
  }
  
++#define blkoff(vboxvfsmp, loc)	((loc) & (vboxvfsmp)->bmask)
++
  static int vboxvfs_read(struct vop_read_args *ap)
  {
 -    return 0;
-+#if 0
-+	static const int clustersize = MAXBSIZE;
-+
-+	struct vnode *vp = ap->a_vp;
-+	struct uio *uio = ap->a_uio;
-+	struct vboxvfs_node *node = VTON(vp);
-+	struct vboxvfs_mnt *vboxvfsmp;
-+	struct buf *bp;
-+	daddr_t lbn;
-+	off_t diff, fsize;
-+	int error = 0;
-+	long size, n, on;
-+
-+	if (uio->uio_resid == 0)
-+		return (0);
-+	if (uio->uio_offset < 0)
-+		return (EINVAL);
++	static const int clustersize = MAXBSIZE;	
 +
-+	if (vp->v_type == VCHR || vp->v_type == VBLK)
-+		return (EOPNOTSUPP);
-+	if (vp->v_type != VREG)
-+		return (EINVAL);
++	struct vnode            *vp = ap->a_vp;
++	struct uio 		*uio = ap->a_uio;
++	struct vboxvfs_node	*np = VTOVBOXFS(vp);
++        int             	error = 0;
++        uint32_t        	bytes;
++        uint32_t        	done;
++        unsigned long         	offset;
++        ssize_t         	total;
++	long 			on;
++
++        if (vp->v_type == VDIR)
++                return (EISDIR);
++        if (vp->v_type != VREG)
++                return (EINVAL);
++#if 0
++        if (uio->uio_loffset >= MAXOFFSET_T)
++        {
++                proc_t *p = ttoproc(curthread);
++                (void) rctl_action(rctlproc_legacy[RLIMIT_FSIZE], p->p_rctls,
++                        p, RCA_UNSAFE_SIGINFO);
++                return (EFBIG);
++        }
++        if (uio->uio_loffset < 0)
++                return (EINVAL);
++#endif
++        total = uio->uio_resid;
++        if (total == 0)
++                return (0);
 +
-+	vboxvfsmp = node->vboxvfsmp;
-+	fsize = vboxvfsmp->size;
++        vfsnode_open(np);
++        if (np->sf_file == NULL) {
++                return (EINVAL);
++        }
 +
-+	do {
-+		lbn = lblkno(vboxvfsmp, uio->uio_offset);
-+		on = blkoff(vboxvfsmp, uio->uio_offset);
-+		n = min((u_int)(clustersize - on), uio->uio_resid);
-+		diff = fsize - uio->uio_offset;
-+		if (diff <= 0)
-+			return (0);
-+		if (diff < n)
-+			n = diff;
++        do {
++                offset = uio->uio_offset;
++		on = blkoff(np->vboxvfsmp, uio->uio_offset);
++                done = bytes = min((u_int)(clustersize - on), uio->uio_resid);
++                error = sfprov_read(np->sf_file, vboxvfs_buffer, offset, &done);
++                if (error == 0 && done > 0)
++                        error = uiomove(vboxvfs_buffer, done, uio);
++        } while (error == 0 && uio->uio_resid > 0 && done > 0);
 +
-+		size = (n + vboxvfsmp->bmask) & ~vboxvfsmp->bmask;
-+		if (vboxvfsmp->use_devvp)
-+			error = bread(vboxvfsmp->im_devvp,
-+			    lbn << (vboxvfsmp->bshift - DEV_BSHIFT),
-+			    size, NOCRED, &bp);
-+		else
-+			error = bread(vp, lbn, size, NOCRED, &bp);
 +
-+		n = min(n, size - bp->b_resid);
-+		if (error) {
-+			brelse(bp);
-+			return (error);
-+		}
-+		error = uiomove(bp->b_data + on, (int)n, uio);
-+		brelse(bp);
-+	} while (error == 0 && uio->uio_resid > 0 && n != 0);
-+	return (error);
-+#endif
-+	return (0);
++        /*
++         * a partial read is never an error
++         */
++        if (total != uio->uio_resid)
++                error = 0;
++        return (error);
  }
  
  static int vboxvfs_write(struct vop_write_args *ap)
@@ -1419,100 +1462,123 @@
  static int vboxvfs_readdir(struct vop_readdir_args *ap)
  {
 -    return 0;
++	struct vnode *vp = ap->a_vp;
++	struct uio *uio = ap->a_uio;
++	struct vboxvfs_node *dir = VTOVBOXFS(vp);
++        struct vboxvfs_node *node;
++        struct sffs_dirent *dirent = NULL;
++        sffs_dirents_t *cur_buf;
++        off_t offset = 0;
++        off_t orig_off = uio->uio_offset;
++        int error = 0;
 +#if 0
-+	struct vnode *vp;
-+	struct uio *uio;
-+	struct dirent dir;
-+	struct vboxvfs_node *node;
-+	struct vboxvfs_mnt *vboxvfsmp;
-+	struct vboxvfs_uiodir uiodir;
-+	u_long *cookies = NULL;
-+	int ncookies;
-+	int error = 0;
++        if (uio->uio_iovcnt != 1)
++                return (EINVAL);
 +
-+	vp = ap->a_vp;
-+	uio = ap->a_uio;
-+	node = VTON(vp);
-+	vboxvfsmp = node->vboxvfsmp;
-+	uiodir.eofflag = 1;
++        if (vp->v_type != VDIR)
++                return (ENOTDIR);
 +
-+	if (a->a_ncookies != NULL) {
-+		/*
-+		 * Guess how many entries are needed.  If we run out, this
-+		 * function will be called again and thing will pick up were
-+		 * it left off.
-+		 */
-+		ncookies = uio->uio_resid / 8;
-+		cookies = malloc(sizeof(u_long) * ncookies,
-+		    M_TEMP, M_WAITOK);
-+		if (cookies == NULL)
-+			return (ENOMEM);
-+		uiodir.ncookies = ncookies;
-+		uiodir.cookies = cookies;
-+		uiodir.acookies = 0;
-+	} else {
-+		uiodir.cookies = NULL;
-+	}
++        if (eofp == NULL)
++                eofp = &dummy_eof;
++        *eofp = 0;
++
++        if (uio->uio_loffset >= MAXOFFSET_T) {
++                *eofp = 1;
++                return (0);
++        }
++#endif
++        /*
++         * Get the directory entry names from the host. This gets all
++         * entries. These are stored in a linked list of sffs_dirents_t
++         * buffers, each of which contains a list of dirent64_t's.
++         */
 +
-+	/* Do up the '.' and '..' entries.  Dummy values are
-+	 * used for the cookies since the offset here is
-+	 * usually zero, and NFS doesn't like that value
-+	 */
-+	if (uio->uio_offset == 0) {
-+		dir.d_fileno = node->hash_id; /* AVG_ROOTDIR_INO */
-+		dir.d_type = DT_DIR;
-+		dir.d_name[0] = '.';
-+		dir.d_name[1] = '\0';
-+		dir.d_namlen = 1;
-+		dir.d_reclen = GENERIC_DIRSIZ(&dir);
-+		uiodir.dirent = &dir;
-+		error = vboxvfs_uiodir(&uiodir, dir.d_reclen, uio, 1);
-+		if (error)
-+			goto finished;
-+
-+		dir.d_fileno = node->hash_id; /* AVG_ROOTDIR_INO */
-+		dir.d_type = DT_DIR;
-+		dir.d_name[0] = '.';
-+		dir.d_name[1] = '.';
-+		dir.d_name[2] = '\0';
-+		dir.d_namlen = 2;
-+		dir.d_reclen = GENERIC_DIRSIZ(&dir);
-+		uiodir.dirent = &dir;
-+		error = vboxvfs_uiodir(&uiodir, dir.d_reclen, uio, 2);
-+		if (error)
-+			goto finished;
-+
-+		strcpy(&dir.d_name[0], AVG_THEFILE_NAME);
-+		dir.d_namlen = strlen(AVG_THEFILE_NAME);
-+		dir.d_fileno = AVG_THEFILE_INO;
-+		dir.d_type = DT_REG;
-+		dir.d_reclen = GENERIC_DIRSIZ(&dir);
-+		uiodir.dirent = &dir;
-+		error = vboxvfs_uiodir(&uiodir, dir.d_reclen, uio, 3);
-+		if (error)
-+			goto finished;
-+	}
-+
-+finished:
-+
-+	/* tell the calling layer whether we need to be called again */
-+	*ap->a_eofflag = uiodir.eofflag;
-+
-+	if (error < 0)
-+		error = 0;
-+
-+	if (ap-g>a_ncookies != NULL) {
-+		if (error)
-+			free(cookies, M_TEMP);
-+		else {
-+			*ap->a_ncookies = uiodir.acookies;
-+			*ap->a_cookies = cookies;
-+		}
-+	}
++        if (dir->sf_dir_list == NULL) {
++                error = sfprov_readdir(dir->vboxvfsmp->sf_handle, dir->sf_path,
++                    &dir->sf_dir_list);
++                if (error != 0)
++                        goto done;
++        }
 +
-+	return (error);
++        /*
++         * Validate and skip to the desired offset.
++         */
++        cur_buf = dir->sf_dir_list;
++        offset = 0;
++
++        while (cur_buf != NULL &&
++            offset + cur_buf->sf_len <= uio->uio_offset) {
++                offset += cur_buf->sf_len;
++                cur_buf = cur_buf->sf_next;
++        }
++	
++	if (cur_buf == NULL && offset != uio->uio_offset) {
++                error = EINVAL;
++                goto done;
++        }
++        if (cur_buf != NULL && offset != uio->uio_offset) {
++                off_t off = offset;
++                int step;
++                dirent = &cur_buf->sf_entries[0];
++
++                while (off < uio->uio_offset) {
++                        step = sizeof(sffs_stat_t) + dirent->sf_entry.d_reclen;
++                        dirent = (struct sffs_dirent *) (((char *) dirent) + step);
++                        off += step;
++                }
++
++                if (off >= uio->uio_offset) {
++                        error = EINVAL;
++                        goto done;
++                }
++        }
++
++        offset = uio->uio_offset - offset;
++
++	/*
++         * Lookup each of the names, so that we have ino's, and copy to
++         * result buffer.
++         */
++        while (cur_buf != NULL) {
++                if (offset >= cur_buf->sf_len) {
++                        cur_buf = cur_buf->sf_next;
++                        offset = 0;
++                        continue;
++                }
++
++                dirent = (struct sffs_dirent *)
++                    (((char *) &cur_buf->sf_entries[0]) + offset);
++                if (dirent->sf_entry.d_reclen > uio->uio_resid)
++                        break;
++
++                if (strcmp(dirent->sf_entry.d_name, ".") == 0) {
++                        node = dir;
++                } else if (strcmp(dirent->sf_entry.d_name, "..") == 0) {
++                        node = dir->sf_parent;
++                        if (node == NULL)
++                                node = dir;
++                } else {
++#if 0
++                        node = sfnode_lookup(dir, dirent->sf_entry.d_name, VNON,
++                                0, &dirent->sf_stat, sfnode_cur_time_usec(), NULL);
++                        if (node == NULL)
++                                panic("sffs_readdir() lookup failed");
 +#endif
-+	return (0);
++                }
++
++                error = uiomove(&dirent->sf_entry, dirent->sf_entry.d_reclen, uio);
++                if (error != 0)
++                        break;
++
++                uio->uio_offset= dirent->sf_entry.d_fileno;
++                offset += sizeof(sffs_stat_t) + dirent->sf_entry.d_reclen;
++        }
++done:
++#if 0
++        if (error != 0)
++           uio->uio_offset = orig_off;
++#endif
++        return (error);
  }
  
  static int vboxvfs_fsync(struct vop_fsync_args *ap)
@@ -1524,15 +1590,19 @@
  static int vboxvfs_print (struct vop_print_args *ap)
  {
 -    return 0;
-+#if 0
 +	struct vnode *vp = ap->a_vp;
-+	struct vboxvfs_node *node;
++	struct vboxvfs_node *np;
++
++	np = VTOVBOXFS(vp);
 +
-+	node = VTON(vp);
-+	printf("    ino %lu, on dev %s", (u_long)node->hash_id,
-+	    devtoname(node->vboxvfsmp->im_dev));
++	if (np == NULL) {
++                printf("No vboxvfs_node data\n");
++                return (0);
++        }
++
++	printf("\tpath = %s, parent = %p", np->sf_path,
++            np->sf_parent ? np->sf_parent : NULL);
 +	printf("\n");
-+#endif
 +	return (0);
  }
  
@@ -1562,49 +1632,47 @@
  static int vboxvfs_strategy (struct vop_strategy_args *ap)
  {
 -    return 0;
-+#if 0
 +	struct buf *bp;
 +	struct vnode *vp;
-+	struct vboxvfs_node *node;
++	struct vboxvfs_node *np;
 +	struct bufobj *bo;
 +
 +	bp = ap->a_bp;
 +	vp = ap->a_vp;
-+	node = VTON(vp);
++	np = VTOVBOXFS(vp);
 +
 +	if (bp->b_blkno == bp->b_lblkno) {
-+		bp->b_blkno = bp->b_lblkno << (node->vboxvfsmp->bshift - DEV_BSHIFT);
++		bp->b_blkno = bp->b_lblkno << (np->vboxvfsmp->bshift - DEV_BSHIFT);
 +	}
-+	bo = node->vboxfsmp->im_bo;
++	bo = np->vboxvfsmp->sf_bo;
 +	bp->b_iooffset = dbtob(bp->b_blkno);
 +	BO_STRATEGY(bo, bp);
-+#endif
 +	return (0);
  }
  
 +static int
 +vboxvfs_bmap(struct vop_bmap_args *ap)
 +{
-+#if 0
-+	struct vboxvfs_node *node;
-+
-+	node = VTON(ap->a_vp);
++	struct vnode *vp;	
++	struct vboxvfs_node *np;
++	
++	vp = ap->a_vp;
++	np = VTOVBOXFS(vp);
 +
 +	if (ap->a_bop != NULL)
-+		*ap->a_bop = &node->vboxvfsmp->im_devvp->v_bufobj;
++		*ap->a_bop = &np->vboxvfsmp->sf_devvp->v_bufobj;
 +	if (ap->a_bnp == NULL)
 +		return (0);
 +	if (ap->a_runb)
 +		*ap->a_runb = 0;
 +
 +	/* Translate logical to physical sector number */
-+	*ap->a_bnp = ap->a_bn << (node->vboxvfsmp->bshift - DEV_BSHIFT);
++	*ap->a_bnp = ap->a_bn << (np->vboxvfsmp->bshift - DEV_BSHIFT);
 +
 +	if (ap->a_runp)
 +		*ap->a_runp = 0;
 +	if (ap->a_runb)
 +		*ap->a_runb = 0;
-+#endif
 +	return (0);
 +}
 +
@@ -1630,83 +1698,179 @@
 +    	return (0);
  }
  
- static int vboxvfs_lookup(struct vop_lookup_args *ap)
- {
--    return 0;
+-static int vboxvfs_lookup(struct vop_lookup_args *ap)
++/*
++ * Look for a cached node, if not found either handle ".." or try looking
++ * via the provider. Create an entry in sfnodes if found but not cached yet.
++ * If the create flag is set, a file or directory is created. If the file
++ * already existed, an error is returned.
++ * Nodes returned from this routine always have a vnode with its ref count
++ * bumped by 1.
++ */
 +#if 0
-+	struct vnode *dvp;
-+	struct vnode *tdp = NULL;
-+	struct vnode **vpp = ap->a_vpp;
-+	struct vboxvfs_node *node;
-+	struct vboxvfs_mnt *vboxvfsmp;
-+	u_long nameiop;
-+	u_long flags;
-+	char *nameptr;
-+	long namelen;
-+	ino_t id = 0;
-+	int offset, error = 0;
-+	int lkflags, ltype;
++static struct vboxvfs_node *
++vfsnode_lookup(
++        struct vboxvfs_node *dir,
++        char *name,
++        vtype_t create,
++        mode_t c_mode,
++        sffs_stat_t *stat,
++        uint64_t stat_time,
++        int *err)
+ {
+-    return 0;
++        avl_index_t     where;
++        vboxvfs_node    template;
++        vboxvfs_node    *node;
++        int             error = 0;
++        int             type;
++        char            *fullpath;
++        sfp_file_t      *fp;
++        sffs_stat_t     tmp_stat;
++
++        if (err)
++                *err = error;
++
++        /*
++         * handle referencing myself
++         */
++        if (strcmp(name, "") == 0 || strcmp(name, ".") == 0)
++                return (dir);
++
++        /*
++         * deal with parent
++         */
++        if (strcmp(name, "..") == 0)
++                return (dir->sf_parent);
++
++        /*
++         * Look for an existing node.
++         */
++        fullpath = sfnode_construct_path(dir, name);
++        template.sf_sffs = dir->sf_sffs;
++        template.sf_path = fullpath;
++        template.sf_is_stale = 0;
++        node = avl_find(&sfnodes, &template, &where);
++        if (node != NULL) {
++                free(fullpath, M_VBOXVFS);
++                if (create != VNON)
++                        return (NULL);
++                return (node);
++        }
 +
++	/*
++         * No entry for this path currently.
++         * Check if the file exists with the provider and get the type from
++         * there.
++         */
++        if (create == VREG) {
++                type = VREG;
++                stat = &tmp_stat;
++                error = sfprov_create(dir->sf_sffs->sf_handle, fullpath, c_mode,
++                                        &fp, stat);
++                stat_time = sfnode_cur_time_usec();
++        } else if (create == VDIR) {
++                type = VDIR;
++                stat = &tmp_stat;
++                error = sfprov_mkdir(dir->sf_sffs->sf_handle, fullpath, c_mode,
++                                        &fp, stat);
++                stat_time = sfnode_cur_time_usec();
++        } else {
++                mode_t m;
++                fp = NULL;
++                type = VNON;
++                if (stat == NULL) {
++                        stat = &tmp_stat;
++                        error = sfprov_get_attr(dir->sf_sffs->sf_handle,
++                            fullpath, stat);
++                        stat_time = sfnode_cur_time_usec();
++                } else {
++                        error = 0;
++                }
++                m = stat->sf_mode;
++                if (error != 0)
++                        error = ENOENT;
++                else if (S_ISDIR(m))
++                        type = VDIR;
++                else if (S_ISREG(m))
++                        type = VREG;
++                else if (S_ISLNK(m))
++                        type = VLNK;
++        }
++
++        if (err)
++                *err = error;
++
++        /*
++         * If no errors, make a new node and return it.
++         */
++        if (error) {
++                kmem_free(fullpath, strlen(fullpath) + 1);
++                return (NULL);
++        }
++        node = sfnode_make(dir->sf_sffs, fullpath, type, fp, dir, stat,
++            stat_time);
++        return (node);
+ }
++#endif
++	
++static int vboxvfs_lookup(struct vop_lookup_args /* {
++		struct vnodeop_desc *a_desc;
++                struct vnode *a_dvp;
++                struct vnode **a_vpp;
++                struct componentname *a_cnp;
++        } */ *ap)
++{
++#if 0
++	struct componentname *cnp = ap->a_cnp;
++	struct vnode 	*dvp;
++	struct vnode 	*vpp;
++        struct vboxvfs_node    *np;
++	char *name = cnp->cn_nameptr;
++	int             error;
+ 
 +	dvp = ap->a_dvp;
-+	node = VTON(dvp);
-+	vboxvfsmp = node->vboxvfsmp;
-+	nameiop = ap->a_cnp->cn_nameiop;
-+	flags = ap->a_cnp->cn_flags;
-+	lkflags = ap->a_cnp->cn_lkflags;
-+	nameptr = ap->a_cnp->cn_nameptr;
-+	namelen = ap->a_cnp->cn_namelen;
++	vpp = ap->a_vvp;
 +
-+	offset = 0;
++        /*
++         * dvp must be a directory
++         */
++        if (dvp->v_type != VDIR)
++                return (ENOTDIR);
 +
-+	if (strcmp(nameptr, AVG_THEFILE_NAME) == 0)
-+		id = AVG_THEFILE_INO;
-+	else if (flags & ISDOTDOT)
-+		id = AVG_ROOTDIR_INO;
-+
-+	/* Did we have a match? */
-+	if (id) {
-+		if (flags & ISDOTDOT) {
-+			error = vn_vget_ino(dvp, id, lkflags, &tdp);
-+		} else if (node->hash_id == id) {
-+			VREF(dvp);	/* we want ourself, ie "." */
-+			/*
-+			 * When we lookup "." we still can be asked to lock it
-+			 * differently.
-+			 */
-+			ltype = lkflags & LK_TYPE_MASK;
-+			if (ltype != VOP_ISLOCKED(dvp)) {
-+				if (ltype == LK_EXCLUSIVE)
-+					vn_lock(dvp, LK_UPGRADE | LK_RETRY);
-+				else /* if (ltype == LK_SHARED) */
-+					vn_lock(dvp, LK_DOWNGRADE | LK_RETRY);
-+			}
-+			tdp = dvp;
-+		} else
-+			error = vboxvfs_vget(vboxvfsmp->im_mountp, id, lkflags, &tdp);
-+		if (!error) {
-+			*vpp = tdp;
-+			/* Put this entry in the cache */
-+			if (flags & MAKEENTRY)
-+				cache_enter(dvp, *vpp, ap->a_cnp);
-+		}
-+	} else {
-+		/* Enter name into cache as non-existant */
-+		if (flags & MAKEENTRY)
-+			cache_enter(dvp, *vpp, ap->a_cnp);
-+
-+		if ((flags & ISLASTCN) &&
-+		    (nameiop == CREATE || nameiop == RENAME)) {
-+			error = EROFS;
-+		} else {
-+			error = ENOENT;
-+		}
-+	}
++        /*
++         * An empty component name or just "." means the directory itself.
++         * Don't do any further lookup or checking.
++         */
++        if (strcmp(name, "") == 0 || strcmp(name, ".") == 0) {
++                vref(dvp);
++                *vpp = dvp;
++                return (0);
++        }
++
++        /*
++         * Check permission to look at this directory. We always allow "..".
++         */
++
++        if (strcmp(nameiop, "..") != 0) {
++                error = vfsnode_access(VN2SFN(dvp), VEXEC, cred);
++                if (error) {
++                        return (error);
++                }
++        }
++
++        /*
++         * Lookup the node.
++         */
++        np = vfsnode_lookup(VTOVBOXFS(dvp), name, VNON, 0, NULL, 0, NULL);
++        if (node != NULL)
++                *vpp = vfsnode_get_vnode(np);
++        return ((np == NULL) ? ENOENT : 0);
 +
-+	return (error);
 +#endif
 +	return (0);
- }
- 
++}
++
  static int vboxvfs_inactive(struct vop_inactive_args *ap)
  {
 -    return 0;
@@ -1716,24 +1880,22 @@
  static int vboxvfs_reclaim(struct vop_reclaim_args *ap)
  {
 -    return 0;
-+#if 0
 +	struct vnode *vp;
-+	struct vboxvfs_node *unode;
++	struct vboxvfs_node *np;
 +
 +	vp = ap->a_vp;
-+	unode = VTON(vp);
++	np = VTOVBOXFS(vp);
 +
 +	/*
 +	 * Destroy the vm object and flush associated pages.
 +	 */
 +	vnode_destroy_vobject(vp);
 +
-+	if (unode != NULL) {
++	if (np != NULL) {
 +		vfs_hash_remove(vp);
-+		free(unode, M_AVGFS);
++		free(np, M_VBOXVFS);
 +		vp->v_data = NULL;
 +	}
-+#endif
 +	return (0);
  }
  
@@ -1787,7 +1949,7 @@
 ===================================================================
 --- src/VBox/Additions/freebsd/vboxvfs/vboxvfs_prov.c	(revision 0)
 +++ src/VBox/Additions/freebsd/vboxvfs/vboxvfs_prov.c	(working copy)
-@@ -0,0 +1,1010 @@
+@@ -0,0 +1,1009 @@
 +/** @file
 + * VirtualBox File System for FreeBSD Guests, provider implementation.
 + * Portions contributed by: Ronald.
@@ -1821,6 +1983,7 @@
 +#include <sys/types.h>
 +#include <sys/stat.h>
 +#include <sys/param.h>
++#include <sys/systm.h>
 +#include <sys/kernel.h>
 +#include <sys/malloc.h>
 +#include <sys/mount.h>
@@ -2653,7 +2816,6 @@
 + * for each dirent, all fields except the d_ino will be set appropriately.
 + * The caller is responsible for freeing the dirents buffer.
 + */
-+#if 0
 +int
 +sfprov_readdir(
 +	sfp_mount_t *mnt,
@@ -2745,7 +2907,7 @@
 +		 */
 +		for (info = infobuff; (char *) info < (char *) infobuff + numbytes; nents--) {
 +			/* expand buffers if we need more space */
-+			reclen = DIRENT64_RECLEN(strlen(info->name.String.utf8));
++			reclen = DIRENT_RECLEN(strlen(info->name.String.utf8));
 +			entlen = sizeof(sffs_stat_t) + reclen;
 +			if (SFFS_DIRENTS_OFF + cur_buf->sf_len + entlen > SFFS_DIRENTS_SIZE) {
 +				cur_buf->sf_next = malloc(SFFS_DIRENTS_SIZE, M_VBOXVFS, M_WAITOK | M_ZERO);
@@ -2761,7 +2923,7 @@
 +			/* create the dirent with the name, offset, and len */
 +			dirent = (struct sffs_dirent *)
 +			    (((char *) &cur_buf->sf_entries[0]) + cur_buf->sf_len);
-+			strncpy(&dirent->sf_entry.d_name[0], info->name.String.utf8, DIRENT64_NAMELEN(reclen));
++			strncpy(&dirent->sf_entry.d_name[0], info->name.String.utf8, DIRENT_NAMELEN(reclen));
 +			dirent->sf_entry.d_reclen = reclen;
 +			offset += entlen;
 +			dirent->sf_entry.d_off = offset;
@@ -2774,8 +2936,8 @@
 +			size = offsetof (SHFLDIRINFO, name.String) + info->name.u16Size;
 +			info = (SHFLDIRINFO *) ((uintptr_t) info + size);
 +		}
-+		ASSERT(nents == 0);
-+		ASSERT((char *) info == (char *) infobuff + numbytes);
++		CTASSERT(nents == 0);
++		CTASSERT((char *) info == (char *) infobuff + numbytes);
 +
 +		if (error == VERR_NO_MORE_FILES)
 +			break;
@@ -2797,7 +2959,6 @@
 +	sfprov_close(fp);
 +	return (error);
 +}
-+#endif
 Index: src/VBox/Additions/freebsd/Makefile.kmk
 ===================================================================
 --- src/VBox/Additions/freebsd/Makefile.kmk	(revision 4)
@@ -2811,3 +2972,16 @@
  include $(PATH_SUB_CURRENT)/drm/Makefile.kmk
  
  #
+Index: src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c
+===================================================================
+--- src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c	(revision 4)
++++ src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c	(working copy)
+@@ -2367,7 +2367,7 @@
+ 	VOPNAME_LOOKUP,		{ .vop_lookup = sffs_lookup },
+ 	VOPNAME_MKDIR,		{ .vop_mkdir = sffs_mkdir },
+ 	VOPNAME_OPEN,		{ .vop_open = sffs_open },
+-	VOPNAME_PATHCONF,	{ .vop_pathconf = sffs_pathconf },
++	VOPNAME_PATHCONF,	{ .vop_pathconf = sffs_athconf },
+ 	VOPNAME_READ,		{ .vop_read = sffs_read },
+ 	VOPNAME_READDIR,	{ .vop_readdir = sffs_readdir },
+ 	VOPNAME_READLINK,	{ .vop_readlink = sffs_readlink },



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307252122.r6PLMj6Y036807>