diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Additions/solaris/SharedFolders | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-master.tar.gz |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Additions/solaris/SharedFolders')
7 files changed, 101 insertions, 68 deletions
diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c index 1851ed6a..3e5356eb 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_mount.c @@ -6,7 +6,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c index 766941ed..c19f264b 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.c @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2008-2010 Oracle Corporation + * Copyright (C) 2008-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -40,6 +40,7 @@ #include <sys/ddi.h> #include <sys/sunddi.h> #include <sys/dirent.h> +#include <sys/file.h> #include "vboxfs_prov.h" #ifdef u #undef u @@ -356,7 +357,7 @@ sfprov_create( } int -sfprov_open(sfp_mount_t *mnt, char *path, sfp_file_t **fp) +sfprov_diropen(sfp_mount_t *mnt, char *path, sfp_file_t **fp) { int rc; SHFLCREATEPARMS parms; @@ -364,40 +365,34 @@ sfprov_open(sfp_mount_t *mnt, char *path, sfp_file_t **fp) int size; sfp_file_t *newfp; - /* - * First we attempt to open it read/write. If that fails we - * try read only. - */ bzero(&parms, sizeof(parms)); str = sfprov_string(path, &size); parms.Handle = SHFL_HANDLE_NIL; parms.Info.cbObject = 0; - parms.CreateFlags = SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READWRITE; + parms.CreateFlags = SHFL_CF_DIRECTORY + | SHFL_CF_ACCESS_READ + | SHFL_CF_ACT_OPEN_IF_EXISTS + | SHFL_CF_ACT_FAIL_IF_NEW; + + /* + * Open the host directory. + */ rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); - if (RT_FAILURE(rc) && rc != VERR_ACCESS_DENIED) { + + /* + * Our VBoxFS interface here isn't very clear regarding failure and informational status. + * Check the file-handle as well as the return code to make sure the operation succeeded. + */ + if (RT_FAILURE(rc)) { kmem_free(str, size); return (sfprov_vbox2errno(rc)); } + if (parms.Handle == SHFL_HANDLE_NIL) { - if (parms.Result == SHFL_PATH_NOT_FOUND || - parms.Result == SHFL_FILE_NOT_FOUND) { - kmem_free(str, size); - return (ENOENT); - } - parms.CreateFlags = - SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ; - rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); - if (RT_FAILURE(rc)) { - kmem_free(str, size); - return (sfprov_vbox2errno(rc)); - } - if (parms.Handle == SHFL_HANDLE_NIL) { - kmem_free(str, size); - return (ENOENT); - } - } - else kmem_free(str, size); + return (ENOENT); + } + newfp = kmem_alloc(sizeof(sfp_file_t), KM_SLEEP); newfp->handle = parms.Handle; newfp->map = mnt->map; @@ -406,28 +401,62 @@ sfprov_open(sfp_mount_t *mnt, char *path, sfp_file_t **fp) } int -sfprov_trunc(sfp_mount_t *mnt, char *path) +sfprov_open(sfp_mount_t *mnt, char *path, sfp_file_t **fp, int flag) { int rc; SHFLCREATEPARMS parms; SHFLSTRING *str; int size; + sfp_file_t *newfp; - /* - * open it read/write. - */ + bzero(&parms, sizeof(parms)); str = sfprov_string(path, &size); - parms.Handle = 0; + parms.Handle = SHFL_HANDLE_NIL; parms.Info.cbObject = 0; - parms.CreateFlags = SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READWRITE | - SHFL_CF_ACT_OVERWRITE_IF_EXISTS; + + /* + * Translate file modes. + */ + if (flag & FCREAT) { + parms.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW; + if (!(flag & FTRUNC)) + parms.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS; + } + else + parms.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW; + + if (flag & FTRUNC) + parms.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS | SHFL_CF_ACCESS_WRITE; + if (flag & FWRITE) + parms.CreateFlags |= SHFL_CF_ACCESS_WRITE; + if (flag & FREAD) + parms.CreateFlags |= SHFL_CF_ACCESS_READ; + if (flag & FAPPEND) + parms.CreateFlags |= SHFL_CF_ACCESS_APPEND; + + /* + * Open/create the host file. + */ rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); - kmem_free(str, size); + /* + * Our VBoxFS interface here isn't very clear regarding failure and informational status. + * Check the file-handle as well as the return code to make sure the operation succeeded. + */ if (RT_FAILURE(rc)) { - return (EINVAL); + kmem_free(str, size); + return (sfprov_vbox2errno(rc)); + } + + if (parms.Handle == SHFL_HANDLE_NIL) { + kmem_free(str, size); + return (ENOENT); } - (void)vboxCallClose(&vbox_client, &mnt->map, parms.Handle); + + newfp = kmem_alloc(sizeof(sfp_file_t), KM_SLEEP); + newfp->handle = parms.Handle; + newfp->map = mnt->map; + *fp = newfp; return (0); } @@ -889,7 +918,8 @@ int sfprov_readdir( sfp_mount_t *mnt, char *path, - sffs_dirents_t **dirents) + sffs_dirents_t **dirents, + int flag) { int error; char *cp; @@ -910,7 +940,7 @@ sfprov_readdir( *dirents = NULL; - error = sfprov_open(mnt, path, &fp); + error = sfprov_diropen(mnt, path, &fp); if (error != 0) return (ENOENT); diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h index 40ce7c06..f7e97fb2 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_prov.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -100,7 +100,8 @@ typedef struct sfp_file sfp_file_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_diropen(sfp_mount_t *mnt, char *path, sfp_file_t **fp); +extern int sfprov_open(sfp_mount_t *, char *path, sfp_file_t **fp, int flag); extern int sfprov_close(sfp_file_t *fp); extern int sfprov_read(sfp_file_t *, char * buffer, uint64_t offset, uint32_t *numbytes); @@ -126,7 +127,6 @@ 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, uint_t is_link); extern int sfprov_mkdir(sfp_mount_t *, char *path, mode_t mode, sfp_file_t **fp, sffs_stat_t *stat); @@ -164,7 +164,7 @@ typedef struct sffs_dirents { #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); + sffs_dirents_t **dirents, int flag); #ifdef __cplusplus } diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c index 6a06e5cd..09ed0dae 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h index ab4d9cb4..8b6e6b0e 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vfs.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2011 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c index 7acac060..c30dfb7d 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -185,16 +185,21 @@ sfnode_clear_dir_list(sfnode_t *node) * same host file in the host in light of the possibility of host side renames. */ static void -sfnode_open(sfnode_t *node) +sfnode_open(sfnode_t *node, int flag) { int error; sfp_file_t *fp; if (node->sf_file != NULL) return; - error = sfprov_open(node->sf_sffs->sf_handle, node->sf_path, &fp); + error = sfprov_open(node->sf_sffs->sf_handle, node->sf_path, &fp, flag); if (error == 0) + { node->sf_file = fp; + node->sf_flag = flag; + } + else + node->sf_flag = ~0; } /* @@ -255,6 +260,7 @@ sfnode_make( node->sf_type = type; node->sf_is_stale = 0; /* never stale at creation */ node->sf_file = fp; + node->sf_flag = ~0; node->sf_vnode = NULL; /* do this before any sfnode_get_vnode() */ node->sf_children = 0; node->sf_parent = parent; @@ -698,7 +704,7 @@ sffs_readdir( cred_t *cred, int *eofp, caller_context_t *ct, - int flags) + int flag) { sfnode_t *dir = VN2SFN(vp); sfnode_t *node; @@ -733,7 +739,7 @@ sffs_readdir( if (dir->sf_dir_list == NULL) { error = sfprov_readdir(dir->sf_sffs->sf_handle, dir->sf_path, - &dir->sf_dir_list); + &dir->sf_dir_list, flag); if (error != 0) goto done; } @@ -1031,10 +1037,11 @@ sffs_read( return (0); mutex_enter(&sffs_lock); - sfnode_open(node); if (node->sf_file == NULL) { - mutex_exit(&sffs_lock); - return (EINVAL); + ASSERT(node->sf_flag != ~0); + sfnode_open(node, node->sf_flag); + if (node->sf_file == NULL) + return (EBADF); } do { @@ -1082,10 +1089,11 @@ sffs_write( * multiple FAPPEND writes from intermixing */ mutex_enter(&sffs_lock); - sfnode_open(node); if (node->sf_file == NULL) { - mutex_exit(&sffs_lock); - return (EINVAL); + ASSERT(node->sf_flag != ~0); + sfnode_open(node, node->sf_flag); + if (node->sf_file == NULL) + return (EBADF); } sfnode_invalidate_stat_cache(node); @@ -1304,16 +1312,11 @@ sffs_create( */ if (vp->v_type == VREG && (vap->va_mask & AT_SIZE) && vap->va_size == 0) { - sfnode_open(node); - if (node->sf_path == NULL) - error = ENOENT; - else - error = sfprov_trunc(node->sf_sffs->sf_handle, - node->sf_path); - if (error) { + sfnode_open(node, flag | FTRUNC); + if (node->sf_path == NULL) { mutex_exit(&sffs_lock); VN_RELE(vp); - return (error); + return (ENOENT); } } mutex_exit(&sffs_lock); @@ -2218,7 +2221,7 @@ sffs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct) } /* - * All the work for this is really done in lookup. + * All the work for this is really done in sffs_lookup(). */ /*ARGSUSED*/ static int @@ -2230,10 +2233,9 @@ sffs_open(vnode_t **vpp, int flag, cred_t *cr, caller_context_t *ct) mutex_enter(&sffs_lock); node = VN2SFN(*vpp); - sfnode_open(node); + sfnode_open(node, flag); if (node->sf_file == NULL) error = EINVAL; - mutex_exit(&sffs_lock); return (error); diff --git a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h index f76795fe..70ab06af 100644 --- a/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h +++ b/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.h @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2009-2010 Oracle Corporation + * Copyright (C) 2009-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -52,6 +52,7 @@ typedef struct sfnode { uint64_t sf_ino; /* assigned unique ID number */ vnode_t *sf_vnode; /* vnode if active */ sfp_file_t *sf_file; /* non NULL if open */ + int sf_flag; /* last opened file-mode. */ struct sfnode *sf_parent; /* parent sfnode of this one */ uint16_t sf_children; /* number of children sfnodes */ uint8_t sf_type; /* VDIR or VREG */ |