1 | /* $Id: vboxvfs_utils.c 10067 2008-07-01 11:07:51Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VirtualBox File System Driver for Solaris Guests, Utility functions.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2008 Sun Microsystems, Inc.
|
---|
8 | *
|
---|
9 | * Sun Microsystems, Inc. confidential
|
---|
10 | * All rights reserved
|
---|
11 | */
|
---|
12 |
|
---|
13 |
|
---|
14 | /*******************************************************************************
|
---|
15 | * Header Files *
|
---|
16 | *******************************************************************************/
|
---|
17 | #include <time.h>
|
---|
18 | #include <sys/stat.h>
|
---|
19 | #include <sys/vnode.h>
|
---|
20 | #include <sys/sunddi.h>
|
---|
21 | #include "vboxvfs.h"
|
---|
22 |
|
---|
23 | #include <VBox/log.h>
|
---|
24 | #include <iprt/time.h>
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * Convert from RTTIMESPEC to timestruct_t.
|
---|
28 | *
|
---|
29 | * @param pTime Pointer to destination timestruct_t object.
|
---|
30 | * @param pRTTime Pointer to source time RTTIMESPEC object.
|
---|
31 | */
|
---|
32 | static void vboxvfs_FileTimeFromTimeSpec(timestruc_t *pTime, PRTTIMESPEC pRTTime)
|
---|
33 | {
|
---|
34 | int64_t t = RTTimeSpecGetNano(pRTTime);
|
---|
35 | int64_t nsec = t / 1000000000;
|
---|
36 |
|
---|
37 | pTime->tv_sec = t;
|
---|
38 | pTime->tv_nsec = nsec;
|
---|
39 | }
|
---|
40 |
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * Stat for a file on the host.
|
---|
44 | *
|
---|
45 | * @returns errno error code.
|
---|
46 | * @param pszCaller Entity calling this function (just used for logging sake)
|
---|
47 | * @param pVBoxVFSGlobalInfo Pointer to the global filesystem info. struct.
|
---|
48 | * @param pPath Pointer to file path on the guest to stat.
|
---|
49 | * @param pResult Where to store the result of stat.
|
---|
50 | * @param fAllowFailure Whether failure is acceptable to the caller (currently just logging).
|
---|
51 | */
|
---|
52 | int vboxvfs_Stat(const char *pszCaller, vboxvfs_globinfo_t *pVBoxVFSGlobalInfo, SHFLSTRING *pPath,
|
---|
53 | RTFSOBJINFO *pResult, boolean_t fAllowFailure)
|
---|
54 | {
|
---|
55 | int rc;
|
---|
56 | SHFLCREATEPARMS Params;
|
---|
57 |
|
---|
58 | LogFlow((DEVICE_NAME ":vboxvfs_Stat caller=%s fAllowFailure=%d\n", pszCaller, fAllowFailure));
|
---|
59 |
|
---|
60 | Params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
|
---|
61 | rc = vboxCallCreate(&g_VBoxVFSClient, &pVBoxVFSGlobalInfo->Map, pPath, &Params);
|
---|
62 | if (VBOX_FAILURE(rc))
|
---|
63 | {
|
---|
64 | Log((DEVICE_NAME ":vboxCallCreate failed! caller=%s rc=%Vrc\n", pszCaller, rc));
|
---|
65 | return EPROTO;
|
---|
66 | }
|
---|
67 |
|
---|
68 | if (Params.Result != SHFL_FILE_EXISTS)
|
---|
69 | {
|
---|
70 | if (fAllowFailure)
|
---|
71 | {
|
---|
72 | LogRel((DEVICE_NAME ":vboxCallCreate(%s) file does not exist. caller=%s result=%d\n",
|
---|
73 | pPath->String.utf8, Params.Result, pszCaller));
|
---|
74 | }
|
---|
75 | return ENOENT;
|
---|
76 | }
|
---|
77 | *pResult = Params.Info;
|
---|
78 | return 0;
|
---|
79 | }
|
---|
80 |
|
---|
81 | /**
|
---|
82 | * Initializes VNode structure.
|
---|
83 | *
|
---|
84 | * @param pVBoxVFSGlobalInfo Pointer to the global filesystem info. struct.
|
---|
85 | * @param pVBoxVNode Pointer to the pre-allocated vboxvfs_vnode_t object to initialize.
|
---|
86 | * @param pInfo Pointer to the RTFSOBJINFO used for initialization.
|
---|
87 | */
|
---|
88 | void vboxvfs_InitVNode(vboxvfs_globinfo_t *pVBoxVFSGlobalInfo, vboxvfs_vnode_t *pVBoxVNode,
|
---|
89 | RTFSOBJINFO *pFSInfo)
|
---|
90 | {
|
---|
91 | RTFSOBJATTR *pFSAttr;
|
---|
92 | int fDir;
|
---|
93 | vfs_t *pVFS;
|
---|
94 |
|
---|
95 | mutex_enter(&pVBoxVNode->MtxContents);
|
---|
96 |
|
---|
97 | pVFS = VBOXVFS_TO_VFS(pVBoxVFSGlobalInfo);
|
---|
98 | pFSAttr = &pFSInfo->Attr;
|
---|
99 | fDir = RTFS_IS_DIRECTORY(pFSAttr->fMode);
|
---|
100 | int Mode = 0;
|
---|
101 |
|
---|
102 | #define VBOXMODESET(r) pFSAttr->fMode & (RTFS_UNIX_##r) ? (S_##r) : 0;
|
---|
103 | Mode |= VBOXMODESET(ISUID);
|
---|
104 | Mode |= VBOXMODESET(ISGID);
|
---|
105 |
|
---|
106 | Mode |= VBOXMODESET(IRUSR);
|
---|
107 | Mode |= VBOXMODESET(IWUSR);
|
---|
108 | Mode |= VBOXMODESET(IXUSR);
|
---|
109 |
|
---|
110 | Mode |= VBOXMODESET(IRGRP);
|
---|
111 | Mode |= VBOXMODESET(IWGRP);
|
---|
112 | Mode |= VBOXMODESET(IXGRP);
|
---|
113 |
|
---|
114 | Mode |= VBOXMODESET(IROTH);
|
---|
115 | Mode |= VBOXMODESET(IWOTH);
|
---|
116 | Mode |= VBOXMODESET(IXOTH);
|
---|
117 | #undef VBOXMODESET
|
---|
118 |
|
---|
119 | bzero(&pVBoxVNode->Attr, sizeof(vattr_t));
|
---|
120 | if (fDir)
|
---|
121 | {
|
---|
122 | pVBoxVNode->Attr.va_mode = (mode_t)(S_IFDIR | Mode);
|
---|
123 | pVBoxVNode->Attr.va_type = VDIR;
|
---|
124 | }
|
---|
125 | else
|
---|
126 | {
|
---|
127 | pVBoxVNode->Attr.va_mode = (mode_t)(S_IFREG | Mode);
|
---|
128 | pVBoxVNode->Attr.va_type = VREG;
|
---|
129 | }
|
---|
130 |
|
---|
131 | pVBoxVNode->Attr.va_rdev = 0; /* @todo Verify if setting it to zero is okay, not sure of this. */
|
---|
132 | pVBoxVNode->Attr.va_mask = 0;
|
---|
133 | pVBoxVNode->Attr.va_seq = 0;
|
---|
134 | pVBoxVNode->Attr.va_nlink = 1;
|
---|
135 | pVBoxVNode->Attr.va_uid = pVBoxVFSGlobalInfo->Uid;
|
---|
136 | pVBoxVNode->Attr.va_gid = pVBoxVFSGlobalInfo->Gid;
|
---|
137 | pVBoxVNode->Attr.va_fsid = pVFS->vfs_dev;
|
---|
138 | pVBoxVNode->Attr.va_size = pFSInfo->cbObject;
|
---|
139 | pVBoxVNode->Attr.va_nblocks = (pFSInfo->cbObject + 4095) / 4096;
|
---|
140 | pVBoxVNode->Attr.va_blksize = 4096;
|
---|
141 |
|
---|
142 | vboxvfs_FileTimeFromTimeSpec(&pVBoxVNode->Attr.va_atime, &pFSInfo->AccessTime);
|
---|
143 | vboxvfs_FileTimeFromTimeSpec(&pVBoxVNode->Attr.va_ctime, &pFSInfo->ChangeTime);
|
---|
144 | vboxvfs_FileTimeFromTimeSpec(&pVBoxVNode->Attr.va_mtime, &pFSInfo->ModificationTime);
|
---|
145 |
|
---|
146 | /* Allocate and initialize the vnode */
|
---|
147 | pVBoxVNode->pVNode = vn_alloc(KM_SLEEP);
|
---|
148 |
|
---|
149 | vn_setops(pVBoxVNode->pVNode, g_pVBoxVFS_vnodeops);
|
---|
150 | pVBoxVNode->pVNode->v_data = pVBoxVNode;
|
---|
151 | pVBoxVNode->pVNode->v_vfsp = pVFS;
|
---|
152 | pVBoxVNode->pVNode->v_type = pVBoxVNode->Attr.va_type;
|
---|
153 | pVBoxVNode->pVNode->v_rdev = pVBoxVNode->Attr.va_rdev;
|
---|
154 |
|
---|
155 | mutex_exit(&pVBoxVNode->MtxContents);
|
---|
156 | vn_exists(pVBoxVNode->pVNode);
|
---|
157 | }
|
---|
158 |
|
---|