From owner-svn-soc-all@FreeBSD.ORG Thu Jul 25 21:22:46 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id F1797946 for ; Thu, 25 Jul 2013 21:22:45 +0000 (UTC) (envelope-from oleksandr@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id CF04320E1 for ; Thu, 25 Jul 2013 21:22:45 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6PLMj7R036816 for ; Thu, 25 Jul 2013 21:22:45 GMT (envelope-from oleksandr@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6PLMj6Y036807 for svn-soc-all@FreeBSD.org; Thu, 25 Jul 2013 21:22:45 GMT (envelope-from oleksandr@FreeBSD.org) Date: Thu, 25 Jul 2013 21:22:45 GMT Message-Id: <201307252122.r6PLMj6Y036807@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to oleksandr@FreeBSD.org using -f From: oleksandr@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r255173 - soc2013/oleksandr/ports/emulators/virtualbox-ose-additions/files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Jul 2013 21:22:46 -0000 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 +#include +#include ++#include +#include +#include +#include @@ -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 },