FreeBSD Bugzilla – Attachment 244335 Details for
Bug 245865
emulators/virtualbox-ose-additions: doesn't let go of files placed on a Windows host shared folder
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for the vboxvfs module source (VirtualBox-6.1.46/src/VBox/Additions/freebsd/vboxvfs)
for-vboxvfs-module-source.patch (text/plain), 10.96 KB, created by
takahiro.kurosawa
on 2023-08-25 10:50:19 UTC
(
hide
)
Description:
Patch for the vboxvfs module source (VirtualBox-6.1.46/src/VBox/Additions/freebsd/vboxvfs)
Filename:
MIME Type:
Creator:
takahiro.kurosawa
Created:
2023-08-25 10:50:19 UTC
Size:
10.96 KB
patch
obsolete
>diff --git a/vboxvfs.h b/vboxvfs.h >index 4bd6e34..0c77793 100644 >--- a/vboxvfs.h >+++ b/vboxvfs.h >@@ -224,6 +224,7 @@ struct vboxfs_node { > struct vnode *sf_vnode; /* vnode if active */ > sfp_file_t *sf_file; /* non NULL if open */ > struct vboxfs_node *sf_parent; /* parent sfnode of this one */ >+ uint32_t sf_opencnt; /* sf_file reference counter */ > uint16_t sf_children; /* number of children sfnodes */ > uint8_t sf_type; /* VDIR or VREG */ > uint8_t sf_vpstate; /* XXX: ADD COMMENT */ >@@ -232,7 +233,7 @@ struct vboxfs_node { > uint64_t sf_stat_time; /* last-modified time of sf_stat */ > sffs_dirents_t *sf_dir_list; /* list of entries for this directory */ > >- /* interlock to protect sf_vpstate */ >+ /* interlock to protect sf_vpstate, sf_file and sf_opencnt */ > struct mtx sf_interlock; > }; > >@@ -340,7 +341,7 @@ typedef struct sffs_fsinfo { > 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); >+ 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, >@@ -370,7 +371,7 @@ extern int sfprov_set_size(sfp_mount_t *, char *, uint64_t); > 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); >+ 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); > >diff --git a/vboxvfs_prov.c b/vboxvfs_prov.c >index da90630..6933321 100644 >--- a/vboxvfs_prov.c >+++ b/vboxvfs_prov.c >@@ -305,7 +305,6 @@ sfprov_create( > sfp_mount_t *mnt, > char *path, > mode_t mode, >- sfp_file_t **fp, > sffs_stat_t *stat) > { > int rc; >@@ -330,10 +329,7 @@ sfprov_create( > return (EEXIST); > return (ENOENT); > } >- newfp = malloc(sizeof(sfp_file_t), M_VBOXVFS, M_WAITOK | M_ZERO); >- newfp->handle = parms.Handle; >- newfp->map = mnt->map; >- *fp = newfp; >+ (void)VbglR0SfClose(&vbox_client, &mnt->map, parms.Handle); > sfprov_stat_from_info(stat, &parms.Info); > return (0); > } >@@ -710,14 +706,12 @@ sfprov_mkdir( > sfp_mount_t *mnt, > char *path, > mode_t mode, >- sfp_file_t **fp, > sffs_stat_t *stat) > { > int rc; > SHFLCREATEPARMS parms; > SHFLSTRING *str; > int size; >- sfp_file_t *newfp; > > str = sfprov_string(path, &size); > parms.Handle = SHFL_HANDLE_NIL; >@@ -735,10 +729,7 @@ sfprov_mkdir( > return (EEXIST); > return (ENOENT); > } >- newfp = malloc(sizeof(sfp_file_t), M_VBOXVFS, M_WAITOK | M_ZERO); >- newfp->handle = parms.Handle; >- newfp->map = mnt->map; >- *fp = newfp; >+ (void)VbglR0SfClose(&vbox_client, &mnt->map, parms.Handle); > sfprov_stat_from_info(stat, &parms.Info); > return (0); > } >diff --git a/vboxvfs_vnops.c b/vboxvfs_vnops.c >index ef05842..a6725be 100644 >--- a/vboxvfs_vnops.c >+++ b/vboxvfs_vnops.c >@@ -55,7 +55,8 @@ static vop_write_t vboxfs_write; > static vop_fsync_t vboxfs_fsync; > static vop_remove_t vboxfs_remove; > static vop_link_t vboxfs_link; >-static vop_cachedlookup_t vboxfs_lookup; >+static vop_lookup_t vboxfs_lookup; >+static vop_cachedlookup_t vboxfs_cachedlookup; > static vop_rename_t vboxfs_rename; > static vop_mkdir_t vboxfs_mkdir; > static vop_rmdir_t vboxfs_rmdir; >@@ -82,8 +83,8 @@ struct vop_vector vboxfs_vnodeops = { > .vop_inactive = vboxfs_inactive, > .vop_ioctl = vboxfs_ioctl, > .vop_link = vboxfs_link, >- .vop_lookup = vfs_cache_lookup, >- .vop_cachedlookup = vboxfs_lookup, >+ .vop_lookup = vboxfs_lookup, >+ .vop_cachedlookup = vboxfs_cachedlookup, > .vop_mkdir = vboxfs_mkdir, > .vop_mknod = VOP_EOPNOTSUPP, > .vop_open = vboxfs_open, >@@ -386,13 +387,15 @@ static char * > sfnode_construct_path(struct vboxfs_node *node, char *tail, int len) > { > char *p; >+ size_t dstsz; > > if (len <= 2 && tail[0] == '.' && (len == 1 || tail[1] == '.')) > panic("construct path for %s", tail); >- p = malloc(strlen(node->sf_path) + 1 + len + 1, M_VBOXVFS, M_WAITOK); >+ dstsz = strlen(node->sf_path) + 1 + len + 1; >+ p = malloc(dstsz, M_VBOXVFS, M_WAITOK); > strcpy(p, node->sf_path); > strcat(p, "/"); >- strcat(p, tail); >+ strlcat(p, tail, dstsz); > return (p); > } > >@@ -449,23 +452,66 @@ vfsnode_clear_dir_list(struct vboxfs_node *np) > } > } > >+static int >+vboxfs_get_sfp_file(struct vboxfs_node *np) >+{ >+ sfp_file_t *fp; >+ int error; >+ >+ fp = NULL; >+ VBOXFS_NODE_LOCK(np); >+ for (;;) { >+ if (np->sf_file != NULL) { >+ if (fp != NULL) >+ (void) sfprov_close(fp); >+ np->sf_opencnt++; >+ fp = np->sf_file; >+ break; >+ } else if (fp != NULL) { >+ np->sf_file = fp; >+ KASSERT(np->sf_opencnt == 0, >+ ("np %p opencnt (%d) must be zero.", >+ np, np->sf_opencnt)); >+ np->sf_opencnt = 1; >+ break; >+ } >+ VBOXFS_NODE_UNLOCK(np); >+ error = sfprov_open(np->vboxfsmp->sf_handle, np->sf_path, &fp); >+ if (error != 0) >+ return (error); >+ VBOXFS_NODE_LOCK(np); >+ } >+ VBOXFS_NODE_UNLOCK(np); >+ >+ return (0); >+} >+ >+static void >+vboxfs_put_sfp_file(struct vboxfs_node *np) >+{ >+ VBOXFS_NODE_LOCK(np); >+ np->sf_opencnt--; >+ if (np->sf_opencnt == 0) { >+ (void) sfprov_close(np->sf_file); >+ np->sf_file = NULL; >+ } >+ VBOXFS_NODE_UNLOCK(np); >+} >+ > static int > vboxfs_open(struct vop_open_args *ap) > { > struct vboxfs_node *np; >- sfp_file_t *fp; > int error; > > MPASS(VOP_ISLOCKED(vp)); > > np = VP_TO_VBOXFS_NODE(ap->a_vp); >- error = sfprov_open(np->vboxfsmp->sf_handle, np->sf_path, &fp); >+ error = vboxfs_get_sfp_file(np); > if (error != 0) > goto out; > >- np->sf_file = fp; > vnode_create_vobject(ap->a_vp, 0, ap->a_td); >- > out: > MPASS(VOP_ISLOCKED(vp)); > >@@ -499,10 +545,7 @@ vboxfs_close(struct vop_close_args *ap) > > vfsnode_invalidate_stat_cache(np); > >- if (np->sf_file != NULL && vp->v_usecount <= 1) { >- (void) sfprov_close(np->sf_file); >- np->sf_file = NULL; >- } >+ vboxfs_put_sfp_file(np); > > return (0); > } >@@ -684,6 +727,13 @@ vboxfs_read(struct vop_read_args *ap) > if (tmpbuf == 0) > return (ENOMEM); > >+ /* >+ * XXX VOP_READ() is called without VOP_OPEN() on exec case. >+ * We need to ensure the file is opened here. >+ */ >+ error = vboxfs_get_sfp_file(np); >+ if (error != 0) /* Maybe removed on the host. */ >+ return (EIO); > do { > offset = uio->uio_offset; > done = bytes = min(PAGE_SIZE, uio->uio_resid); >@@ -692,6 +742,7 @@ vboxfs_read(struct vop_read_args *ap) > if (error == 0 && done > 0) > error = uiomove(tmpbuf, done, uio); > } while (error == 0 && uio->uio_resid > 0 && done > 0); >+ vboxfs_put_sfp_file(np); > > contigfree(tmpbuf, PAGE_SIZE, M_DEVBUF); > >@@ -771,7 +822,6 @@ vboxfs_create(struct vop_create_args *ap) > sffs_stat_t stat; > char *fullpath = NULL; > struct vboxfs_node *dir = VP_TO_VBOXFS_NODE(dvp); >- sfp_file_t *fp; > int error; > struct vboxfs_mnt *vboxfsmp = dir->vboxfsmp; > >@@ -779,7 +829,7 @@ vboxfs_create(struct vop_create_args *ap) > > fullpath = sfnode_construct_path(dir, cnp->cn_nameptr, cnp->cn_namelen); > error = sfprov_create(dir->vboxfsmp->sf_handle, fullpath, vap->va_mode, >- &fp, &stat); >+ &stat); > > if (error) > goto out; >@@ -816,22 +866,6 @@ vboxfs_remove(struct vop_remove_args *ap) > np = VP_TO_VBOXFS_NODE(vp); > dir = VP_TO_VBOXFS_NODE(vp); > >- /* >- * If anything else is using this vnode, then fail the remove. >- * Why? Windows hosts can't sfprov_remove() a file that is open, >- * so we have to sfprov_close() it first. >- * There is no errno for this - since it's not a problem on UNIX, >- * but ETXTBSY is the closest. >- */ >- if (np->sf_file != NULL) { >- if (vp->v_usecount > 1) { >- error = ETXTBSY; >- goto out; >- } >- sfprov_close(np->sf_file); >- np->sf_file = NULL; >- } >- > error = sfprov_remove(np->vboxfsmp->sf_handle, np->sf_path, > np->sf_type == VLNK); > >@@ -938,7 +972,6 @@ vboxfs_mkdir(struct vop_mkdir_args *ap) > sffs_stat_t stat; > char *fullpath = NULL; > struct vboxfs_node *dir = VP_TO_VBOXFS_NODE(dvp); >- sfp_file_t *fp; > int error; > struct vboxfs_mnt *vboxfsmp = dir->vboxfsmp; > >@@ -946,7 +979,7 @@ vboxfs_mkdir(struct vop_mkdir_args *ap) > > fullpath = sfnode_construct_path(dir, cnp->cn_nameptr, cnp->cn_namelen); > error = sfprov_mkdir(dir->vboxfsmp->sf_handle, fullpath, vap->va_mode, >- &fp, &stat); >+ &stat); > > if (error) > goto out; >@@ -980,22 +1013,6 @@ vboxfs_rmdir(struct vop_rmdir_args *ap) > np = VP_TO_VBOXFS_NODE(vp); > dir = VP_TO_VBOXFS_NODE(vp); > >- /* >- * If anything else is using this vnode, then fail the remove. >- * Why? Windows hosts can't sfprov_remove() a file that is open, >- * so we have to sfprov_close() it first. >- * There is no errno for this - since it's not a problem on UNIX, >- * but ETXTBSY is the closest. >- */ >- if (np->sf_file != NULL) { >- if (vp->v_usecount > 1) { >- error = ETXTBSY; >- goto out; >- } >- sfprov_close(np->sf_file); >- np->sf_file = NULL; >- } >- > error = sfprov_rmdir(np->vboxfsmp->sf_handle, np->sf_path); > > #if 0 >@@ -1235,17 +1252,10 @@ vboxfs_ioctl(struct vop_ioctl_args *ap) > * Lookup an entry in a directory and create a new vnode if found. > */ > static int >-vboxfs_lookup(struct vop_cachedlookup_args /* { >- struct vnodeop_desc *a_desc; >- struct vnode *a_dvp; >- struct vnode **a_vpp; >- struct componentname *a_cnp; >- } */ *ap) >+vboxfs_lookup1(struct vnode *dvp, struct vnode **vpp, >+ struct componentname *cnp) > { >- struct componentname *cnp = ap->a_cnp; >- struct vnode *dvp = ap->a_dvp; /* the directory vnode */ > char *nameptr = cnp->cn_nameptr; /* the name of the file or directory */ >- struct vnode **vpp = ap->a_vpp; /* the vnode we found or NULL */ > struct vnode *tdp = NULL; > struct vboxfs_node *node = VP_TO_VBOXFS_NODE(dvp); > struct vboxfs_mnt *vboxfsmp = node->vboxfsmp; >@@ -1258,6 +1268,7 @@ vboxfs_lookup(struct vop_cachedlookup_args /* { > int lkflags = cnp->cn_lkflags; > char *fullpath = NULL; > >+ *vpp = NULLVP; > error = ENOENT; > if (cnp->cn_flags & ISDOTDOT) { > error = vn_vget_ino_gen(dvp, vboxfs_vn_get_ino_alloc, >@@ -1329,6 +1340,47 @@ out: > return (error); > } > >+static int >+vboxfs_cachedlookup(struct vop_cachedlookup_args *ap) >+{ >+ return (vboxfs_lookup1(ap->a_dvp, ap->a_vpp, ap->a_cnp)); >+} >+ >+static int >+vboxfs_lookup(struct vop_lookup_args *ap) >+{ >+ struct vnode *dvp = ap->a_dvp; >+ struct componentname *cnp = ap->a_cnp; >+ struct vboxfs_node *np = VP_TO_VBOXFS_NODE(dvp); >+ struct timespec mtime; >+ int flags = cnp->cn_flags; >+ int error; >+ >+ if (dvp->v_type != VDIR) >+ return (ENOTDIR); >+ >+ if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && >+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) >+ return (EROFS); >+ >+ error = vn_dir_check_exec(dvp, cnp); >+ if (error != 0) >+ return (error); >+ >+ /* Check if the directory is unmodified on the host. */ >+ mtime = np->sf_stat.sf_mtime; >+ error = vsfnode_update_stat_cache(np); >+ if (error == 0) { >+ if (mtime.tv_sec == np->sf_stat.sf_mtime.tv_sec && >+ mtime.tv_nsec == np->sf_stat.sf_mtime.tv_nsec) >+ return (vfs_cache_lookup(ap)); >+ } >+ >+ cache_purge(dvp); >+ >+ return (vboxfs_lookup1(ap->a_dvp, ap->a_vpp, ap->a_cnp)); >+} >+ > static int > vboxfs_inactive(struct vop_inactive_args *ap) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 245865
:
244334
|
244335
|
256435