Skip to main content

async_fuser/ll/
fuse_abi.rs

1//! FUSE kernel interface.
2//!
3//! Types and definitions used for communication between the kernel driver and the userspace
4//! part of a FUSE filesystem. Since the kernel driver may be installed independently, the ABI
5//! interface is versioned and capabilities are exchanged during the initialization (mounting)
6//! of a filesystem.
7//!
8//! macfuse (macOS): <https://github.com/macfuse/library/blob/master/include/fuse_kernel.h>
9//! - supports ABI 7.8 in OSXFUSE 2.x
10//! - supports ABI 7.19 since OSXFUSE 3.0.0
11//!
12//! libfuse (Linux/BSD): <https://github.com/libfuse/libfuse/blob/master/include/fuse_kernel.h>
13//! - supports ABI 7.8 since FUSE 2.6.0
14//! - supports ABI 7.12 since FUSE 2.8.0
15//! - supports ABI 7.18 since FUSE 2.9.0
16//! - supports ABI 7.19 since FUSE 2.9.1
17//! - supports ABI 7.26 since FUSE 3.0.0
18//!
19//! FreeBSD kernel headers: <https://github.com/freebsd/freebsd-src/blob/main/sys/fs/fuse/fuse_kernel.h>
20//!
21//! Items without a version annotation are valid with ABI 7.8 and later
22
23#![warn(missing_debug_implementations)]
24#![allow(missing_docs)]
25
26use num_enum::TryFromPrimitive;
27use zerocopy::FromBytes;
28use zerocopy::Immutable;
29use zerocopy::IntoBytes;
30use zerocopy::KnownLayout;
31
32use crate::ll::flags::fattr_flags::FattrFlags;
33
34pub(crate) const FUSE_KERNEL_VERSION: u32 = 7;
35
36pub(crate) const FUSE_KERNEL_MINOR_VERSION: u32 = if cfg!(target_os = "macos") {
37    // macfuse headers declared the latest version as 19.
38    // In theory, it is supposed to quietly handle a newer version, but
39    // we are not sure, and it may break if the release new version.
40    // So let's declare protocol version 19 to be safe.
41    19
42} else {
43    40
44};
45
46#[repr(C)]
47#[derive(Debug, IntoBytes, Clone, Copy, KnownLayout, Immutable)]
48pub(crate) struct fuse_attr {
49    pub(crate) ino: u64,
50    pub(crate) size: u64,
51    pub(crate) blocks: u64,
52    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
53    // to match stat.st_atime
54    pub(crate) atime: i64,
55    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
56    // to match stat.st_mtime
57    pub(crate) mtime: i64,
58    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
59    // to match stat.st_ctime
60    pub(crate) ctime: i64,
61    #[cfg(target_os = "macos")]
62    pub(crate) crtime: u64,
63    pub(crate) atimensec: u32,
64    pub(crate) mtimensec: u32,
65    pub(crate) ctimensec: u32,
66    #[cfg(target_os = "macos")]
67    pub(crate) crtimensec: u32,
68    pub(crate) mode: u32,
69    pub(crate) nlink: u32,
70    pub(crate) uid: u32,
71    pub(crate) gid: u32,
72    pub(crate) rdev: u32,
73    #[cfg(target_os = "macos")]
74    pub(crate) flags: u32, // see chflags(2)
75    pub(crate) blksize: u32,
76    pub(crate) padding: u32,
77}
78
79#[repr(C)]
80#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
81pub(crate) struct fuse_kstatfs {
82    pub(crate) blocks: u64,  // Total blocks (in units of frsize)
83    pub(crate) bfree: u64,   // Free blocks
84    pub(crate) bavail: u64,  // Free blocks for unprivileged users
85    pub(crate) files: u64,   // Total inodes
86    pub(crate) ffree: u64,   // Free inodes
87    pub(crate) bsize: u32,   // Filesystem block size
88    pub(crate) namelen: u32, // Maximum filename length
89    pub(crate) frsize: u32,  // Fundamental file system block size
90    pub(crate) padding: u32,
91    pub(crate) spare: [u32; 6],
92}
93
94#[repr(C)]
95#[derive(Debug, IntoBytes, FromBytes, KnownLayout, Immutable)]
96pub(crate) struct fuse_file_lock {
97    pub(crate) start: u64,
98    pub(crate) end: u64,
99    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is treated as signed
100    pub(crate) typ: i32,
101    pub(crate) pid: u32,
102}
103
104pub mod consts {
105    // Lock flags
106    pub const FUSE_LK_FLOCK: u32 = 1 << 0;
107
108    // IOCTL constant
109    pub const FUSE_IOCTL_MAX_IOV: u32 = 256; // maximum of in_iovecs + out_iovecs
110
111    // The read buffer is required to be at least 8k, but may be much larger
112    pub const FUSE_MIN_READ_BUFFER: usize = 8192;
113}
114
115#[repr(u32)]
116#[derive(Debug, TryFromPrimitive)]
117#[allow(non_camel_case_types)]
118pub(crate) enum fuse_opcode {
119    FUSE_LOOKUP = 1,
120    FUSE_FORGET = 2, // no reply
121    FUSE_GETATTR = 3,
122    FUSE_SETATTR = 4,
123    FUSE_READLINK = 5,
124    FUSE_SYMLINK = 6,
125    FUSE_MKNOD = 8,
126    FUSE_MKDIR = 9,
127    FUSE_UNLINK = 10,
128    FUSE_RMDIR = 11,
129    FUSE_RENAME = 12,
130    FUSE_LINK = 13,
131    FUSE_OPEN = 14,
132    FUSE_READ = 15,
133    FUSE_WRITE = 16,
134    FUSE_STATFS = 17,
135    FUSE_RELEASE = 18,
136    FUSE_FSYNC = 20,
137    FUSE_SETXATTR = 21,
138    FUSE_GETXATTR = 22,
139    FUSE_LISTXATTR = 23,
140    FUSE_REMOVEXATTR = 24,
141    FUSE_FLUSH = 25,
142    FUSE_INIT = 26,
143    FUSE_OPENDIR = 27,
144    FUSE_READDIR = 28,
145    FUSE_RELEASEDIR = 29,
146    FUSE_FSYNCDIR = 30,
147    FUSE_GETLK = 31,
148    FUSE_SETLK = 32,
149    FUSE_SETLKW = 33,
150    FUSE_ACCESS = 34,
151    FUSE_CREATE = 35,
152    FUSE_INTERRUPT = 36,
153    FUSE_BMAP = 37,
154    FUSE_DESTROY = 38,
155    FUSE_IOCTL = 39,
156    FUSE_POLL = 40,
157    FUSE_NOTIFY_REPLY = 41,
158    FUSE_BATCH_FORGET = 42,
159    FUSE_FALLOCATE = 43,
160    FUSE_READDIRPLUS = 44,
161    FUSE_RENAME2 = 45,
162    FUSE_LSEEK = 46,
163    FUSE_COPY_FILE_RANGE = 47,
164
165    #[cfg(target_os = "macos")]
166    FUSE_SETVOLNAME = 61,
167    #[cfg(target_os = "macos")]
168    FUSE_GETXTIMES = 62,
169    #[cfg(target_os = "macos")]
170    FUSE_EXCHANGE = 63,
171
172    CUSE_INIT = 4096,
173}
174
175#[repr(u32)]
176#[derive(Debug, TryFromPrimitive)]
177#[allow(non_camel_case_types)]
178pub(crate) enum fuse_notify_code {
179    FUSE_POLL = 1,
180    FUSE_NOTIFY_INVAL_INODE = 2,
181    FUSE_NOTIFY_INVAL_ENTRY = 3,
182    FUSE_NOTIFY_STORE = 4,
183    FUSE_NOTIFY_RETRIEVE = 5,
184    FUSE_NOTIFY_DELETE = 6,
185}
186
187#[repr(C)]
188#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
189pub(crate) struct fuse_entry_out {
190    pub(crate) nodeid: u64,
191    pub(crate) generation: u64,
192    pub(crate) entry_valid: u64,
193    pub(crate) attr_valid: u64,
194    pub(crate) entry_valid_nsec: u32,
195    pub(crate) attr_valid_nsec: u32,
196    pub(crate) attr: fuse_attr,
197}
198
199#[repr(C)]
200#[derive(Debug, FromBytes, KnownLayout, Immutable)]
201pub(crate) struct fuse_forget_in {
202    pub(crate) nlookup: u64,
203}
204
205#[repr(C)]
206#[derive(Debug, FromBytes, KnownLayout, Immutable)]
207pub(crate) struct fuse_forget_one {
208    pub nodeid: u64,
209    pub nlookup: u64,
210}
211
212#[repr(C)]
213#[derive(Debug, FromBytes, KnownLayout, Immutable)]
214pub(crate) struct fuse_batch_forget_in {
215    pub(crate) count: u32,
216    pub(crate) dummy: u32,
217}
218
219#[repr(C)]
220#[derive(Debug, FromBytes, KnownLayout, Immutable)]
221pub(crate) struct fuse_getattr_in {
222    pub(crate) getattr_flags: u32,
223    pub(crate) dummy: u32,
224    pub(crate) fh: u64,
225}
226
227#[repr(C)]
228#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
229pub(crate) struct fuse_attr_out {
230    pub(crate) attr_valid: u64,
231    pub(crate) attr_valid_nsec: u32,
232    pub(crate) dummy: u32,
233    pub(crate) attr: fuse_attr,
234}
235
236#[cfg(target_os = "macos")]
237#[repr(C)]
238#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
239pub(crate) struct fuse_getxtimes_out {
240    pub(crate) bkuptime: u64,
241    pub(crate) crtime: u64,
242    pub(crate) bkuptimensec: u32,
243    pub(crate) crtimensec: u32,
244}
245
246#[repr(C)]
247#[derive(Debug, FromBytes, KnownLayout, Immutable)]
248pub(crate) struct fuse_mknod_in {
249    pub(crate) mode: u32,
250    pub(crate) rdev: u32,
251    pub(crate) umask: u32,
252    pub(crate) padding: u32,
253}
254
255#[repr(C)]
256#[derive(Debug, FromBytes, KnownLayout, Immutable)]
257pub(crate) struct fuse_mkdir_in {
258    pub(crate) mode: u32,
259    pub(crate) umask: u32,
260}
261
262#[repr(C)]
263#[derive(Debug, FromBytes, KnownLayout, Immutable)]
264pub(crate) struct fuse_rename_in {
265    pub(crate) newdir: u64,
266    #[cfg(feature = "macfuse-4-compat")]
267    pub(crate) flags: u32,
268    #[cfg(feature = "macfuse-4-compat")]
269    pub(crate) padding: u32,
270}
271
272#[repr(C)]
273#[derive(Debug, FromBytes, KnownLayout, Immutable)]
274pub(crate) struct fuse_rename2_in {
275    pub(crate) newdir: u64,
276    pub(crate) flags: u32,
277    pub(crate) padding: u32,
278}
279
280#[cfg(target_os = "macos")]
281#[repr(C)]
282#[derive(Debug, FromBytes, KnownLayout, Immutable)]
283pub(crate) struct fuse_exchange_in {
284    pub(crate) olddir: u64,
285    pub(crate) newdir: u64,
286    pub(crate) options: u64,
287}
288
289#[repr(C)]
290#[derive(Debug, FromBytes, KnownLayout, Immutable)]
291pub(crate) struct fuse_link_in {
292    pub(crate) oldnodeid: u64,
293}
294
295#[repr(C)]
296#[derive(Debug, FromBytes, KnownLayout, Immutable)]
297pub(crate) struct fuse_setattr_in {
298    pub(crate) valid: u32,
299    pub(crate) padding: u32,
300    pub(crate) fh: u64,
301    pub(crate) size: u64,
302    pub(crate) lock_owner: u64,
303    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
304    // to match stat.st_atime
305    pub(crate) atime: i64,
306    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
307    // to match stat.st_mtime
308    pub(crate) mtime: i64,
309    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
310    // to match stat.st_ctime
311    pub(crate) ctime: i64, // Used since ABI 7.23.
312    pub(crate) atimensec: u32,
313    pub(crate) mtimensec: u32,
314    pub(crate) ctimensec: u32, // Used since ABI 7.23.
315    pub(crate) mode: u32,
316    pub(crate) unused4: u32,
317    pub(crate) uid: u32,
318    pub(crate) gid: u32,
319    pub(crate) unused5: u32,
320    #[cfg(target_os = "macos")]
321    pub(crate) bkuptime: u64,
322    #[cfg(target_os = "macos")]
323    pub(crate) chgtime: u64,
324    #[cfg(target_os = "macos")]
325    pub(crate) crtime: u64,
326    #[cfg(target_os = "macos")]
327    pub(crate) bkuptimensec: u32,
328    #[cfg(target_os = "macos")]
329    pub(crate) chgtimensec: u32,
330    #[cfg(target_os = "macos")]
331    pub(crate) crtimensec: u32,
332    #[cfg(target_os = "macos")]
333    pub(crate) flags: u32, // see chflags(2)
334}
335
336impl fuse_setattr_in {
337    pub(crate) fn atime_now(&self) -> bool {
338        FattrFlags::from_bits_retain(self.valid).contains(FattrFlags::FATTR_ATIME_NOW)
339    }
340
341    pub(crate) fn mtime_now(&self) -> bool {
342        FattrFlags::from_bits_retain(self.valid).contains(FattrFlags::FATTR_MTIME_NOW)
343    }
344}
345
346#[repr(C)]
347#[derive(Debug, FromBytes, KnownLayout, Immutable)]
348pub(crate) struct fuse_open_in {
349    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
350    // to an i32 when invoking the filesystem's open method and this matches the open() syscall
351    pub(crate) flags: i32,
352    pub(crate) unused: u32,
353}
354
355#[repr(C)]
356#[derive(Debug, FromBytes, KnownLayout, Immutable)]
357pub(crate) struct fuse_create_in {
358    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
359    // to an i32 when invoking the filesystem's create method and this matches the open() syscall
360    pub(crate) flags: i32,
361    pub(crate) mode: u32,
362    pub(crate) umask: u32,
363    pub(crate) padding: u32,
364}
365
366#[repr(C)]
367#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
368pub(crate) struct fuse_create_out(pub(crate) fuse_entry_out, pub(crate) fuse_open_out);
369
370#[repr(C)]
371#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
372pub(crate) struct fuse_open_out {
373    pub(crate) fh: u64,
374    pub(crate) open_flags: u32,
375    pub(crate) backing_id: u32, // Used since ABI 7.40.
376}
377
378#[repr(C)]
379#[derive(Debug, FromBytes, KnownLayout, Immutable)]
380pub(crate) struct fuse_release_in {
381    pub(crate) fh: u64,
382    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
383    // to an i32 when invoking the filesystem's read method
384    pub(crate) flags: i32,
385    pub(crate) release_flags: u32,
386    pub(crate) lock_owner: u64,
387}
388
389#[repr(C)]
390#[derive(Debug, FromBytes, KnownLayout, Immutable)]
391pub(crate) struct fuse_flush_in {
392    pub(crate) fh: u64,
393    pub(crate) unused: u32,
394    pub(crate) padding: u32,
395    pub(crate) lock_owner: u64,
396}
397
398#[repr(C)]
399#[derive(Debug, FromBytes, KnownLayout, Immutable)]
400pub(crate) struct fuse_read_in {
401    pub(crate) fh: u64,
402    pub(crate) offset: u64,
403    pub(crate) size: u32,
404    pub(crate) read_flags: u32,
405    pub(crate) lock_owner: u64,
406    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
407    // to an i32 when invoking the filesystem's read method
408    pub(crate) flags: i32,
409    pub(crate) padding: u32,
410}
411
412#[repr(C)]
413#[derive(Debug, FromBytes, KnownLayout, Immutable)]
414pub(crate) struct fuse_write_in {
415    pub(crate) fh: u64,
416    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is then cast
417    // to an i64 when invoking the filesystem's write method
418    pub(crate) offset: i64,
419    pub(crate) size: u32,
420    pub(crate) write_flags: u32,
421    pub(crate) lock_owner: u64,
422    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
423    // to an i32 when invoking the filesystem's read method
424    pub(crate) flags: i32,
425    pub(crate) padding: u32,
426}
427
428#[repr(C)]
429#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
430pub(crate) struct fuse_write_out {
431    pub(crate) size: u32,
432    pub(crate) padding: u32,
433}
434
435#[repr(C)]
436#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
437pub(crate) struct fuse_statfs_out {
438    pub(crate) st: fuse_kstatfs,
439}
440
441#[repr(C)]
442#[derive(Debug, FromBytes, KnownLayout, Immutable)]
443pub(crate) struct fuse_fsync_in {
444    pub(crate) fh: u64,
445    pub(crate) fsync_flags: u32,
446    pub(crate) padding: u32,
447}
448
449#[repr(C)]
450#[derive(Debug, FromBytes, KnownLayout, Immutable)]
451pub(crate) struct fuse_setxattr_in {
452    pub(crate) size: u32,
453    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
454    // to an i32 when invoking the filesystem's setxattr method
455    pub(crate) flags: i32,
456    #[cfg(target_os = "macos")]
457    pub(crate) position: u32,
458    #[cfg(target_os = "macos")]
459    pub(crate) padding: u32,
460}
461
462#[repr(C)]
463#[derive(Debug, FromBytes, KnownLayout, Immutable)]
464pub(crate) struct fuse_getxattr_in {
465    pub(crate) size: u32,
466    pub(crate) padding: u32,
467    #[cfg(target_os = "macos")]
468    pub(crate) position: u32,
469    #[cfg(target_os = "macos")]
470    pub(crate) padding2: u32,
471}
472
473#[repr(C)]
474#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
475pub(crate) struct fuse_getxattr_out {
476    pub(crate) size: u32,
477    pub(crate) padding: u32,
478}
479
480#[repr(C)]
481#[derive(Debug, FromBytes, KnownLayout, Immutable)]
482pub(crate) struct fuse_lk_in {
483    pub(crate) fh: u64,
484    pub(crate) owner: u64,
485    pub(crate) lk: fuse_file_lock,
486    pub(crate) lk_flags: u32,
487    pub(crate) padding: u32,
488}
489
490#[repr(C)]
491#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
492pub(crate) struct fuse_lk_out {
493    pub(crate) lk: fuse_file_lock,
494}
495
496#[repr(C)]
497#[derive(Debug, FromBytes, KnownLayout, Immutable)]
498pub(crate) struct fuse_access_in {
499    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is then cast
500    // to an i32 when invoking the filesystem's access method
501    pub(crate) mask: i32,
502    pub(crate) padding: u32,
503}
504
505#[repr(C)]
506#[derive(Debug, FromBytes, KnownLayout, Immutable, IntoBytes)]
507pub(crate) struct fuse_init_in {
508    pub(crate) major: u32,
509    pub(crate) minor: u32,
510    pub(crate) max_readahead: u32,
511    pub(crate) flags: u32,
512    pub(crate) flags2: u32,
513    pub(crate) unused: [u32; 11],
514}
515
516pub(crate) const FUSE_COMPAT_INIT_OUT_SIZE: usize = 8;
517pub(crate) const FUSE_COMPAT_22_INIT_OUT_SIZE: usize = 24;
518
519#[repr(C)]
520#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
521pub(crate) struct fuse_init_out {
522    pub(crate) major: u32,
523    pub(crate) minor: u32,
524    pub(crate) max_readahead: u32,
525    pub(crate) flags: u32,
526    pub(crate) max_background: u16,
527    pub(crate) congestion_threshold: u16,
528    pub(crate) max_write: u32,
529    pub(crate) time_gran: u32,
530    pub(crate) max_pages: u16,
531    pub(crate) unused2: u16,
532    pub(crate) flags2: u32,
533    pub(crate) max_stack_depth: u32,
534    pub(crate) reserved: [u32; 6],
535}
536
537#[repr(C)]
538#[derive(Debug, FromBytes, KnownLayout, Immutable)]
539pub(crate) struct cuse_init_in {
540    pub(crate) major: u32,
541    pub(crate) minor: u32,
542    pub(crate) unused: u32,
543    pub(crate) flags: u32,
544}
545
546#[repr(C)]
547#[derive(Debug, KnownLayout, Immutable)]
548pub(crate) struct cuse_init_out {
549    pub(crate) major: u32,
550    pub(crate) minor: u32,
551    pub(crate) unused: u32,
552    pub(crate) flags: u32,
553    pub(crate) max_read: u32,
554    pub(crate) max_write: u32,
555    pub(crate) dev_major: u32, // chardev major
556    pub(crate) dev_minor: u32, // chardev minor
557    pub(crate) spare: [u32; 10],
558}
559
560#[repr(C)]
561#[derive(Debug, FromBytes, KnownLayout, Immutable)]
562pub(crate) struct fuse_interrupt_in {
563    pub(crate) unique: u64,
564}
565
566#[repr(C)]
567#[derive(Debug, FromBytes, KnownLayout, Immutable)]
568pub(crate) struct fuse_bmap_in {
569    pub(crate) block: u64,
570    pub(crate) blocksize: u32,
571    pub(crate) padding: u32,
572}
573
574#[repr(C)]
575#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
576pub(crate) struct fuse_bmap_out {
577    pub(crate) block: u64,
578}
579
580#[repr(C)]
581#[derive(Debug, FromBytes, KnownLayout, Immutable)]
582pub(crate) struct fuse_ioctl_in {
583    pub(crate) fh: u64,
584    pub(crate) flags: u32,
585    pub(crate) cmd: u32,
586    pub(crate) arg: u64,
587    pub(crate) in_size: u32,
588    pub(crate) out_size: u32,
589}
590
591#[repr(C)]
592#[derive(Debug, KnownLayout, Immutable)]
593pub(crate) struct fuse_ioctl_iovec {
594    pub(crate) base: u64,
595    pub(crate) len: u64,
596}
597
598#[repr(C)]
599#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
600pub(crate) struct fuse_ioctl_out {
601    pub(crate) result: i32,
602    pub(crate) flags: u32,
603    pub(crate) in_iovs: u32,
604    pub(crate) out_iovs: u32,
605}
606
607#[repr(C)]
608#[derive(Debug, FromBytes, KnownLayout, Immutable)]
609pub(crate) struct fuse_poll_in {
610    pub(crate) fh: u64,
611    pub(crate) kh: u64,
612    pub(crate) flags: u32,
613    pub(crate) events: u32, // Used since ABI 7.21.
614}
615
616#[repr(C)]
617#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
618pub(crate) struct fuse_poll_out {
619    pub(crate) revents: u32,
620    pub(crate) padding: u32,
621}
622
623#[repr(C)]
624#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
625pub(crate) struct fuse_notify_poll_wakeup_out {
626    pub(crate) kh: u64,
627}
628
629#[repr(C)]
630#[derive(Debug, FromBytes, KnownLayout, Immutable)]
631pub(crate) struct fuse_fallocate_in {
632    pub(crate) fh: u64,
633    pub(crate) offset: u64,
634    pub(crate) length: u64,
635    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is treated as signed
636    pub(crate) mode: i32,
637    pub(crate) padding: u32,
638}
639
640#[repr(C)]
641#[derive(Debug, FromBytes, KnownLayout, Immutable)]
642pub(crate) struct fuse_in_header {
643    pub(crate) len: u32,
644    pub(crate) opcode: u32,
645    pub(crate) unique: u64,
646    pub(crate) nodeid: u64,
647    pub(crate) uid: u32,
648    pub(crate) gid: u32,
649    pub(crate) pid: u32,
650    pub(crate) padding: u32,
651}
652
653#[repr(C)]
654#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
655pub(crate) struct fuse_out_header {
656    pub(crate) len: u32,
657    pub(crate) error: i32,
658    pub(crate) unique: u64,
659}
660
661#[repr(C)]
662#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
663pub(crate) struct fuse_dirent {
664    pub(crate) ino: u64,
665    pub(crate) off: u64,
666    pub(crate) namelen: u32,
667    pub(crate) typ: u32,
668    // followed by name of namelen bytes
669}
670
671#[repr(C)]
672#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
673pub(crate) struct fuse_direntplus {
674    pub(crate) entry_out: fuse_entry_out,
675    pub(crate) dirent: fuse_dirent,
676}
677
678#[repr(C)]
679#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
680pub(crate) struct fuse_notify_inval_inode_out {
681    pub(crate) ino: u64,
682    pub(crate) off: i64,
683    pub(crate) len: i64,
684}
685
686#[repr(C)]
687#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
688pub(crate) struct fuse_notify_inval_entry_out {
689    pub(crate) parent: u64,
690    pub(crate) namelen: u32,
691    pub(crate) padding: u32,
692}
693
694#[repr(C)]
695#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
696pub(crate) struct fuse_notify_delete_out {
697    pub(crate) parent: u64,
698    pub(crate) child: u64,
699    pub(crate) namelen: u32,
700    pub(crate) padding: u32,
701}
702
703#[repr(C)]
704#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
705pub(crate) struct fuse_notify_store_out {
706    pub(crate) nodeid: u64,
707    pub(crate) offset: u64,
708    pub(crate) size: u32,
709    pub(crate) padding: u32,
710}
711
712#[repr(C)]
713#[derive(Debug, KnownLayout, Immutable)]
714pub(crate) struct fuse_notify_retrieve_out {
715    pub(crate) notify_unique: u64,
716    pub(crate) nodeid: u64,
717    pub(crate) offset: u64,
718    pub(crate) size: u32,
719    pub(crate) padding: u32,
720}
721
722#[repr(C)]
723#[derive(Debug, FromBytes, KnownLayout, Immutable)]
724pub(crate) struct fuse_notify_retrieve_in {
725    // matches the size of fuse_write_in
726    pub(crate) dummy1: u64,
727    pub(crate) offset: u64,
728    pub(crate) size: u32,
729    pub(crate) dummy2: u32,
730    pub(crate) dummy3: u64,
731    pub(crate) dummy4: u64,
732}
733
734#[repr(C)]
735#[derive(Debug, FromBytes, KnownLayout, Immutable)]
736pub(crate) struct fuse_lseek_in {
737    pub(crate) fh: u64,
738    pub(crate) offset: i64,
739    // NOTE: this field is defined as u32 in fuse_kernel.h in libfuse. However, it is treated as signed
740    pub(crate) whence: i32,
741    pub(crate) padding: u32,
742}
743
744#[repr(C)]
745#[derive(Debug, IntoBytes, KnownLayout, Immutable)]
746pub(crate) struct fuse_lseek_out {
747    pub(crate) offset: i64,
748}
749
750#[repr(C)]
751#[derive(Debug, FromBytes, KnownLayout, Immutable)]
752pub(crate) struct fuse_copy_file_range_in {
753    pub(crate) fh_in: u64,
754    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
755    pub(crate) off_in: i64,
756    pub(crate) nodeid_out: u64,
757    pub(crate) fh_out: u64,
758    // NOTE: this field is defined as u64 in fuse_kernel.h in libfuse. However, it is treated as signed
759    pub(crate) off_out: i64,
760    pub(crate) len: u64,
761    pub(crate) flags: u64,
762}