]>
Commit | Line | Data |
---|---|---|
334c13e1 LE |
1 | /** @file\r |
2 | EFI_FILE_PROTOCOL.Open() member function for the Virtio Filesystem driver.\r | |
3 | \r | |
4 | Copyright (C) 2020, Red Hat, Inc.\r | |
5 | \r | |
6 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
7 | **/\r | |
8 | \r | |
de0e1190 LE |
9 | #include <Library/BaseLib.h> // AsciiStrCmp()\r |
10 | #include <Library/MemoryAllocationLib.h> // AllocatePool()\r | |
11 | \r | |
334c13e1 LE |
12 | #include "VirtioFsDxe.h"\r |
13 | \r | |
de0e1190 LE |
14 | /**\r |
15 | Open the root directory, possibly for writing.\r | |
16 | \r | |
17 | @param[in,out] VirtioFs The Virtio Filesystem device whose root directory\r | |
18 | should be opened.\r | |
19 | \r | |
20 | @param[out] NewHandle The new EFI_FILE_PROTOCOL instance through which\r | |
21 | the root directory can be accessed.\r | |
22 | \r | |
23 | @param[in] OpenForWriting TRUE if the root directory should be opened for\r | |
24 | read-write access. FALSE if the root directory\r | |
25 | should be opened for read-only access. Opening the\r | |
26 | root directory for read-write access is useful for\r | |
27 | calling EFI_FILE_PROTOCOL.Flush() or\r | |
28 | EFI_FILE_PROTOCOL.SetInfo() later, for syncing or\r | |
29 | touching the root directory, respectively.\r | |
30 | \r | |
31 | @retval EFI_SUCCESS The root directory has been opened successfully.\r | |
32 | \r | |
33 | @retval EFI_ACCESS_DENIED OpenForWriting is TRUE, but the root directory is\r | |
34 | marked as read-only.\r | |
35 | \r | |
36 | @return Error codes propagated from underlying functions.\r | |
37 | **/\r | |
38 | STATIC\r | |
39 | EFI_STATUS\r | |
40 | OpenRootDirectory (\r | |
41 | IN OUT VIRTIO_FS *VirtioFs,\r | |
42 | OUT EFI_FILE_PROTOCOL **NewHandle,\r | |
43 | IN BOOLEAN OpenForWriting\r | |
44 | )\r | |
45 | {\r | |
46 | EFI_STATUS Status;\r | |
47 | VIRTIO_FS_FILE *NewVirtioFsFile;\r | |
48 | \r | |
49 | //\r | |
50 | // VirtioFsOpenVolume() opens the root directory for read-only access. If the\r | |
51 | // current request is to open the root directory for read-write access, so\r | |
52 | // that EFI_FILE_PROTOCOL.Flush() or EFI_FILE_PROTOCOL.SetInfo()+timestamps\r | |
53 | // can be used on the root directory later, then we have to check for write\r | |
54 | // permission first.\r | |
55 | //\r | |
56 | if (OpenForWriting) {\r | |
57 | VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr;\r | |
58 | EFI_FILE_INFO FileInfo;\r | |
59 | \r | |
60 | Status = VirtioFsFuseGetAttr (VirtioFs, VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID,\r | |
61 | &FuseAttr);\r | |
62 | if (EFI_ERROR (Status)) {\r | |
63 | return Status;\r | |
64 | }\r | |
65 | Status = VirtioFsFuseAttrToEfiFileInfo (&FuseAttr, &FileInfo);\r | |
66 | if (EFI_ERROR (Status)) {\r | |
67 | return Status;\r | |
68 | }\r | |
69 | if ((FileInfo.Attribute & EFI_FILE_READ_ONLY) != 0) {\r | |
70 | return EFI_ACCESS_DENIED;\r | |
71 | }\r | |
72 | }\r | |
73 | \r | |
74 | Status = VirtioFsOpenVolume (&VirtioFs->SimpleFs, NewHandle);\r | |
75 | if (EFI_ERROR (Status)) {\r | |
76 | return Status;\r | |
77 | }\r | |
78 | \r | |
79 | NewVirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (*NewHandle);\r | |
80 | NewVirtioFsFile->IsOpenForWriting = OpenForWriting;\r | |
81 | return EFI_SUCCESS;\r | |
82 | }\r | |
83 | \r | |
84 | /**\r | |
85 | Open an existent regular file or non-root directory.\r | |
86 | \r | |
87 | @param[in,out] VirtioFs The Virtio Filesystem device on which the\r | |
88 | regular file or directory should be opened.\r | |
89 | \r | |
90 | @param[in] DirNodeId The inode number of the immediate parent\r | |
91 | directory of the regular file or directory to\r | |
92 | open.\r | |
93 | \r | |
94 | @param[in] Name The single-component filename of the regular\r | |
95 | file or directory to open, under the immediate\r | |
96 | parent directory identified by DirNodeId.\r | |
97 | \r | |
98 | @param[in] OpenForWriting TRUE if the regular file or directory should be\r | |
99 | opened for read-write access. FALSE if the\r | |
100 | regular file or directory should be opened for\r | |
101 | read-only access. Opening a directory for\r | |
102 | read-write access is useful for deleting,\r | |
103 | renaming, syncing or touching the directory\r | |
104 | later.\r | |
105 | \r | |
106 | @param[out] NodeId The inode number of the regular file or\r | |
107 | directory, returned by the Virtio Filesystem\r | |
108 | device.\r | |
109 | \r | |
110 | @param[out] FuseHandle The open handle to the regular file or\r | |
111 | directory, returned by the Virtio Filesystem\r | |
112 | device.\r | |
113 | \r | |
114 | @param[out] NodeIsDirectory Set to TRUE on output if Name was found to refer\r | |
115 | to a directory. Set to FALSE if Name was found\r | |
116 | to refer to a regular file.\r | |
117 | \r | |
118 | @retval EFI_SUCCESS The regular file or directory has been looked up\r | |
119 | and opened successfully.\r | |
120 | \r | |
121 | @retval EFI_ACCESS_DENIED OpenForWriting is TRUE, but the regular file or\r | |
122 | directory is marked read-only.\r | |
123 | \r | |
124 | @retval EFI_NOT_FOUND A directory entry called Name was not found in the\r | |
125 | directory identified by DirNodeId. (EFI_NOT_FOUND\r | |
126 | is not returned for any other condition.)\r | |
127 | \r | |
128 | @return Errors propagated from underlying functions. If\r | |
129 | the error code to propagate were EFI_NOT_FOUND, it\r | |
130 | is remapped to EFI_DEVICE_ERROR.\r | |
131 | **/\r | |
132 | STATIC\r | |
133 | EFI_STATUS\r | |
134 | OpenExistentFileOrDirectory (\r | |
135 | IN OUT VIRTIO_FS *VirtioFs,\r | |
136 | IN UINT64 DirNodeId,\r | |
137 | IN CHAR8 *Name,\r | |
138 | IN BOOLEAN OpenForWriting,\r | |
139 | OUT UINT64 *NodeId,\r | |
140 | OUT UINT64 *FuseHandle,\r | |
141 | OUT BOOLEAN *NodeIsDirectory\r | |
142 | )\r | |
143 | {\r | |
144 | EFI_STATUS Status;\r | |
145 | UINT64 ResolvedNodeId;\r | |
146 | VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr;\r | |
147 | EFI_FILE_INFO FileInfo;\r | |
148 | BOOLEAN IsDirectory;\r | |
149 | UINT64 NewFuseHandle;\r | |
150 | \r | |
151 | Status = VirtioFsFuseLookup (VirtioFs, DirNodeId, Name, &ResolvedNodeId,\r | |
152 | &FuseAttr);\r | |
153 | if (EFI_ERROR (Status)) {\r | |
154 | return Status;\r | |
155 | }\r | |
156 | Status = VirtioFsFuseAttrToEfiFileInfo (&FuseAttr, &FileInfo);\r | |
157 | if (EFI_ERROR (Status)) {\r | |
158 | goto ForgetResolvedNodeId;\r | |
159 | }\r | |
160 | \r | |
161 | if (OpenForWriting && (FileInfo.Attribute & EFI_FILE_READ_ONLY) != 0) {\r | |
162 | Status = EFI_ACCESS_DENIED;\r | |
163 | goto ForgetResolvedNodeId;\r | |
164 | }\r | |
165 | \r | |
166 | IsDirectory = (BOOLEAN)((FileInfo.Attribute & EFI_FILE_DIRECTORY) != 0);\r | |
167 | if (IsDirectory) {\r | |
168 | //\r | |
169 | // If OpenForWriting is TRUE here, that's not passed to\r | |
170 | // VirtioFsFuseOpenDir(); it does not affect the FUSE_OPENDIR request we\r | |
171 | // send. OpenForWriting=TRUE will only permit attempts to delete, rename,\r | |
172 | // flush (sync), and touch the directory.\r | |
173 | //\r | |
174 | Status = VirtioFsFuseOpenDir (VirtioFs, ResolvedNodeId, &NewFuseHandle);\r | |
175 | } else {\r | |
176 | Status = VirtioFsFuseOpen (VirtioFs, ResolvedNodeId, OpenForWriting,\r | |
177 | &NewFuseHandle);\r | |
178 | }\r | |
179 | if (EFI_ERROR (Status)) {\r | |
180 | goto ForgetResolvedNodeId;\r | |
181 | }\r | |
182 | \r | |
183 | *NodeId = ResolvedNodeId;\r | |
184 | *FuseHandle = NewFuseHandle;\r | |
185 | *NodeIsDirectory = IsDirectory;\r | |
186 | return EFI_SUCCESS;\r | |
187 | \r | |
188 | ForgetResolvedNodeId:\r | |
189 | VirtioFsFuseForget (VirtioFs, ResolvedNodeId);\r | |
190 | return (Status == EFI_NOT_FOUND) ? EFI_DEVICE_ERROR : Status;\r | |
191 | }\r | |
192 | \r | |
193 | /**\r | |
194 | Create a directory.\r | |
195 | \r | |
196 | @param[in,out] VirtioFs The Virtio Filesystem device on which the directory\r | |
197 | should be created.\r | |
198 | \r | |
199 | @param[in] DirNodeId The inode number of the immediate parent directory\r | |
200 | of the directory to create.\r | |
201 | \r | |
202 | @param[in] Name The single-component filename of the directory to\r | |
203 | create, under the immediate parent directory\r | |
204 | identified by DirNodeId.\r | |
205 | \r | |
206 | @param[out] NodeId The inode number of the directory created, returned\r | |
207 | by the Virtio Filesystem device.\r | |
208 | \r | |
209 | @param[out] FuseHandle The open handle to the directory created, returned\r | |
210 | by the Virtio Filesystem device.\r | |
211 | \r | |
212 | @retval EFI_SUCCESS The directory has been created successfully.\r | |
213 | \r | |
214 | @return Errors propagated from underlying functions.\r | |
215 | **/\r | |
216 | STATIC\r | |
217 | EFI_STATUS\r | |
218 | CreateDirectory (\r | |
219 | IN OUT VIRTIO_FS *VirtioFs,\r | |
220 | IN UINT64 DirNodeId,\r | |
221 | IN CHAR8 *Name,\r | |
222 | OUT UINT64 *NodeId,\r | |
223 | OUT UINT64 *FuseHandle\r | |
224 | )\r | |
225 | {\r | |
226 | EFI_STATUS Status;\r | |
227 | UINT64 NewChildDirNodeId;\r | |
228 | UINT64 NewFuseHandle;\r | |
229 | \r | |
230 | Status = VirtioFsFuseMkDir (VirtioFs, DirNodeId, Name, &NewChildDirNodeId);\r | |
231 | if (EFI_ERROR (Status)) {\r | |
232 | return Status;\r | |
233 | }\r | |
234 | \r | |
235 | Status = VirtioFsFuseOpenDir (VirtioFs, NewChildDirNodeId, &NewFuseHandle);\r | |
236 | if (EFI_ERROR (Status)) {\r | |
237 | goto RemoveNewChildDir;\r | |
238 | }\r | |
239 | \r | |
240 | *NodeId = NewChildDirNodeId;\r | |
241 | *FuseHandle = NewFuseHandle;\r | |
242 | return EFI_SUCCESS;\r | |
243 | \r | |
244 | RemoveNewChildDir:\r | |
245 | VirtioFsFuseRemoveFileOrDir (VirtioFs, DirNodeId, Name, TRUE /* IsDir */);\r | |
246 | VirtioFsFuseForget (VirtioFs, NewChildDirNodeId);\r | |
247 | return Status;\r | |
248 | }\r | |
249 | \r | |
250 | /**\r | |
251 | Create a regular file.\r | |
252 | \r | |
253 | @param[in,out] VirtioFs The Virtio Filesystem device on which the regular\r | |
254 | file should be created.\r | |
255 | \r | |
256 | @param[in] DirNodeId The inode number of the immediate parent directory\r | |
257 | of the regular file to create.\r | |
258 | \r | |
259 | @param[in] Name The single-component filename of the regular file to\r | |
260 | create, under the immediate parent directory\r | |
261 | identified by DirNodeId.\r | |
262 | \r | |
263 | @param[out] NodeId The inode number of the regular file created,\r | |
264 | returned by the Virtio Filesystem device.\r | |
265 | \r | |
266 | @param[out] FuseHandle The open handle to the regular file created,\r | |
267 | returned by the Virtio Filesystem device.\r | |
268 | \r | |
269 | @retval EFI_SUCCESS The regular file has been created successfully.\r | |
270 | \r | |
271 | @return Errors propagated from underlying functions.\r | |
272 | **/\r | |
273 | STATIC\r | |
274 | EFI_STATUS\r | |
275 | CreateRegularFile (\r | |
276 | IN OUT VIRTIO_FS *VirtioFs,\r | |
277 | IN UINT64 DirNodeId,\r | |
278 | IN CHAR8 *Name,\r | |
279 | OUT UINT64 *NodeId,\r | |
280 | OUT UINT64 *FuseHandle\r | |
281 | )\r | |
282 | {\r | |
283 | return VirtioFsFuseOpenOrCreate (VirtioFs, DirNodeId, Name, NodeId,\r | |
284 | FuseHandle);\r | |
285 | }\r | |
286 | \r | |
334c13e1 LE |
287 | EFI_STATUS\r |
288 | EFIAPI\r | |
289 | VirtioFsSimpleFileOpen (\r | |
290 | IN EFI_FILE_PROTOCOL *This,\r | |
291 | OUT EFI_FILE_PROTOCOL **NewHandle,\r | |
292 | IN CHAR16 *FileName,\r | |
293 | IN UINT64 OpenMode,\r | |
294 | IN UINT64 Attributes\r | |
295 | )\r | |
296 | {\r | |
de0e1190 LE |
297 | VIRTIO_FS_FILE *VirtioFsFile;\r |
298 | VIRTIO_FS *VirtioFs;\r | |
299 | BOOLEAN OpenForWriting;\r | |
300 | BOOLEAN PermitCreation;\r | |
301 | BOOLEAN CreateDirectoryIfCreating;\r | |
302 | VIRTIO_FS_FILE *NewVirtioFsFile;\r | |
303 | EFI_STATUS Status;\r | |
304 | CHAR8 *NewCanonicalPath;\r | |
305 | BOOLEAN RootEscape;\r | |
306 | UINT64 DirNodeId;\r | |
307 | CHAR8 *LastComponent;\r | |
308 | UINT64 NewNodeId;\r | |
309 | UINT64 NewFuseHandle;\r | |
310 | BOOLEAN NewNodeIsDirectory;\r | |
311 | \r | |
312 | VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r | |
313 | VirtioFs = VirtioFsFile->OwnerFs;\r | |
314 | \r | |
315 | //\r | |
316 | // Validate OpenMode.\r | |
317 | //\r | |
318 | switch (OpenMode) {\r | |
319 | case EFI_FILE_MODE_READ:\r | |
320 | OpenForWriting = FALSE;\r | |
321 | PermitCreation = FALSE;\r | |
322 | break;\r | |
323 | case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:\r | |
324 | OpenForWriting = TRUE;\r | |
325 | PermitCreation = FALSE;\r | |
326 | break;\r | |
327 | case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE:\r | |
328 | OpenForWriting = TRUE;\r | |
329 | PermitCreation = TRUE;\r | |
330 | break;\r | |
331 | default:\r | |
332 | return EFI_INVALID_PARAMETER;\r | |
333 | }\r | |
334 | \r | |
335 | //\r | |
336 | // Validate the Attributes requested for the case when the file ends up being\r | |
337 | // created, provided creation is permitted.\r | |
338 | //\r | |
339 | if (PermitCreation) {\r | |
340 | if ((Attributes & ~EFI_FILE_VALID_ATTR) != 0) {\r | |
341 | //\r | |
342 | // Unknown attribute requested.\r | |
343 | //\r | |
344 | return EFI_INVALID_PARAMETER;\r | |
345 | }\r | |
346 | \r | |
347 | ASSERT (OpenForWriting);\r | |
348 | if ((Attributes & EFI_FILE_READ_ONLY) != 0) {\r | |
349 | DEBUG ((\r | |
350 | DEBUG_ERROR,\r | |
351 | ("%a: Label=\"%s\" CanonicalPathname=\"%a\" FileName=\"%s\" "\r | |
352 | "OpenMode=0x%Lx Attributes=0x%Lx: nonsensical request to possibly "\r | |
353 | "create a file marked read-only, for read-write access\n"),\r | |
354 | __FUNCTION__,\r | |
355 | VirtioFs->Label,\r | |
356 | VirtioFsFile->CanonicalPathname,\r | |
357 | FileName,\r | |
358 | OpenMode,\r | |
359 | Attributes\r | |
360 | ));\r | |
361 | return EFI_INVALID_PARAMETER;\r | |
362 | }\r | |
363 | CreateDirectoryIfCreating = (BOOLEAN)((Attributes &\r | |
364 | EFI_FILE_DIRECTORY) != 0);\r | |
365 | }\r | |
366 | \r | |
367 | //\r | |
368 | // Referring to a file relative to a regular file makes no sense (or at least\r | |
369 | // it cannot be implemented consistently with how a file is referred to\r | |
370 | // relative to a directory).\r | |
371 | //\r | |
372 | if (!VirtioFsFile->IsDirectory) {\r | |
373 | DEBUG ((\r | |
374 | DEBUG_ERROR,\r | |
375 | ("%a: Label=\"%s\" CanonicalPathname=\"%a\" FileName=\"%s\": "\r | |
376 | "nonsensical request to open a file or directory relative to a regular "\r | |
377 | "file\n"),\r | |
378 | __FUNCTION__,\r | |
379 | VirtioFs->Label,\r | |
380 | VirtioFsFile->CanonicalPathname,\r | |
381 | FileName\r | |
382 | ));\r | |
383 | return EFI_INVALID_PARAMETER;\r | |
384 | }\r | |
385 | \r | |
386 | //\r | |
387 | // Allocate the new VIRTIO_FS_FILE object.\r | |
388 | //\r | |
389 | NewVirtioFsFile = AllocatePool (sizeof *NewVirtioFsFile);\r | |
390 | if (NewVirtioFsFile == NULL) {\r | |
391 | return EFI_OUT_OF_RESOURCES;\r | |
392 | }\r | |
393 | \r | |
394 | //\r | |
395 | // Create the canonical pathname at which the desired file is expected to\r | |
396 | // exist.\r | |
397 | //\r | |
398 | Status = VirtioFsAppendPath (VirtioFsFile->CanonicalPathname, FileName,\r | |
399 | &NewCanonicalPath, &RootEscape);\r | |
400 | if (EFI_ERROR (Status)) {\r | |
401 | goto FreeNewVirtioFsFile;\r | |
402 | }\r | |
403 | if (RootEscape) {\r | |
404 | Status = EFI_ACCESS_DENIED;\r | |
405 | goto FreeNewCanonicalPath;\r | |
406 | }\r | |
407 | \r | |
408 | //\r | |
409 | // If the desired file is the root directory, just open the volume one more\r | |
410 | // time, without looking up anything.\r | |
411 | //\r | |
412 | if (AsciiStrCmp (NewCanonicalPath, "/") == 0) {\r | |
413 | FreePool (NewCanonicalPath);\r | |
414 | FreePool (NewVirtioFsFile);\r | |
415 | return OpenRootDirectory (VirtioFs, NewHandle, OpenForWriting);\r | |
416 | }\r | |
417 | \r | |
418 | //\r | |
419 | // Split the new canonical pathname into most specific parent directory\r | |
420 | // (given by DirNodeId) and last pathname component (i.e., immediate child\r | |
421 | // within that parent directory).\r | |
422 | //\r | |
423 | Status = VirtioFsLookupMostSpecificParentDir (VirtioFs, NewCanonicalPath,\r | |
424 | &DirNodeId, &LastComponent);\r | |
425 | if (EFI_ERROR (Status)) {\r | |
426 | goto FreeNewCanonicalPath;\r | |
427 | }\r | |
428 | \r | |
429 | //\r | |
430 | // Try to open LastComponent directly under DirNodeId, as an existent regular\r | |
431 | // file or directory.\r | |
432 | //\r | |
433 | Status = OpenExistentFileOrDirectory (VirtioFs, DirNodeId, LastComponent,\r | |
434 | OpenForWriting, &NewNodeId, &NewFuseHandle, &NewNodeIsDirectory);\r | |
435 | //\r | |
436 | // If LastComponent could not be found under DirNodeId, but the request\r | |
437 | // allows us to create a new entry, attempt creating the requested regular\r | |
438 | // file or directory.\r | |
439 | //\r | |
440 | if (Status == EFI_NOT_FOUND && PermitCreation) {\r | |
441 | ASSERT (OpenForWriting);\r | |
442 | if (CreateDirectoryIfCreating) {\r | |
443 | Status = CreateDirectory (VirtioFs, DirNodeId, LastComponent, &NewNodeId,\r | |
444 | &NewFuseHandle);\r | |
445 | } else {\r | |
446 | Status = CreateRegularFile (VirtioFs, DirNodeId, LastComponent,\r | |
447 | &NewNodeId, &NewFuseHandle);\r | |
448 | }\r | |
449 | NewNodeIsDirectory = CreateDirectoryIfCreating;\r | |
450 | }\r | |
451 | \r | |
452 | //\r | |
453 | // Regardless of the branch taken, we're done with DirNodeId.\r | |
454 | //\r | |
455 | if (DirNodeId != VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID) {\r | |
456 | VirtioFsFuseForget (VirtioFs, DirNodeId);\r | |
457 | }\r | |
458 | \r | |
459 | if (EFI_ERROR (Status)) {\r | |
460 | goto FreeNewCanonicalPath;\r | |
461 | }\r | |
462 | \r | |
463 | //\r | |
464 | // Populate the new VIRTIO_FS_FILE object.\r | |
465 | //\r | |
466 | NewVirtioFsFile->Signature = VIRTIO_FS_FILE_SIG;\r | |
467 | NewVirtioFsFile->SimpleFile.Revision = EFI_FILE_PROTOCOL_REVISION;\r | |
468 | NewVirtioFsFile->SimpleFile.Open = VirtioFsSimpleFileOpen;\r | |
469 | NewVirtioFsFile->SimpleFile.Close = VirtioFsSimpleFileClose;\r | |
470 | NewVirtioFsFile->SimpleFile.Delete = VirtioFsSimpleFileDelete;\r | |
471 | NewVirtioFsFile->SimpleFile.Read = VirtioFsSimpleFileRead;\r | |
472 | NewVirtioFsFile->SimpleFile.Write = VirtioFsSimpleFileWrite;\r | |
473 | NewVirtioFsFile->SimpleFile.GetPosition = VirtioFsSimpleFileGetPosition;\r | |
474 | NewVirtioFsFile->SimpleFile.SetPosition = VirtioFsSimpleFileSetPosition;\r | |
475 | NewVirtioFsFile->SimpleFile.GetInfo = VirtioFsSimpleFileGetInfo;\r | |
476 | NewVirtioFsFile->SimpleFile.SetInfo = VirtioFsSimpleFileSetInfo;\r | |
477 | NewVirtioFsFile->SimpleFile.Flush = VirtioFsSimpleFileFlush;\r | |
478 | NewVirtioFsFile->IsDirectory = NewNodeIsDirectory;\r | |
479 | NewVirtioFsFile->IsOpenForWriting = OpenForWriting;\r | |
480 | NewVirtioFsFile->OwnerFs = VirtioFs;\r | |
481 | NewVirtioFsFile->CanonicalPathname = NewCanonicalPath;\r | |
c4edb49b | 482 | NewVirtioFsFile->FilePosition = 0;\r |
de0e1190 LE |
483 | NewVirtioFsFile->NodeId = NewNodeId;\r |
484 | NewVirtioFsFile->FuseHandle = NewFuseHandle;\r | |
485 | \r | |
486 | //\r | |
487 | // One more file is now open for the filesystem.\r | |
488 | //\r | |
489 | InsertTailList (&VirtioFs->OpenFiles, &NewVirtioFsFile->OpenFilesEntry);\r | |
490 | \r | |
491 | *NewHandle = &NewVirtioFsFile->SimpleFile;\r | |
492 | return EFI_SUCCESS;\r | |
493 | \r | |
494 | FreeNewCanonicalPath:\r | |
495 | FreePool (NewCanonicalPath);\r | |
496 | \r | |
497 | FreeNewVirtioFsFile:\r | |
498 | FreePool (NewVirtioFsFile);\r | |
499 | \r | |
500 | return Status;\r | |
334c13e1 | 501 | }\r |