]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Include/IndustryStandard/VirtioFs.h
OvmfPkg/VirtioFsDxe: handle file rename/move in EFI_FILE_PROTOCOL.SetInfo
[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 // Flags for VirtioFsFuseOpRename2.
146 //
147 #define VIRTIO_FS_FUSE_RENAME2_REQ_F_NOREPLACE BIT0
148
149 //
150 // FUSE operation codes.
151 //
152 typedef enum {
153 VirtioFsFuseOpLookup = 1,
154 VirtioFsFuseOpForget = 2,
155 VirtioFsFuseOpGetAttr = 3,
156 VirtioFsFuseOpMkDir = 9,
157 VirtioFsFuseOpUnlink = 10,
158 VirtioFsFuseOpRmDir = 11,
159 VirtioFsFuseOpOpen = 14,
160 VirtioFsFuseOpRead = 15,
161 VirtioFsFuseOpWrite = 16,
162 VirtioFsFuseOpStatFs = 17,
163 VirtioFsFuseOpRelease = 18,
164 VirtioFsFuseOpFsync = 20,
165 VirtioFsFuseOpFlush = 25,
166 VirtioFsFuseOpInit = 26,
167 VirtioFsFuseOpOpenDir = 27,
168 VirtioFsFuseOpReleaseDir = 29,
169 VirtioFsFuseOpFsyncDir = 30,
170 VirtioFsFuseOpCreate = 35,
171 VirtioFsFuseOpReadDirPlus = 44,
172 VirtioFsFuseOpRename2 = 45,
173 } VIRTIO_FS_FUSE_OPCODE;
174
175 #pragma pack (1)
176 //
177 // Request-response headers common to all request types.
178 //
179 typedef struct {
180 UINT32 Len;
181 UINT32 Opcode;
182 UINT64 Unique;
183 UINT64 NodeId;
184 UINT32 Uid;
185 UINT32 Gid;
186 UINT32 Pid;
187 UINT32 Padding;
188 } VIRTIO_FS_FUSE_REQUEST;
189
190 typedef struct {
191 UINT32 Len;
192 INT32 Error;
193 UINT64 Unique;
194 } VIRTIO_FS_FUSE_RESPONSE;
195
196 //
197 // Structure with which the Virtio Filesystem device reports a NodeId to the
198 // FUSE client (i.e., to the Virtio Filesystem driver). This structure is a
199 // part of the response headers for operations that inform the FUSE client of
200 // an inode.
201 //
202 typedef struct {
203 UINT64 NodeId;
204 UINT64 Generation;
205 UINT64 EntryValid;
206 UINT64 AttrValid;
207 UINT32 EntryValidNsec;
208 UINT32 AttrValidNsec;
209 } VIRTIO_FS_FUSE_NODE_RESPONSE;
210
211 //
212 // Structure describing the host-side attributes of an inode. This structure is
213 // a part of the response headers for operations that inform the FUSE client of
214 // an inode.
215 //
216 typedef struct {
217 UINT64 Ino;
218 UINT64 Size;
219 UINT64 Blocks;
220 UINT64 Atime;
221 UINT64 Mtime;
222 UINT64 Ctime;
223 UINT32 AtimeNsec;
224 UINT32 MtimeNsec;
225 UINT32 CtimeNsec;
226 UINT32 Mode;
227 UINT32 Nlink;
228 UINT32 Uid;
229 UINT32 Gid;
230 UINT32 Rdev;
231 UINT32 Blksize;
232 UINT32 Padding;
233 } VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE;
234
235 //
236 // Header for VirtioFsFuseOpForget.
237 //
238 typedef struct {
239 UINT64 NumberOfLookups;
240 } VIRTIO_FS_FUSE_FORGET_REQUEST;
241
242 //
243 // Headers for VirtioFsFuseOpGetAttr.
244 //
245 typedef struct {
246 UINT32 GetAttrFlags;
247 UINT32 Dummy;
248 UINT64 FileHandle;
249 } VIRTIO_FS_FUSE_GETATTR_REQUEST;
250
251 typedef struct {
252 UINT64 AttrValid;
253 UINT32 AttrValidNsec;
254 UINT32 Dummy;
255 } VIRTIO_FS_FUSE_GETATTR_RESPONSE;
256
257 //
258 // Header for VirtioFsFuseOpMkDir.
259 //
260 typedef struct {
261 UINT32 Mode;
262 UINT32 Umask;
263 } VIRTIO_FS_FUSE_MKDIR_REQUEST;
264
265 //
266 // Headers for VirtioFsFuseOpOpen and VirtioFsFuseOpOpenDir.
267 //
268 typedef struct {
269 UINT32 Flags;
270 UINT32 Unused;
271 } VIRTIO_FS_FUSE_OPEN_REQUEST;
272
273 typedef struct {
274 UINT64 FileHandle;
275 UINT32 OpenFlags;
276 UINT32 Padding;
277 } VIRTIO_FS_FUSE_OPEN_RESPONSE;
278
279 //
280 // Header for VirtioFsFuseOpRead and VirtioFsFuseOpReadDirPlus.
281 //
282 typedef struct {
283 UINT64 FileHandle;
284 UINT64 Offset;
285 UINT32 Size;
286 UINT32 ReadFlags;
287 UINT64 LockOwner;
288 UINT32 Flags;
289 UINT32 Padding;
290 } VIRTIO_FS_FUSE_READ_REQUEST;
291
292 //
293 // Headers for VirtioFsFuseOpWrite.
294 //
295 typedef struct {
296 UINT64 FileHandle;
297 UINT64 Offset;
298 UINT32 Size;
299 UINT32 WriteFlags;
300 UINT64 LockOwner;
301 UINT32 Flags;
302 UINT32 Padding;
303 } VIRTIO_FS_FUSE_WRITE_REQUEST;
304
305 typedef struct {
306 UINT32 Size;
307 UINT32 Padding;
308 } VIRTIO_FS_FUSE_WRITE_RESPONSE;
309
310 //
311 // Header for VirtioFsFuseOpStatFs.
312 //
313 typedef struct {
314 UINT64 Blocks;
315 UINT64 Bfree;
316 UINT64 Bavail;
317 UINT64 Files;
318 UINT64 Ffree;
319 UINT32 Bsize;
320 UINT32 Namelen;
321 UINT32 Frsize;
322 UINT32 Padding;
323 UINT32 Spare[6];
324 } VIRTIO_FS_FUSE_STATFS_RESPONSE;
325
326 //
327 // Header for VirtioFsFuseOpRelease and VirtioFsFuseOpReleaseDir.
328 //
329 typedef struct {
330 UINT64 FileHandle;
331 UINT32 Flags;
332 UINT32 ReleaseFlags;
333 UINT64 LockOwner;
334 } VIRTIO_FS_FUSE_RELEASE_REQUEST;
335
336 //
337 // Header for VirtioFsFuseOpFsync and VirtioFsFuseOpFsyncDir.
338 //
339 typedef struct {
340 UINT64 FileHandle;
341 UINT32 FsyncFlags;
342 UINT32 Padding;
343 } VIRTIO_FS_FUSE_FSYNC_REQUEST;
344
345 //
346 // Header for VirtioFsFuseOpFlush.
347 //
348 typedef struct {
349 UINT64 FileHandle;
350 UINT32 Unused;
351 UINT32 Padding;
352 UINT64 LockOwner;
353 } VIRTIO_FS_FUSE_FLUSH_REQUEST;
354
355 //
356 // Headers for VirtioFsFuseOpInit.
357 //
358 typedef struct {
359 UINT32 Major;
360 UINT32 Minor;
361 UINT32 MaxReadahead;
362 UINT32 Flags;
363 } VIRTIO_FS_FUSE_INIT_REQUEST;
364
365 typedef struct {
366 UINT32 Major;
367 UINT32 Minor;
368 UINT32 MaxReadahead;
369 UINT32 Flags;
370 UINT16 MaxBackground;
371 UINT16 CongestionThreshold;
372 UINT32 MaxWrite;
373 UINT32 TimeGran;
374 UINT16 MaxPages;
375 UINT16 MapAlignment;
376 UINT32 Unused[8];
377 } VIRTIO_FS_FUSE_INIT_RESPONSE;
378
379 //
380 // Header for VirtioFsFuseOpCreate.
381 //
382 typedef struct {
383 UINT32 Flags;
384 UINT32 Mode;
385 UINT32 Umask;
386 UINT32 Padding;
387 } VIRTIO_FS_FUSE_CREATE_REQUEST;
388
389 //
390 // Header for VirtioFsFuseOpReadDirPlus.
391 //
392 // Diverging from the rest of the headers, this structure embeds other
393 // structures. The reason is that a scatter list cannot be used to receive
394 // NodeResp and AttrResp separately; the record below is followed by a variable
395 // size filename byte array, and then such pairs are repeated a number of
396 // times. Thus, later header start offsets depend on earlier filename array
397 // sizes.
398 //
399 typedef struct {
400 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp;
401 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp;
402 UINT64 NodeId;
403 UINT64 CookieForNextEntry;
404 UINT32 Namelen;
405 UINT32 Type;
406 } VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE;
407
408 //
409 // Header for VirtioFsFuseOpRename2.
410 //
411 typedef struct {
412 UINT64 NewDir;
413 UINT32 Flags;
414 UINT32 Padding;
415 } VIRTIO_FS_FUSE_RENAME2_REQUEST;
416 #pragma pack ()
417
418 #endif // VIRTIO_FS_H_