]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
a704acdd520e4a3dfc23f7b61566dd6099b4a9d7
[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 EFI_EVENT ExitBoot; // DriverBindingStart 0
82 LIST_ENTRY OpenFiles; // DriverBindingStart 0
83 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; // DriverBindingStart 0
84 } VIRTIO_FS;
85
86 #define VIRTIO_FS_FROM_SIMPLE_FS(SimpleFsReference) \
87 CR (SimpleFsReference, VIRTIO_FS, SimpleFs, VIRTIO_FS_SIG);
88
89 //
90 // Structure for describing a contiguous buffer, potentially mapped for Virtio
91 // transfer.
92 //
93 typedef struct {
94 //
95 // The following fields originate from the owner of the buffer.
96 //
97 VOID *Buffer;
98 UINTN Size;
99 //
100 // All of the fields below, until the end of the structure, are
101 // zero-initialized when the structure is initially validated.
102 //
103 // Mapped, MappedAddress and Mapping are updated when the buffer is mapped
104 // for VirtioOperationBusMasterRead or VirtioOperationBusMasterWrite. They
105 // are again updated when the buffer is unmapped.
106 //
107 BOOLEAN Mapped;
108 EFI_PHYSICAL_ADDRESS MappedAddress;
109 VOID *Mapping;
110 //
111 // Transferred is updated after VirtioFlush() returns successfully:
112 // - for VirtioOperationBusMasterRead, Transferred is set to Size;
113 // - for VirtioOperationBusMasterWrite, Transferred is calculated from the
114 // UsedLen output parameter of VirtioFlush().
115 //
116 UINTN Transferred;
117 } VIRTIO_FS_IO_VECTOR;
118
119 //
120 // Structure for describing a list of IO Vectors.
121 //
122 typedef struct {
123 //
124 // The following fields originate from the owner of the buffers.
125 //
126 VIRTIO_FS_IO_VECTOR *IoVec;
127 UINTN NumVec;
128 //
129 // TotalSize is calculated when the scatter-gather list is initially
130 // validated.
131 //
132 UINT32 TotalSize;
133 } VIRTIO_FS_SCATTER_GATHER_LIST;
134
135 //
136 // Private context structure that exposes EFI_FILE_PROTOCOL on top of an open
137 // FUSE file reference.
138 //
139 typedef struct {
140 UINT64 Signature;
141 EFI_FILE_PROTOCOL SimpleFile;
142 BOOLEAN IsDirectory;
143 BOOLEAN IsOpenForWriting;
144 VIRTIO_FS *OwnerFs;
145 LIST_ENTRY OpenFilesEntry;
146 CHAR8 *CanonicalPathname;
147 UINT64 FilePosition;
148 //
149 // In the FUSE wire protocol, every request except FUSE_INIT refers to a
150 // file, namely by the "VIRTIO_FS_FUSE_REQUEST.NodeId" field; that is, by the
151 // inode number of the file. However, some of the FUSE requests that we need
152 // for some of the EFI_FILE_PROTOCOL member functions require an open file
153 // handle *in addition* to the inode number. For simplicity, whenever a
154 // VIRTIO_FS_FILE object is created, primarily defined by its NodeId field,
155 // we also *open* the referenced file at once, and save the returned file
156 // handle in the FuseHandle field. This way, when an EFI_FILE_PROTOCOL member
157 // function must send a FUSE request that needs the file handle *in addition*
158 // to the inode number, FuseHandle will be at our disposal at once.
159 //
160 UINT64 NodeId;
161 UINT64 FuseHandle;
162 //
163 // EFI_FILE_INFO objects cached for an in-flight directory read.
164 //
165 // For reading through a directory stream with tolerable performance, we have
166 // to call FUSE_READDIRPLUS each time with such a buffer that can deliver a
167 // good number of variable size records (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE
168 // elements). Every time we do that, we turn the whole bunch into an array of
169 // EFI_FILE_INFOs immediately. EFI_FILE_PROTOCOL.Read() invocations (on
170 // directories) will be served from this EFI_FILE_INFO cache.
171 //
172 UINT8 *FileInfoArray;
173 UINTN SingleFileInfoSize;
174 UINTN NumFileInfo;
175 UINTN NextFileInfo;
176 } VIRTIO_FS_FILE;
177
178 #define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \
179 CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);
180
181 #define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \
182 CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \
183 VIRTIO_FS_FILE_SIG);
184
185 //
186 // Initialization and helper routines for the Virtio Filesystem device.
187 //
188
189 EFI_STATUS
190 VirtioFsInit (
191 IN OUT VIRTIO_FS *VirtioFs
192 );
193
194 VOID
195 VirtioFsUninit (
196 IN OUT VIRTIO_FS *VirtioFs
197 );
198
199 VOID
200 EFIAPI
201 VirtioFsExitBoot (
202 IN EFI_EVENT ExitBootEvent,
203 IN VOID *VirtioFsAsVoid
204 );
205
206 EFI_STATUS
207 VirtioFsSgListsValidate (
208 IN VIRTIO_FS *VirtioFs,
209 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
210 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
211 );
212
213 EFI_STATUS
214 VirtioFsSgListsSubmit (
215 IN OUT VIRTIO_FS *VirtioFs,
216 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
217 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
218 );
219
220 EFI_STATUS
221 VirtioFsFuseNewRequest (
222 IN OUT VIRTIO_FS *VirtioFs,
223 OUT VIRTIO_FS_FUSE_REQUEST *Request,
224 IN UINT32 RequestSize,
225 IN VIRTIO_FS_FUSE_OPCODE Opcode,
226 IN UINT64 NodeId
227 );
228
229 EFI_STATUS
230 VirtioFsFuseCheckResponse (
231 IN VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList,
232 IN UINT64 RequestId,
233 OUT UINTN *TailBufferFill
234 );
235
236 EFI_STATUS
237 VirtioFsErrnoToEfiStatus (
238 IN INT32 Errno
239 );
240
241 EFI_STATUS
242 VirtioFsAppendPath (
243 IN CHAR8 *LhsPath8,
244 IN CHAR16 *RhsPath16,
245 OUT CHAR8 **ResultPath8,
246 OUT BOOLEAN *RootEscape
247 );
248
249 EFI_STATUS
250 VirtioFsLookupMostSpecificParentDir (
251 IN OUT VIRTIO_FS *VirtioFs,
252 IN OUT CHAR8 *Path,
253 OUT UINT64 *DirNodeId,
254 OUT CHAR8 **LastComponent
255 );
256
257 EFI_STATUS
258 VirtioFsGetBasename (
259 IN CHAR8 *Path,
260 OUT CHAR16 *Basename OPTIONAL,
261 IN OUT UINTN *BasenameSize
262 );
263
264 EFI_STATUS
265 VirtioFsFuseAttrToEfiFileInfo (
266 IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,
267 OUT EFI_FILE_INFO *FileInfo
268 );
269
270 EFI_STATUS
271 VirtioFsFuseDirentPlusToEfiFileInfo (
272 IN VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *FuseDirent,
273 IN OUT EFI_FILE_INFO *FileInfo
274 );
275
276 //
277 // Wrapper functions for FUSE commands (primitives).
278 //
279
280 EFI_STATUS
281 VirtioFsFuseLookup (
282 IN OUT VIRTIO_FS *VirtioFs,
283 IN UINT64 DirNodeId,
284 IN CHAR8 *Name,
285 OUT UINT64 *NodeId,
286 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
287 );
288
289 EFI_STATUS
290 VirtioFsFuseForget (
291 IN OUT VIRTIO_FS *VirtioFs,
292 IN UINT64 NodeId
293 );
294
295 EFI_STATUS
296 VirtioFsFuseGetAttr (
297 IN OUT VIRTIO_FS *VirtioFs,
298 IN UINT64 NodeId,
299 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
300 );
301
302 EFI_STATUS
303 VirtioFsFuseMkDir (
304 IN OUT VIRTIO_FS *VirtioFs,
305 IN UINT64 ParentNodeId,
306 IN CHAR8 *Name,
307 OUT UINT64 *NodeId
308 );
309
310 EFI_STATUS
311 VirtioFsFuseRemoveFileOrDir (
312 IN OUT VIRTIO_FS *VirtioFs,
313 IN UINT64 ParentNodeId,
314 IN CHAR8 *Name,
315 IN BOOLEAN IsDir
316 );
317
318 EFI_STATUS
319 VirtioFsFuseOpen (
320 IN OUT VIRTIO_FS *VirtioFs,
321 IN UINT64 NodeId,
322 IN BOOLEAN ReadWrite,
323 OUT UINT64 *FuseHandle
324 );
325
326 EFI_STATUS
327 VirtioFsFuseReadFileOrDir (
328 IN OUT VIRTIO_FS *VirtioFs,
329 IN UINT64 NodeId,
330 IN UINT64 FuseHandle,
331 IN BOOLEAN IsDir,
332 IN UINT64 Offset,
333 IN OUT UINT32 *Size,
334 OUT VOID *Data
335 );
336
337 EFI_STATUS
338 VirtioFsFuseStatFs (
339 IN OUT VIRTIO_FS *VirtioFs,
340 IN UINT64 NodeId,
341 OUT VIRTIO_FS_FUSE_STATFS_RESPONSE *FilesysAttr
342 );
343
344 EFI_STATUS
345 VirtioFsFuseReleaseFileOrDir (
346 IN OUT VIRTIO_FS *VirtioFs,
347 IN UINT64 NodeId,
348 IN UINT64 FuseHandle,
349 IN BOOLEAN IsDir
350 );
351
352 EFI_STATUS
353 VirtioFsFuseFsyncFileOrDir (
354 IN OUT VIRTIO_FS *VirtioFs,
355 IN UINT64 NodeId,
356 IN UINT64 FuseHandle,
357 IN BOOLEAN IsDir
358 );
359
360 EFI_STATUS
361 VirtioFsFuseFlush (
362 IN OUT VIRTIO_FS *VirtioFs,
363 IN UINT64 NodeId,
364 IN UINT64 FuseHandle
365 );
366
367 EFI_STATUS
368 VirtioFsFuseInitSession (
369 IN OUT VIRTIO_FS *VirtioFs
370 );
371
372 EFI_STATUS
373 VirtioFsFuseOpenDir (
374 IN OUT VIRTIO_FS *VirtioFs,
375 IN UINT64 NodeId,
376 OUT UINT64 *FuseHandle
377 );
378
379 EFI_STATUS
380 VirtioFsFuseOpenOrCreate (
381 IN OUT VIRTIO_FS *VirtioFs,
382 IN UINT64 ParentNodeId,
383 IN CHAR8 *Name,
384 OUT UINT64 *NodeId,
385 OUT UINT64 *FuseHandle
386 );
387
388 //
389 // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member functions for the Virtio Filesystem
390 // driver.
391 //
392
393 EFI_STATUS
394 EFIAPI
395 VirtioFsOpenVolume (
396 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
397 OUT EFI_FILE_PROTOCOL **Root
398 );
399
400 //
401 // EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.
402 //
403
404 EFI_STATUS
405 EFIAPI
406 VirtioFsSimpleFileClose (
407 IN EFI_FILE_PROTOCOL *This
408 );
409
410 EFI_STATUS
411 EFIAPI
412 VirtioFsSimpleFileDelete (
413 IN EFI_FILE_PROTOCOL *This
414 );
415
416 EFI_STATUS
417 EFIAPI
418 VirtioFsSimpleFileFlush (
419 IN EFI_FILE_PROTOCOL *This
420 );
421
422 EFI_STATUS
423 EFIAPI
424 VirtioFsSimpleFileGetInfo (
425 IN EFI_FILE_PROTOCOL *This,
426 IN EFI_GUID *InformationType,
427 IN OUT UINTN *BufferSize,
428 OUT VOID *Buffer
429 );
430
431 EFI_STATUS
432 EFIAPI
433 VirtioFsSimpleFileGetPosition (
434 IN EFI_FILE_PROTOCOL *This,
435 OUT UINT64 *Position
436 );
437
438 EFI_STATUS
439 EFIAPI
440 VirtioFsSimpleFileOpen (
441 IN EFI_FILE_PROTOCOL *This,
442 OUT EFI_FILE_PROTOCOL **NewHandle,
443 IN CHAR16 *FileName,
444 IN UINT64 OpenMode,
445 IN UINT64 Attributes
446 );
447
448 EFI_STATUS
449 EFIAPI
450 VirtioFsSimpleFileRead (
451 IN EFI_FILE_PROTOCOL *This,
452 IN OUT UINTN *BufferSize,
453 OUT VOID *Buffer
454 );
455
456 EFI_STATUS
457 EFIAPI
458 VirtioFsSimpleFileSetInfo (
459 IN EFI_FILE_PROTOCOL *This,
460 IN EFI_GUID *InformationType,
461 IN UINTN BufferSize,
462 IN VOID *Buffer
463 );
464
465 EFI_STATUS
466 EFIAPI
467 VirtioFsSimpleFileSetPosition (
468 IN EFI_FILE_PROTOCOL *This,
469 IN UINT64 Position
470 );
471
472 EFI_STATUS
473 EFIAPI
474 VirtioFsSimpleFileWrite (
475 IN EFI_FILE_PROTOCOL *This,
476 IN OUT UINTN *BufferSize,
477 IN VOID *Buffer
478 );
479
480 #endif // VIRTIO_FS_DXE_H_