]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
OvmfPkg/VirtioFsDxe: add helper for determining access time updates
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / VirtioFsDxe.h
CommitLineData
b55d6622
LE
1/** @file\r
2 Internal macro definitions, type definitions, and function declarations for\r
3 the Virtio Filesystem device driver.\r
4\r
5 Copyright (C) 2020, Red Hat, Inc.\r
6\r
7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
8**/\r
9\r
10#ifndef VIRTIO_FS_DXE_H_\r
11#define VIRTIO_FS_DXE_H_\r
12\r
13#include <Base.h> // SIGNATURE_64()\r
cd473d41 14#include <Guid/FileInfo.h> // EFI_FILE_INFO\r
eaa7115d 15#include <IndustryStandard/VirtioFs.h> // VIRTIO_FS_TAG_BYTES\r
b55d6622
LE
16#include <Library/DebugLib.h> // CR()\r
17#include <Protocol/SimpleFileSystem.h> // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL\r
18#include <Protocol/VirtioDevice.h> // VIRTIO_DEVICE_PROTOCOL\r
eaa7115d 19#include <Uefi/UefiBaseType.h> // EFI_EVENT\r
b55d6622
LE
20\r
21#define VIRTIO_FS_SIG SIGNATURE_64 ('V', 'I', 'R', 'T', 'I', 'O', 'F', 'S')\r
22\r
334c13e1
LE
23#define VIRTIO_FS_FILE_SIG \\r
24 SIGNATURE_64 ('V', 'I', 'O', 'F', 'S', 'F', 'I', 'L')\r
25\r
9307d7c7
LE
26//\r
27// The following limit applies to two kinds of pathnames.\r
28//\r
29// - The length of a POSIX-style, canonical pathname *at rest* never exceeds\r
30// VIRTIO_FS_MAX_PATHNAME_LENGTH. (Length is defined as the number of CHAR8\r
31// elements in the canonical pathname, excluding the terminating '\0'.) This\r
32// is an invariant that is ensured for canonical pathnames created, and that\r
33// is assumed about canonical pathname inputs (which all originate\r
34// internally).\r
35//\r
36// - If the length of a UEFI-style pathname *argument*, originating directly or\r
37// indirectly from the EFI_FILE_PROTOCOL caller, exceeds\r
38// VIRTIO_FS_MAX_PATHNAME_LENGTH, then the argument is rejected. (Length is\r
39// defined as the number of CHAR16 elements in the UEFI-style pathname,\r
40// excluding the terminating L'\0'.) This is a restriction that's checked on\r
41// external UEFI-style pathname inputs.\r
42//\r
43// The limit is not expected to be a practical limitation; it's only supposed\r
44// to prevent attempts at overflowing size calculations. For both kinds of\r
45// pathnames, separate limits could be used; a common limit is used purely for\r
46// simplicity.\r
47//\r
48#define VIRTIO_FS_MAX_PATHNAME_LENGTH ((UINTN)65535)\r
49\r
b845de89
LE
50//\r
51// Maximum value for VIRTIO_FS_FILE.NumFileInfo.\r
52//\r
53#define VIRTIO_FS_FILE_MAX_FILE_INFO 256\r
54\r
eaa7115d
LE
55//\r
56// Filesystem label encoded in UCS-2, transformed from the UTF-8 representation\r
57// in "VIRTIO_FS_CONFIG.Tag", and NUL-terminated. Only the printable ASCII code\r
58// points (U+0020 through U+007E) are supported.\r
59//\r
60typedef CHAR16 VIRTIO_FS_LABEL[VIRTIO_FS_TAG_BYTES + 1];\r
61\r
b55d6622
LE
62//\r
63// Main context structure, expressing an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL\r
64// interface on top of the Virtio Filesystem device.\r
65//\r
66typedef struct {\r
67 //\r
68 // Parts of this structure are initialized / torn down in various functions\r
69 // at various call depths. The table to the right should make it easier to\r
70 // track them.\r
71 //\r
72 // field init function init depth\r
73 // ----------- ------------------ ----------\r
74 UINT64 Signature; // DriverBindingStart 0\r
75 VIRTIO_DEVICE_PROTOCOL *Virtio; // DriverBindingStart 0\r
eaa7115d
LE
76 VIRTIO_FS_LABEL Label; // VirtioFsInit 1\r
77 UINT16 QueueSize; // VirtioFsInit 1\r
78 VRING Ring; // VirtioRingInit 2\r
79 VOID *RingMap; // VirtioRingMap 2\r
fa97e372 80 UINT64 RequestId; // FuseInitSession 1\r
6f7bc719 81 UINT32 MaxWrite; // FuseInitSession 1\r
eaa7115d 82 EFI_EVENT ExitBoot; // DriverBindingStart 0\r
334c13e1 83 LIST_ENTRY OpenFiles; // DriverBindingStart 0\r
b55d6622
LE
84 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; // DriverBindingStart 0\r
85} VIRTIO_FS;\r
86\r
87#define VIRTIO_FS_FROM_SIMPLE_FS(SimpleFsReference) \\r
88 CR (SimpleFsReference, VIRTIO_FS, SimpleFs, VIRTIO_FS_SIG);\r
89\r
6578cacb
LE
90//\r
91// Structure for describing a contiguous buffer, potentially mapped for Virtio\r
92// transfer.\r
93//\r
94typedef struct {\r
95 //\r
96 // The following fields originate from the owner of the buffer.\r
97 //\r
98 VOID *Buffer;\r
99 UINTN Size;\r
100 //\r
101 // All of the fields below, until the end of the structure, are\r
102 // zero-initialized when the structure is initially validated.\r
103 //\r
104 // Mapped, MappedAddress and Mapping are updated when the buffer is mapped\r
105 // for VirtioOperationBusMasterRead or VirtioOperationBusMasterWrite. They\r
106 // are again updated when the buffer is unmapped.\r
107 //\r
108 BOOLEAN Mapped;\r
109 EFI_PHYSICAL_ADDRESS MappedAddress;\r
110 VOID *Mapping;\r
111 //\r
112 // Transferred is updated after VirtioFlush() returns successfully:\r
113 // - for VirtioOperationBusMasterRead, Transferred is set to Size;\r
114 // - for VirtioOperationBusMasterWrite, Transferred is calculated from the\r
115 // UsedLen output parameter of VirtioFlush().\r
116 //\r
117 UINTN Transferred;\r
118} VIRTIO_FS_IO_VECTOR;\r
119\r
120//\r
121// Structure for describing a list of IO Vectors.\r
122//\r
123typedef struct {\r
124 //\r
125 // The following fields originate from the owner of the buffers.\r
126 //\r
127 VIRTIO_FS_IO_VECTOR *IoVec;\r
128 UINTN NumVec;\r
129 //\r
130 // TotalSize is calculated when the scatter-gather list is initially\r
131 // validated.\r
132 //\r
133 UINT32 TotalSize;\r
134} VIRTIO_FS_SCATTER_GATHER_LIST;\r
135\r
334c13e1
LE
136//\r
137// Private context structure that exposes EFI_FILE_PROTOCOL on top of an open\r
138// FUSE file reference.\r
139//\r
140typedef struct {\r
141 UINT64 Signature;\r
142 EFI_FILE_PROTOCOL SimpleFile;\r
143 BOOLEAN IsDirectory;\r
28092a39 144 BOOLEAN IsOpenForWriting;\r
334c13e1
LE
145 VIRTIO_FS *OwnerFs;\r
146 LIST_ENTRY OpenFilesEntry;\r
7e8c83f7 147 CHAR8 *CanonicalPathname;\r
c4edb49b 148 UINT64 FilePosition;\r
334c13e1
LE
149 //\r
150 // In the FUSE wire protocol, every request except FUSE_INIT refers to a\r
151 // file, namely by the "VIRTIO_FS_FUSE_REQUEST.NodeId" field; that is, by the\r
152 // inode number of the file. However, some of the FUSE requests that we need\r
153 // for some of the EFI_FILE_PROTOCOL member functions require an open file\r
154 // handle *in addition* to the inode number. For simplicity, whenever a\r
155 // VIRTIO_FS_FILE object is created, primarily defined by its NodeId field,\r
156 // we also *open* the referenced file at once, and save the returned file\r
157 // handle in the FuseHandle field. This way, when an EFI_FILE_PROTOCOL member\r
158 // function must send a FUSE request that needs the file handle *in addition*\r
159 // to the inode number, FuseHandle will be at our disposal at once.\r
160 //\r
161 UINT64 NodeId;\r
162 UINT64 FuseHandle;\r
b845de89
LE
163 //\r
164 // EFI_FILE_INFO objects cached for an in-flight directory read.\r
165 //\r
166 // For reading through a directory stream with tolerable performance, we have\r
167 // to call FUSE_READDIRPLUS each time with such a buffer that can deliver a\r
168 // good number of variable size records (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE\r
169 // elements). Every time we do that, we turn the whole bunch into an array of\r
170 // EFI_FILE_INFOs immediately. EFI_FILE_PROTOCOL.Read() invocations (on\r
171 // directories) will be served from this EFI_FILE_INFO cache.\r
172 //\r
173 UINT8 *FileInfoArray;\r
174 UINTN SingleFileInfoSize;\r
175 UINTN NumFileInfo;\r
176 UINTN NextFileInfo;\r
334c13e1
LE
177} VIRTIO_FS_FILE;\r
178\r
179#define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \\r
180 CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);\r
181\r
182#define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \\r
183 CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \\r
184 VIRTIO_FS_FILE_SIG);\r
185\r
eaa7115d
LE
186//\r
187// Initialization and helper routines for the Virtio Filesystem device.\r
188//\r
189\r
190EFI_STATUS\r
191VirtioFsInit (\r
192 IN OUT VIRTIO_FS *VirtioFs\r
193 );\r
194\r
195VOID\r
196VirtioFsUninit (\r
197 IN OUT VIRTIO_FS *VirtioFs\r
198 );\r
199\r
200VOID\r
201EFIAPI\r
202VirtioFsExitBoot (\r
203 IN EFI_EVENT ExitBootEvent,\r
204 IN VOID *VirtioFsAsVoid\r
205 );\r
206\r
6578cacb
LE
207EFI_STATUS\r
208VirtioFsSgListsValidate (\r
209 IN VIRTIO_FS *VirtioFs,\r
210 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,\r
211 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL\r
212 );\r
213\r
214EFI_STATUS\r
215VirtioFsSgListsSubmit (\r
216 IN OUT VIRTIO_FS *VirtioFs,\r
217 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,\r
218 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL\r
219 );\r
220\r
6a2dc768
LE
221EFI_STATUS\r
222VirtioFsFuseNewRequest (\r
223 IN OUT VIRTIO_FS *VirtioFs,\r
224 OUT VIRTIO_FS_FUSE_REQUEST *Request,\r
225 IN UINT32 RequestSize,\r
fa97e372 226 IN VIRTIO_FS_FUSE_OPCODE Opcode,\r
6a2dc768
LE
227 IN UINT64 NodeId\r
228 );\r
229\r
230EFI_STATUS\r
231VirtioFsFuseCheckResponse (\r
232 IN VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList,\r
233 IN UINT64 RequestId,\r
234 OUT UINTN *TailBufferFill\r
235 );\r
236\r
e8a74c9a
LE
237EFI_STATUS\r
238VirtioFsErrnoToEfiStatus (\r
239 IN INT32 Errno\r
240 );\r
241\r
9307d7c7
LE
242EFI_STATUS\r
243VirtioFsAppendPath (\r
244 IN CHAR8 *LhsPath8,\r
245 IN CHAR16 *RhsPath16,\r
246 OUT CHAR8 **ResultPath8,\r
247 OUT BOOLEAN *RootEscape\r
248 );\r
249\r
ca61b845
LE
250EFI_STATUS\r
251VirtioFsLookupMostSpecificParentDir (\r
252 IN OUT VIRTIO_FS *VirtioFs,\r
253 IN OUT CHAR8 *Path,\r
254 OUT UINT64 *DirNodeId,\r
255 OUT CHAR8 **LastComponent\r
256 );\r
257\r
44bc7879
LE
258EFI_STATUS\r
259VirtioFsGetBasename (\r
260 IN CHAR8 *Path,\r
261 OUT CHAR16 *Basename OPTIONAL,\r
262 IN OUT UINTN *BasenameSize\r
263 );\r
264\r
cd473d41 265EFI_STATUS\r
c3f76ef8
LE
266VirtioFsComposeRenameDestination (\r
267 IN CHAR8 *LhsPath8,\r
268 IN CHAR16 *RhsPath16,\r
269 OUT CHAR8 **ResultPath8,\r
270 OUT BOOLEAN *RootEscape\r
271 );\r
272\r
273EFI_STATUS\r
cd473d41
LE
274VirtioFsFuseAttrToEfiFileInfo (\r
275 IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,\r
276 OUT EFI_FILE_INFO *FileInfo\r
277 );\r
278\r
7a775209
LE
279EFI_STATUS\r
280VirtioFsFuseDirentPlusToEfiFileInfo (\r
281 IN VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *FuseDirent,\r
282 IN OUT EFI_FILE_INFO *FileInfo\r
283 );\r
284\r
6c33d7b2
LE
285VOID\r
286VirtioFsGetFuseSizeUpdate (\r
287 IN EFI_FILE_INFO *Info,\r
288 IN EFI_FILE_INFO *NewInfo,\r
289 OUT BOOLEAN *Update,\r
290 OUT UINT64 *Size\r
291 );\r
292\r
3cbd54b9
LE
293EFI_STATUS\r
294VirtioFsGetFuseTimeUpdates (\r
295 IN EFI_FILE_INFO *Info,\r
296 IN EFI_FILE_INFO *NewInfo,\r
297 OUT BOOLEAN *UpdateAtime,\r
298 OUT BOOLEAN *UpdateMtime,\r
299 OUT UINT64 *Atime,\r
300 OUT UINT64 *Mtime\r
301 );\r
302\r
fa97e372
LE
303//\r
304// Wrapper functions for FUSE commands (primitives).\r
305//\r
306\r
b6ce961a
LE
307EFI_STATUS\r
308VirtioFsFuseLookup (\r
309 IN OUT VIRTIO_FS *VirtioFs,\r
310 IN UINT64 DirNodeId,\r
311 IN CHAR8 *Name,\r
312 OUT UINT64 *NodeId,\r
313 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr\r
314 );\r
315\r
92a4d30e
LE
316EFI_STATUS\r
317VirtioFsFuseForget (\r
318 IN OUT VIRTIO_FS *VirtioFs,\r
319 IN UINT64 NodeId\r
320 );\r
321\r
e3bc9577
LE
322EFI_STATUS\r
323VirtioFsFuseGetAttr (\r
324 IN OUT VIRTIO_FS *VirtioFs,\r
325 IN UINT64 NodeId,\r
326 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr\r
327 );\r
328\r
f058cb69 329EFI_STATUS\r
647340b0
LE
330VirtioFsFuseSetAttr (\r
331 IN OUT VIRTIO_FS *VirtioFs,\r
332 IN UINT64 NodeId,\r
333 IN UINT64 *Size OPTIONAL,\r
334 IN UINT64 *Atime OPTIONAL,\r
335 IN UINT64 *Mtime OPTIONAL,\r
336 IN UINT32 *Mode OPTIONAL\r
337 );\r
338\r
339EFI_STATUS\r
f058cb69
LE
340VirtioFsFuseMkDir (\r
341 IN OUT VIRTIO_FS *VirtioFs,\r
342 IN UINT64 ParentNodeId,\r
343 IN CHAR8 *Name,\r
344 OUT UINT64 *NodeId\r
345 );\r
346\r
0771671c
LE
347EFI_STATUS\r
348VirtioFsFuseRemoveFileOrDir (\r
349 IN OUT VIRTIO_FS *VirtioFs,\r
350 IN UINT64 ParentNodeId,\r
351 IN CHAR8 *Name,\r
352 IN BOOLEAN IsDir\r
353 );\r
354\r
da82d2e3
LE
355EFI_STATUS\r
356VirtioFsFuseOpen (\r
357 IN OUT VIRTIO_FS *VirtioFs,\r
358 IN UINT64 NodeId,\r
359 IN BOOLEAN ReadWrite,\r
360 OUT UINT64 *FuseHandle\r
361 );\r
362\r
d98d7e30
LE
363EFI_STATUS\r
364VirtioFsFuseReadFileOrDir (\r
365 IN OUT VIRTIO_FS *VirtioFs,\r
366 IN UINT64 NodeId,\r
367 IN UINT64 FuseHandle,\r
368 IN BOOLEAN IsDir,\r
369 IN UINT64 Offset,\r
370 IN OUT UINT32 *Size,\r
371 OUT VOID *Data\r
372 );\r
373\r
6f7bc719
LE
374EFI_STATUS\r
375VirtioFsFuseWrite (\r
376 IN OUT VIRTIO_FS *VirtioFs,\r
377 IN UINT64 NodeId,\r
378 IN UINT64 FuseHandle,\r
379 IN UINT64 Offset,\r
380 IN OUT UINT32 *Size,\r
381 IN VOID *Data\r
382 );\r
383\r
ba118463
LE
384EFI_STATUS\r
385VirtioFsFuseStatFs (\r
386 IN OUT VIRTIO_FS *VirtioFs,\r
387 IN UINT64 NodeId,\r
388 OUT VIRTIO_FS_FUSE_STATFS_RESPONSE *FilesysAttr\r
389 );\r
390\r
72d4f133
LE
391EFI_STATUS\r
392VirtioFsFuseReleaseFileOrDir (\r
393 IN OUT VIRTIO_FS *VirtioFs,\r
394 IN UINT64 NodeId,\r
395 IN UINT64 FuseHandle,\r
396 IN BOOLEAN IsDir\r
397 );\r
398\r
2e151d26
LE
399EFI_STATUS\r
400VirtioFsFuseFsyncFileOrDir (\r
401 IN OUT VIRTIO_FS *VirtioFs,\r
402 IN UINT64 NodeId,\r
403 IN UINT64 FuseHandle,\r
404 IN BOOLEAN IsDir\r
405 );\r
406\r
d0474399
LE
407EFI_STATUS\r
408VirtioFsFuseFlush (\r
409 IN OUT VIRTIO_FS *VirtioFs,\r
410 IN UINT64 NodeId,\r
411 IN UINT64 FuseHandle\r
412 );\r
413\r
fa97e372
LE
414EFI_STATUS\r
415VirtioFsFuseInitSession (\r
416 IN OUT VIRTIO_FS *VirtioFs\r
417 );\r
418\r
b62a0c56
LE
419EFI_STATUS\r
420VirtioFsFuseOpenDir (\r
421 IN OUT VIRTIO_FS *VirtioFs,\r
422 IN UINT64 NodeId,\r
423 OUT UINT64 *FuseHandle\r
424 );\r
425\r
a70860f4
LE
426EFI_STATUS\r
427VirtioFsFuseOpenOrCreate (\r
428 IN OUT VIRTIO_FS *VirtioFs,\r
429 IN UINT64 ParentNodeId,\r
430 IN CHAR8 *Name,\r
431 OUT UINT64 *NodeId,\r
432 OUT UINT64 *FuseHandle\r
433 );\r
434\r
bea1f51d
LE
435EFI_STATUS\r
436VirtioFsFuseRename (\r
437 IN OUT VIRTIO_FS *VirtioFs,\r
438 IN UINT64 OldParentNodeId,\r
439 IN CHAR8 *OldName,\r
440 IN UINT64 NewParentNodeId,\r
441 IN CHAR8 *NewName\r
442 );\r
443\r
b55d6622
LE
444//\r
445// EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member functions for the Virtio Filesystem\r
446// driver.\r
447//\r
448\r
449EFI_STATUS\r
450EFIAPI\r
451VirtioFsOpenVolume (\r
452 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
453 OUT EFI_FILE_PROTOCOL **Root\r
454 );\r
455\r
334c13e1
LE
456//\r
457// EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.\r
458//\r
459\r
460EFI_STATUS\r
461EFIAPI\r
462VirtioFsSimpleFileClose (\r
463 IN EFI_FILE_PROTOCOL *This\r
464 );\r
465\r
466EFI_STATUS\r
467EFIAPI\r
468VirtioFsSimpleFileDelete (\r
469 IN EFI_FILE_PROTOCOL *This\r
470 );\r
471\r
472EFI_STATUS\r
473EFIAPI\r
474VirtioFsSimpleFileFlush (\r
475 IN EFI_FILE_PROTOCOL *This\r
476 );\r
477\r
478EFI_STATUS\r
479EFIAPI\r
480VirtioFsSimpleFileGetInfo (\r
481 IN EFI_FILE_PROTOCOL *This,\r
482 IN EFI_GUID *InformationType,\r
483 IN OUT UINTN *BufferSize,\r
484 OUT VOID *Buffer\r
485 );\r
486\r
487EFI_STATUS\r
488EFIAPI\r
489VirtioFsSimpleFileGetPosition (\r
490 IN EFI_FILE_PROTOCOL *This,\r
491 OUT UINT64 *Position\r
492 );\r
493\r
494EFI_STATUS\r
495EFIAPI\r
496VirtioFsSimpleFileOpen (\r
497 IN EFI_FILE_PROTOCOL *This,\r
498 OUT EFI_FILE_PROTOCOL **NewHandle,\r
499 IN CHAR16 *FileName,\r
500 IN UINT64 OpenMode,\r
501 IN UINT64 Attributes\r
502 );\r
503\r
504EFI_STATUS\r
505EFIAPI\r
506VirtioFsSimpleFileRead (\r
507 IN EFI_FILE_PROTOCOL *This,\r
508 IN OUT UINTN *BufferSize,\r
509 OUT VOID *Buffer\r
510 );\r
511\r
512EFI_STATUS\r
513EFIAPI\r
514VirtioFsSimpleFileSetInfo (\r
515 IN EFI_FILE_PROTOCOL *This,\r
516 IN EFI_GUID *InformationType,\r
517 IN UINTN BufferSize,\r
518 IN VOID *Buffer\r
519 );\r
520\r
521EFI_STATUS\r
522EFIAPI\r
523VirtioFsSimpleFileSetPosition (\r
524 IN EFI_FILE_PROTOCOL *This,\r
525 IN UINT64 Position\r
526 );\r
527\r
528EFI_STATUS\r
529EFIAPI\r
530VirtioFsSimpleFileWrite (\r
531 IN EFI_FILE_PROTOCOL *This,\r
532 IN OUT UINTN *BufferSize,\r
533 IN VOID *Buffer\r
534 );\r
535\r
b55d6622 536#endif // VIRTIO_FS_DXE_H_\r