]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Include/IndustryStandard/VirtioFs.h
fa8c40019f4e2d5bc027d6f56489bce6512cfa6f
[mirror_edk2.git] / OvmfPkg / Include / IndustryStandard / VirtioFs.h
1 /** @file
2 Type and macro definitions specific to the Virtio Filesystem device.
3
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>.
8
9 This header file is minimal, and only defines the types and macros that are
10 necessary for the OvmfPkg implementation.
11
12 Copyright (C) 2020, Red Hat, Inc.
13
14 SPDX-License-Identifier: BSD-2-Clause-Patent
15 **/
16
17 #ifndef VIRTIO_FS_H_
18 #define VIRTIO_FS_H_
19
20 #include <IndustryStandard/Virtio.h>
21
22 //
23 // Lowest numbered queue for sending normal priority requests.
24 //
25 #define VIRTIO_FS_REQUEST_QUEUE 1
26
27 //
28 // Number of bytes in the "VIRTIO_FS_CONFIG.Tag" field.
29 //
30 #define VIRTIO_FS_TAG_BYTES 36
31
32 //
33 // Device configuration layout.
34 //
35 #pragma pack (1)
36 typedef struct {
37 //
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
41 // terminator.
42 //
43 UINT8 Tag[VIRTIO_FS_TAG_BYTES];
44 //
45 // The total number of request virtqueues exposed by the device (i.e.,
46 // excluding the "hiprio" queue).
47 //
48 UINT32 NumReqQueues;
49 } VIRTIO_FS_CONFIG;
50 #pragma pack ()
51
52 //
53 // FUSE-related definitions follow.
54 //
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 [...]"
58 //
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.
63 //
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).
69 //
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.
75 //
76 #define VIRTIO_FS_FUSE_MAJOR 7
77 #define VIRTIO_FS_FUSE_MINOR 31
78
79 //
80 // The inode number of the root directory.
81 //
82 #define VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID 1
83
84 //
85 // Distinguished errno values.
86 //
87 #define VIRTIO_FS_FUSE_ERRNO_ENOENT (-2)
88
89 //
90 // File mode bitmasks.
91 //
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_RWXG 0000070u
99 #define VIRTIO_FS_FUSE_MODE_PERM_RGRP 0000040u
100 #define VIRTIO_FS_FUSE_MODE_PERM_WGRP 0000020u
101 #define VIRTIO_FS_FUSE_MODE_PERM_RWXO 0000007u
102 #define VIRTIO_FS_FUSE_MODE_PERM_ROTH 0000004u
103 #define VIRTIO_FS_FUSE_MODE_PERM_WOTH 0000002u
104
105 //
106 // Flags for VirtioFsFuseOpOpen.
107 //
108 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDONLY 0
109 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDWR 2
110
111 //
112 // Flags for VirtioFsFuseOpInit.
113 //
114 #define VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS BIT13
115
116 /**
117 Macro for calculating the size of a directory stream entry.
118
119 The macro may evaluate Namelen multiple times.
120
121 The macro evaluates to a UINTN value that is safe to cast to UINT32.
122
123 @param[in] Namelen The size of the filename byte array that follows
124 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE in the directory
125 stream, as reported by
126 VIRTIO_FS_FUSE_STATFS_RESPONSE.Namelen or
127 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE.Namelen. The filename
128 byte array is not NUL-terminated.
129
130 @retval 0 Namelen was zero or greater than SIZE_4KB.
131
132 @return The number of bytes in the directory entry, including the
133 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE header.
134 **/
135 #define VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE(Namelen) \
136 ((Namelen) == 0 || (Namelen) > SIZE_4KB ? \
137 (UINTN)0 : \
138 ALIGN_VALUE ( \
139 sizeof (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE) + (UINTN)(Namelen), \
140 sizeof (UINT64) \
141 ) \
142 )
143
144 //
145 // FUSE operation codes.
146 //
147 typedef enum {
148 VirtioFsFuseOpLookup = 1,
149 VirtioFsFuseOpForget = 2,
150 VirtioFsFuseOpGetAttr = 3,
151 VirtioFsFuseOpMkDir = 9,
152 VirtioFsFuseOpUnlink = 10,
153 VirtioFsFuseOpRmDir = 11,
154 VirtioFsFuseOpOpen = 14,
155 VirtioFsFuseOpRead = 15,
156 VirtioFsFuseOpStatFs = 17,
157 VirtioFsFuseOpRelease = 18,
158 VirtioFsFuseOpFsync = 20,
159 VirtioFsFuseOpFlush = 25,
160 VirtioFsFuseOpInit = 26,
161 VirtioFsFuseOpOpenDir = 27,
162 VirtioFsFuseOpReleaseDir = 29,
163 VirtioFsFuseOpFsyncDir = 30,
164 VirtioFsFuseOpCreate = 35,
165 VirtioFsFuseOpReadDirPlus = 44,
166 } VIRTIO_FS_FUSE_OPCODE;
167
168 #pragma pack (1)
169 //
170 // Request-response headers common to all request types.
171 //
172 typedef struct {
173 UINT32 Len;
174 UINT32 Opcode;
175 UINT64 Unique;
176 UINT64 NodeId;
177 UINT32 Uid;
178 UINT32 Gid;
179 UINT32 Pid;
180 UINT32 Padding;
181 } VIRTIO_FS_FUSE_REQUEST;
182
183 typedef struct {
184 UINT32 Len;
185 INT32 Error;
186 UINT64 Unique;
187 } VIRTIO_FS_FUSE_RESPONSE;
188
189 //
190 // Structure with which the Virtio Filesystem device reports a NodeId to the
191 // FUSE client (i.e., to the Virtio Filesystem driver). This structure is a
192 // part of the response headers for operations that inform the FUSE client of
193 // an inode.
194 //
195 typedef struct {
196 UINT64 NodeId;
197 UINT64 Generation;
198 UINT64 EntryValid;
199 UINT64 AttrValid;
200 UINT32 EntryValidNsec;
201 UINT32 AttrValidNsec;
202 } VIRTIO_FS_FUSE_NODE_RESPONSE;
203
204 //
205 // Structure describing the host-side attributes of an inode. This structure is
206 // a part of the response headers for operations that inform the FUSE client of
207 // an inode.
208 //
209 typedef struct {
210 UINT64 Ino;
211 UINT64 Size;
212 UINT64 Blocks;
213 UINT64 Atime;
214 UINT64 Mtime;
215 UINT64 Ctime;
216 UINT32 AtimeNsec;
217 UINT32 MtimeNsec;
218 UINT32 CtimeNsec;
219 UINT32 Mode;
220 UINT32 Nlink;
221 UINT32 Uid;
222 UINT32 Gid;
223 UINT32 Rdev;
224 UINT32 Blksize;
225 UINT32 Padding;
226 } VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE;
227
228 //
229 // Header for VirtioFsFuseOpForget.
230 //
231 typedef struct {
232 UINT64 NumberOfLookups;
233 } VIRTIO_FS_FUSE_FORGET_REQUEST;
234
235 //
236 // Headers for VirtioFsFuseOpGetAttr.
237 //
238 typedef struct {
239 UINT32 GetAttrFlags;
240 UINT32 Dummy;
241 UINT64 FileHandle;
242 } VIRTIO_FS_FUSE_GETATTR_REQUEST;
243
244 typedef struct {
245 UINT64 AttrValid;
246 UINT32 AttrValidNsec;
247 UINT32 Dummy;
248 } VIRTIO_FS_FUSE_GETATTR_RESPONSE;
249
250 //
251 // Header for VirtioFsFuseOpMkDir.
252 //
253 typedef struct {
254 UINT32 Mode;
255 UINT32 Umask;
256 } VIRTIO_FS_FUSE_MKDIR_REQUEST;
257
258 //
259 // Headers for VirtioFsFuseOpOpen and VirtioFsFuseOpOpenDir.
260 //
261 typedef struct {
262 UINT32 Flags;
263 UINT32 Unused;
264 } VIRTIO_FS_FUSE_OPEN_REQUEST;
265
266 typedef struct {
267 UINT64 FileHandle;
268 UINT32 OpenFlags;
269 UINT32 Padding;
270 } VIRTIO_FS_FUSE_OPEN_RESPONSE;
271
272 //
273 // Header for VirtioFsFuseOpRead and VirtioFsFuseOpReadDirPlus.
274 //
275 typedef struct {
276 UINT64 FileHandle;
277 UINT64 Offset;
278 UINT32 Size;
279 UINT32 ReadFlags;
280 UINT64 LockOwner;
281 UINT32 Flags;
282 UINT32 Padding;
283 } VIRTIO_FS_FUSE_READ_REQUEST;
284
285 //
286 // Header for VirtioFsFuseOpStatFs.
287 //
288 typedef struct {
289 UINT64 Blocks;
290 UINT64 Bfree;
291 UINT64 Bavail;
292 UINT64 Files;
293 UINT64 Ffree;
294 UINT32 Bsize;
295 UINT32 Namelen;
296 UINT32 Frsize;
297 UINT32 Padding;
298 UINT32 Spare[6];
299 } VIRTIO_FS_FUSE_STATFS_RESPONSE;
300
301 //
302 // Header for VirtioFsFuseOpRelease and VirtioFsFuseOpReleaseDir.
303 //
304 typedef struct {
305 UINT64 FileHandle;
306 UINT32 Flags;
307 UINT32 ReleaseFlags;
308 UINT64 LockOwner;
309 } VIRTIO_FS_FUSE_RELEASE_REQUEST;
310
311 //
312 // Header for VirtioFsFuseOpFsync and VirtioFsFuseOpFsyncDir.
313 //
314 typedef struct {
315 UINT64 FileHandle;
316 UINT32 FsyncFlags;
317 UINT32 Padding;
318 } VIRTIO_FS_FUSE_FSYNC_REQUEST;
319
320 //
321 // Header for VirtioFsFuseOpFlush.
322 //
323 typedef struct {
324 UINT64 FileHandle;
325 UINT32 Unused;
326 UINT32 Padding;
327 UINT64 LockOwner;
328 } VIRTIO_FS_FUSE_FLUSH_REQUEST;
329
330 //
331 // Headers for VirtioFsFuseOpInit.
332 //
333 typedef struct {
334 UINT32 Major;
335 UINT32 Minor;
336 UINT32 MaxReadahead;
337 UINT32 Flags;
338 } VIRTIO_FS_FUSE_INIT_REQUEST;
339
340 typedef struct {
341 UINT32 Major;
342 UINT32 Minor;
343 UINT32 MaxReadahead;
344 UINT32 Flags;
345 UINT16 MaxBackground;
346 UINT16 CongestionThreshold;
347 UINT32 MaxWrite;
348 UINT32 TimeGran;
349 UINT16 MaxPages;
350 UINT16 MapAlignment;
351 UINT32 Unused[8];
352 } VIRTIO_FS_FUSE_INIT_RESPONSE;
353
354 //
355 // Header for VirtioFsFuseOpCreate.
356 //
357 typedef struct {
358 UINT32 Flags;
359 UINT32 Mode;
360 UINT32 Umask;
361 UINT32 Padding;
362 } VIRTIO_FS_FUSE_CREATE_REQUEST;
363
364 //
365 // Header for VirtioFsFuseOpReadDirPlus.
366 //
367 // Diverging from the rest of the headers, this structure embeds other
368 // structures. The reason is that a scatter list cannot be used to receive
369 // NodeResp and AttrResp separately; the record below is followed by a variable
370 // size filename byte array, and then such pairs are repeated a number of
371 // times. Thus, later header start offsets depend on earlier filename array
372 // sizes.
373 //
374 typedef struct {
375 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp;
376 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp;
377 UINT64 NodeId;
378 UINT64 CookieForNextEntry;
379 UINT32 Namelen;
380 UINT32 Type;
381 } VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE;
382 #pragma pack ()
383
384 #endif // VIRTIO_FS_H_