mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-01 12:53:27 +01:00
455 lines
12 KiB
C
455 lines
12 KiB
C
|
/** @file
|
||
|
Type and macro definitions specific to the Virtio Filesystem device.
|
||
|
|
||
|
At the time of this writing, the latest released Virtio specification (v1.1)
|
||
|
does not include the virtio-fs device. The development version of the
|
||
|
specification defines it however; see the latest version at
|
||
|
<https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>.
|
||
|
|
||
|
This header file is minimal, and only defines the types and macros that are
|
||
|
necessary for the OvmfPkg implementation.
|
||
|
|
||
|
Copyright (C) 2020, Red Hat, Inc.
|
||
|
|
||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||
|
**/
|
||
|
|
||
|
#ifndef VIRTIO_FS_H_
|
||
|
#define VIRTIO_FS_H_
|
||
|
|
||
|
#include <IndustryStandard/Virtio.h>
|
||
|
|
||
|
//
|
||
|
// Lowest numbered queue for sending normal priority requests.
|
||
|
//
|
||
|
#define VIRTIO_FS_REQUEST_QUEUE 1
|
||
|
|
||
|
//
|
||
|
// Number of bytes in the "VIRTIO_FS_CONFIG.Tag" field.
|
||
|
//
|
||
|
#define VIRTIO_FS_TAG_BYTES 36
|
||
|
|
||
|
//
|
||
|
// Device configuration layout.
|
||
|
//
|
||
|
#pragma pack (1)
|
||
|
typedef struct {
|
||
|
//
|
||
|
// The Tag field can be considered the filesystem label, or a mount point
|
||
|
// hint. It is UTF-8 encoded, and padded to full size with NUL bytes. If the
|
||
|
// encoded bytes take up the entire Tag field, then there is no NUL
|
||
|
// terminator.
|
||
|
//
|
||
|
UINT8 Tag[VIRTIO_FS_TAG_BYTES];
|
||
|
//
|
||
|
// The total number of request virtqueues exposed by the device (i.e.,
|
||
|
// excluding the "hiprio" queue).
|
||
|
//
|
||
|
UINT32 NumReqQueues;
|
||
|
} VIRTIO_FS_CONFIG;
|
||
|
#pragma pack ()
|
||
|
|
||
|
//
|
||
|
// FUSE-related definitions follow.
|
||
|
//
|
||
|
// From virtio-v1.1-cs01-87fa6b5d8155, 5.11 File System Device: "[...] The
|
||
|
// driver acts as the FUSE client mounting the file system. The virtio file
|
||
|
// system device provides the mechanism for transporting FUSE requests [...]"
|
||
|
//
|
||
|
// Unfortunately, the documentation of the FUSE wire protocol is lacking. The
|
||
|
// Virtio spec (as of this writing) simply defers to
|
||
|
// "include/uapi/linux/fuse.h" in the Linux kernel source -- see the reference
|
||
|
// in virtio spec file "introduction.tex", at commit 87fa6b5d8155.
|
||
|
//
|
||
|
// Of course, "include/uapi/linux/fuse.h" is a moving target (the virtio spec
|
||
|
// does not specify a particular FUSE interface version). The OvmfPkg code
|
||
|
// targets version 7.31, because that's the lowest version that the QEMU
|
||
|
// virtio-fs daemon supports at this time -- see QEMU commit 72c42e2d6551
|
||
|
// ("virtiofsd: Trim out compatibility code", 2020-01-23).
|
||
|
//
|
||
|
// Correspondingly, Linux's "include/uapi/linux/fuse.h" is consulted as checked
|
||
|
// out at commit (c6ff213fe5b8^) = d78092e4937d ("fuse: fix page dereference
|
||
|
// after free", 2020-09-18); that is, right before commit c6ff213fe5b8 ("fuse:
|
||
|
// add submount support to <uapi/linux/fuse.h>", 2020-09-18) introduces FUSE
|
||
|
// interface version 7.32.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_MAJOR 7
|
||
|
#define VIRTIO_FS_FUSE_MINOR 31
|
||
|
|
||
|
//
|
||
|
// The inode number of the root directory.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID 1
|
||
|
|
||
|
//
|
||
|
// Distinguished errno values.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_ERRNO_ENOENT (-2)
|
||
|
|
||
|
//
|
||
|
// File mode bitmasks.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_MODE_TYPE_MASK 0170000u
|
||
|
#define VIRTIO_FS_FUSE_MODE_TYPE_REG 0100000u
|
||
|
#define VIRTIO_FS_FUSE_MODE_TYPE_DIR 0040000u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_RWXU 0000700u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_RUSR 0000400u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_WUSR 0000200u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_XUSR 0000100u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_RWXG 0000070u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_RGRP 0000040u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_WGRP 0000020u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_XGRP 0000010u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_RWXO 0000007u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_ROTH 0000004u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_WOTH 0000002u
|
||
|
#define VIRTIO_FS_FUSE_MODE_PERM_XOTH 0000001u
|
||
|
|
||
|
//
|
||
|
// Flags for VirtioFsFuseOpSetAttr, in the VIRTIO_FS_FUSE_SETATTR_REQUEST.Valid
|
||
|
// field.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_SETATTR_REQ_F_MODE BIT0
|
||
|
#define VIRTIO_FS_FUSE_SETATTR_REQ_F_SIZE BIT3
|
||
|
#define VIRTIO_FS_FUSE_SETATTR_REQ_F_ATIME BIT4
|
||
|
#define VIRTIO_FS_FUSE_SETATTR_REQ_F_MTIME BIT5
|
||
|
|
||
|
//
|
||
|
// Flags for VirtioFsFuseOpOpen.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_OPEN_REQ_F_RDONLY 0
|
||
|
#define VIRTIO_FS_FUSE_OPEN_REQ_F_RDWR 2
|
||
|
|
||
|
//
|
||
|
// Flags for VirtioFsFuseOpInit.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS BIT13
|
||
|
|
||
|
/**
|
||
|
Macro for calculating the size of a directory stream entry.
|
||
|
|
||
|
The macro may evaluate Namelen multiple times.
|
||
|
|
||
|
The macro evaluates to a UINTN value that is safe to cast to UINT32.
|
||
|
|
||
|
@param[in] Namelen The size of the filename byte array that follows
|
||
|
VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE in the directory
|
||
|
stream, as reported by
|
||
|
VIRTIO_FS_FUSE_STATFS_RESPONSE.Namelen or
|
||
|
VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE.Namelen. The filename
|
||
|
byte array is not NUL-terminated.
|
||
|
|
||
|
@retval 0 Namelen was zero or greater than SIZE_4KB.
|
||
|
|
||
|
@return The number of bytes in the directory entry, including the
|
||
|
VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE header.
|
||
|
**/
|
||
|
#define VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE(Namelen) \
|
||
|
((Namelen) == 0 || (Namelen) > SIZE_4KB ? \
|
||
|
(UINTN)0 : \
|
||
|
ALIGN_VALUE ( \
|
||
|
sizeof (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE) + (UINTN)(Namelen), \
|
||
|
sizeof (UINT64) \
|
||
|
) \
|
||
|
)
|
||
|
|
||
|
//
|
||
|
// Flags for VirtioFsFuseOpRename2.
|
||
|
//
|
||
|
#define VIRTIO_FS_FUSE_RENAME2_REQ_F_NOREPLACE BIT0
|
||
|
|
||
|
//
|
||
|
// FUSE operation codes.
|
||
|
//
|
||
|
typedef enum {
|
||
|
VirtioFsFuseOpLookup = 1,
|
||
|
VirtioFsFuseOpForget = 2,
|
||
|
VirtioFsFuseOpGetAttr = 3,
|
||
|
VirtioFsFuseOpSetAttr = 4,
|
||
|
VirtioFsFuseOpMkDir = 9,
|
||
|
VirtioFsFuseOpUnlink = 10,
|
||
|
VirtioFsFuseOpRmDir = 11,
|
||
|
VirtioFsFuseOpOpen = 14,
|
||
|
VirtioFsFuseOpRead = 15,
|
||
|
VirtioFsFuseOpWrite = 16,
|
||
|
VirtioFsFuseOpStatFs = 17,
|
||
|
VirtioFsFuseOpRelease = 18,
|
||
|
VirtioFsFuseOpFsync = 20,
|
||
|
VirtioFsFuseOpFlush = 25,
|
||
|
VirtioFsFuseOpInit = 26,
|
||
|
VirtioFsFuseOpOpenDir = 27,
|
||
|
VirtioFsFuseOpReleaseDir = 29,
|
||
|
VirtioFsFuseOpFsyncDir = 30,
|
||
|
VirtioFsFuseOpCreate = 35,
|
||
|
VirtioFsFuseOpReadDirPlus = 44,
|
||
|
VirtioFsFuseOpRename2 = 45,
|
||
|
} VIRTIO_FS_FUSE_OPCODE;
|
||
|
|
||
|
#pragma pack (1)
|
||
|
//
|
||
|
// Request-response headers common to all request types.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 Len;
|
||
|
UINT32 Opcode;
|
||
|
UINT64 Unique;
|
||
|
UINT64 NodeId;
|
||
|
UINT32 Uid;
|
||
|
UINT32 Gid;
|
||
|
UINT32 Pid;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_REQUEST;
|
||
|
|
||
|
typedef struct {
|
||
|
UINT32 Len;
|
||
|
INT32 Error;
|
||
|
UINT64 Unique;
|
||
|
} VIRTIO_FS_FUSE_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Structure with which the Virtio Filesystem device reports a NodeId to the
|
||
|
// FUSE client (i.e., to the Virtio Filesystem driver). This structure is a
|
||
|
// part of the response headers for operations that inform the FUSE client of
|
||
|
// an inode.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 NodeId;
|
||
|
UINT64 Generation;
|
||
|
UINT64 EntryValid;
|
||
|
UINT64 AttrValid;
|
||
|
UINT32 EntryValidNsec;
|
||
|
UINT32 AttrValidNsec;
|
||
|
} VIRTIO_FS_FUSE_NODE_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Structure describing the host-side attributes of an inode. This structure is
|
||
|
// a part of the response headers for operations that inform the FUSE client of
|
||
|
// an inode.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 Ino;
|
||
|
UINT64 Size;
|
||
|
UINT64 Blocks;
|
||
|
UINT64 Atime;
|
||
|
UINT64 Mtime;
|
||
|
UINT64 Ctime;
|
||
|
UINT32 AtimeNsec;
|
||
|
UINT32 MtimeNsec;
|
||
|
UINT32 CtimeNsec;
|
||
|
UINT32 Mode;
|
||
|
UINT32 Nlink;
|
||
|
UINT32 Uid;
|
||
|
UINT32 Gid;
|
||
|
UINT32 Rdev;
|
||
|
UINT32 Blksize;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpForget.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 NumberOfLookups;
|
||
|
} VIRTIO_FS_FUSE_FORGET_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Headers for VirtioFsFuseOpGetAttr (VIRTIO_FS_FUSE_GETATTR_RESPONSE is also
|
||
|
// for VirtioFsFuseOpSetAttr).
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 GetAttrFlags;
|
||
|
UINT32 Dummy;
|
||
|
UINT64 FileHandle;
|
||
|
} VIRTIO_FS_FUSE_GETATTR_REQUEST;
|
||
|
|
||
|
typedef struct {
|
||
|
UINT64 AttrValid;
|
||
|
UINT32 AttrValidNsec;
|
||
|
UINT32 Dummy;
|
||
|
} VIRTIO_FS_FUSE_GETATTR_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpSetAttr.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 Valid;
|
||
|
UINT32 Padding;
|
||
|
UINT64 FileHandle;
|
||
|
UINT64 Size;
|
||
|
UINT64 LockOwner;
|
||
|
UINT64 Atime;
|
||
|
UINT64 Mtime;
|
||
|
UINT64 Ctime;
|
||
|
UINT32 AtimeNsec;
|
||
|
UINT32 MtimeNsec;
|
||
|
UINT32 CtimeNsec;
|
||
|
UINT32 Mode;
|
||
|
UINT32 Unused4;
|
||
|
UINT32 Uid;
|
||
|
UINT32 Gid;
|
||
|
UINT32 Unused5;
|
||
|
} VIRTIO_FS_FUSE_SETATTR_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpMkDir.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 Mode;
|
||
|
UINT32 Umask;
|
||
|
} VIRTIO_FS_FUSE_MKDIR_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Headers for VirtioFsFuseOpOpen and VirtioFsFuseOpOpenDir.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 Flags;
|
||
|
UINT32 Unused;
|
||
|
} VIRTIO_FS_FUSE_OPEN_REQUEST;
|
||
|
|
||
|
typedef struct {
|
||
|
UINT64 FileHandle;
|
||
|
UINT32 OpenFlags;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_OPEN_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpRead and VirtioFsFuseOpReadDirPlus.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 FileHandle;
|
||
|
UINT64 Offset;
|
||
|
UINT32 Size;
|
||
|
UINT32 ReadFlags;
|
||
|
UINT64 LockOwner;
|
||
|
UINT32 Flags;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_READ_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Headers for VirtioFsFuseOpWrite.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 FileHandle;
|
||
|
UINT64 Offset;
|
||
|
UINT32 Size;
|
||
|
UINT32 WriteFlags;
|
||
|
UINT64 LockOwner;
|
||
|
UINT32 Flags;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_WRITE_REQUEST;
|
||
|
|
||
|
typedef struct {
|
||
|
UINT32 Size;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_WRITE_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpStatFs.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 Blocks;
|
||
|
UINT64 Bfree;
|
||
|
UINT64 Bavail;
|
||
|
UINT64 Files;
|
||
|
UINT64 Ffree;
|
||
|
UINT32 Bsize;
|
||
|
UINT32 Namelen;
|
||
|
UINT32 Frsize;
|
||
|
UINT32 Padding;
|
||
|
UINT32 Spare[6];
|
||
|
} VIRTIO_FS_FUSE_STATFS_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpRelease and VirtioFsFuseOpReleaseDir.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 FileHandle;
|
||
|
UINT32 Flags;
|
||
|
UINT32 ReleaseFlags;
|
||
|
UINT64 LockOwner;
|
||
|
} VIRTIO_FS_FUSE_RELEASE_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpFsync and VirtioFsFuseOpFsyncDir.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 FileHandle;
|
||
|
UINT32 FsyncFlags;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_FSYNC_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpFlush.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 FileHandle;
|
||
|
UINT32 Unused;
|
||
|
UINT32 Padding;
|
||
|
UINT64 LockOwner;
|
||
|
} VIRTIO_FS_FUSE_FLUSH_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Headers for VirtioFsFuseOpInit.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 Major;
|
||
|
UINT32 Minor;
|
||
|
UINT32 MaxReadahead;
|
||
|
UINT32 Flags;
|
||
|
} VIRTIO_FS_FUSE_INIT_REQUEST;
|
||
|
|
||
|
typedef struct {
|
||
|
UINT32 Major;
|
||
|
UINT32 Minor;
|
||
|
UINT32 MaxReadahead;
|
||
|
UINT32 Flags;
|
||
|
UINT16 MaxBackground;
|
||
|
UINT16 CongestionThreshold;
|
||
|
UINT32 MaxWrite;
|
||
|
UINT32 TimeGran;
|
||
|
UINT16 MaxPages;
|
||
|
UINT16 MapAlignment;
|
||
|
UINT32 Unused[8];
|
||
|
} VIRTIO_FS_FUSE_INIT_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpCreate.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT32 Flags;
|
||
|
UINT32 Mode;
|
||
|
UINT32 Umask;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_CREATE_REQUEST;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpReadDirPlus.
|
||
|
//
|
||
|
// Diverging from the rest of the headers, this structure embeds other
|
||
|
// structures. The reason is that a scatter list cannot be used to receive
|
||
|
// NodeResp and AttrResp separately; the record below is followed by a variable
|
||
|
// size filename byte array, and then such pairs are repeated a number of
|
||
|
// times. Thus, later header start offsets depend on earlier filename array
|
||
|
// sizes.
|
||
|
//
|
||
|
typedef struct {
|
||
|
VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp;
|
||
|
VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp;
|
||
|
UINT64 NodeId;
|
||
|
UINT64 CookieForNextEntry;
|
||
|
UINT32 Namelen;
|
||
|
UINT32 Type;
|
||
|
} VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE;
|
||
|
|
||
|
//
|
||
|
// Header for VirtioFsFuseOpRename2.
|
||
|
//
|
||
|
typedef struct {
|
||
|
UINT64 NewDir;
|
||
|
UINT32 Flags;
|
||
|
UINT32 Padding;
|
||
|
} VIRTIO_FS_FUSE_RENAME2_REQUEST;
|
||
|
#pragma pack ()
|
||
|
|
||
|
#endif // VIRTIO_FS_H_
|