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