polyfuse_kernel/
lib.rs

1//! FUSE application binary interface for `polyfuse`.
2//!
3//! The binding is compatible with ABI 7.44 (Linux 6.16.11).
4
5#![allow(nonstandard_style, clippy::identity_op)]
6
7use libc::{c_char, c_ulong};
8use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, TryFromBytes};
9
10/// The major version number of FUSE protocol.
11pub const FUSE_KERNEL_VERSION: u32 = 7;
12
13/// The minor version number of FUSE protocol.
14pub const FUSE_KERNEL_MINOR_VERSION: u32 = 44;
15
16/// The minimum length of read buffer.
17pub const FUSE_MIN_READ_BUFFER: u32 = 8192;
18
19/// Maximum of in_iovecs + out_iovecs
20pub const FUSE_IOCTL_MAX_IOV: u32 = 256;
21
22// Bitmasks for fuse_setattr_in.valid
23pub const FATTR_MODE: u32 = 1 << 0;
24pub const FATTR_UID: u32 = 1 << 1;
25pub const FATTR_GID: u32 = 1 << 2;
26pub const FATTR_SIZE: u32 = 1 << 3;
27pub const FATTR_ATIME: u32 = 1 << 4;
28pub const FATTR_MTIME: u32 = 1 << 5;
29pub const FATTR_FH: u32 = 1 << 6;
30pub const FATTR_ATIME_NOW: u32 = 1 << 7;
31pub const FATTR_MTIME_NOW: u32 = 1 << 8;
32pub const FATTR_LOCKOWNER: u32 = 1 << 9;
33pub const FATTR_CTIME: u32 = 1 << 10;
34pub const FATTR_KILL_SUIDGID: u32 = 1 << 11;
35
36// Bitmasks for fuse_attr.flags
37pub const FUSE_ATTR_SUBMOUNT: u32 = 1 << 0;
38
39// Flags returned by the OPEN request.
40pub const FOPEN_DIRECT_IO: u32 = 1 << 0;
41pub const FOPEN_KEEP_CACHE: u32 = 1 << 1;
42pub const FOPEN_NONSEEKABLE: u32 = 1 << 2;
43pub const FOPEN_CACHE_DIR: u32 = 1 << 3;
44pub const FOPEN_STREAM: u32 = 1 << 4;
45pub const FOPEN_NOFLUSH: u32 = 1 << 5;
46pub const FOPEN_PARALLEL_DIRECT_WRITES: u32 = 1 << 6;
47pub const FOPEN_PASSTHROUGH: u32 = 1 << 7;
48
49// INIT request/reply flags.
50pub const FUSE_ASYNC_READ: u32 = 1;
51pub const FUSE_POSIX_LOCKS: u32 = 1 << 1;
52pub const FUSE_FILE_OPS: u32 = 1 << 2;
53pub const FUSE_ATOMIC_O_TRUNC: u32 = 1 << 3;
54pub const FUSE_EXPORT_SUPPORT: u32 = 1 << 4;
55pub const FUSE_BIG_WRITES: u32 = 1 << 5;
56pub const FUSE_DONT_MASK: u32 = 1 << 6;
57pub const FUSE_SPLICE_WRITE: u32 = 1 << 7;
58pub const FUSE_SPLICE_MOVE: u32 = 1 << 8;
59pub const FUSE_SPLICE_READ: u32 = 1 << 9;
60pub const FUSE_FLOCK_LOCKS: u32 = 1 << 10;
61pub const FUSE_HAS_IOCTL_DIR: u32 = 1 << 11;
62pub const FUSE_AUTO_INVAL_DATA: u32 = 1 << 12;
63pub const FUSE_DO_READDIRPLUS: u32 = 1 << 13;
64pub const FUSE_READDIRPLUS_AUTO: u32 = 1 << 14;
65pub const FUSE_ASYNC_DIO: u32 = 1 << 15;
66pub const FUSE_WRITEBACK_CACHE: u32 = 1 << 16;
67pub const FUSE_NO_OPEN_SUPPORT: u32 = 1 << 17;
68pub const FUSE_PARALLEL_DIROPS: u32 = 1 << 18;
69pub const FUSE_HANDLE_KILLPRIV: u32 = 1 << 19;
70pub const FUSE_POSIX_ACL: u32 = 1 << 20;
71pub const FUSE_ABORT_ERROR: u32 = 1 << 21;
72pub const FUSE_MAX_PAGES: u32 = 1 << 22;
73pub const FUSE_CACHE_SYMLINKS: u32 = 1 << 23;
74pub const FUSE_NO_OPENDIR_SUPPORT: u32 = 1 << 24;
75pub const FUSE_EXPLICIT_INVAL_DATA: u32 = 1 << 25;
76pub const FUSE_MAP_ALIGNMENT: u32 = 1 << 26;
77pub const FUSE_SUBMOUNTS: u32 = 1 << 27;
78pub const FUSE_HANDLE_KILLPRIV_V2: u32 = 1 << 28;
79pub const FUSE_SETXATTR_EXT: u32 = 1 << 29;
80pub const FUSE_INIT_EXT: u32 = 1 << 30;
81pub const FUSE_INIT_RESERVED: u32 = 1 << 31;
82// flags2.
83pub const FUSE_SECURITY_CTX: u64 = 1 << 32;
84pub const FUSE_HAS_INODE_DAX: u64 = 1 << 33;
85pub const FUSE_CREATE_SUPP_GROUP: u64 = 1 << 34;
86pub const FUSE_HAS_EXPIRE_ONLY: u64 = 1 << 35;
87pub const FUSE_DIRECT_IO_ALLOW_MMAP: u64 = 1 << 36;
88pub const FUSE_PASSTHROUGH: u64 = 1 << 37;
89pub const FUSE_NO_EXPORT_SUPPORT: u64 = 1 << 38;
90pub const FUSE_HAS_RESEND: u64 = 1 << 39;
91pub const FUSE_ALLOW_IDMAP: u64 = 1 << 40;
92pub const FUSE_OVER_IO_URING: u64 = 1 << 41;
93pub const FUSE_REQUEST_TIMEOUT: u64 = 1 << 42;
94
95// CUSE INIT request/reply flags.
96pub const CUSE_UNRESTRICTED_IOCTL: u32 = 1 << 0;
97
98// Release flags.
99pub const FUSE_RELEASE_FLUSH: u32 = 1 << 0;
100pub const FUSE_RELEASE_FLOCK_UNLOCK: u32 = 1 << 1;
101
102// Getattr flags.
103pub const FUSE_GETATTR_FH: u32 = 1;
104
105// Lock flags.
106pub const FUSE_LK_FLOCK: u32 = 1 << 0;
107
108// WRITE flags.
109pub const FUSE_WRITE_CACHE: u32 = 1 << 0;
110pub const FUSE_WRITE_LOCKOWNER: u32 = 1 << 1;
111pub const FUSE_WRITE_KILL_SUIDGID: u32 = 1 << 2;
112
113#[deprecated(since = "0.3.0", note = "use `FUSE_WRITE_KILL_SUIDGID` instead")]
114pub const FUSE_WRITE_KILL_PRIV: u32 = FUSE_WRITE_KILL_SUIDGID;
115
116// Read flags.
117pub const FUSE_READ_LOCKOWNER: u32 = 1 << 1;
118
119// Ioctl flags.
120pub const FUSE_IOCTL_COMPAT: u32 = 1 << 0;
121pub const FUSE_IOCTL_UNRESTRICTED: u32 = 1 << 1;
122pub const FUSE_IOCTL_RETRY: u32 = 1 << 2;
123pub const FUSE_IOCTL_32BIT: u32 = 1 << 3;
124pub const FUSE_IOCTL_DIR: u32 = 1 << 4;
125pub const FUSE_IOCTL_COMPAT_X32: u32 = 1 << 5;
126
127// Poll flags.
128pub const FUSE_POLL_SCHEDULE_NOTIFY: u32 = 1 << 0;
129
130// Fsync flags.
131pub const FUSE_FSYNC_FDATASYNC: u32 = 1 << 0;
132
133// Open flags.
134pub const FUSE_OPEN_KILL_SUIDGID: u32 = 1 << 0;
135
136// notify_inval_entry flags.
137pub const FUSE_EXPIRE_ONLY: u32 = 1 << 0;
138
139// misc
140pub const CUSE_INIT_INFO_MAX: u32 = 4096;
141
142// FUSE_SETUPMAPPING flags.
143pub const FUSE_SETUPMAPPING_FLAG_WRITE: u64 = 1 << 0;
144pub const FUSE_SETUPMAPPING_FLAG_READ: u64 = 1 << 1;
145
146// Setxattr flags.
147pub const FUSE_SETXATTR_ACL_KILL_SGID: u32 = 1 << 0;
148
149// Device ioctls
150pub const FUSE_DEV_IOC_MAGIC: u32 = 229;
151pub const FUSE_DEV_IOC_CLONE: c_ulong = libc::_IOR::<u32>(FUSE_DEV_IOC_MAGIC, 0);
152pub const FUSE_DEV_IOC_BACKING_OPEN: c_ulong =
153    libc::_IOW::<fuse_backing_map>(FUSE_DEV_IOC_MAGIC, 1);
154pub const FUSE_DEV_IOC_BACKING_CLOSE: c_ulong = libc::_IOW::<u32>(FUSE_DEV_IOC_MAGIC, 2);
155
156// FUSE over io_uring.
157pub const FUSE_URING_IN_OUT_HEADER_SZ: usize = 128;
158pub const FUSE_URING_OP_IN_OUT_SZ: usize = 128;
159
160// ~ ABI 7.8
161#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
162#[repr(C)]
163pub struct fuse_attr_compat_8 {
164    pub ino: u64,
165    pub size: u64,
166    pub blocks: u64,
167    pub atime: u64,
168    pub mtime: u64,
169    pub ctime: u64,
170    pub atimensec: u32,
171    pub mtimensec: u32,
172    pub ctimensec: u32,
173    pub mode: u32,
174    pub nlink: u32,
175    pub uid: u32,
176    pub gid: u32,
177    pub rdev: u32,
178}
179
180// ABI 7.9 ~
181#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
182#[repr(C)]
183pub struct fuse_attr {
184    pub ino: u64,
185    pub size: u64,
186    pub blocks: u64,
187    pub atime: u64,
188    pub mtime: u64,
189    pub ctime: u64,
190    pub atimensec: u32,
191    pub mtimensec: u32,
192    pub ctimensec: u32,
193    pub mode: u32,
194    pub nlink: u32,
195    pub uid: u32,
196    pub gid: u32,
197    pub rdev: u32,
198    pub blksize: u32,
199    pub flags: u32,
200}
201
202#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
203#[repr(C)]
204pub struct fuse_dirent {
205    pub ino: u64,
206    pub off: u64,
207    pub namelen: u32,
208    pub typ: u32,
209    pub name: [u8; 0],
210}
211
212#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
213#[repr(C)]
214pub struct fuse_direntplus {
215    pub entry_out: fuse_entry_out,
216    pub dirent: fuse_dirent,
217}
218
219#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
220#[repr(C)]
221pub struct fuse_sx_time {
222    pub tv_sec: i64,
223    pub tv_nsec: u32,
224    pub __reserved: i32,
225}
226
227#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
228#[repr(C)]
229pub struct fuse_statx {
230    pub mask: u32,
231    pub blksize: u32,
232    pub attributes: u64,
233    pub nlink: u32,
234    pub uid: u32,
235    pub gid: u32,
236    pub mode: u16,
237    pub __spare0: [u16; 1],
238    pub ino: u64,
239    pub size: u64,
240    pub blocks: u64,
241    pub attributes_mask: u64,
242    pub atime: fuse_sx_time,
243    pub btime: fuse_sx_time,
244    pub ctime: fuse_sx_time,
245    pub mtime: fuse_sx_time,
246    pub rdev_major: u32,
247    pub rdev_minor: u32,
248    pub dev_major: u32,
249    pub dev_minor: u32,
250    pub __spare2: [u64; 14],
251}
252
253// ~ ABI 7.3
254#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
255#[repr(C)]
256pub struct fuse_kstatfs_compat_3 {
257    pub blocks: u64,
258    pub bfree: u64,
259    pub bavail: u64,
260    pub files: u64,
261    pub ffree: u64,
262    pub bsize: u32,
263    pub namelen: u32,
264}
265
266// ABI 7.4 ~
267#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
268#[repr(C)]
269pub struct fuse_kstatfs {
270    pub blocks: u64,
271    pub bfree: u64,
272    pub bavail: u64,
273    pub files: u64,
274    pub ffree: u64,
275    pub bsize: u32,
276    pub namelen: u32,
277    pub frsize: u32,
278    pub padding: u32,
279    pub spare: [u32; 6usize],
280}
281
282#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
283#[repr(C)]
284pub struct fuse_file_lock {
285    pub start: u64,
286    pub end: u64,
287    pub typ: u32,
288    pub pid: u32,
289}
290
291macro_rules! define_opcode {
292    ($(
293        $(#[$m:meta])*
294        $VARIANT:ident = $val:expr,
295    )*) => {
296        $(
297            #[doc(hidden)]
298            pub const $VARIANT: u32 = $val;
299        )*
300
301        #[derive(Clone, Copy, Debug, Hash, PartialEq, TryFromBytes, IntoBytes, Immutable, KnownLayout)]
302        #[repr(u32)]
303        pub enum fuse_opcode {
304            $(
305                $(#[$m])*
306                $VARIANT = $val,
307            )*
308        }
309    };
310}
311
312define_opcode! {
313    FUSE_LOOKUP = 1,
314    FUSE_FORGET = 2,
315    FUSE_GETATTR = 3,
316    FUSE_SETATTR = 4,
317    FUSE_READLINK = 5,
318    FUSE_SYMLINK = 6,
319    // _ = 7,
320    FUSE_MKNOD = 8,
321    FUSE_MKDIR = 9,
322    FUSE_UNLINK = 10,
323    FUSE_RMDIR = 11,
324    FUSE_RENAME = 12,
325    FUSE_LINK = 13,
326    FUSE_OPEN = 14,
327    FUSE_READ = 15,
328    FUSE_WRITE = 16,
329    FUSE_STATFS = 17,
330    FUSE_RELEASE = 18,
331    // _ = 19,
332    FUSE_FSYNC = 20,
333    FUSE_SETXATTR = 21,
334    FUSE_GETXATTR = 22,
335    FUSE_LISTXATTR = 23,
336    FUSE_REMOVEXATTR = 24,
337    FUSE_FLUSH = 25,
338    FUSE_INIT = 26,
339    FUSE_OPENDIR = 27,
340    FUSE_READDIR = 28,
341    FUSE_RELEASEDIR = 29,
342    FUSE_FSYNCDIR = 30,
343    FUSE_GETLK = 31,
344    FUSE_SETLK = 32,
345    FUSE_SETLKW = 33,
346    FUSE_ACCESS = 34,
347    FUSE_CREATE = 35,
348    FUSE_INTERRUPT = 36,
349    FUSE_BMAP = 37,
350    FUSE_DESTROY = 38,
351    FUSE_IOCTL = 39,
352    FUSE_POLL = 40,
353    FUSE_NOTIFY_REPLY = 41,
354    FUSE_BATCH_FORGET = 42,
355    FUSE_FALLOCATE = 43,
356    FUSE_READDIRPLUS = 44,
357    FUSE_RENAME2 = 45,
358    FUSE_LSEEK = 46,
359    FUSE_COPY_FILE_RANGE = 47,
360    FUSE_SETUPMAPPING = 48,
361    FUSE_REMOVEMAPPING = 49,
362    FUSE_SYNCFS = 50,
363    FUSE_TMPFILE = 51,
364    FUSE_STATX = 52,
365
366    CUSE_INIT = 4096,
367}
368
369pub const CUSE_INIT_BSWAP_RESERVED: u32 = 1048576; // CUSE_INIT << 8;
370pub const FUSE_INIT_BSWAP_RESERVED: u32 = 436207616; // FUSE_INIT << 24;
371
372#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
373#[repr(C)]
374pub struct fuse_in_header {
375    pub len: u32,
376    pub opcode: u32,
377    pub unique: u64,
378    pub nodeid: u64,
379    pub uid: u32,
380    pub gid: u32,
381    pub pid: u32,
382    pub total_extlen: u16,
383    pub padding: u16,
384}
385
386#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
387#[repr(C)]
388pub struct fuse_init_in_compat_35 {
389    pub major: u32,
390    pub minor: u32,
391    pub max_readahead: u32,
392    pub flags: u32,
393}
394
395#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
396#[repr(C)]
397pub struct fuse_init_in {
398    pub major: u32,
399    pub minor: u32,
400    pub max_readahead: u32,
401    pub flags: u32,
402    pub flags2: u32,
403    pub unused: [u32; 11],
404}
405
406#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
407#[repr(C)]
408pub struct fuse_forget_in {
409    pub nlookup: u64,
410}
411
412#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
413#[repr(C)]
414pub struct fuse_getattr_in {
415    pub getattr_flags: u32,
416    pub dummy: u32,
417    pub fh: u64,
418}
419
420#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
421#[repr(C)]
422pub struct fuse_setattr_in {
423    pub valid: u32,
424    pub padding: u32,
425    pub fh: u64,
426    pub size: u64,
427    pub lock_owner: u64,
428    pub atime: u64,
429    pub mtime: u64,
430    pub ctime: u64,
431    pub atimensec: u32,
432    pub mtimensec: u32,
433    pub ctimensec: u32,
434    pub mode: u32,
435    pub unused4: u32,
436    pub uid: u32,
437    pub gid: u32,
438    pub unused5: u32,
439}
440
441// ~ ABI 7.11
442#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
443#[repr(C)]
444pub struct fuse_mknod_in_compat_11 {
445    pub mode: u32,
446    pub rdev: u32,
447}
448pub const FUSE_COMPAT_MKNOD_IN_SIZE: usize = 8;
449
450// ABI 7.12 ~
451#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
452#[repr(C)]
453pub struct fuse_mknod_in {
454    pub mode: u32,
455    pub rdev: u32,
456    pub umask: u32,
457    pub padding: u32,
458}
459
460#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
461#[repr(C)]
462pub struct fuse_mkdir_in {
463    pub mode: u32,
464    pub umask: u32,
465}
466
467#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
468#[repr(C)]
469pub struct fuse_rename_in {
470    pub newdir: u64,
471}
472
473#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
474#[repr(C)]
475pub struct fuse_link_in {
476    pub oldnodeid: u64,
477}
478
479#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
480#[repr(C)]
481pub struct fuse_open_in {
482    pub flags: u32,
483    pub open_flags: u32,
484}
485
486#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
487#[repr(C)]
488pub struct fuse_read_in {
489    pub fh: u64,
490    pub offset: u64,
491    pub size: u32,
492    pub read_flags: u32,
493    pub lock_owner: u64,
494    pub flags: u32,
495    pub padding: u32,
496}
497
498// ~ ABI 7.8
499#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
500#[repr(C)]
501pub struct fuse_write_in_compat_8 {
502    pub fh: u64,
503    pub offset: u64,
504    pub size: u32,
505    pub write_flags: u32,
506}
507pub const FUSE_COMPAT_WRITE_IN_SIZE: usize = 24;
508
509// ABI 7.9~
510#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
511#[repr(C)]
512pub struct fuse_write_in {
513    pub fh: u64,
514    pub offset: u64,
515    pub size: u32,
516    pub write_flags: u32,
517    pub lock_owner: u64,
518    pub flags: u32,
519    pub padding: u32,
520}
521
522#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
523#[repr(C)]
524pub struct fuse_flush_in {
525    pub fh: u64,
526    pub unused: u32,
527    pub padding: u32,
528    pub lock_owner: u64,
529}
530
531#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
532#[repr(C)]
533pub struct fuse_release_in {
534    pub fh: u64,
535    pub flags: u32,
536    pub release_flags: u32,
537    pub lock_owner: u64,
538}
539
540#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
541#[repr(C)]
542pub struct fuse_fsync_in {
543    pub fh: u64,
544    pub fsync_flags: u32,
545    pub padding: u32,
546}
547
548#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
549#[repr(C)]
550pub struct fuse_getxattr_in {
551    pub size: u32,
552    pub padding: u32,
553}
554
555// ~ ABI 7.32
556#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
557#[repr(C)]
558pub struct fuse_setxattr_in_compat_32 {
559    pub size: u32,
560    pub flags: u32,
561}
562
563pub const FUSE_COMPAT_SETXATTR_IN_SIZE: usize = 8;
564
565// ABI 7.33 ~
566#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
567#[repr(C)]
568pub struct fuse_setxattr_in {
569    pub size: u32,
570    pub flags: u32,
571    pub setxattr_flags: u32,
572    pub padding: u32,
573}
574
575#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
576#[repr(C)]
577pub struct fuse_lk_in {
578    pub fh: u64,
579    pub owner: u64,
580    pub lk: fuse_file_lock,
581    pub lk_flags: u32,
582    pub padding: u32,
583}
584
585#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
586#[repr(C)]
587pub struct fuse_access_in {
588    pub mask: u32,
589    pub padding: u32,
590}
591
592#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
593#[repr(C)]
594pub struct fuse_create_in {
595    pub flags: u32,
596    pub mode: u32,
597    pub umask: u32,
598    pub open_flags: u32,
599}
600
601#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
602#[repr(C)]
603pub struct fuse_bmap_in {
604    pub block: u64,
605    pub blocksize: u32,
606    pub padding: u32,
607}
608
609#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
610#[repr(C)]
611pub struct fuse_out_header {
612    pub len: u32,
613    pub error: i32,
614    pub unique: u64,
615}
616
617#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
618#[repr(C)]
619pub struct fuse_attr_out_compat_8 {
620    pub attr_valid: u64,
621    pub attr_valid_nsec: u32,
622    pub dummy: u32,
623    pub attr: fuse_attr_compat_8,
624}
625pub const FUSE_COMPAT_ATTR_OUT_SIZE: usize = 96;
626
627#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
628#[repr(C)]
629pub struct fuse_attr_out {
630    pub attr_valid: u64,
631    pub attr_valid_nsec: u32,
632    pub dummy: u32,
633    pub attr: fuse_attr,
634}
635
636#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
637#[repr(C)]
638pub struct fuse_entry_out_compat_8 {
639    pub nodeid: u64,
640    pub generation: u64,
641    pub entry_valid: u64,
642    pub attr_valid: u64,
643    pub entry_valid_nsec: u32,
644    pub attr_valid_nsec: u32,
645    pub attr: fuse_attr_compat_8,
646}
647pub const FUSE_COMPAT_ENTRY_OUT_SIZE: usize = 120;
648
649#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
650#[repr(C)]
651pub struct fuse_entry_out {
652    pub nodeid: u64,
653    pub generation: u64,
654    pub entry_valid: u64,
655    pub attr_valid: u64,
656    pub entry_valid_nsec: u32,
657    pub attr_valid_nsec: u32,
658    pub attr: fuse_attr,
659}
660
661// ~ ABI 7.3 (both fuse_init_in and fuse_init_out)
662#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
663#[repr(C)]
664pub struct fuse_init_in_out_compat_3 {
665    pub major: u32,
666    pub minor: u32,
667}
668pub const FUSE_COMPAT_INIT_OUT_SIZE: usize = 8;
669
670// ~ ABI 7.5
671#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
672#[repr(C)]
673pub struct fuse_init_out_compat_22 {
674    pub major: u32,
675    pub minor: u32,
676    pub max_readahead: u32,
677    pub flags: u32,
678    pub max_background: u16,
679    pub congestion_threshold: u16,
680    pub max_write: u32,
681}
682pub const FUSE_COMPAT_22_INIT_OUT_SIZE: usize = 24;
683
684// ABI 7.23 ~
685#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
686#[repr(C)]
687pub struct fuse_init_out {
688    pub major: u32,
689    pub minor: u32,
690    pub max_readahead: u32,
691    pub flags: u32,
692    pub max_background: u16,
693    pub congestion_threshold: u16,
694    pub max_write: u32,
695    pub time_gran: u32,
696    pub max_pages: u16,
697    pub map_alignment: u16,
698    pub flags2: u32,
699    pub max_stack_depth: u32,
700    pub request_timeout: u16,
701    pub unused: [u16; 11],
702}
703
704#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
705#[repr(C)]
706pub struct fuse_getxattr_out {
707    pub size: u32,
708    pub padding: u32,
709}
710
711#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
712#[repr(C)]
713pub struct fuse_open_out {
714    pub fh: u64,
715    pub open_flags: u32,
716    pub backing_id: i32,
717}
718
719#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
720#[repr(C)]
721pub struct fuse_write_out {
722    pub size: u32,
723    pub padding: u32,
724}
725
726// ~ ABI 7.3
727#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
728#[repr(C)]
729pub struct fuse_statfs_out_compat_3 {
730    pub st: fuse_kstatfs_compat_3,
731}
732pub const FUSE_COMPAT_STATFS_SIZE: usize = 48;
733
734// ABI 7.4 ~
735#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
736#[repr(C)]
737pub struct fuse_statfs_out {
738    pub st: fuse_kstatfs,
739}
740
741#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
742#[repr(C)]
743pub struct fuse_lk_out {
744    pub lk: fuse_file_lock,
745}
746
747#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
748#[repr(C)]
749pub struct fuse_bmap_out {
750    pub block: u64,
751}
752
753#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
754#[repr(C)]
755pub struct fuse_ioctl_in {
756    pub fh: u64,
757    pub flags: u32,
758    pub cmd: u32,
759    pub arg: u64,
760    pub in_size: u32,
761    pub out_size: u32,
762}
763
764#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
765#[repr(C)]
766pub struct fuse_ioctl_out {
767    pub result: i32,
768    pub flags: u32,
769    pub in_iovs: u32,
770    pub out_iovs: u32,
771}
772
773#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
774#[repr(C)]
775pub struct fuse_ioctl_iovec {
776    pub base: u64,
777    pub len: u64,
778}
779
780#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
781#[repr(C)]
782pub struct fuse_poll_in {
783    pub fh: u64,
784    pub kh: u64,
785    pub flags: u32,
786    pub events: u32,
787}
788
789#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
790#[repr(C)]
791pub struct fuse_poll_out {
792    pub revents: u32,
793    pub padding: u32,
794}
795
796#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
797#[repr(C)]
798pub struct fuse_interrupt_in {
799    pub unique: u64,
800}
801
802#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
803#[repr(C)]
804pub struct fuse_fallocate_in {
805    pub fh: u64,
806    pub offset: u64,
807    pub length: u64,
808    pub mode: u32,
809    pub padding: u32,
810}
811
812#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
813#[repr(C)]
814pub struct fuse_batch_forget_in {
815    pub count: u32,
816    pub dummy: u32,
817}
818
819#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
820#[repr(C)]
821pub struct fuse_forget_one {
822    pub nodeid: u64,
823    pub nlookup: u64,
824}
825
826#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
827#[repr(C)]
828pub struct fuse_rename2_in {
829    pub newdir: u64,
830    pub flags: u32,
831    pub padding: u32,
832}
833
834#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
835#[repr(C)]
836pub struct fuse_lseek_in {
837    pub fh: u64,
838    pub offset: u64,
839    pub whence: u32,
840    pub padding: u32,
841}
842
843#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
844#[repr(C)]
845pub struct fuse_lseek_out {
846    pub offset: u64,
847}
848
849#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
850#[repr(C)]
851pub struct fuse_copy_file_range_in {
852    pub fh_in: u64,
853    pub off_in: u64,
854    pub nodeid_out: u64,
855    pub fh_out: u64,
856    pub off_out: u64,
857    pub len: u64,
858    pub flags: u64,
859}
860
861macro_rules! define_notify_code {
862    ($(
863        $(#[$m:meta])*
864        $VARIANT:ident = $val:expr,
865    )*) => {
866        $(
867            #[doc(hidden)]
868            pub const $VARIANT: u32 = $val;
869        )*
870
871        #[derive(Clone, Copy, Debug, PartialEq, Hash, TryFromBytes, IntoBytes, Immutable, KnownLayout)]
872        #[repr(u32)]
873        pub enum fuse_notify_code {
874            $(
875                $(#[$m])*
876                $VARIANT = $val,
877            )*
878        }
879    };
880}
881
882define_notify_code! {
883    FUSE_NOTIFY_POLL = 1,
884    FUSE_NOTIFY_INVAL_INODE = 2,
885    FUSE_NOTIFY_INVAL_ENTRY = 3,
886    FUSE_NOTIFY_STORE = 4,
887    FUSE_NOTIFY_RETRIEVE = 5,
888    FUSE_NOTIFY_DELETE = 6,
889    FUSE_NOTIFY_RESEND = 7,
890    FUSE_NOTIFY_INC_EPOCH = 8,
891}
892
893#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
894#[repr(C)]
895pub struct fuse_notify_poll_wakeup_out {
896    pub kh: u64,
897}
898
899#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
900#[repr(C)]
901pub struct fuse_notify_inval_inode_out {
902    pub ino: u64,
903    pub off: i64,
904    pub len: i64,
905}
906
907#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
908#[repr(C)]
909pub struct fuse_notify_inval_entry_out {
910    pub parent: u64,
911    pub namelen: u32,
912    pub flags: u32,
913}
914
915#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
916#[repr(C)]
917pub struct fuse_notify_delete_out {
918    pub parent: u64,
919    pub child: u64,
920    pub namelen: u32,
921    pub padding: u32,
922}
923
924#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
925#[repr(C)]
926pub struct fuse_notify_store_out {
927    pub nodeid: u64,
928    pub offset: u64,
929    pub size: u32,
930    pub padding: u32,
931}
932
933#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
934#[repr(C)]
935pub struct fuse_notify_retrieve_out {
936    pub notify_unique: u64,
937    pub nodeid: u64,
938    pub offset: u64,
939    pub size: u32,
940    pub padding: u32,
941}
942
943#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
944#[repr(C)]
945pub struct fuse_notify_retrieve_in {
946    pub dummy1: u64,
947    pub offset: u64,
948    pub size: u32,
949    pub dummy2: u32,
950    pub dummy3: u64,
951    pub dummy4: u64,
952}
953
954#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
955#[repr(C)]
956pub struct fuse_backing_map {
957    pub fd: i32,
958    pub flags: u32,
959    pub padding: u64,
960}
961
962#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
963#[repr(C)]
964pub struct cuse_init_in {
965    pub major: u32,
966    pub minor: u32,
967    pub unused: u32,
968    pub flags: u32,
969}
970
971#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
972#[repr(C)]
973pub struct cuse_init_out {
974    pub major: u32,
975    pub minor: u32,
976    pub unused: u32,
977    pub flags: u32,
978    pub max_read: u32,
979    pub max_write: u32,
980    pub dev_major: u32,
981    pub dev_minor: u32,
982    pub spare: [u32; 10],
983}
984
985#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
986#[repr(C)]
987pub struct fuse_setupmapping_in {
988    pub fh: u64,
989    pub foffset: u64,
990    pub len: u64,
991    pub flags: u64,
992    pub moffset: u64,
993}
994
995#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
996#[repr(C)]
997pub struct fuse_removemapping_in {
998    pub count: u32,
999}
1000
1001#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1002#[repr(C)]
1003pub struct fuse_removemapping_one {
1004    pub moffset: u64,
1005    pub len: u64,
1006}
1007
1008// #define FUSE_REMOVEMAPPING_MAX_ENTRY   \
1009// 		(PAGE_SIZE / sizeof(struct fuse_removemapping_one))
1010
1011#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1012#[repr(C)]
1013pub struct fuse_syncfs_in {
1014    pub padding: u64,
1015}
1016
1017macro_rules! define_ext_type {
1018    ($(
1019        $(#[$m:meta])*
1020        $VARIANT:ident = $val:expr,
1021    )*) => {
1022        $(
1023            #[doc(hidden)]
1024            pub const $VARIANT: u32 = $val;
1025        )*
1026
1027        #[derive(Clone, Copy, Debug, PartialEq, Hash, TryFromBytes, IntoBytes, Immutable, KnownLayout)]
1028        #[repr(u32)]
1029        pub enum fuse_ext_type {
1030            $(
1031                $(#[$m])*
1032                $VARIANT = $val,
1033            )*
1034        }
1035    };
1036}
1037
1038define_ext_type! {
1039    // 0 ~ 31: reserved for fuse_secctx_header
1040    FUSE_MAX_NR_SECCTX = 31,
1041    FUSE_EXT_GROUPS = 32,
1042}
1043
1044#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1045#[repr(C)]
1046pub struct fuse_secctx {
1047    pub size: u32,
1048    pub padding: u32,
1049}
1050
1051#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1052#[repr(C)]
1053pub struct fuse_secctx_header {
1054    pub size: u32,
1055    pub nr_secctx: u32,
1056}
1057
1058#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1059#[repr(C)]
1060pub struct fuse_ext_header {
1061    pub size: u32,
1062    pub typ: u32,
1063}
1064
1065#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1066#[repr(C)]
1067pub struct fuse_supp_groups {
1068    pub nr_groups: u32,
1069    pub groups: [u32; 0],
1070}
1071
1072#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1073#[repr(C)]
1074pub struct fuse_uring_ent_in_out {
1075    pub flags: u64,
1076    pub commit_id: u64,
1077    pub payload_sz: u32,
1078    pub padding: u32,
1079    pub reserved: u64,
1080}
1081
1082#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1083#[repr(C)]
1084pub struct fuse_uring_req_header {
1085    pub in_out: [c_char; FUSE_URING_IN_OUT_HEADER_SZ],
1086    pub op_in: [c_char; FUSE_URING_OP_IN_OUT_SZ],
1087    pub ring_ent_in_out: fuse_uring_ent_in_out,
1088}
1089
1090macro_rules! define_uring_cmd {
1091    ($(
1092        $(#[$m:meta])*
1093        $VARIANT:ident = $val:expr,
1094    )*) => {
1095        $(
1096            #[doc(hidden)]
1097            pub const $VARIANT: u32 = $val;
1098        )*
1099
1100        #[derive(Clone, Copy, Debug, PartialEq, Hash, TryFromBytes, IntoBytes, Immutable, KnownLayout)]
1101        #[repr(u32)]
1102        pub enum fuse_uring_cmd {
1103            $(
1104                $(#[$m])*
1105                $VARIANT = $val,
1106            )*
1107        }
1108    };
1109}
1110
1111define_uring_cmd! {
1112    FUSE_IO_URING_CMD_INVALID = 0,
1113    FUSE_IO_URING_CMD_REGISTER = 1,
1114    FUSE_IO_URING_CMD_COMMIT_AND_FETCH = 2,
1115}
1116
1117#[derive(Clone, Copy, Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
1118#[repr(C)]
1119pub struct fuse_uring_cmd_req {
1120    pub flags: u64,
1121    pub commit_id: u64,
1122    pub qid: u16,
1123    pub padding: [u8; 6],
1124}