VirtualBox

source: vbox/trunk/src/VBox/Additions/darwin/VBoxSF/VBoxSF-VfsOps.cpp@ 75675

Last change on this file since 75675 was 75675, checked in by vboxsync, 6 years ago

darwin/VBoxSF: Started rewriting this...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.6 KB
Line 
1/* $Id: VBoxSF-VfsOps.cpp 75675 2018-11-22 21:16:48Z vboxsync $ */
2/** @file
3 * VBoxFS - Darwin Shared Folders, Virtual File System Operations.
4 */
5
6/*
7 * Copyright (C) 2013-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_SHARED_FOLDERS
23#include "VBoxSFInternal.h"
24
25#include <iprt/assert.h>
26#include <iprt/asm.h>
27#include <iprt/mem.h>
28#include <iprt/string.h>
29#include <VBox/log.h>
30
31
32/* States of VBoxVFS object used in atomic variables
33 * in order to reach sync between several concurrently running threads. */
34#define VBOXVFS_OBJECT_UNINITIALIZED (0)
35#define VBOXVFS_OBJECT_INITIALIZING (1)
36#define VBOXVFS_OBJECT_INITIALIZED (2)
37#define VBOXVFS_OBJECT_INVALID (3)
38
39
40
41/**
42 * vfsops::vfs_getattr implementation.
43 *
44 * @returns 0 on success or errno.h value on failure.
45 * @param pMount The mount data structure.
46 * @param pFsAttr Input & output structure.
47 * @param pContext Unused kAuth parameter.
48 */
49static int vboxSfDwnVfsGetAttr(mount_t pMount, struct vfs_attr *pFsAttr, vfs_context_t pContext)
50{
51 PVBOXSFMNT pThis = (PVBOXSFMNT)vfs_fsprivate(pMount);
52 AssertReturn(pThis, EBADMSG);
53 LogFlow(("vboxSfDwnVfsGetAttr: %s\n", pThis->MntInfo.szFolder));
54 RT_NOREF(pContext);
55
56 /*
57 * Get the file system stats from the host.
58 */
59 int rc;
60 struct MyEmbReq
61 {
62 VBGLIOCIDCHGCMFASTCALL Hdr;
63 VMMDevHGCMCall Call;
64 VBoxSFParmInformation Parms;
65 SHFLVOLINFO VolInfo;
66 } *pReq = (struct MyEmbReq *)VbglR0PhysHeapAlloc(sizeof(*pReq));
67 if (pReq)
68 {
69 RT_ZERO(pReq->VolInfo);
70
71 VBGLIOCIDCHGCMFASTCALL_INIT(&pReq->Hdr, VbglR0PhysHeapGetPhysAddr(pReq), &pReq->Call, g_SfClientDarwin.idClient,
72 SHFL_FN_INFORMATION, SHFL_CPARMS_INFORMATION, sizeof(*pReq));
73 pReq->Parms.id32Root.type = VMMDevHGCMParmType_32bit;
74 pReq->Parms.id32Root.u.value32 = pThis->hHostFolder.root;
75 pReq->Parms.u64Handle.type = VMMDevHGCMParmType_64bit;
76 pReq->Parms.u64Handle.u.value64 = 0;
77 pReq->Parms.f32Flags.type = VMMDevHGCMParmType_32bit;
78 pReq->Parms.f32Flags.u.value32 = SHFL_INFO_VOLUME | SHFL_INFO_GET;
79 pReq->Parms.cb32.type = VMMDevHGCMParmType_32bit;
80 pReq->Parms.cb32.u.value32 = sizeof(pReq->VolInfo);
81 pReq->Parms.pInfo.type = VMMDevHGCMParmType_Embedded;
82 pReq->Parms.pInfo.u.Embedded.cbData = sizeof(pReq->VolInfo);
83 pReq->Parms.pInfo.u.Embedded.offData = RT_UOFFSETOF(struct MyEmbReq, VolInfo) - sizeof(VBGLIOCIDCHGCMFASTCALL);
84 pReq->Parms.pInfo.u.Embedded.fFlags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
85
86 int vrc = VbglR0HGCMFastCall(g_SfClientDarwin.handle, &pReq->Hdr, sizeof(*pReq));
87 if (RT_SUCCESS(vrc))
88 vrc = pReq->Call.header.result;
89 if (RT_SUCCESS(vrc))
90 {
91 /*
92 * Fill in stuff.
93 */
94 /* Copy over the results we got from the host. */
95 uint32_t cbUnit = pReq->VolInfo.ulBytesPerSector * pReq->VolInfo.ulBytesPerAllocationUnit;
96 VFSATTR_RETURN(pFsAttr, f_bsize, cbUnit);
97 VFSATTR_RETURN(pFsAttr, f_iosize, _64K); /** @todo what's a good block size... */
98 VFSATTR_RETURN(pFsAttr, f_blocks, (uint64_t)pReq->VolInfo.ullTotalAllocationBytes / cbUnit);
99 VFSATTR_RETURN(pFsAttr, f_bavail, (uint64_t)pReq->VolInfo.ullAvailableAllocationBytes / cbUnit);
100 VFSATTR_RETURN(pFsAttr, f_bfree, (uint64_t)pReq->VolInfo.ullAvailableAllocationBytes / cbUnit);
101 VFSATTR_RETURN(pFsAttr, f_bused,
102 ((uint64_t)pReq->VolInfo.ullTotalAllocationBytes - (uint64_t)pReq->VolInfo.ullAvailableAllocationBytes) / cbUnit);
103 fsid_t const fsid = { { vfs_statfs(pMount)->f_fsid.val[0], vfs_typenum(pMount) } };
104 VFSATTR_RETURN(pFsAttr, f_fsid, fsid);
105
106 /* f_owner is handled by caller. */
107 /* f_signature is handled by caller. */
108
109 struct timespec TmpTv = { 1084190406, 0 };
110 VFSATTR_RETURN(pFsAttr, f_create_time, TmpTv);
111
112 /*
113 * Unsupported bits.
114 */
115 /* Dummies for some values we don't support. */
116 VFSATTR_RETURN(pFsAttr, f_objcount, 0);
117 VFSATTR_RETURN(pFsAttr, f_filecount, 0);
118 VFSATTR_RETURN(pFsAttr, f_dircount, 0);
119 VFSATTR_RETURN(pFsAttr, f_maxobjcount, UINT32_MAX);
120 VFSATTR_RETURN(pFsAttr, f_files, UINT32_MAX);
121 VFSATTR_RETURN(pFsAttr, f_ffree, UINT32_MAX);
122 VFSATTR_RETURN(pFsAttr, f_fssubtype, 0);
123 VFSATTR_RETURN(pFsAttr, f_carbon_fsid, 0);
124
125 /* Totally not supported: */
126 VFSATTR_CLEAR_ACTIVE(pFsAttr, f_modify_time);
127 VFSATTR_CLEAR_ACTIVE(pFsAttr, f_access_time);
128 VFSATTR_CLEAR_ACTIVE(pFsAttr, f_backup_time);
129
130 /*
131 * Annoying capability stuff.
132 * The 'valid' bits are only supposed to be set when we know for sure.
133 */
134 if (VFSATTR_IS_ACTIVE(pFsAttr, f_capabilities))
135 {
136 vol_capabilities_attr_t *pCaps = &pFsAttr->f_capabilities;
137
138 pCaps->valid[VOL_CAPABILITIES_FORMAT] = VOL_CAP_FMT_PERSISTENTOBJECTIDS
139 | VOL_CAP_FMT_SYMBOLICLINKS
140 | VOL_CAP_FMT_HARDLINKS
141 | VOL_CAP_FMT_JOURNAL
142 | VOL_CAP_FMT_JOURNAL_ACTIVE
143 | VOL_CAP_FMT_NO_ROOT_TIMES
144 | VOL_CAP_FMT_SPARSE_FILES
145 | VOL_CAP_FMT_ZERO_RUNS
146 | VOL_CAP_FMT_CASE_SENSITIVE
147 | VOL_CAP_FMT_CASE_PRESERVING
148 | VOL_CAP_FMT_FAST_STATFS
149 | VOL_CAP_FMT_2TB_FILESIZE
150 | VOL_CAP_FMT_OPENDENYMODES
151 | VOL_CAP_FMT_HIDDEN_FILES
152 | VOL_CAP_FMT_PATH_FROM_ID
153 | VOL_CAP_FMT_NO_VOLUME_SIZES
154 | VOL_CAP_FMT_DECMPFS_COMPRESSION
155 | VOL_CAP_FMT_64BIT_OBJECT_IDS;
156 pCaps->capabilities[VOL_CAPABILITIES_FORMAT] = VOL_CAP_FMT_2TB_FILESIZE
157 ///@todo | VOL_CAP_FMT_SYMBOLICLINKS - later
158 ///@todo | VOL_CAP_FMT_SPARSE_FILES - probably, needs testing.
159 /*| VOL_CAP_FMT_CASE_SENSITIVE - case-insensitive */
160 | VOL_CAP_FMT_CASE_PRESERVING
161 ///@todo | VOL_CAP_FMT_HIDDEN_FILES - if windows host.
162 ///@todo | VOL_CAP_FMT_OPENDENYMODES - if windows host.
163 ;
164 pCaps->valid[VOL_CAPABILITIES_INTERFACES] = VOL_CAP_INT_SEARCHFS
165 | VOL_CAP_INT_ATTRLIST
166 | VOL_CAP_INT_NFSEXPORT
167 | VOL_CAP_INT_READDIRATTR
168 | VOL_CAP_INT_EXCHANGEDATA
169 | VOL_CAP_INT_COPYFILE
170 | VOL_CAP_INT_ALLOCATE
171 | VOL_CAP_INT_VOL_RENAME
172 | VOL_CAP_INT_ADVLOCK
173 | VOL_CAP_INT_FLOCK
174 | VOL_CAP_INT_EXTENDED_SECURITY
175 | VOL_CAP_INT_USERACCESS
176 | VOL_CAP_INT_MANLOCK
177 | VOL_CAP_INT_NAMEDSTREAMS
178 | VOL_CAP_INT_EXTENDED_ATTR;
179 pCaps->capabilities[VOL_CAPABILITIES_INTERFACES] = 0
180 ///@todo | VOL_CAP_INT_SEARCHFS
181 ///@todo | VOL_CAP_INT_COPYFILE
182 ///@todo | VOL_CAP_INT_READDIRATTR
183 ;
184
185 pCaps->valid[VOL_CAPABILITIES_RESERVED1] = 0;
186 pCaps->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
187
188 pCaps->valid[VOL_CAPABILITIES_RESERVED2] = 0;
189 pCaps->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
190
191 VFSATTR_SET_SUPPORTED(pFsAttr, f_capabilities);
192 }
193
194
195 /*
196 * Annoying attribute stuff.
197 * The 'valid' bits are only supposed to be set when we know for sure.
198 */
199 if (VFSATTR_IS_ACTIVE(pFsAttr, f_attributes))
200 {
201 vol_attributes_attr_t *pAt = &pFsAttr->f_attributes;
202
203 pAt->validattr.commonattr = ATTR_CMN_NAME
204 | ATTR_CMN_DEVID
205 | ATTR_CMN_FSID
206 | ATTR_CMN_OBJTYPE
207 | ATTR_CMN_OBJTAG
208 | ATTR_CMN_OBJID
209 | ATTR_CMN_OBJPERMANENTID
210 | ATTR_CMN_PAROBJID
211 | ATTR_CMN_SCRIPT
212 | ATTR_CMN_CRTIME
213 | ATTR_CMN_MODTIME
214 | ATTR_CMN_CHGTIME
215 | ATTR_CMN_ACCTIME
216 | ATTR_CMN_BKUPTIME
217 | ATTR_CMN_FNDRINFO
218 | ATTR_CMN_OWNERID
219 | ATTR_CMN_GRPID
220 | ATTR_CMN_ACCESSMASK
221 | ATTR_CMN_FLAGS
222 | ATTR_CMN_USERACCESS
223 | ATTR_CMN_EXTENDED_SECURITY
224 | ATTR_CMN_UUID
225 | ATTR_CMN_GRPUUID
226 | ATTR_CMN_FILEID
227 | ATTR_CMN_PARENTID
228 | ATTR_CMN_FULLPATH
229 | ATTR_CMN_ADDEDTIME;
230 pAt->nativeattr.commonattr = ATTR_CMN_NAME
231 | ATTR_CMN_DEVID
232 | ATTR_CMN_FSID
233 | ATTR_CMN_OBJTYPE
234 | ATTR_CMN_OBJTAG
235 | ATTR_CMN_OBJID
236 //| ATTR_CMN_OBJPERMANENTID
237 | ATTR_CMN_PAROBJID
238 //| ATTR_CMN_SCRIPT
239 | ATTR_CMN_CRTIME
240 | ATTR_CMN_MODTIME
241 | ATTR_CMN_CHGTIME
242 | ATTR_CMN_ACCTIME
243 //| ATTR_CMN_BKUPTIME
244 //| ATTR_CMN_FNDRINFO
245 //| ATTR_CMN_OWNERID
246 //| ATTR_CMN_GRPID
247 | ATTR_CMN_ACCESSMASK
248 //| ATTR_CMN_FLAGS
249 //| ATTR_CMN_USERACCESS
250 //| ATTR_CMN_EXTENDED_SECURITY
251 //| ATTR_CMN_UUID
252 //| ATTR_CMN_GRPUUID
253 | ATTR_CMN_FILEID
254 | ATTR_CMN_PARENTID
255 | ATTR_CMN_FULLPATH
256 //| ATTR_CMN_ADDEDTIME
257 ;
258 pAt->validattr.volattr = ATTR_VOL_FSTYPE
259 | ATTR_VOL_SIGNATURE
260 | ATTR_VOL_SIZE
261 | ATTR_VOL_SPACEFREE
262 | ATTR_VOL_SPACEAVAIL
263 | ATTR_VOL_MINALLOCATION
264 | ATTR_VOL_ALLOCATIONCLUMP
265 | ATTR_VOL_IOBLOCKSIZE
266 | ATTR_VOL_OBJCOUNT
267 | ATTR_VOL_FILECOUNT
268 | ATTR_VOL_DIRCOUNT
269 | ATTR_VOL_MAXOBJCOUNT
270 | ATTR_VOL_MOUNTPOINT
271 | ATTR_VOL_NAME
272 | ATTR_VOL_MOUNTFLAGS
273 | ATTR_VOL_MOUNTEDDEVICE
274 | ATTR_VOL_ENCODINGSUSED
275 | ATTR_VOL_CAPABILITIES
276 | ATTR_VOL_UUID
277 | ATTR_VOL_ATTRIBUTES
278 | ATTR_VOL_INFO;
279 pAt->nativeattr.volattr = ATTR_VOL_FSTYPE
280 //| ATTR_VOL_SIGNATURE
281 | ATTR_VOL_SIZE
282 | ATTR_VOL_SPACEFREE
283 | ATTR_VOL_SPACEAVAIL
284 | ATTR_VOL_MINALLOCATION
285 | ATTR_VOL_ALLOCATIONCLUMP
286 | ATTR_VOL_IOBLOCKSIZE
287 //| ATTR_VOL_OBJCOUNT
288 //| ATTR_VOL_FILECOUNT
289 //| ATTR_VOL_DIRCOUNT
290 //| ATTR_VOL_MAXOBJCOUNT
291 //| ATTR_VOL_MOUNTPOINT - ??
292 | ATTR_VOL_NAME
293 | ATTR_VOL_MOUNTFLAGS
294 | ATTR_VOL_MOUNTEDDEVICE
295 //| ATTR_VOL_ENCODINGSUSED
296 | ATTR_VOL_CAPABILITIES
297 //| ATTR_VOL_UUID
298 | ATTR_VOL_ATTRIBUTES
299 //| ATTR_VOL_INFO
300 ;
301 pAt->validattr.dirattr = ATTR_DIR_LINKCOUNT
302 | ATTR_DIR_ENTRYCOUNT
303 | ATTR_DIR_MOUNTSTATUS;
304 pAt->nativeattr.dirattr = 0 //ATTR_DIR_LINKCOUNT
305 | ATTR_DIR_ENTRYCOUNT
306 | ATTR_DIR_MOUNTSTATUS
307 ;
308 pAt->validattr.fileattr = ATTR_FILE_LINKCOUNT
309 | ATTR_FILE_TOTALSIZE
310 | ATTR_FILE_ALLOCSIZE
311 | ATTR_FILE_IOBLOCKSIZE
312 | ATTR_FILE_DEVTYPE
313 | ATTR_FILE_FORKCOUNT
314 | ATTR_FILE_FORKLIST
315 | ATTR_FILE_DATALENGTH
316 | ATTR_FILE_DATAALLOCSIZE
317 | ATTR_FILE_RSRCLENGTH
318 | ATTR_FILE_RSRCALLOCSIZE;
319 pAt->nativeattr.fileattr = 0
320 //|ATTR_FILE_LINKCOUNT
321 | ATTR_FILE_TOTALSIZE
322 | ATTR_FILE_ALLOCSIZE
323 //| ATTR_FILE_IOBLOCKSIZE
324 | ATTR_FILE_DEVTYPE
325 //| ATTR_FILE_FORKCOUNT
326 //| ATTR_FILE_FORKLIST
327 | ATTR_FILE_DATALENGTH
328 | ATTR_FILE_DATAALLOCSIZE
329 | ATTR_FILE_RSRCLENGTH
330 | ATTR_FILE_RSRCALLOCSIZE
331 ;
332 pAt->validattr.forkattr = ATTR_FORK_TOTALSIZE
333 | ATTR_FORK_ALLOCSIZE;
334 pAt->nativeattr.forkattr = 0
335 //| ATTR_FORK_TOTALSIZE
336 //| ATTR_FORK_ALLOCSIZE
337 ;
338 VFSATTR_SET_SUPPORTED(pFsAttr, f_attributes);
339 }
340
341 if (VFSATTR_IS_ACTIVE(pFsAttr, f_vol_name))
342 {
343 RTStrCopy(pFsAttr->f_vol_name, MAXPATHLEN, pThis->MntInfo.szFolder);
344 VFSATTR_SET_SUPPORTED(pFsAttr, f_vol_name);
345 }
346
347 rc = 0;
348 }
349 else
350 {
351 Log(("vboxSfOs2QueryFileInfo: VbglR0SfFsInfo failed: %Rrc\n", vrc));
352 rc = RTErrConvertToErrno(vrc);
353 }
354
355 VbglR0PhysHeapFree(pReq);
356 }
357 else
358 rc = ENOMEM;
359 return rc;
360}
361
362
363/**
364 * vfsops::vfs_root implementation.
365 *
366 * @returns 0 on success or errno.h value on failure.
367 * @param pMount The mount data structure.
368 * @param ppVnode Where to return the referenced root node on success.
369 * @param pContext Unused kAuth parameter.
370 */
371static int vboxSfDwnVfsRoot(mount_t pMount, vnode_t *ppVnode, vfs_context_t pContext)
372{
373 PVBOXSFMNT pThis = (PVBOXSFMNT)vfs_fsprivate(pMount);
374 AssertReturn(pThis, EBADMSG);
375 LogFlow(("vboxSfDwnVfsRoot: pThis=%p:{%s}\n", pThis, pThis->MntInfo.szFolder));
376
377 /*
378 * We shouldn't be callable during unmount, should we?
379 */
380 AssertReturn(vfs_isunmount(pMount), EBUSY);
381
382 /*
383 * There should always be a root node around.
384 */
385 if (pThis->pVnRoot)
386 {
387 int rc = vnode_get(pThis->pVnRoot);
388 if (rc == 0)
389 {
390 *ppVnode = pThis->pVnRoot;
391 LogFlow(("vboxSfDwnVfsRoot: return %p\n", *ppVnode));
392 return 0;
393 }
394 Log(("vboxSfDwnVfsRoot: vnode_get failed! %d\n", rc));
395 return rc;
396 }
397
398 LogRel(("vboxSfDwnVfsRoot: pVnRoot is NULL!\n"));
399 return EILSEQ;
400}
401
402
403/**
404 * vfsops::vfs_umount implementation.
405 *
406 * @returns 0 on success or errno.h value on failure.
407 * @param pMount The mount data.
408 * @param fFlags Unmount flags.
409 * @param pContext kAuth context which we don't care much about.
410 *
411 */
412static int vboxSfDwnVfsUnmount(mount_t pMount, int fFlags, vfs_context_t pContext)
413{
414 PVBOXSFMNT pThis = (PVBOXSFMNT)vfs_fsprivate(pMount);
415 AssertReturn(pThis, 0);
416 LogFlowFunc(("pThis=%p:{%s} fFlags=%#x\n", pThis, pThis->MntInfo.szFolder, fFlags));
417
418 /*
419 * Flush vnodes.
420 */
421 int rc = vflush(pMount, pThis->pVnRoot, fFlags & MNT_FORCE ? FORCECLOSE : 0);
422 if (rc == 0)
423 {
424 /*
425 * Is the file system still busy?
426 *
427 * Until we find a way of killing any active host calls, we cannot properly
428 * respect the MNT_FORCE flag here. So, MNT_FORCE is ignored here.
429 */
430 if ( !pThis->pVnRoot
431 || !vnode_isinuse(pThis->pVnRoot, 1))
432 {
433 /*
434 * Release our root vnode reference and do another flush.
435 */
436 if (pThis->pVnRoot)
437 {
438 vnode_put(pThis->pVnRoot);
439 pThis->pVnRoot = NULL;
440 }
441 vflush(pMount, NULLVP, FORCECLOSE);
442
443 /*
444 * Unmap the shared folder and destroy our mount info structure.
445 */
446 vfs_setfsprivate(pMount, NULL);
447
448 rc = VbglR0SfUnmapFolder(&g_SfClientDarwin, &pThis->hHostFolder);
449 AssertRC(rc);
450
451 RT_ZERO(*pThis);
452 RTMemFree(pThis);
453
454 vfs_clearflags(pMount, MNT_LOCAL); /* ?? */
455 rc = 0;
456
457 g_cVBoxSfMounts--;
458 }
459 else
460 {
461 Log(("VBoxSF: umount failed: file system busy! (%s)\n", pThis->MntInfo.szFolder));
462 rc = EBUSY;
463 }
464 }
465 return rc;
466}
467
468
469/**
470 * vfsops::vfs_start implementation.
471 */
472static int vboxSfDwnVfsStart(mount_t pMount, int fFlags, vfs_context_t pContext)
473{
474 RT_NOREF(pMount, fFlags, pContext);
475 return 0;
476}
477
478
479/**
480 * vfsops::vfs_mount implementation.
481 *
482 * @returns 0 on success or errno.h value on failure.
483 * @param pMount The mount data structure.
484 * @param pDevVp The device to mount. Not used by us.
485 * @param pUserData User space address of parameters supplied to mount().
486 * We expect a VBOXSFDRWNMOUNTINFO structure.
487 * @param pContext kAuth context needed in order to authentificate mount
488 * operation.
489 */
490static int vboxSfDwnVfsMount(mount_t pMount, vnode_t pDevVp, user_addr_t pUserData, vfs_context_t pContext)
491{
492 RT_NOREF(pDevVp)
493
494 /*
495 * We don't support mount updating.
496 */
497 if (vfs_isupdate(pMount))
498 {
499 LogRel(("VBoxSF: mount: MNT_UPDATE is not supported.\n"));
500 return ENOTSUP;
501 }
502 if (pUserData == USER_ADDR_NULL)
503 {
504 LogRel(("VBoxSF: mount: pUserData is NULL.\n"));
505 return EINVAL;
506 }
507 struct vfsstatfs *pFsStats = vfs_statfs(pMount);
508 AssertReturn(pFsStats, EINVAL);
509
510 /*
511 * Get the mount information from userland.
512 */
513 PVBOXSFMNT pThis = (PVBOXSFMNT)RTMemAllocZ(sizeof(*pThis));
514 if (!pThis)
515 return ENOMEM;
516 pThis->uidMounter = pFsStats->f_owner;
517
518 int rc = RTR0MemUserCopyFrom(&pThis->MntInfo, (RTR3PTR)pUserData, sizeof(pThis->MntInfo));
519 if (RT_FAILURE(rc))
520 {
521 LogRel(("VBoxSF: mount: Failed to copy in mount user data: %Rrc\n", rc));
522 rc = EFAULT;
523 }
524 else if (pThis->MntInfo.u32Magic != VBOXSFDRWNMOUNTINFO_MAGIC)
525 {
526 LogRel(("VBoxSF: mount: Invalid user data magic (%#x)\n", pThis->MntInfo.u32Magic));
527 rc = EINVAL;
528 }
529 else if ( (rc = RTStrValidateEncodingEx(pThis->MntInfo.szFolder, sizeof(pThis->MntInfo.szFolder),
530 RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED)) != VINF_SUCCESS
531 || pThis->MntInfo.szFolder[0] == '\0')
532 {
533 LogRel(("VBoxSF: mount: Invalid or empty share name!\n"));
534 rc = EINVAL;
535 }
536 else
537 {
538 /*
539 * Try map the shared folder.
540 */
541 if (vboxSfDwnConnect())
542 {
543 PSHFLSTRING pName = ShflStringDupUtf8(pThis->MntInfo.szFolder);
544 if (pName)
545 {
546 rc = VbglR0SfMapFolder(&g_SfClientDarwin, pName, &pThis->hHostFolder);
547 RTMemFree(pName);
548 if (RT_SUCCESS(rc))
549 {
550
551 /*
552 * Create a root node, that avoid races later.
553 */
554 pThis->pVnRoot = vboxSfDwnVnAlloc(pMount, VDIR, NULL /*pParent*/, 0);
555 if (pThis->pVnRoot)
556 {
557 /*
558 * Fill file system stats with dummy data.
559 */
560 pFsStats->f_bsize = 512;
561 pFsStats->f_iosize = _64K;
562 pFsStats->f_blocks = _1M;
563 pFsStats->f_bavail = _1M / 4 * 3;
564 pFsStats->f_bused = _1M / 4;
565 pFsStats->f_files = 1024;
566 pFsStats->f_ffree = _64K;
567 vfs_getnewfsid(pMount); /* f_fsid */
568 /* pFsStats->f_fowner - don't touch */
569 /* pFsStats->f_fstypename - don't touch */
570 /* pFsStats->f_mntonname - don't touch */
571 RTStrCopy(pFsStats->f_mntfromname, sizeof(pFsStats->f_mntfromname), pThis->MntInfo.szFolder);
572 /* pFsStats->f_fssubtype - don't touch? */
573 /* pFsStats->f_reserved[0] - don't touch? */
574 /* pFsStats->f_reserved[1] - don't touch? */
575
576 /*
577 * We're good. Set private data and flags.
578 */
579 vfs_setfsprivate(pMount, pThis);
580 vfs_setflags(pMount, MNT_SYNCHRONOUS | MNT_NOSUID | MNT_NODEV);
581 /** @todo Consider flags like MNT_NOEXEC ? */
582
583 /// @todo vfs_setauthopaque(pMount)?
584 /// @todo vfs_clearauthopaqueaccess(pMount)?
585 /// @todo vfs_clearextendedsecurity(pMount)?
586
587 LogRel(("VBoxSF: mount: Successfully mounted '%s' (uidMounter=%u).\n",
588 pThis->MntInfo.szFolder, pThis->uidMounter));
589 return 0;
590 }
591
592 LogRel(("VBoxSF: mount: Failed to allocate root node!\n"));
593 rc = ENOMEM;
594 }
595 else
596 {
597 LogRel(("VBoxSF: mount: VbglR0SfMapFolder failed on '%s': %Rrc\n", pThis->MntInfo.szFolder, rc));
598 rc = ENOENT;
599 }
600 }
601 else
602 rc = ENOMEM;
603 }
604 else
605 {
606 LogRel(("VBoxSF: mount: Not connected to shared folders service!\n"));
607 rc = ENOTCONN;
608 }
609 }
610 RTMemFree(pThis);
611 return rc;
612}
613
614
615/**
616 * VFS operations
617 */
618struct vfsops g_VBoxSfVfsOps =
619{
620 vboxSfDwnVfsMount,
621 vboxSfDwnVfsStart,
622 vboxSfDwnVfsUnmount,
623 vboxSfDwnVfsRoot,
624 NULL, /* Skipped: vfs_quotactl */
625 vboxSfDwnVfsGetAttr,
626 NULL, /* Skipped: vfs_sync */
627 NULL, /* Skipped: vfs_vget */
628 NULL, /* Skipped: vfs_fhtovp */
629 NULL, /* Skipped: vfs_vptofh */
630 NULL, /* Skipped: vfs_init */
631 NULL, /* Skipped: vfs_sysctl */
632 NULL, /* Skipped: vfs_setattr */
633 /* Reserved */
634 { NULL, NULL, NULL, NULL, NULL, NULL, NULL, },
635};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette