VirtualBox

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

Last change on this file since 94130 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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