]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.GetPosition, .SetPosition
[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 // Filesystem label encoded in UCS-2, transformed from the UTF-8 representation
52 // in "VIRTIO_FS_CONFIG.Tag", and NUL-terminated. Only the printable ASCII code
53 // points (U+0020 through U+007E) are supported.
54 //
55 typedef CHAR16 VIRTIO_FS_LABEL[VIRTIO_FS_TAG_BYTES + 1];
56
57 //
58 // Main context structure, expressing an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
59 // interface on top of the Virtio Filesystem device.
60 //
61 typedef struct {
62 //
63 // Parts of this structure are initialized / torn down in various functions
64 // at various call depths. The table to the right should make it easier to
65 // track them.
66 //
67 // field init function init depth
68 // ----------- ------------------ ----------
69 UINT64 Signature; // DriverBindingStart 0
70 VIRTIO_DEVICE_PROTOCOL *Virtio; // DriverBindingStart 0
71 VIRTIO_FS_LABEL Label; // VirtioFsInit 1
72 UINT16 QueueSize; // VirtioFsInit 1
73 VRING Ring; // VirtioRingInit 2
74 VOID *RingMap; // VirtioRingMap 2
75 UINT64 RequestId; // FuseInitSession 1
76 EFI_EVENT ExitBoot; // DriverBindingStart 0
77 LIST_ENTRY OpenFiles; // DriverBindingStart 0
78 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; // DriverBindingStart 0
79 } VIRTIO_FS;
80
81 #define VIRTIO_FS_FROM_SIMPLE_FS(SimpleFsReference) \
82 CR (SimpleFsReference, VIRTIO_FS, SimpleFs, VIRTIO_FS_SIG);
83
84 //
85 // Structure for describing a contiguous buffer, potentially mapped for Virtio
86 // transfer.
87 //
88 typedef struct {
89 //
90 // The following fields originate from the owner of the buffer.
91 //
92 VOID *Buffer;
93 UINTN Size;
94 //
95 // All of the fields below, until the end of the structure, are
96 // zero-initialized when the structure is initially validated.
97 //
98 // Mapped, MappedAddress and Mapping are updated when the buffer is mapped
99 // for VirtioOperationBusMasterRead or VirtioOperationBusMasterWrite. They
100 // are again updated when the buffer is unmapped.
101 //
102 BOOLEAN Mapped;
103 EFI_PHYSICAL_ADDRESS MappedAddress;
104 VOID *Mapping;
105 //
106 // Transferred is updated after VirtioFlush() returns successfully:
107 // - for VirtioOperationBusMasterRead, Transferred is set to Size;
108 // - for VirtioOperationBusMasterWrite, Transferred is calculated from the
109 // UsedLen output parameter of VirtioFlush().
110 //
111 UINTN Transferred;
112 } VIRTIO_FS_IO_VECTOR;
113
114 //
115 // Structure for describing a list of IO Vectors.
116 //
117 typedef struct {
118 //
119 // The following fields originate from the owner of the buffers.
120 //
121 VIRTIO_FS_IO_VECTOR *IoVec;
122 UINTN NumVec;
123 //
124 // TotalSize is calculated when the scatter-gather list is initially
125 // validated.
126 //
127 UINT32 TotalSize;
128 } VIRTIO_FS_SCATTER_GATHER_LIST;
129
130 //
131 // Private context structure that exposes EFI_FILE_PROTOCOL on top of an open
132 // FUSE file reference.
133 //
134 typedef struct {
135 UINT64 Signature;
136 EFI_FILE_PROTOCOL SimpleFile;
137 BOOLEAN IsDirectory;
138 BOOLEAN IsOpenForWriting;
139 VIRTIO_FS *OwnerFs;
140 LIST_ENTRY OpenFilesEntry;
141 CHAR8 *CanonicalPathname;
142 UINT64 FilePosition;
143 //
144 // In the FUSE wire protocol, every request except FUSE_INIT refers to a
145 // file, namely by the "VIRTIO_FS_FUSE_REQUEST.NodeId" field; that is, by the
146 // inode number of the file. However, some of the FUSE requests that we need
147 // for some of the EFI_FILE_PROTOCOL member functions require an open file
148 // handle *in addition* to the inode number. For simplicity, whenever a
149 // VIRTIO_FS_FILE object is created, primarily defined by its NodeId field,
150 // we also *open* the referenced file at once, and save the returned file
151 // handle in the FuseHandle field. This way, when an EFI_FILE_PROTOCOL member
152 // function must send a FUSE request that needs the file handle *in addition*
153 // to the inode number, FuseHandle will be at our disposal at once.
154 //
155 UINT64 NodeId;
156 UINT64 FuseHandle;
157 } VIRTIO_FS_FILE;
158
159 #define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \
160 CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);
161
162 #define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \
163 CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \
164 VIRTIO_FS_FILE_SIG);
165
166 //
167 // Initialization and helper routines for the Virtio Filesystem device.
168 //
169
170 EFI_STATUS
171 VirtioFsInit (
172 IN OUT VIRTIO_FS *VirtioFs
173 );
174
175 VOID
176 VirtioFsUninit (
177 IN OUT VIRTIO_FS *VirtioFs
178 );
179
180 VOID
181 EFIAPI
182 VirtioFsExitBoot (
183 IN EFI_EVENT ExitBootEvent,
184 IN VOID *VirtioFsAsVoid
185 );
186
187 EFI_STATUS
188 VirtioFsSgListsValidate (
189 IN VIRTIO_FS *VirtioFs,
190 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
191 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
192 );
193
194 EFI_STATUS
195 VirtioFsSgListsSubmit (
196 IN OUT VIRTIO_FS *VirtioFs,
197 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
198 IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
199 );
200
201 EFI_STATUS
202 VirtioFsFuseNewRequest (
203 IN OUT VIRTIO_FS *VirtioFs,
204 OUT VIRTIO_FS_FUSE_REQUEST *Request,
205 IN UINT32 RequestSize,
206 IN VIRTIO_FS_FUSE_OPCODE Opcode,
207 IN UINT64 NodeId
208 );
209
210 EFI_STATUS
211 VirtioFsFuseCheckResponse (
212 IN VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList,
213 IN UINT64 RequestId,
214 OUT UINTN *TailBufferFill
215 );
216
217 EFI_STATUS
218 VirtioFsErrnoToEfiStatus (
219 IN INT32 Errno
220 );
221
222 EFI_STATUS
223 VirtioFsAppendPath (
224 IN CHAR8 *LhsPath8,
225 IN CHAR16 *RhsPath16,
226 OUT CHAR8 **ResultPath8,
227 OUT BOOLEAN *RootEscape
228 );
229
230 EFI_STATUS
231 VirtioFsLookupMostSpecificParentDir (
232 IN OUT VIRTIO_FS *VirtioFs,
233 IN OUT CHAR8 *Path,
234 OUT UINT64 *DirNodeId,
235 OUT CHAR8 **LastComponent
236 );
237
238 EFI_STATUS
239 VirtioFsGetBasename (
240 IN CHAR8 *Path,
241 OUT CHAR16 *Basename OPTIONAL,
242 IN OUT UINTN *BasenameSize
243 );
244
245 EFI_STATUS
246 VirtioFsFuseAttrToEfiFileInfo (
247 IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,
248 OUT EFI_FILE_INFO *FileInfo
249 );
250
251 //
252 // Wrapper functions for FUSE commands (primitives).
253 //
254
255 EFI_STATUS
256 VirtioFsFuseLookup (
257 IN OUT VIRTIO_FS *VirtioFs,
258 IN UINT64 DirNodeId,
259 IN CHAR8 *Name,
260 OUT UINT64 *NodeId,
261 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
262 );
263
264 EFI_STATUS
265 VirtioFsFuseForget (
266 IN OUT VIRTIO_FS *VirtioFs,
267 IN UINT64 NodeId
268 );
269
270 EFI_STATUS
271 VirtioFsFuseGetAttr (
272 IN OUT VIRTIO_FS *VirtioFs,
273 IN UINT64 NodeId,
274 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
275 );
276
277 EFI_STATUS
278 VirtioFsFuseMkDir (
279 IN OUT VIRTIO_FS *VirtioFs,
280 IN UINT64 ParentNodeId,
281 IN CHAR8 *Name,
282 OUT UINT64 *NodeId
283 );
284
285 EFI_STATUS
286 VirtioFsFuseRemoveFileOrDir (
287 IN OUT VIRTIO_FS *VirtioFs,
288 IN UINT64 ParentNodeId,
289 IN CHAR8 *Name,
290 IN BOOLEAN IsDir
291 );
292
293 EFI_STATUS
294 VirtioFsFuseOpen (
295 IN OUT VIRTIO_FS *VirtioFs,
296 IN UINT64 NodeId,
297 IN BOOLEAN ReadWrite,
298 OUT UINT64 *FuseHandle
299 );
300
301 EFI_STATUS
302 VirtioFsFuseStatFs (
303 IN OUT VIRTIO_FS *VirtioFs,
304 IN UINT64 NodeId,
305 OUT VIRTIO_FS_FUSE_STATFS_RESPONSE *FilesysAttr
306 );
307
308 EFI_STATUS
309 VirtioFsFuseReleaseFileOrDir (
310 IN OUT VIRTIO_FS *VirtioFs,
311 IN UINT64 NodeId,
312 IN UINT64 FuseHandle,
313 IN BOOLEAN IsDir
314 );
315
316 EFI_STATUS
317 VirtioFsFuseFsyncFileOrDir (
318 IN OUT VIRTIO_FS *VirtioFs,
319 IN UINT64 NodeId,
320 IN UINT64 FuseHandle,
321 IN BOOLEAN IsDir
322 );
323
324 EFI_STATUS
325 VirtioFsFuseFlush (
326 IN OUT VIRTIO_FS *VirtioFs,
327 IN UINT64 NodeId,
328 IN UINT64 FuseHandle
329 );
330
331 EFI_STATUS
332 VirtioFsFuseInitSession (
333 IN OUT VIRTIO_FS *VirtioFs
334 );
335
336 EFI_STATUS
337 VirtioFsFuseOpenDir (
338 IN OUT VIRTIO_FS *VirtioFs,
339 IN UINT64 NodeId,
340 OUT UINT64 *FuseHandle
341 );
342
343 EFI_STATUS
344 VirtioFsFuseOpenOrCreate (
345 IN OUT VIRTIO_FS *VirtioFs,
346 IN UINT64 ParentNodeId,
347 IN CHAR8 *Name,
348 OUT UINT64 *NodeId,
349 OUT UINT64 *FuseHandle
350 );
351
352 //
353 // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member functions for the Virtio Filesystem
354 // driver.
355 //
356
357 EFI_STATUS
358 EFIAPI
359 VirtioFsOpenVolume (
360 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
361 OUT EFI_FILE_PROTOCOL **Root
362 );
363
364 //
365 // EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.
366 //
367
368 EFI_STATUS
369 EFIAPI
370 VirtioFsSimpleFileClose (
371 IN EFI_FILE_PROTOCOL *This
372 );
373
374 EFI_STATUS
375 EFIAPI
376 VirtioFsSimpleFileDelete (
377 IN EFI_FILE_PROTOCOL *This
378 );
379
380 EFI_STATUS
381 EFIAPI
382 VirtioFsSimpleFileFlush (
383 IN EFI_FILE_PROTOCOL *This
384 );
385
386 EFI_STATUS
387 EFIAPI
388 VirtioFsSimpleFileGetInfo (
389 IN EFI_FILE_PROTOCOL *This,
390 IN EFI_GUID *InformationType,
391 IN OUT UINTN *BufferSize,
392 OUT VOID *Buffer
393 );
394
395 EFI_STATUS
396 EFIAPI
397 VirtioFsSimpleFileGetPosition (
398 IN EFI_FILE_PROTOCOL *This,
399 OUT UINT64 *Position
400 );
401
402 EFI_STATUS
403 EFIAPI
404 VirtioFsSimpleFileOpen (
405 IN EFI_FILE_PROTOCOL *This,
406 OUT EFI_FILE_PROTOCOL **NewHandle,
407 IN CHAR16 *FileName,
408 IN UINT64 OpenMode,
409 IN UINT64 Attributes
410 );
411
412 EFI_STATUS
413 EFIAPI
414 VirtioFsSimpleFileRead (
415 IN EFI_FILE_PROTOCOL *This,
416 IN OUT UINTN *BufferSize,
417 OUT VOID *Buffer
418 );
419
420 EFI_STATUS
421 EFIAPI
422 VirtioFsSimpleFileSetInfo (
423 IN EFI_FILE_PROTOCOL *This,
424 IN EFI_GUID *InformationType,
425 IN UINTN BufferSize,
426 IN VOID *Buffer
427 );
428
429 EFI_STATUS
430 EFIAPI
431 VirtioFsSimpleFileSetPosition (
432 IN EFI_FILE_PROTOCOL *This,
433 IN UINT64 Position
434 );
435
436 EFI_STATUS
437 EFIAPI
438 VirtioFsSimpleFileWrite (
439 IN EFI_FILE_PROTOCOL *This,
440 IN OUT UINTN *BufferSize,
441 IN VOID *Buffer
442 );
443
444 #endif // VIRTIO_FS_DXE_H_