2 Type and macro definitions specific to the Virtio Filesystem device.
4 At the time of this writing, the latest released Virtio specification (v1.1)
5 does not include the virtio-fs device. The development version of the
6 specification defines it however; see the latest version at
7 <https://github.com/oasis-tcs/virtio-spec/blob/87fa6b5d8155/virtio-fs.tex>.
9 This header file is minimal, and only defines the types and macros that are
10 necessary for the OvmfPkg implementation.
12 Copyright (C) 2020, Red Hat, Inc.
14 SPDX-License-Identifier: BSD-2-Clause-Patent
20 #include <IndustryStandard/Virtio.h>
23 // Lowest numbered queue for sending normal priority requests.
25 #define VIRTIO_FS_REQUEST_QUEUE 1
28 // Number of bytes in the "VIRTIO_FS_CONFIG.Tag" field.
30 #define VIRTIO_FS_TAG_BYTES 36
33 // Device configuration layout.
38 // The Tag field can be considered the filesystem label, or a mount point
39 // hint. It is UTF-8 encoded, and padded to full size with NUL bytes. If the
40 // encoded bytes take up the entire Tag field, then there is no NUL
43 UINT8 Tag
[VIRTIO_FS_TAG_BYTES
];
45 // The total number of request virtqueues exposed by the device (i.e.,
46 // excluding the "hiprio" queue).
53 // FUSE-related definitions follow.
55 // From virtio-v1.1-cs01-87fa6b5d8155, 5.11 File System Device: "[...] The
56 // driver acts as the FUSE client mounting the file system. The virtio file
57 // system device provides the mechanism for transporting FUSE requests [...]"
59 // Unfortunately, the documentation of the FUSE wire protocol is lacking. The
60 // Virtio spec (as of this writing) simply defers to
61 // "include/uapi/linux/fuse.h" in the Linux kernel source -- see the reference
62 // in virtio spec file "introduction.tex", at commit 87fa6b5d8155.
64 // Of course, "include/uapi/linux/fuse.h" is a moving target (the virtio spec
65 // does not specify a particular FUSE interface version). The OvmfPkg code
66 // targets version 7.31, because that's the lowest version that the QEMU
67 // virtio-fs daemon supports at this time -- see QEMU commit 72c42e2d6551
68 // ("virtiofsd: Trim out compatibility code", 2020-01-23).
70 // Correspondingly, Linux's "include/uapi/linux/fuse.h" is consulted as checked
71 // out at commit (c6ff213fe5b8^) = d78092e4937d ("fuse: fix page dereference
72 // after free", 2020-09-18); that is, right before commit c6ff213fe5b8 ("fuse:
73 // add submount support to <uapi/linux/fuse.h>", 2020-09-18) introduces FUSE
74 // interface version 7.32.
76 #define VIRTIO_FS_FUSE_MAJOR 7
77 #define VIRTIO_FS_FUSE_MINOR 31
80 // The inode number of the root directory.
82 #define VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID 1
85 // Distinguished errno values.
87 #define VIRTIO_FS_FUSE_ERRNO_ENOENT (-2)
90 // File mode bitmasks.
92 #define VIRTIO_FS_FUSE_MODE_TYPE_MASK 0170000u
93 #define VIRTIO_FS_FUSE_MODE_TYPE_REG 0100000u
94 #define VIRTIO_FS_FUSE_MODE_TYPE_DIR 0040000u
95 #define VIRTIO_FS_FUSE_MODE_PERM_RWXU 0000700u
96 #define VIRTIO_FS_FUSE_MODE_PERM_RUSR 0000400u
97 #define VIRTIO_FS_FUSE_MODE_PERM_WUSR 0000200u
98 #define VIRTIO_FS_FUSE_MODE_PERM_XUSR 0000100u
99 #define VIRTIO_FS_FUSE_MODE_PERM_RWXG 0000070u
100 #define VIRTIO_FS_FUSE_MODE_PERM_RGRP 0000040u
101 #define VIRTIO_FS_FUSE_MODE_PERM_WGRP 0000020u
102 #define VIRTIO_FS_FUSE_MODE_PERM_XGRP 0000010u
103 #define VIRTIO_FS_FUSE_MODE_PERM_RWXO 0000007u
104 #define VIRTIO_FS_FUSE_MODE_PERM_ROTH 0000004u
105 #define VIRTIO_FS_FUSE_MODE_PERM_WOTH 0000002u
106 #define VIRTIO_FS_FUSE_MODE_PERM_XOTH 0000001u
109 // Flags for VirtioFsFuseOpSetAttr, in the VIRTIO_FS_FUSE_SETATTR_REQUEST.Valid
112 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MODE BIT0
113 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_SIZE BIT3
114 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_ATIME BIT4
115 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MTIME BIT5
118 // Flags for VirtioFsFuseOpOpen.
120 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDONLY 0
121 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDWR 2
124 // Flags for VirtioFsFuseOpInit.
126 #define VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS BIT13
129 Macro for calculating the size of a directory stream entry.
131 The macro may evaluate Namelen multiple times.
133 The macro evaluates to a UINTN value that is safe to cast to UINT32.
135 @param[in] Namelen The size of the filename byte array that follows
136 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE in the directory
137 stream, as reported by
138 VIRTIO_FS_FUSE_STATFS_RESPONSE.Namelen or
139 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE.Namelen. The filename
140 byte array is not NUL-terminated.
142 @retval 0 Namelen was zero or greater than SIZE_4KB.
144 @return The number of bytes in the directory entry, including the
145 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE header.
147 #define VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE(Namelen) \
148 ((Namelen) == 0 || (Namelen) > SIZE_4KB ? \
151 sizeof (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE) + (UINTN)(Namelen), \
157 // Flags for VirtioFsFuseOpRename2.
159 #define VIRTIO_FS_FUSE_RENAME2_REQ_F_NOREPLACE BIT0
162 // FUSE operation codes.
165 VirtioFsFuseOpLookup
= 1,
166 VirtioFsFuseOpForget
= 2,
167 VirtioFsFuseOpGetAttr
= 3,
168 VirtioFsFuseOpSetAttr
= 4,
169 VirtioFsFuseOpMkDir
= 9,
170 VirtioFsFuseOpUnlink
= 10,
171 VirtioFsFuseOpRmDir
= 11,
172 VirtioFsFuseOpOpen
= 14,
173 VirtioFsFuseOpRead
= 15,
174 VirtioFsFuseOpWrite
= 16,
175 VirtioFsFuseOpStatFs
= 17,
176 VirtioFsFuseOpRelease
= 18,
177 VirtioFsFuseOpFsync
= 20,
178 VirtioFsFuseOpFlush
= 25,
179 VirtioFsFuseOpInit
= 26,
180 VirtioFsFuseOpOpenDir
= 27,
181 VirtioFsFuseOpReleaseDir
= 29,
182 VirtioFsFuseOpFsyncDir
= 30,
183 VirtioFsFuseOpCreate
= 35,
184 VirtioFsFuseOpReadDirPlus
= 44,
185 VirtioFsFuseOpRename2
= 45,
186 } VIRTIO_FS_FUSE_OPCODE
;
190 // Request-response headers common to all request types.
201 } VIRTIO_FS_FUSE_REQUEST
;
207 } VIRTIO_FS_FUSE_RESPONSE
;
210 // Structure with which the Virtio Filesystem device reports a NodeId to the
211 // FUSE client (i.e., to the Virtio Filesystem driver). This structure is a
212 // part of the response headers for operations that inform the FUSE client of
220 UINT32 EntryValidNsec
;
221 UINT32 AttrValidNsec
;
222 } VIRTIO_FS_FUSE_NODE_RESPONSE
;
225 // Structure describing the host-side attributes of an inode. This structure is
226 // a part of the response headers for operations that inform the FUSE client of
246 } VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE
;
249 // Header for VirtioFsFuseOpForget.
252 UINT64 NumberOfLookups
;
253 } VIRTIO_FS_FUSE_FORGET_REQUEST
;
256 // Headers for VirtioFsFuseOpGetAttr (VIRTIO_FS_FUSE_GETATTR_RESPONSE is also
257 // for VirtioFsFuseOpSetAttr).
263 } VIRTIO_FS_FUSE_GETATTR_REQUEST
;
267 UINT32 AttrValidNsec
;
269 } VIRTIO_FS_FUSE_GETATTR_RESPONSE
;
272 // Header for VirtioFsFuseOpSetAttr.
291 } VIRTIO_FS_FUSE_SETATTR_REQUEST
;
294 // Header for VirtioFsFuseOpMkDir.
299 } VIRTIO_FS_FUSE_MKDIR_REQUEST
;
302 // Headers for VirtioFsFuseOpOpen and VirtioFsFuseOpOpenDir.
307 } VIRTIO_FS_FUSE_OPEN_REQUEST
;
313 } VIRTIO_FS_FUSE_OPEN_RESPONSE
;
316 // Header for VirtioFsFuseOpRead and VirtioFsFuseOpReadDirPlus.
326 } VIRTIO_FS_FUSE_READ_REQUEST
;
329 // Headers for VirtioFsFuseOpWrite.
339 } VIRTIO_FS_FUSE_WRITE_REQUEST
;
344 } VIRTIO_FS_FUSE_WRITE_RESPONSE
;
347 // Header for VirtioFsFuseOpStatFs.
360 } VIRTIO_FS_FUSE_STATFS_RESPONSE
;
363 // Header for VirtioFsFuseOpRelease and VirtioFsFuseOpReleaseDir.
370 } VIRTIO_FS_FUSE_RELEASE_REQUEST
;
373 // Header for VirtioFsFuseOpFsync and VirtioFsFuseOpFsyncDir.
379 } VIRTIO_FS_FUSE_FSYNC_REQUEST
;
382 // Header for VirtioFsFuseOpFlush.
389 } VIRTIO_FS_FUSE_FLUSH_REQUEST
;
392 // Headers for VirtioFsFuseOpInit.
399 } VIRTIO_FS_FUSE_INIT_REQUEST
;
406 UINT16 MaxBackground
;
407 UINT16 CongestionThreshold
;
413 } VIRTIO_FS_FUSE_INIT_RESPONSE
;
416 // Header for VirtioFsFuseOpCreate.
423 } VIRTIO_FS_FUSE_CREATE_REQUEST
;
426 // Header for VirtioFsFuseOpReadDirPlus.
428 // Diverging from the rest of the headers, this structure embeds other
429 // structures. The reason is that a scatter list cannot be used to receive
430 // NodeResp and AttrResp separately; the record below is followed by a variable
431 // size filename byte array, and then such pairs are repeated a number of
432 // times. Thus, later header start offsets depend on earlier filename array
436 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp
;
437 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp
;
439 UINT64 CookieForNextEntry
;
442 } VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE
;
445 // Header for VirtioFsFuseOpRename2.
451 } VIRTIO_FS_FUSE_RENAME2_REQUEST
;
454 #endif // VIRTIO_FS_H_