]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Include/IndustryStandard/VirtioFs.h
15fb28f95a28f0c5ce917205b708b7e9f66c97d8
[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 VirtioFsFuseOpSetAttr, in the VIRTIO_FS_FUSE_SETATTR_REQUEST.Valid
107 // field.
108 //
109 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MODE BIT0
110 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_SIZE BIT3
111 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_ATIME BIT4
112 #define VIRTIO_FS_FUSE_SETATTR_REQ_F_MTIME BIT5
113
114 //
115 // Flags for VirtioFsFuseOpOpen.
116 //
117 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDONLY 0
118 #define VIRTIO_FS_FUSE_OPEN_REQ_F_RDWR 2
119
120 //
121 // Flags for VirtioFsFuseOpInit.
122 //
123 #define VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS BIT13
124
125 /**
126 Macro for calculating the size of a directory stream entry.
127
128 The macro may evaluate Namelen multiple times.
129
130 The macro evaluates to a UINTN value that is safe to cast to UINT32.
131
132 @param[in] Namelen The size of the filename byte array that follows
133 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE in the directory
134 stream, as reported by
135 VIRTIO_FS_FUSE_STATFS_RESPONSE.Namelen or
136 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE.Namelen. The filename
137 byte array is not NUL-terminated.
138
139 @retval 0 Namelen was zero or greater than SIZE_4KB.
140
141 @return The number of bytes in the directory entry, including the
142 VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE header.
143 **/
144 #define VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE(Namelen) \
145 ((Namelen) == 0 || (Namelen) > SIZE_4KB ? \
146 (UINTN)0 : \
147 ALIGN_VALUE ( \
148 sizeof (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE) + (UINTN)(Namelen), \
149 sizeof (UINT64) \
150 ) \
151 )
152
153 //
154 // Flags for VirtioFsFuseOpRename2.
155 //
156 #define VIRTIO_FS_FUSE_RENAME2_REQ_F_NOREPLACE BIT0
157
158 //
159 // FUSE operation codes.
160 //
161 typedef enum {
162 VirtioFsFuseOpLookup = 1,
163 VirtioFsFuseOpForget = 2,
164 VirtioFsFuseOpGetAttr = 3,
165 VirtioFsFuseOpSetAttr = 4,
166 VirtioFsFuseOpMkDir = 9,
167 VirtioFsFuseOpUnlink = 10,
168 VirtioFsFuseOpRmDir = 11,
169 VirtioFsFuseOpOpen = 14,
170 VirtioFsFuseOpRead = 15,
171 VirtioFsFuseOpWrite = 16,
172 VirtioFsFuseOpStatFs = 17,
173 VirtioFsFuseOpRelease = 18,
174 VirtioFsFuseOpFsync = 20,
175 VirtioFsFuseOpFlush = 25,
176 VirtioFsFuseOpInit = 26,
177 VirtioFsFuseOpOpenDir = 27,
178 VirtioFsFuseOpReleaseDir = 29,
179 VirtioFsFuseOpFsyncDir = 30,
180 VirtioFsFuseOpCreate = 35,
181 VirtioFsFuseOpReadDirPlus = 44,
182 VirtioFsFuseOpRename2 = 45,
183 } VIRTIO_FS_FUSE_OPCODE;
184
185 #pragma pack (1)
186 //
187 // Request-response headers common to all request types.
188 //
189 typedef struct {
190 UINT32 Len;
191 UINT32 Opcode;
192 UINT64 Unique;
193 UINT64 NodeId;
194 UINT32 Uid;
195 UINT32 Gid;
196 UINT32 Pid;
197 UINT32 Padding;
198 } VIRTIO_FS_FUSE_REQUEST;
199
200 typedef struct {
201 UINT32 Len;
202 INT32 Error;
203 UINT64 Unique;
204 } VIRTIO_FS_FUSE_RESPONSE;
205
206 //
207 // Structure with which the Virtio Filesystem device reports a NodeId to the
208 // FUSE client (i.e., to the Virtio Filesystem driver). This structure is a
209 // part of the response headers for operations that inform the FUSE client of
210 // an inode.
211 //
212 typedef struct {
213 UINT64 NodeId;
214 UINT64 Generation;
215 UINT64 EntryValid;
216 UINT64 AttrValid;
217 UINT32 EntryValidNsec;
218 UINT32 AttrValidNsec;
219 } VIRTIO_FS_FUSE_NODE_RESPONSE;
220
221 //
222 // Structure describing the host-side attributes of an inode. This structure is
223 // a part of the response headers for operations that inform the FUSE client of
224 // an inode.
225 //
226 typedef struct {
227 UINT64 Ino;
228 UINT64 Size;
229 UINT64 Blocks;
230 UINT64 Atime;
231 UINT64 Mtime;
232 UINT64 Ctime;
233 UINT32 AtimeNsec;
234 UINT32 MtimeNsec;
235 UINT32 CtimeNsec;
236 UINT32 Mode;
237 UINT32 Nlink;
238 UINT32 Uid;
239 UINT32 Gid;
240 UINT32 Rdev;
241 UINT32 Blksize;
242 UINT32 Padding;
243 } VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE;
244
245 //
246 // Header for VirtioFsFuseOpForget.
247 //
248 typedef struct {
249 UINT64 NumberOfLookups;
250 } VIRTIO_FS_FUSE_FORGET_REQUEST;
251
252 //
253 // Headers for VirtioFsFuseOpGetAttr (VIRTIO_FS_FUSE_GETATTR_RESPONSE is also
254 // for VirtioFsFuseOpSetAttr).
255 //
256 typedef struct {
257 UINT32 GetAttrFlags;
258 UINT32 Dummy;
259 UINT64 FileHandle;
260 } VIRTIO_FS_FUSE_GETATTR_REQUEST;
261
262 typedef struct {
263 UINT64 AttrValid;
264 UINT32 AttrValidNsec;
265 UINT32 Dummy;
266 } VIRTIO_FS_FUSE_GETATTR_RESPONSE;
267
268 //
269 // Header for VirtioFsFuseOpSetAttr.
270 //
271 typedef struct {
272 UINT32 Valid;
273 UINT32 Padding;
274 UINT64 FileHandle;
275 UINT64 Size;
276 UINT64 LockOwner;
277 UINT64 Atime;
278 UINT64 Mtime;
279 UINT64 Ctime;
280 UINT32 AtimeNsec;
281 UINT32 MtimeNsec;
282 UINT32 CtimeNsec;
283 UINT32 Mode;
284 UINT32 Unused4;
285 UINT32 Uid;
286 UINT32 Gid;
287 UINT32 Unused5;
288 } VIRTIO_FS_FUSE_SETATTR_REQUEST;
289
290 //
291 // Header for VirtioFsFuseOpMkDir.
292 //
293 typedef struct {
294 UINT32 Mode;
295 UINT32 Umask;
296 } VIRTIO_FS_FUSE_MKDIR_REQUEST;
297
298 //
299 // Headers for VirtioFsFuseOpOpen and VirtioFsFuseOpOpenDir.
300 //
301 typedef struct {
302 UINT32 Flags;
303 UINT32 Unused;
304 } VIRTIO_FS_FUSE_OPEN_REQUEST;
305
306 typedef struct {
307 UINT64 FileHandle;
308 UINT32 OpenFlags;
309 UINT32 Padding;
310 } VIRTIO_FS_FUSE_OPEN_RESPONSE;
311
312 //
313 // Header for VirtioFsFuseOpRead and VirtioFsFuseOpReadDirPlus.
314 //
315 typedef struct {
316 UINT64 FileHandle;
317 UINT64 Offset;
318 UINT32 Size;
319 UINT32 ReadFlags;
320 UINT64 LockOwner;
321 UINT32 Flags;
322 UINT32 Padding;
323 } VIRTIO_FS_FUSE_READ_REQUEST;
324
325 //
326 // Headers for VirtioFsFuseOpWrite.
327 //
328 typedef struct {
329 UINT64 FileHandle;
330 UINT64 Offset;
331 UINT32 Size;
332 UINT32 WriteFlags;
333 UINT64 LockOwner;
334 UINT32 Flags;
335 UINT32 Padding;
336 } VIRTIO_FS_FUSE_WRITE_REQUEST;
337
338 typedef struct {
339 UINT32 Size;
340 UINT32 Padding;
341 } VIRTIO_FS_FUSE_WRITE_RESPONSE;
342
343 //
344 // Header for VirtioFsFuseOpStatFs.
345 //
346 typedef struct {
347 UINT64 Blocks;
348 UINT64 Bfree;
349 UINT64 Bavail;
350 UINT64 Files;
351 UINT64 Ffree;
352 UINT32 Bsize;
353 UINT32 Namelen;
354 UINT32 Frsize;
355 UINT32 Padding;
356 UINT32 Spare[6];
357 } VIRTIO_FS_FUSE_STATFS_RESPONSE;
358
359 //
360 // Header for VirtioFsFuseOpRelease and VirtioFsFuseOpReleaseDir.
361 //
362 typedef struct {
363 UINT64 FileHandle;
364 UINT32 Flags;
365 UINT32 ReleaseFlags;
366 UINT64 LockOwner;
367 } VIRTIO_FS_FUSE_RELEASE_REQUEST;
368
369 //
370 // Header for VirtioFsFuseOpFsync and VirtioFsFuseOpFsyncDir.
371 //
372 typedef struct {
373 UINT64 FileHandle;
374 UINT32 FsyncFlags;
375 UINT32 Padding;
376 } VIRTIO_FS_FUSE_FSYNC_REQUEST;
377
378 //
379 // Header for VirtioFsFuseOpFlush.
380 //
381 typedef struct {
382 UINT64 FileHandle;
383 UINT32 Unused;
384 UINT32 Padding;
385 UINT64 LockOwner;
386 } VIRTIO_FS_FUSE_FLUSH_REQUEST;
387
388 //
389 // Headers for VirtioFsFuseOpInit.
390 //
391 typedef struct {
392 UINT32 Major;
393 UINT32 Minor;
394 UINT32 MaxReadahead;
395 UINT32 Flags;
396 } VIRTIO_FS_FUSE_INIT_REQUEST;
397
398 typedef struct {
399 UINT32 Major;
400 UINT32 Minor;
401 UINT32 MaxReadahead;
402 UINT32 Flags;
403 UINT16 MaxBackground;
404 UINT16 CongestionThreshold;
405 UINT32 MaxWrite;
406 UINT32 TimeGran;
407 UINT16 MaxPages;
408 UINT16 MapAlignment;
409 UINT32 Unused[8];
410 } VIRTIO_FS_FUSE_INIT_RESPONSE;
411
412 //
413 // Header for VirtioFsFuseOpCreate.
414 //
415 typedef struct {
416 UINT32 Flags;
417 UINT32 Mode;
418 UINT32 Umask;
419 UINT32 Padding;
420 } VIRTIO_FS_FUSE_CREATE_REQUEST;
421
422 //
423 // Header for VirtioFsFuseOpReadDirPlus.
424 //
425 // Diverging from the rest of the headers, this structure embeds other
426 // structures. The reason is that a scatter list cannot be used to receive
427 // NodeResp and AttrResp separately; the record below is followed by a variable
428 // size filename byte array, and then such pairs are repeated a number of
429 // times. Thus, later header start offsets depend on earlier filename array
430 // sizes.
431 //
432 typedef struct {
433 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp;
434 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp;
435 UINT64 NodeId;
436 UINT64 CookieForNextEntry;
437 UINT32 Namelen;
438 UINT32 Type;
439 } VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE;
440
441 //
442 // Header for VirtioFsFuseOpRename2.
443 //
444 typedef struct {
445 UINT64 NewDir;
446 UINT32 Flags;
447 UINT32 Padding;
448 } VIRTIO_FS_FUSE_RENAME2_REQUEST;
449 #pragma pack ()
450
451 #endif // VIRTIO_FS_H_