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