Skip to main content

fuse/
protocol.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Defines the kernel interface of FUSE.
5//!
6//! This was derived from the official fuse.h from the Linux kernel sources. It represents
7//! FUSE protocol version 7.39.
8//!
9//! For more details, see fuse.h.
10#![expect(unused_parens)]
11
12use bitfield_struct::bitfield;
13use zerocopy::FromBytes;
14use zerocopy::Immutable;
15use zerocopy::IntoBytes;
16use zerocopy::KnownLayout;
17
18/*
19 * Version negotiation:
20 *
21 * Both the kernel and userspace send the version they support in the
22 * INIT request and reply respectively.
23 *
24 * If the major versions match then both shall use the smallest
25 * of the two minor versions for communication.
26 *
27 * If the kernel supports a larger major version, then userspace shall
28 * reply with the major version it supports, ignore the rest of the
29 * INIT message and expect a new INIT message from the kernel with a
30 * matching major version.
31 *
32 * If the library supports a larger major version, then it shall fall
33 * back to the major protocol version sent by the kernel for
34 * communication and reply with that major version (and an arbitrary
35 * supported minor version).
36 */
37
38/** Version number of this interface */
39pub const FUSE_KERNEL_VERSION: u32 = 7;
40
41/** Minor version number of this interface */
42pub const FUSE_KERNEL_MINOR_VERSION: u32 = 39;
43
44/** The node ID of the root inode */
45pub const FUSE_ROOT_ID: u64 = 1;
46
47/* Make sure all structures are padded to 64bit boundary, so 32bit
48userspace works under 64bit kernels */
49
50#[repr(C)]
51#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
52pub struct fuse_attr {
53    pub ino: u64,
54    pub size: u64,
55    pub blocks: u64,
56    pub atime: u64,
57    pub mtime: u64,
58    pub ctime: u64,
59    pub atimensec: u32,
60    pub mtimensec: u32,
61    pub ctimensec: u32,
62    pub mode: u32,
63    pub nlink: u32,
64    pub uid: u32,
65    pub gid: u32,
66    pub rdev: u32,
67    pub blksize: u32,
68    pub padding: u32,
69}
70
71#[repr(C)]
72#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
73pub struct fuse_sx_time {
74    pub sec: i64,
75    pub nsec: u32,
76    pub _rsvd: u32,
77}
78
79#[repr(C)]
80#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
81pub struct fuse_statx {
82    pub mask: u32,
83    pub blksize: u32,
84    pub attributes: u64,
85    pub nlink: u32,
86    pub uid: u32,
87    pub gid: u32,
88    pub mode: u16,
89    pub _rsvd1: u16,
90    pub ino: u64,
91    pub size: u64,
92    pub blocks: u64,
93    pub attributes_mask: u64,
94    pub atime: fuse_sx_time,
95    pub btime: fuse_sx_time,
96    pub ctime: fuse_sx_time,
97    pub mtime: fuse_sx_time,
98    pub rdev_major: u32,
99    pub rdev_minor: u32,
100    pub dev_major: u32,
101    pub dev_minor: u32,
102    pub _rsvd2: [u64; 14],
103}
104
105#[repr(C)]
106#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
107pub struct fuse_kstatfs {
108    pub blocks: u64,
109    pub bfree: u64,
110    pub bavail: u64,
111    pub files: u64,
112    pub ffree: u64,
113    pub bsize: u32,
114    pub namelen: u32,
115    pub frsize: u32,
116    pub padding: u32,
117    pub spare: [u32; 6],
118}
119
120#[repr(C)]
121#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
122pub struct fuse_file_lock {
123    pub start: u64,
124    pub end: u64,
125    pub lock_type: u32,
126    pub pid: u32, /* tgid */
127}
128
129/**
130 * Bitmasks for fuse_setattr_in.valid
131 */
132pub const FATTR_MODE: u32 = (1 << 0);
133pub const FATTR_UID: u32 = (1 << 1);
134pub const FATTR_GID: u32 = (1 << 2);
135pub const FATTR_SIZE: u32 = (1 << 3);
136pub const FATTR_ATIME: u32 = (1 << 4);
137pub const FATTR_MTIME: u32 = (1 << 5);
138pub const FATTR_FH: u32 = (1 << 6);
139pub const FATTR_ATIME_NOW: u32 = (1 << 7);
140pub const FATTR_MTIME_NOW: u32 = (1 << 8);
141pub const FATTR_LOCKOWNER: u32 = (1 << 9);
142pub const FATTR_CTIME: u32 = (1 << 10);
143pub const FATTR_KILL_SUIDGID: u32 = (1 << 11);
144
145/**
146 * Flags returned by the OPEN request
147 *
148 * FOPEN_DIRECT_IO: bypass page cache for this open file
149 * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
150 * FOPEN_NONSEEKABLE: the file is not seekable
151 * FOPEN_CACHE_DIR: allow caching this directory
152 * FOPEN_STREAM: the file is stream-like (no file position at all)
153 */
154pub const FOPEN_DIRECT_IO: u32 = (1 << 0);
155pub const FOPEN_KEEP_CACHE: u32 = (1 << 1);
156pub const FOPEN_NONSEEKABLE: u32 = (1 << 2);
157pub const FOPEN_CACHE_DIR: u32 = (1 << 3);
158pub const FOPEN_STREAM: u32 = (1 << 4);
159
160/**
161 * INIT request/reply flags
162 *
163 * FUSE_ASYNC_READ: asynchronous read requests
164 * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
165 * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
166 * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
167 * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
168 * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
169 * FUSE_DONT_MASK: don't apply umask to file mode on create operations
170 * FUSE_SPLICE_WRITE: kernel supports splice write on the device
171 * FUSE_SPLICE_MOVE: kernel supports splice move on the device
172 * FUSE_SPLICE_READ: kernel supports splice read on the device
173 * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
174 * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
175 * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
176 * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one)
177 * FUSE_READDIRPLUS_AUTO: adaptive readdirplus
178 * FUSE_ASYNC_DIO: asynchronous direct I/O submission
179 * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
180 * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens
181 * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir
182 * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc
183 * FUSE_POSIX_ACL: filesystem supports posix acls
184 * FUSE_ABORT_ERROR: reading the device after abort returns ECONNABORTED
185 * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages
186 * FUSE_CACHE_SYMLINKS: cache READLINK responses
187 * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir
188 * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit request
189 * FUSE_MAP_ALIGNMENT: map_alignment field is valid
190 * FUSE_SUBMOUNTS: kernel supports auto-mounting directory submounts
191 * FUSE_HANDLE_KILLPRIV_V2: fs kills suid/sgid/cap on write/chown/trunc
192 * FUSE_SETXATTR_EXT: server supports extended struct fuse_setxattr_in
193 * FUSE_INIT_EXT: extended fuse_init_in request (flags2 field is valid)
194 * FUSE_INIT_RESERVED: reserved, do not use
195 */
196pub const FUSE_ASYNC_READ: u32 = (1 << 0);
197pub const FUSE_POSIX_LOCKS: u32 = (1 << 1);
198pub const FUSE_FILE_OPS: u32 = (1 << 2);
199pub const FUSE_ATOMIC_O_TRUNC: u32 = (1 << 3);
200pub const FUSE_EXPORT_SUPPORT: u32 = (1 << 4);
201pub const FUSE_BIG_WRITES: u32 = (1 << 5);
202pub const FUSE_DONT_MASK: u32 = (1 << 6);
203pub const FUSE_SPLICE_WRITE: u32 = (1 << 7);
204pub const FUSE_SPLICE_MOVE: u32 = (1 << 8);
205pub const FUSE_SPLICE_READ: u32 = (1 << 9);
206pub const FUSE_FLOCK_LOCKS: u32 = (1 << 10);
207pub const FUSE_HAS_IOCTL_DIR: u32 = (1 << 11);
208pub const FUSE_AUTO_INVAL_DATA: u32 = (1 << 12);
209pub const FUSE_DO_READDIRPLUS: u32 = (1 << 13);
210pub const FUSE_READDIRPLUS_AUTO: u32 = (1 << 14);
211pub const FUSE_ASYNC_DIO: u32 = (1 << 15);
212pub const FUSE_WRITEBACK_CACHE: u32 = (1 << 16);
213pub const FUSE_NO_OPEN_SUPPORT: u32 = (1 << 17);
214pub const FUSE_PARALLEL_DIROPS: u32 = (1 << 18);
215pub const FUSE_HANDLE_KILLPRIV: u32 = (1 << 19);
216pub const FUSE_POSIX_ACL: u32 = (1 << 20);
217pub const FUSE_ABORT_ERROR: u32 = (1 << 21);
218pub const FUSE_MAX_PAGES: u32 = (1 << 22);
219pub const FUSE_CACHE_SYMLINKS: u32 = (1 << 23);
220pub const FUSE_NO_OPENDIR_SUPPORT: u32 = (1 << 24);
221pub const FUSE_EXPLICIT_INVAL_DATA: u32 = (1 << 25);
222pub const FUSE_MAP_ALIGNMENT: u32 = (1 << 26);
223pub const FUSE_SUBMOUNTS: u32 = (1 << 27);
224pub const FUSE_HANDLE_KILLPRIV_V2: u32 = (1 << 28);
225pub const FUSE_SETXATTR_EXT: u32 = (1 << 29);
226pub const FUSE_INIT_EXT: u32 = (1 << 30);
227pub const FUSE_INIT_RESERVED: u32 = (1 << 31);
228
229/**
230 * INIT flags2 (bits 32..63 of the combined flag space, shifted down by 32)
231 *
232 * FUSE_SECURITY_CTX: add security context to create, mkdir, symlink, and mknod
233 * FUSE_HAS_INODE_DAX: use per inode DAX
234 * FUSE_CREATE_SUPP_GROUP: add supplementary group info to create, mkdir, symlink and mknod
235 * FUSE_HAS_EXPIRE_ONLY: kernel supports expiry-only entry invalidation
236 * FUSE_DIRECT_IO_ALLOW_MMAP: allow shared mmap in FOPEN_DIRECT_IO mode
237 */
238pub const FUSE_SECURITY_CTX_FLAG2: u32 = (1 << 0);
239pub const FUSE_HAS_INODE_DAX_FLAG2: u32 = (1 << 1);
240pub const FUSE_CREATE_SUPP_GROUP_FLAG2: u32 = (1 << 2);
241pub const FUSE_HAS_EXPIRE_ONLY_FLAG2: u32 = (1 << 3);
242pub const FUSE_DIRECT_IO_ALLOW_MMAP_FLAG2: u32 = (1 << 4);
243
244/**
245 * CUSE INIT request/reply flags
246 *
247 * CUSE_UNRESTRICTED_IOCTL:  use unrestricted ioctl
248 */
249pub const CUSE_UNRESTRICTED_IOCTL: u32 = (1 << 0);
250
251/**
252 * Release flags
253 */
254pub const FUSE_RELEASE_FLUSH: u32 = (1 << 0);
255pub const FUSE_RELEASE_FLOCK_UNLOCK: u32 = (1 << 1);
256
257/**
258 * Getattr flags
259 */
260pub const FUSE_GETATTR_FH: u32 = (1 << 0);
261
262/**
263 * Lock flags
264 */
265pub const FUSE_LK_FLOCK: u32 = (1 << 0);
266
267/**
268 * WRITE flags
269 *
270 * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
271 * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
272 * FUSE_WRITE_KILL_PRIV: kill suid and sgid bits
273 */
274pub const FUSE_WRITE_CACHE: u32 = (1 << 0);
275pub const FUSE_WRITE_LOCKOWNER: u32 = (1 << 1);
276pub const FUSE_WRITE_KILL_PRIV: u32 = (1 << 2);
277
278/**
279 * Read flags
280 */
281pub const FUSE_READ_LOCKOWNER: u32 = (1 << 1);
282
283/**
284 * Ioctl flags
285 *
286 * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
287 * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
288 * FUSE_IOCTL_RETRY: retry with new iovecs
289 * FUSE_IOCTL_32BIT: 32bit ioctl
290 * FUSE_IOCTL_DIR: is a directory
291 * FUSE_IOCTL_COMPAT_X32: x32 compat ioctl on 64bit machine (64bit time_t)
292 *
293 * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
294 */
295pub const FUSE_IOCTL_COMPAT: u32 = (1 << 0);
296pub const FUSE_IOCTL_UNRESTRICTED: u32 = (1 << 1);
297pub const FUSE_IOCTL_RETRY: u32 = (1 << 2);
298pub const FUSE_IOCTL_32BIT: u32 = (1 << 3);
299pub const FUSE_IOCTL_DIR: u32 = (1 << 4);
300pub const FUSE_IOCTL_COMPAT_X32: u32 = (1 << 5);
301
302pub const FUSE_IOCTL_MAX_IOV: u32 = 256;
303
304/**
305 * Poll flags
306 *
307 * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
308 */
309pub const FUSE_POLL_SCHEDULE_NOTIFY: u32 = (1 << 0);
310
311/**
312 * Fsync flags
313 *
314 * FUSE_FSYNC_FDATASYNC: Sync data only, not metadata
315 */
316pub const FUSE_FSYNC_FDATASYNC: u32 = (1 << 0);
317
318pub const FUSE_LOOKUP: u32 = 1;
319pub const FUSE_FORGET: u32 = 2; /* no reply */
320pub const FUSE_GETATTR: u32 = 3;
321pub const FUSE_SETATTR: u32 = 4;
322pub const FUSE_READLINK: u32 = 5;
323pub const FUSE_SYMLINK: u32 = 6;
324pub const FUSE_MKNOD: u32 = 8;
325pub const FUSE_MKDIR: u32 = 9;
326pub const FUSE_UNLINK: u32 = 10;
327pub const FUSE_RMDIR: u32 = 11;
328pub const FUSE_RENAME: u32 = 12;
329pub const FUSE_LINK: u32 = 13;
330pub const FUSE_OPEN: u32 = 14;
331pub const FUSE_READ: u32 = 15;
332pub const FUSE_WRITE: u32 = 16;
333pub const FUSE_STATFS: u32 = 17;
334pub const FUSE_RELEASE: u32 = 18;
335pub const FUSE_FSYNC: u32 = 20;
336pub const FUSE_SETXATTR: u32 = 21;
337pub const FUSE_GETXATTR: u32 = 22;
338pub const FUSE_LISTXATTR: u32 = 23;
339pub const FUSE_REMOVEXATTR: u32 = 24;
340pub const FUSE_FLUSH: u32 = 25;
341pub const FUSE_INIT: u32 = 26;
342pub const FUSE_OPENDIR: u32 = 27;
343pub const FUSE_READDIR: u32 = 28;
344pub const FUSE_RELEASEDIR: u32 = 29;
345pub const FUSE_FSYNCDIR: u32 = 30;
346pub const FUSE_GETLK: u32 = 31;
347pub const FUSE_SETLK: u32 = 32;
348pub const FUSE_SETLKW: u32 = 33;
349pub const FUSE_ACCESS: u32 = 34;
350pub const FUSE_CREATE: u32 = 35;
351pub const FUSE_INTERRUPT: u32 = 36;
352pub const FUSE_BMAP: u32 = 37;
353pub const FUSE_DESTROY: u32 = 38;
354pub const FUSE_IOCTL: u32 = 39;
355pub const FUSE_POLL: u32 = 40;
356pub const FUSE_NOTIFY_REPLY: u32 = 41;
357pub const FUSE_BATCH_FORGET: u32 = 42;
358pub const FUSE_FALLOCATE: u32 = 43;
359pub const FUSE_READDIRPLUS: u32 = 44;
360pub const FUSE_RENAME2: u32 = 45;
361pub const FUSE_LSEEK: u32 = 46;
362pub const FUSE_COPY_FILE_RANGE: u32 = 47;
363pub const FUSE_SETUPMAPPING: u32 = 48;
364pub const FUSE_REMOVEMAPPING: u32 = 49;
365pub const FUSE_SYNCFS: u32 = 50;
366pub const FUSE_TMPFILE: u32 = 51;
367pub const FUSE_STATX: u32 = 52;
368/* Special Android FUSE operation */
369pub const FUSE_CANONICAL_PATH: u32 = 2016;
370
371/* CUSE specific operations */
372pub const CUSE_INIT: u32 = 4096;
373
374/* Reserved opcodes: helpful to detect structure endian-ness */
375pub const CUSE_INIT_BSWAP_RESERVED: u32 = 1048576; /* CUSE_INIT << 8 */
376pub const FUSE_INIT_BSWAP_RESERVED: u32 = 436207616; /* FUSE_INIT << 24 */
377
378pub const FUSE_NOTIFY_POLL: u32 = 1;
379pub const FUSE_NOTIFY_INVAL_INODE: u32 = 2;
380pub const FUSE_NOTIFY_INVAL_ENTRY: u32 = 3;
381pub const FUSE_NOTIFY_STORE: u32 = 4;
382pub const FUSE_NOTIFY_RETRIEVE: u32 = 5;
383pub const FUSE_NOTIFY_DELETE: u32 = 6;
384pub const FUSE_NOTIFY_CODE_MAX: u32 = 7;
385
386/* The read buffer is required to be at least 8k, but may be much larger */
387pub const FUSE_MIN_READ_BUFFER: u32 = 8192;
388
389pub const FUSE_COMPAT_ENTRY_OUT_SIZE: u32 = 120;
390
391#[repr(C)]
392#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
393pub struct fuse_entry_out {
394    pub nodeid: u64, /* Inode ID */
395    pub generation: u64, /* Inode generation: nodeid:gen must
396                     be unique for the fs's lifetime */
397    pub entry_valid: u64, /* Cache timeout for the name */
398    pub attr_valid: u64,  /* Cache timeout for the attributes */
399    pub entry_valid_nsec: u32,
400    pub attr_valid_nsec: u32,
401    pub attr: fuse_attr,
402}
403
404#[repr(C)]
405#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
406pub struct fuse_forget_in {
407    pub nlookup: u64,
408}
409
410#[repr(C)]
411#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
412pub struct fuse_forget_one {
413    pub nodeid: u64,
414    pub nlookup: u64,
415}
416
417#[repr(C)]
418#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
419pub struct fuse_batch_forget_in {
420    pub count: u32,
421    pub dummy: u32,
422}
423
424#[repr(C)]
425#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
426pub struct fuse_getattr_in {
427    pub getattr_flags: u32,
428    pub dummy: u32,
429    pub fh: u64,
430}
431
432pub const FUSE_COMPAT_ATTR_OUT_SIZE: u32 = 96;
433
434#[repr(C)]
435#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
436pub struct fuse_attr_out {
437    pub attr_valid: u64, /* Cache timeout for the attributes */
438    pub attr_valid_nsec: u32,
439    pub dummy: u32,
440    pub attr: fuse_attr,
441}
442
443pub const FUSE_COMPAT_MKNOD_IN_SIZE: u32 = 8;
444
445#[repr(C)]
446#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
447pub struct fuse_mknod_in {
448    pub mode: u32,
449    pub rdev: u32,
450    pub umask: u32,
451    pub padding: u32,
452}
453
454#[repr(C)]
455#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
456pub struct fuse_mkdir_in {
457    pub mode: u32,
458    pub umask: u32,
459}
460
461#[repr(C)]
462#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
463pub struct fuse_rename_in {
464    pub newdir: u64,
465}
466
467#[repr(C)]
468#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
469pub struct fuse_rename2_in {
470    pub newdir: u64,
471    pub flags: u32,
472    pub padding: u32,
473}
474
475#[repr(C)]
476#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
477pub struct fuse_link_in {
478    pub oldnodeid: u64,
479}
480
481#[repr(C)]
482#[derive(Clone, Copy, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
483pub struct fuse_setattr_in {
484    pub valid: u32,
485    pub padding: u32,
486    pub fh: u64,
487    pub size: u64,
488    pub lock_owner: u64,
489    pub atime: u64,
490    pub mtime: u64,
491    pub ctime: u64,
492    pub atimensec: u32,
493    pub mtimensec: u32,
494    pub ctimensec: u32,
495    pub mode: u32,
496    pub unused4: u32,
497    pub uid: u32,
498    pub gid: u32,
499    pub unused5: u32,
500}
501
502#[repr(C)]
503#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
504pub struct fuse_open_in {
505    pub flags: u32,
506    pub unused: u32,
507}
508
509#[repr(C)]
510#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
511pub struct fuse_create_in {
512    pub flags: u32,
513    pub mode: u32,
514    pub umask: u32,
515    pub padding: u32,
516}
517
518#[repr(C)]
519#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
520pub struct fuse_open_out {
521    pub fh: u64,
522    pub open_flags: u32,
523    pub padding: u32,
524}
525
526#[repr(C)]
527#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
528pub struct fuse_release_in {
529    pub fh: u64,
530    pub flags: u32,
531    pub release_flags: u32,
532    pub lock_owner: u64,
533}
534
535#[repr(C)]
536#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
537pub struct fuse_flush_in {
538    pub fh: u64,
539    pub unused: u32,
540    pub padding: u32,
541    pub lock_owner: u64,
542}
543
544#[repr(C)]
545#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
546pub struct fuse_read_in {
547    pub fh: u64,
548    pub offset: u64,
549    pub size: u32,
550    pub read_flags: u32,
551    pub lock_owner: u64,
552    pub flags: u32,
553    pub padding: u32,
554}
555
556pub const FUSE_COMPAT_WRITE_IN_SIZE: u32 = 24;
557
558#[repr(C)]
559#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
560pub struct fuse_write_in {
561    pub fh: u64,
562    pub offset: u64,
563    pub size: u32,
564    pub write_flags: u32,
565    pub lock_owner: u64,
566    pub flags: u32,
567    pub padding: u32,
568}
569
570#[repr(C)]
571#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
572pub struct fuse_write_out {
573    pub size: u32,
574    pub padding: u32,
575}
576
577pub const FUSE_COMPAT_STATFS_SIZE: u32 = 48;
578
579#[repr(C)]
580#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
581pub struct fuse_statfs_out {
582    pub st: fuse_kstatfs,
583}
584
585#[repr(C)]
586#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
587pub struct fuse_fsync_in {
588    pub fh: u64,
589    pub fsync_flags: u32,
590    pub padding: u32,
591}
592
593#[repr(C)]
594#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
595pub struct fuse_setxattr_in {
596    pub size: u32,
597    pub flags: u32,
598}
599
600#[repr(C)]
601#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
602pub struct fuse_getxattr_in {
603    pub size: u32,
604    pub padding: u32,
605}
606
607#[repr(C)]
608#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
609pub struct fuse_getxattr_out {
610    pub size: u32,
611    pub padding: u32,
612}
613
614#[repr(C)]
615#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
616pub struct fuse_lk_in {
617    pub fh: u64,
618    pub owner: u64,
619    pub lk: fuse_file_lock,
620    pub lk_flags: u32,
621    pub padding: u32,
622}
623
624#[repr(C)]
625#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
626pub struct fuse_lk_out {
627    pub lk: fuse_file_lock,
628}
629
630#[repr(C)]
631#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
632pub struct fuse_access_in {
633    pub mask: u32,
634    pub padding: u32,
635}
636
637pub const FUSE_COMPAT_INIT_IN_SIZE: u32 = 16;
638
639#[repr(C)]
640#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
641pub struct fuse_init_in {
642    pub major: u32,
643    pub minor: u32,
644    pub max_readahead: u32,
645    pub flags: u32,
646    pub flags2: u32,
647    pub unused: [u32; 11],
648}
649
650pub const FUSE_COMPAT_INIT_OUT_SIZE: u32 = 8;
651pub const FUSE_COMPAT_22_INIT_OUT_SIZE: u32 = 24;
652
653#[repr(C)]
654#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
655pub struct fuse_init_out {
656    pub major: u32,
657    pub minor: u32,
658    pub max_readahead: u32,
659    pub flags: u32,
660    pub max_background: u16,
661    pub congestion_threshold: u16,
662    pub max_write: u32,
663    pub time_gran: u32,
664    pub max_pages: u16,
665    pub map_alignment: u16,
666    pub flags2: u32,
667    pub unused: [u32; 7],
668}
669
670pub const CUSE_INIT_INFO_MAX: u32 = 4096;
671
672#[repr(C)]
673#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
674pub struct cuse_init_in {
675    pub major: u32,
676    pub minor: u32,
677    pub unused: u32,
678    pub flags: u32,
679}
680
681#[repr(C)]
682#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
683pub struct cuse_init_out {
684    pub major: u32,
685    pub minor: u32,
686    pub unused: u32,
687    pub flags: u32,
688    pub max_read: u32,
689    pub max_write: u32,
690    pub dev_major: u32, /* chardev major */
691    pub dev_minor: u32, /* chardev minor */
692    pub spare: [u32; 10],
693}
694
695#[repr(C)]
696#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
697pub struct fuse_interrupt_in {
698    pub unique: u64,
699}
700
701#[repr(C)]
702#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
703pub struct fuse_bmap_in {
704    pub block: u64,
705    pub blocksize: u32,
706    pub padding: u32,
707}
708
709#[repr(C)]
710#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
711pub struct fuse_bmap_out {
712    pub block: u64,
713}
714
715#[repr(C)]
716#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
717pub struct fuse_ioctl_in {
718    pub fh: u64,
719    pub flags: u32,
720    pub cmd: u32,
721    pub arg: u64,
722    pub in_size: u32,
723    pub out_size: u32,
724}
725
726#[repr(C)]
727#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
728pub struct fuse_ioctl_iovec {
729    pub base: u64,
730    pub len: u64,
731}
732
733#[repr(C)]
734#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
735pub struct fuse_ioctl_out {
736    pub result: i32,
737    pub flags: u32,
738    pub in_iovs: u32,
739    pub out_iovs: u32,
740}
741
742#[repr(C)]
743#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
744pub struct fuse_poll_in {
745    pub fh: u64,
746    pub kh: u64,
747    pub flags: u32,
748    pub events: u32,
749}
750
751#[repr(C)]
752#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
753pub struct fuse_poll_out {
754    pub revents: u32,
755    pub padding: u32,
756}
757
758#[repr(C)]
759#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
760pub struct fuse_notify_poll_wakeup_out {
761    pub kh: u64,
762}
763
764#[repr(C)]
765#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
766pub struct fuse_fallocate_in {
767    pub fh: u64,
768    pub offset: u64,
769    pub length: u64,
770    pub mode: u32,
771    pub padding: u32,
772}
773
774#[repr(C)]
775#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
776pub struct fuse_in_header {
777    pub len: u32,
778    pub opcode: u32,
779    pub unique: u64,
780    pub nodeid: u64,
781    pub uid: u32,
782    pub gid: u32,
783    pub pid: u32,
784    pub padding: u32,
785}
786
787#[repr(C)]
788#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
789pub struct fuse_out_header {
790    pub len: u32,
791    pub error: i32,
792    pub unique: u64,
793}
794
795#[repr(C)]
796#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
797pub struct fuse_dirent {
798    pub ino: u64,
799    pub off: u64,
800    pub namelen: u32,
801    pub file_type: u32,
802    // char name[];
803}
804
805pub fn fuse_dirent_align(x: usize) -> usize {
806    (((x) + size_of::<u64>() - 1) & !(size_of::<u64>() - 1))
807}
808#[repr(C)]
809#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
810pub struct fuse_direntplus {
811    pub entry_out: fuse_entry_out,
812    pub dirent: fuse_dirent,
813}
814
815#[repr(C)]
816#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
817pub struct fuse_notify_inval_inode_out {
818    pub ino: u64,
819    pub off: i64,
820    pub len: i64,
821}
822
823#[repr(C)]
824#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
825pub struct fuse_notify_inval_entry_out {
826    pub parent: u64,
827    pub namelen: u32,
828    pub padding: u32,
829}
830
831#[repr(C)]
832#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
833pub struct fuse_notify_delete_out {
834    pub parent: u64,
835    pub child: u64,
836    pub namelen: u32,
837    pub padding: u32,
838}
839
840#[repr(C)]
841#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
842pub struct fuse_notify_store_out {
843    pub nodeid: u64,
844    pub offset: u64,
845    pub size: u32,
846    pub padding: u32,
847}
848
849#[repr(C)]
850#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
851pub struct fuse_notify_retrieve_out {
852    pub notify_unique: u64,
853    pub nodeid: u64,
854    pub offset: u64,
855    pub size: u32,
856    pub padding: u32,
857}
858
859/* Matches the size of fuse_write_in */
860#[repr(C)]
861#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
862pub struct fuse_notify_retrieve_in {
863    pub dummy1: u64,
864    pub offset: u64,
865    pub size: u32,
866    pub dummy2: u32,
867    pub dummy3: u64,
868    pub dummy4: u64,
869}
870
871/* Device ioctls: */
872//  const FUSE_DEV_IOC_CLONE: u32 = _IOR(229, 0, u32);
873
874#[repr(C)]
875#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
876pub struct fuse_lseek_in {
877    pub fh: u64,
878    pub offset: u64,
879    pub whence: u32,
880    pub padding: u32,
881}
882
883#[repr(C)]
884#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
885pub struct fuse_lseek_out {
886    pub offset: u64,
887}
888
889#[repr(C)]
890#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
891pub struct fuse_copy_file_range_in {
892    pub fh_in: u64,
893    pub off_in: u64,
894    pub nodeid_out: u64,
895    pub fh_out: u64,
896    pub off_out: u64,
897    pub len: u64,
898    pub flags: u64,
899}
900
901pub const FUSE_SETUPMAPPING_FLAG_WRITE: u64 = (1 << 0);
902
903#[repr(C)]
904#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
905pub struct fuse_setupmapping_in {
906    /* An already open handle */
907    pub fh: u64,
908    /* Offset into the file to start the mapping */
909    pub foffset: u64,
910    /* Length of mapping required */
911    pub len: u64,
912    /* Flags, FUSE_SETUPMAPPING_FLAG_* */
913    pub flags: u64,
914    /* memory offset in to dax window */
915    pub moffset: u64,
916}
917
918#[repr(C)]
919#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
920pub struct fuse_removemapping_in {
921    /* number of fuse_removemapping_one follows */
922    pub count: u32,
923}
924
925#[repr(C)]
926#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
927pub struct fuse_removemapping_one {
928    /* Offset into the dax to start the unmapping */
929    pub moffset: u64,
930    /* Length of mapping required */
931    pub len: u64,
932}
933
934#[repr(C)]
935#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
936pub struct fuse_syncfs_in {
937    pub padding: u64,
938}
939
940#[bitfield(u32)]
941#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
942pub struct StatxFlags {
943    #[bits(13)]
944    _rsvd1: u32,
945    pub force_sync: bool,
946    pub dont_sync: bool,
947    #[bits(17)]
948    _rsvd2: u32,
949}
950
951#[repr(C)]
952#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
953pub struct fuse_statx_in {
954    pub getattr_flags: u32,
955    _rsvd: u32,
956    pub fh: u64,
957    pub flags: StatxFlags,
958    pub mask: u32,
959}
960
961#[repr(C)]
962#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
963pub struct fuse_statx_out {
964    pub attr_valid: u64, /* Cache timeout for the attributes */
965    pub attr_valid_nsec: u32,
966    pub flags: StatxFlags,
967    pub _rsvd: [u64; 2],
968    pub statx: fuse_statx,
969}