123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- /** @file
- Internal macro definitions, type definitions, and function declarations for
- the Virtio Filesystem device driver.
- Copyright (C) 2020, Red Hat, Inc.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #ifndef VIRTIO_FS_DXE_H_
- #define VIRTIO_FS_DXE_H_
- #include <Base.h> // SIGNATURE_64()
- #include <Guid/FileInfo.h> // EFI_FILE_INFO
- #include <IndustryStandard/VirtioFs.h> // VIRTIO_FS_TAG_BYTES
- #include <Library/DebugLib.h> // CR()
- #include <Protocol/SimpleFileSystem.h> // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
- #include <Protocol/VirtioDevice.h> // VIRTIO_DEVICE_PROTOCOL
- #include <Uefi/UefiBaseType.h> // EFI_EVENT
- #define VIRTIO_FS_SIG SIGNATURE_64 ('V', 'I', 'R', 'T', 'I', 'O', 'F', 'S')
- #define VIRTIO_FS_FILE_SIG \
- SIGNATURE_64 ('V', 'I', 'O', 'F', 'S', 'F', 'I', 'L')
- //
- // The following limit applies to two kinds of pathnames.
- //
- // - The length of a POSIX-style, canonical pathname *at rest* never exceeds
- // VIRTIO_FS_MAX_PATHNAME_LENGTH. (Length is defined as the number of CHAR8
- // elements in the canonical pathname, excluding the terminating '\0'.) This
- // is an invariant that is ensured for canonical pathnames created, and that
- // is assumed about canonical pathname inputs (which all originate
- // internally).
- //
- // - If the length of a UEFI-style pathname *argument*, originating directly or
- // indirectly from the EFI_FILE_PROTOCOL caller, exceeds
- // VIRTIO_FS_MAX_PATHNAME_LENGTH, then the argument is rejected. (Length is
- // defined as the number of CHAR16 elements in the UEFI-style pathname,
- // excluding the terminating L'\0'.) This is a restriction that's checked on
- // external UEFI-style pathname inputs.
- //
- // The limit is not expected to be a practical limitation; it's only supposed
- // to prevent attempts at overflowing size calculations. For both kinds of
- // pathnames, separate limits could be used; a common limit is used purely for
- // simplicity.
- //
- #define VIRTIO_FS_MAX_PATHNAME_LENGTH ((UINTN)65535)
- //
- // Maximum value for VIRTIO_FS_FILE.NumFileInfo.
- //
- #define VIRTIO_FS_FILE_MAX_FILE_INFO 256
- //
- // Filesystem label encoded in UCS-2, transformed from the UTF-8 representation
- // in "VIRTIO_FS_CONFIG.Tag", and NUL-terminated. Only the printable ASCII code
- // points (U+0020 through U+007E) are supported.
- //
- typedef CHAR16 VIRTIO_FS_LABEL[VIRTIO_FS_TAG_BYTES + 1];
- //
- // Main context structure, expressing an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
- // interface on top of the Virtio Filesystem device.
- //
- typedef struct {
- //
- // Parts of this structure are initialized / torn down in various functions
- // at various call depths. The table to the right should make it easier to
- // track them.
- //
- // field init function init depth
- // ----------- ------------------ ----------
- UINT64 Signature; // DriverBindingStart 0
- VIRTIO_DEVICE_PROTOCOL *Virtio; // DriverBindingStart 0
- VIRTIO_FS_LABEL Label; // VirtioFsInit 1
- UINT16 QueueSize; // VirtioFsInit 1
- VRING Ring; // VirtioRingInit 2
- VOID *RingMap; // VirtioRingMap 2
- UINT64 RequestId; // FuseInitSession 1
- UINT32 MaxWrite; // FuseInitSession 1
- EFI_EVENT ExitBoot; // DriverBindingStart 0
- LIST_ENTRY OpenFiles; // DriverBindingStart 0
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; // DriverBindingStart 0
- } VIRTIO_FS;
- #define VIRTIO_FS_FROM_SIMPLE_FS(SimpleFsReference) \
- CR (SimpleFsReference, VIRTIO_FS, SimpleFs, VIRTIO_FS_SIG);
- //
- // Structure for describing a contiguous buffer, potentially mapped for Virtio
- // transfer.
- //
- typedef struct {
- //
- // The following fields originate from the owner of the buffer.
- //
- VOID *Buffer;
- UINTN Size;
- //
- // All of the fields below, until the end of the structure, are
- // zero-initialized when the structure is initially validated.
- //
- // Mapped, MappedAddress and Mapping are updated when the buffer is mapped
- // for VirtioOperationBusMasterRead or VirtioOperationBusMasterWrite. They
- // are again updated when the buffer is unmapped.
- //
- BOOLEAN Mapped;
- EFI_PHYSICAL_ADDRESS MappedAddress;
- VOID *Mapping;
- //
- // Transferred is updated after VirtioFlush() returns successfully:
- // - for VirtioOperationBusMasterRead, Transferred is set to Size;
- // - for VirtioOperationBusMasterWrite, Transferred is calculated from the
- // UsedLen output parameter of VirtioFlush().
- //
- UINTN Transferred;
- } VIRTIO_FS_IO_VECTOR;
- //
- // Structure for describing a list of IO Vectors.
- //
- typedef struct {
- //
- // The following fields originate from the owner of the buffers.
- //
- VIRTIO_FS_IO_VECTOR *IoVec;
- UINTN NumVec;
- //
- // TotalSize is calculated when the scatter-gather list is initially
- // validated.
- //
- UINT32 TotalSize;
- } VIRTIO_FS_SCATTER_GATHER_LIST;
- //
- // Private context structure that exposes EFI_FILE_PROTOCOL on top of an open
- // FUSE file reference.
- //
- typedef struct {
- UINT64 Signature;
- EFI_FILE_PROTOCOL SimpleFile;
- BOOLEAN IsDirectory;
- BOOLEAN IsOpenForWriting;
- VIRTIO_FS *OwnerFs;
- LIST_ENTRY OpenFilesEntry;
- CHAR8 *CanonicalPathname;
- UINT64 FilePosition;
- //
- // In the FUSE wire protocol, every request except FUSE_INIT refers to a
- // file, namely by the "VIRTIO_FS_FUSE_REQUEST.NodeId" field; that is, by the
- // inode number of the file. However, some of the FUSE requests that we need
- // for some of the EFI_FILE_PROTOCOL member functions require an open file
- // handle *in addition* to the inode number. For simplicity, whenever a
- // VIRTIO_FS_FILE object is created, primarily defined by its NodeId field,
- // we also *open* the referenced file at once, and save the returned file
- // handle in the FuseHandle field. This way, when an EFI_FILE_PROTOCOL member
- // function must send a FUSE request that needs the file handle *in addition*
- // to the inode number, FuseHandle will be at our disposal at once.
- //
- UINT64 NodeId;
- UINT64 FuseHandle;
- //
- // EFI_FILE_INFO objects cached for an in-flight directory read.
- //
- // For reading through a directory stream with tolerable performance, we have
- // to call FUSE_READDIRPLUS each time with such a buffer that can deliver a
- // good number of variable size records (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE
- // elements). Every time we do that, we turn the whole bunch into an array of
- // EFI_FILE_INFOs immediately. EFI_FILE_PROTOCOL.Read() invocations (on
- // directories) will be served from this EFI_FILE_INFO cache.
- //
- UINT8 *FileInfoArray;
- UINTN SingleFileInfoSize;
- UINTN NumFileInfo;
- UINTN NextFileInfo;
- } VIRTIO_FS_FILE;
- #define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \
- CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);
- #define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \
- CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \
- VIRTIO_FS_FILE_SIG);
- //
- // Initialization and helper routines for the Virtio Filesystem device.
- //
- EFI_STATUS
- VirtioFsInit (
- IN OUT VIRTIO_FS *VirtioFs
- );
- VOID
- VirtioFsUninit (
- IN OUT VIRTIO_FS *VirtioFs
- );
- VOID
- EFIAPI
- VirtioFsExitBoot (
- IN EFI_EVENT ExitBootEvent,
- IN VOID *VirtioFsAsVoid
- );
- EFI_STATUS
- VirtioFsSgListsValidate (
- IN VIRTIO_FS *VirtioFs,
- IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
- IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
- );
- EFI_STATUS
- VirtioFsSgListsSubmit (
- IN OUT VIRTIO_FS *VirtioFs,
- IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
- IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
- );
- EFI_STATUS
- VirtioFsFuseNewRequest (
- IN OUT VIRTIO_FS *VirtioFs,
- OUT VIRTIO_FS_FUSE_REQUEST *Request,
- IN UINT32 RequestSize,
- IN VIRTIO_FS_FUSE_OPCODE Opcode,
- IN UINT64 NodeId
- );
- EFI_STATUS
- VirtioFsFuseCheckResponse (
- IN VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList,
- IN UINT64 RequestId,
- OUT UINTN *TailBufferFill
- );
- EFI_STATUS
- VirtioFsErrnoToEfiStatus (
- IN INT32 Errno
- );
- EFI_STATUS
- VirtioFsAppendPath (
- IN CHAR8 *LhsPath8,
- IN CHAR16 *RhsPath16,
- OUT CHAR8 **ResultPath8,
- OUT BOOLEAN *RootEscape
- );
- EFI_STATUS
- VirtioFsLookupMostSpecificParentDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN OUT CHAR8 *Path,
- OUT UINT64 *DirNodeId,
- OUT CHAR8 **LastComponent
- );
- EFI_STATUS
- VirtioFsGetBasename (
- IN CHAR8 *Path,
- OUT CHAR16 *Basename OPTIONAL,
- IN OUT UINTN *BasenameSize
- );
- EFI_STATUS
- VirtioFsComposeRenameDestination (
- IN CHAR8 *LhsPath8,
- IN CHAR16 *RhsPath16,
- OUT CHAR8 **ResultPath8,
- OUT BOOLEAN *RootEscape
- );
- EFI_STATUS
- VirtioFsFuseAttrToEfiFileInfo (
- IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,
- OUT EFI_FILE_INFO *FileInfo
- );
- EFI_STATUS
- VirtioFsFuseDirentPlusToEfiFileInfo (
- IN VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *FuseDirent,
- IN OUT EFI_FILE_INFO *FileInfo
- );
- VOID
- VirtioFsGetFuseSizeUpdate (
- IN EFI_FILE_INFO *Info,
- IN EFI_FILE_INFO *NewInfo,
- OUT BOOLEAN *Update,
- OUT UINT64 *Size
- );
- EFI_STATUS
- VirtioFsGetFuseTimeUpdates (
- IN EFI_FILE_INFO *Info,
- IN EFI_FILE_INFO *NewInfo,
- OUT BOOLEAN *UpdateAtime,
- OUT BOOLEAN *UpdateMtime,
- OUT UINT64 *Atime,
- OUT UINT64 *Mtime
- );
- EFI_STATUS
- VirtioFsGetFuseModeUpdate (
- IN EFI_FILE_INFO *Info,
- IN EFI_FILE_INFO *NewInfo,
- OUT BOOLEAN *Update,
- OUT UINT32 *Mode
- );
- //
- // Wrapper functions for FUSE commands (primitives).
- //
- EFI_STATUS
- VirtioFsFuseLookup (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 DirNodeId,
- IN CHAR8 *Name,
- OUT UINT64 *NodeId,
- OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
- );
- EFI_STATUS
- VirtioFsFuseForget (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId
- );
- EFI_STATUS
- VirtioFsFuseGetAttr (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
- );
- EFI_STATUS
- VirtioFsFuseSetAttr (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN UINT64 *Size OPTIONAL,
- IN UINT64 *Atime OPTIONAL,
- IN UINT64 *Mtime OPTIONAL,
- IN UINT32 *Mode OPTIONAL
- );
- EFI_STATUS
- VirtioFsFuseMkDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 ParentNodeId,
- IN CHAR8 *Name,
- OUT UINT64 *NodeId
- );
- EFI_STATUS
- VirtioFsFuseRemoveFileOrDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 ParentNodeId,
- IN CHAR8 *Name,
- IN BOOLEAN IsDir
- );
- EFI_STATUS
- VirtioFsFuseOpen (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN BOOLEAN ReadWrite,
- OUT UINT64 *FuseHandle
- );
- EFI_STATUS
- VirtioFsFuseReadFileOrDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN UINT64 FuseHandle,
- IN BOOLEAN IsDir,
- IN UINT64 Offset,
- IN OUT UINT32 *Size,
- OUT VOID *Data
- );
- EFI_STATUS
- VirtioFsFuseWrite (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN UINT64 FuseHandle,
- IN UINT64 Offset,
- IN OUT UINT32 *Size,
- IN VOID *Data
- );
- EFI_STATUS
- VirtioFsFuseStatFs (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- OUT VIRTIO_FS_FUSE_STATFS_RESPONSE *FilesysAttr
- );
- EFI_STATUS
- VirtioFsFuseReleaseFileOrDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN UINT64 FuseHandle,
- IN BOOLEAN IsDir
- );
- EFI_STATUS
- VirtioFsFuseFsyncFileOrDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN UINT64 FuseHandle,
- IN BOOLEAN IsDir
- );
- EFI_STATUS
- VirtioFsFuseFlush (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- IN UINT64 FuseHandle
- );
- EFI_STATUS
- VirtioFsFuseInitSession (
- IN OUT VIRTIO_FS *VirtioFs
- );
- EFI_STATUS
- VirtioFsFuseOpenDir (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 NodeId,
- OUT UINT64 *FuseHandle
- );
- EFI_STATUS
- VirtioFsFuseOpenOrCreate (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 ParentNodeId,
- IN CHAR8 *Name,
- OUT UINT64 *NodeId,
- OUT UINT64 *FuseHandle
- );
- EFI_STATUS
- VirtioFsFuseRename (
- IN OUT VIRTIO_FS *VirtioFs,
- IN UINT64 OldParentNodeId,
- IN CHAR8 *OldName,
- IN UINT64 NewParentNodeId,
- IN CHAR8 *NewName
- );
- //
- // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member functions for the Virtio Filesystem
- // driver.
- //
- EFI_STATUS
- EFIAPI
- VirtioFsOpenVolume (
- IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **Root
- );
- //
- // EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.
- //
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileClose (
- IN EFI_FILE_PROTOCOL *This
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileDelete (
- IN EFI_FILE_PROTOCOL *This
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileFlush (
- IN EFI_FILE_PROTOCOL *This
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileGetInfo (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileGetPosition (
- IN EFI_FILE_PROTOCOL *This,
- OUT UINT64 *Position
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileOpen (
- IN EFI_FILE_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileRead (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileSetInfo (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN UINTN BufferSize,
- IN VOID *Buffer
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileSetPosition (
- IN EFI_FILE_PROTOCOL *This,
- IN UINT64 Position
- );
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileWrite (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- );
- #endif // VIRTIO_FS_DXE_H_
|