2 Internal macro definitions, type definitions, and function declarations for
3 the Virtio Filesystem device driver.
5 Copyright (C) 2020, Red Hat, Inc.
7 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #ifndef VIRTIO_FS_DXE_H_
11 #define VIRTIO_FS_DXE_H_
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
21 #define VIRTIO_FS_SIG SIGNATURE_64 ('V', 'I', 'R', 'T', 'I', 'O', 'F', 'S')
23 #define VIRTIO_FS_FILE_SIG \
24 SIGNATURE_64 ('V', 'I', 'O', 'F', 'S', 'F', 'I', 'L')
27 // The following limit applies to two kinds of pathnames.
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
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.
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
48 #define VIRTIO_FS_MAX_PATHNAME_LENGTH ((UINTN)65535)
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.
55 typedef CHAR16 VIRTIO_FS_LABEL
[VIRTIO_FS_TAG_BYTES
+ 1];
58 // Main context structure, expressing an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
59 // interface on top of the Virtio Filesystem device.
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
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
81 #define VIRTIO_FS_FROM_SIMPLE_FS(SimpleFsReference) \
82 CR (SimpleFsReference, VIRTIO_FS, SimpleFs, VIRTIO_FS_SIG);
85 // Structure for describing a contiguous buffer, potentially mapped for Virtio
90 // The following fields originate from the owner of the buffer.
95 // All of the fields below, until the end of the structure, are
96 // zero-initialized when the structure is initially validated.
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.
103 EFI_PHYSICAL_ADDRESS MappedAddress
;
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().
112 } VIRTIO_FS_IO_VECTOR
;
115 // Structure for describing a list of IO Vectors.
119 // The following fields originate from the owner of the buffers.
121 VIRTIO_FS_IO_VECTOR
*IoVec
;
124 // TotalSize is calculated when the scatter-gather list is initially
128 } VIRTIO_FS_SCATTER_GATHER_LIST
;
131 // Private context structure that exposes EFI_FILE_PROTOCOL on top of an open
132 // FUSE file reference.
136 EFI_FILE_PROTOCOL SimpleFile
;
138 BOOLEAN IsOpenForWriting
;
140 LIST_ENTRY OpenFilesEntry
;
141 CHAR8
*CanonicalPathname
;
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.
159 #define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \
160 CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);
162 #define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \
163 CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \
167 // Initialization and helper routines for the Virtio Filesystem device.
172 IN OUT VIRTIO_FS
*VirtioFs
177 IN OUT VIRTIO_FS
*VirtioFs
183 IN EFI_EVENT ExitBootEvent
,
184 IN VOID
*VirtioFsAsVoid
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
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
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
,
211 VirtioFsFuseCheckResponse (
212 IN VIRTIO_FS_SCATTER_GATHER_LIST
*ResponseSgList
,
214 OUT UINTN
*TailBufferFill
218 VirtioFsErrnoToEfiStatus (
225 IN CHAR16
*RhsPath16
,
226 OUT CHAR8
**ResultPath8
,
227 OUT BOOLEAN
*RootEscape
231 VirtioFsLookupMostSpecificParentDir (
232 IN OUT VIRTIO_FS
*VirtioFs
,
234 OUT UINT64
*DirNodeId
,
235 OUT CHAR8
**LastComponent
239 VirtioFsGetBasename (
241 OUT CHAR16
*Basename OPTIONAL
,
242 IN OUT UINTN
*BasenameSize
246 VirtioFsFuseAttrToEfiFileInfo (
247 IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE
*FuseAttr
,
248 OUT EFI_FILE_INFO
*FileInfo
252 VirtioFsFuseDirentPlusToEfiFileInfo (
253 IN VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE
*FuseDirent
,
254 IN OUT EFI_FILE_INFO
*FileInfo
258 // Wrapper functions for FUSE commands (primitives).
263 IN OUT VIRTIO_FS
*VirtioFs
,
267 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE
*FuseAttr
272 IN OUT VIRTIO_FS
*VirtioFs
,
277 VirtioFsFuseGetAttr (
278 IN OUT VIRTIO_FS
*VirtioFs
,
280 OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE
*FuseAttr
285 IN OUT VIRTIO_FS
*VirtioFs
,
286 IN UINT64 ParentNodeId
,
292 VirtioFsFuseRemoveFileOrDir (
293 IN OUT VIRTIO_FS
*VirtioFs
,
294 IN UINT64 ParentNodeId
,
301 IN OUT VIRTIO_FS
*VirtioFs
,
303 IN BOOLEAN ReadWrite
,
304 OUT UINT64
*FuseHandle
308 VirtioFsFuseReadFileOrDir (
309 IN OUT VIRTIO_FS
*VirtioFs
,
311 IN UINT64 FuseHandle
,
320 IN OUT VIRTIO_FS
*VirtioFs
,
322 OUT VIRTIO_FS_FUSE_STATFS_RESPONSE
*FilesysAttr
326 VirtioFsFuseReleaseFileOrDir (
327 IN OUT VIRTIO_FS
*VirtioFs
,
329 IN UINT64 FuseHandle
,
334 VirtioFsFuseFsyncFileOrDir (
335 IN OUT VIRTIO_FS
*VirtioFs
,
337 IN UINT64 FuseHandle
,
343 IN OUT VIRTIO_FS
*VirtioFs
,
349 VirtioFsFuseInitSession (
350 IN OUT VIRTIO_FS
*VirtioFs
354 VirtioFsFuseOpenDir (
355 IN OUT VIRTIO_FS
*VirtioFs
,
357 OUT UINT64
*FuseHandle
361 VirtioFsFuseOpenOrCreate (
362 IN OUT VIRTIO_FS
*VirtioFs
,
363 IN UINT64 ParentNodeId
,
366 OUT UINT64
*FuseHandle
370 // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member functions for the Virtio Filesystem
377 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*This
,
378 OUT EFI_FILE_PROTOCOL
**Root
382 // EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.
387 VirtioFsSimpleFileClose (
388 IN EFI_FILE_PROTOCOL
*This
393 VirtioFsSimpleFileDelete (
394 IN EFI_FILE_PROTOCOL
*This
399 VirtioFsSimpleFileFlush (
400 IN EFI_FILE_PROTOCOL
*This
405 VirtioFsSimpleFileGetInfo (
406 IN EFI_FILE_PROTOCOL
*This
,
407 IN EFI_GUID
*InformationType
,
408 IN OUT UINTN
*BufferSize
,
414 VirtioFsSimpleFileGetPosition (
415 IN EFI_FILE_PROTOCOL
*This
,
421 VirtioFsSimpleFileOpen (
422 IN EFI_FILE_PROTOCOL
*This
,
423 OUT EFI_FILE_PROTOCOL
**NewHandle
,
431 VirtioFsSimpleFileRead (
432 IN EFI_FILE_PROTOCOL
*This
,
433 IN OUT UINTN
*BufferSize
,
439 VirtioFsSimpleFileSetInfo (
440 IN EFI_FILE_PROTOCOL
*This
,
441 IN EFI_GUID
*InformationType
,
448 VirtioFsSimpleFileSetPosition (
449 IN EFI_FILE_PROTOCOL
*This
,
455 VirtioFsSimpleFileWrite (
456 IN EFI_FILE_PROTOCOL
*This
,
457 IN OUT UINTN
*BufferSize
,
461 #endif // VIRTIO_FS_DXE_H_