1#![allow(
10 clippy::cast_sign_loss,
11 clippy::cast_possible_wrap,
12 clippy::cast_possible_truncation
13)]
14
15use std::mem::size_of;
16
17pub const FUSE_KERNEL_VERSION: u32 = 7;
23
24pub const FUSE_KERNEL_MINOR_VERSION: u32 = 38;
26
27pub const FUSE_ROOT_ID: u64 = 1;
29
30pub const FUSE_ASYNC_READ: u32 = 1 << 0;
32pub const FUSE_POSIX_LOCKS: u32 = 1 << 1;
33pub const FUSE_FILE_OPS: u32 = 1 << 2;
34pub const FUSE_ATOMIC_O_TRUNC: u32 = 1 << 3;
35pub const FUSE_EXPORT_SUPPORT: u32 = 1 << 4;
36pub const FUSE_BIG_WRITES: u32 = 1 << 5;
37pub const FUSE_DONT_MASK: u32 = 1 << 6;
38pub const FUSE_SPLICE_WRITE: u32 = 1 << 7;
39pub const FUSE_SPLICE_MOVE: u32 = 1 << 8;
40pub const FUSE_SPLICE_READ: u32 = 1 << 9;
41pub const FUSE_FLOCK_LOCKS: u32 = 1 << 10;
42pub const FUSE_HAS_IOCTL_DIR: u32 = 1 << 11;
43pub const FUSE_AUTO_INVAL_DATA: u32 = 1 << 12;
44pub const FUSE_DO_READDIRPLUS: u32 = 1 << 13;
45pub const FUSE_READDIRPLUS_AUTO: u32 = 1 << 14;
46pub const FUSE_ASYNC_DIO: u32 = 1 << 15;
47pub const FUSE_WRITEBACK_CACHE: u32 = 1 << 16;
48pub const FUSE_NO_OPEN_SUPPORT: u32 = 1 << 17;
49pub const FUSE_PARALLEL_DIROPS: u32 = 1 << 18;
50pub const FUSE_HANDLE_KILLPRIV: u32 = 1 << 19;
51pub const FUSE_POSIX_ACL: u32 = 1 << 20;
52pub const FUSE_ABORT_ERROR: u32 = 1 << 21;
53pub const FUSE_MAX_PAGES: u32 = 1 << 22;
54pub const FUSE_CACHE_SYMLINKS: u32 = 1 << 23;
55pub const FUSE_NO_OPENDIR_SUPPORT: u32 = 1 << 24;
56pub const FUSE_EXPLICIT_INVAL_DATA: u32 = 1 << 25;
57pub const FUSE_MAP_ALIGNMENT: u32 = 1 << 26;
59
60pub const FUSE_NO_FH: u64 = u64::MAX;
68
69pub const FUSE_SETUPMAPPING_FLAG_WRITE: u64 = 1 << 0;
71pub const FUSE_SETUPMAPPING_FLAG_READ: u64 = 1 << 1;
72
73pub const FATTR_MODE: u32 = 1 << 0;
75pub const FATTR_UID: u32 = 1 << 1;
76pub const FATTR_GID: u32 = 1 << 2;
77pub const FATTR_SIZE: u32 = 1 << 3;
78pub const FATTR_ATIME: u32 = 1 << 4;
79pub const FATTR_MTIME: u32 = 1 << 5;
80pub const FATTR_FH: u32 = 1 << 6;
81pub const FATTR_ATIME_NOW: u32 = 1 << 7;
82pub const FATTR_MTIME_NOW: u32 = 1 << 8;
83pub const FATTR_LOCKOWNER: u32 = 1 << 9;
84pub const FATTR_CTIME: u32 = 1 << 10;
85
86pub const FOPEN_DIRECT_IO: u32 = 1 << 0;
88pub const FOPEN_KEEP_CACHE: u32 = 1 << 1;
89pub const FOPEN_NONSEEKABLE: u32 = 1 << 2;
90pub const FOPEN_CACHE_DIR: u32 = 1 << 3;
91pub const FOPEN_STREAM: u32 = 1 << 4;
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99#[repr(u32)]
100pub enum FuseOpcode {
101 Lookup = 1,
102 Forget = 2,
103 Getattr = 3,
104 Setattr = 4,
105 Readlink = 5,
106 Symlink = 6,
107 Mknod = 8,
108 Mkdir = 9,
109 Unlink = 10,
110 Rmdir = 11,
111 Rename = 12,
112 Link = 13,
113 Open = 14,
114 Read = 15,
115 Write = 16,
116 Statfs = 17,
117 Release = 18,
118 Fsync = 20,
119 Setxattr = 21,
120 Getxattr = 22,
121 Listxattr = 23,
122 Removexattr = 24,
123 Flush = 25,
124 Init = 26,
125 Opendir = 27,
126 Readdir = 28,
127 Releasedir = 29,
128 Fsyncdir = 30,
129 Getlk = 31,
130 Setlk = 32,
131 Setlkw = 33,
132 Access = 34,
133 Create = 35,
134 Interrupt = 36,
135 Bmap = 37,
136 Destroy = 38,
137 Ioctl = 39,
138 Poll = 40,
139 NotifyReply = 41,
140 BatchForget = 42,
141 Fallocate = 43,
142 Readdirplus = 44,
143 Rename2 = 45,
144 Lseek = 46,
145 CopyFileRange = 47,
146 SetupMapping = 48,
147 RemoveMapping = 49,
148}
149
150#[derive(Debug, Clone, Copy)]
152#[repr(C)]
153pub struct FuseInHeader {
154 pub len: u32,
156 pub opcode: u32,
158 pub unique: u64,
160 pub nodeid: u64,
162 pub uid: u32,
164 pub gid: u32,
166 pub pid: u32,
168 pub padding: u32,
170}
171
172#[derive(Debug, Clone, Copy)]
174#[repr(C)]
175pub struct FuseOutHeader {
176 pub len: u32,
178 pub error: i32,
180 pub unique: u64,
182}
183
184#[derive(Debug, Clone, Copy, Default)]
186#[repr(C)]
187pub struct FuseAttr {
188 pub ino: u64,
189 pub size: u64,
190 pub blocks: u64,
191 pub atime: u64,
192 pub mtime: u64,
193 pub ctime: u64,
194 pub atimensec: u32,
195 pub mtimensec: u32,
196 pub ctimensec: u32,
197 pub mode: u32,
198 pub nlink: u32,
199 pub uid: u32,
200 pub gid: u32,
201 pub rdev: u32,
202 pub blksize: u32,
203 pub padding: u32,
204}
205
206#[derive(Debug, Clone, Copy, Default)]
208#[repr(C)]
209pub struct StatFs {
210 pub blocks: u64,
212 pub bfree: u64,
214 pub bavail: u64,
216 pub files: u64,
218 pub ffree: u64,
220 pub bsize: u32,
222 pub namelen: u32,
224 pub frsize: u32,
226}
227
228#[derive(Debug, Clone, Copy)]
234#[repr(C)]
235pub struct FuseInitIn {
236 pub major: u32,
238 pub minor: u32,
240 pub max_readahead: u32,
242 pub flags: u32,
244}
245
246#[derive(Debug, Clone, Copy)]
248#[repr(C)]
249pub struct FuseGetattrIn {
250 pub getattr_flags: u32,
252 pub dummy: u32,
254 pub fh: u64,
256}
257
258#[derive(Debug, Clone, Copy)]
260#[repr(C)]
261pub struct FuseSetattrIn {
262 pub valid: u32,
264 pub padding: u32,
266 pub fh: u64,
268 pub size: u64,
270 pub lock_owner: u64,
272 pub atime: u64,
274 pub mtime: u64,
276 pub ctime: u64,
278 pub atimensec: u32,
280 pub mtimensec: u32,
282 pub ctimensec: u32,
284 pub mode: u32,
286 pub unused4: u32,
288 pub uid: u32,
290 pub gid: u32,
292 pub unused5: u32,
294}
295
296#[derive(Debug, Clone, Copy)]
298#[repr(C)]
299pub struct FuseMknodIn {
300 pub mode: u32,
302 pub rdev: u32,
304 pub umask: u32,
306 pub padding: u32,
308}
309
310#[derive(Debug, Clone, Copy)]
312#[repr(C)]
313pub struct FuseMkdirIn {
314 pub mode: u32,
316 pub umask: u32,
318}
319
320#[derive(Debug, Clone, Copy)]
322#[repr(C)]
323pub struct FuseRenameIn {
324 pub newdir: u64,
326}
327
328#[derive(Debug, Clone, Copy)]
330#[repr(C)]
331pub struct FuseRename2In {
332 pub newdir: u64,
334 pub flags: u32,
336 pub padding: u32,
338}
339
340#[derive(Debug, Clone, Copy)]
342#[repr(C)]
343pub struct FuseLinkIn {
344 pub oldnodeid: u64,
346}
347
348#[derive(Debug, Clone, Copy)]
350#[repr(C)]
351pub struct FuseOpenIn {
352 pub flags: u32,
354 pub unused: u32,
356}
357
358#[derive(Debug, Clone, Copy)]
360#[repr(C)]
361pub struct FuseCreateIn {
362 pub flags: u32,
364 pub mode: u32,
366 pub umask: u32,
368 pub padding: u32,
370}
371
372#[derive(Debug, Clone, Copy)]
374#[repr(C)]
375pub struct FuseReadIn {
376 pub fh: u64,
378 pub offset: u64,
380 pub size: u32,
382 pub read_flags: u32,
384 pub lock_owner: u64,
386 pub flags: u32,
388 pub padding: u32,
390}
391
392#[derive(Debug, Clone, Copy)]
394#[repr(C)]
395pub struct FuseWriteIn {
396 pub fh: u64,
398 pub offset: u64,
400 pub size: u32,
402 pub write_flags: u32,
404 pub lock_owner: u64,
406 pub flags: u32,
408 pub padding: u32,
410}
411
412#[derive(Debug, Clone, Copy)]
414#[repr(C)]
415pub struct FuseReleaseIn {
416 pub fh: u64,
418 pub flags: u32,
420 pub release_flags: u32,
422 pub lock_owner: u64,
424}
425
426#[derive(Debug, Clone, Copy)]
428#[repr(C)]
429pub struct FuseFlushIn {
430 pub fh: u64,
432 pub unused: u32,
434 pub padding: u32,
436 pub lock_owner: u64,
438}
439
440#[derive(Debug, Clone, Copy)]
442#[repr(C)]
443pub struct FuseFsyncIn {
444 pub fh: u64,
446 pub fsync_flags: u32,
448 pub padding: u32,
450}
451
452#[derive(Debug, Clone, Copy)]
454#[repr(C)]
455pub struct FuseSetxattrIn {
456 pub size: u32,
458 pub flags: u32,
460}
461
462#[derive(Debug, Clone, Copy)]
464#[repr(C)]
465pub struct FuseGetxattrIn {
466 pub size: u32,
468 pub padding: u32,
470}
471
472#[derive(Debug, Clone, Copy)]
474#[repr(C)]
475pub struct FuseAccessIn {
476 pub mask: u32,
478 pub padding: u32,
480}
481
482#[derive(Debug, Clone, Copy)]
484#[repr(C)]
485pub struct FuseLseekIn {
486 pub fh: u64,
488 pub offset: u64,
490 pub whence: u32,
492 pub padding: u32,
494}
495
496#[derive(Debug, Clone, Copy)]
498#[repr(C)]
499pub struct FuseFallocateIn {
500 pub fh: u64,
502 pub offset: u64,
504 pub length: u64,
506 pub mode: u32,
508 pub padding: u32,
510}
511
512#[derive(Debug, Clone, Copy)]
514#[repr(C)]
515pub struct FuseForgetIn {
516 pub nlookup: u64,
518}
519
520#[derive(Debug, Clone, Copy)]
522#[repr(C)]
523pub struct FuseForgetOne {
524 pub nodeid: u64,
526 pub nlookup: u64,
528}
529
530#[derive(Debug, Clone, Copy)]
532#[repr(C)]
533pub struct FuseBatchForgetIn {
534 pub count: u32,
536 pub dummy: u32,
538}
539
540#[derive(Debug, Clone, Copy)]
542#[repr(C)]
543pub struct FuseSetupMappingIn {
544 pub fh: u64,
546 pub foffset: u64,
548 pub len: u64,
550 pub flags: u64,
552 pub moffset: u64,
554}
555
556#[derive(Debug, Clone, Copy)]
558#[repr(C)]
559pub struct FuseRemoveMappingIn {
560 pub count: u32,
562 pub dummy: u32,
563}
564
565#[derive(Debug, Clone, Copy)]
567#[repr(C)]
568pub struct FuseRemoveMappingOne {
569 pub moffset: u64,
571 pub len: u64,
573}
574
575#[derive(Debug, Clone, Copy)]
581#[repr(C)]
582pub struct FuseInitOut {
583 pub major: u32,
585 pub minor: u32,
587 pub max_readahead: u32,
589 pub flags: u32,
591 pub max_background: u16,
593 pub congestion_threshold: u16,
595 pub max_write: u32,
597 pub time_gran: u32,
599 pub max_pages: u16,
601 pub map_alignment: u16,
606 pub flags2: u32,
609 pub unused: [u32; 7],
611}
612
613impl Default for FuseInitOut {
614 fn default() -> Self {
615 Self {
616 major: FUSE_KERNEL_VERSION,
617 minor: FUSE_KERNEL_MINOR_VERSION,
618 max_readahead: 128 * 1024,
619 flags: FUSE_ASYNC_READ | FUSE_BIG_WRITES | FUSE_WRITEBACK_CACHE,
620 max_background: 16,
621 congestion_threshold: 12,
622 max_write: 128 * 1024,
623 time_gran: 1,
624 max_pages: 32,
625 map_alignment: 0,
626 flags2: 0,
627 unused: [0; 7],
628 }
629 }
630}
631
632const _: () = assert!(std::mem::size_of::<FuseInitOut>() == 64);
635
636#[derive(Debug, Clone, Copy, Default)]
638#[repr(C)]
639pub struct FuseEntryOut {
640 pub nodeid: u64,
642 pub generation: u64,
644 pub entry_valid: u64,
646 pub attr_valid: u64,
648 pub entry_valid_nsec: u32,
650 pub attr_valid_nsec: u32,
652 pub attr: FuseAttr,
654}
655
656#[derive(Debug, Clone, Copy, Default)]
658#[repr(C)]
659pub struct FuseAttrOut {
660 pub attr_valid: u64,
662 pub attr_valid_nsec: u32,
664 pub dummy: u32,
666 pub attr: FuseAttr,
668}
669
670#[derive(Debug, Clone, Copy, Default)]
672#[repr(C)]
673pub struct FuseOpenOut {
674 pub fh: u64,
676 pub open_flags: u32,
678 pub padding: u32,
680}
681
682#[derive(Debug, Clone, Copy, Default)]
684#[repr(C)]
685pub struct FuseWriteOut {
686 pub size: u32,
688 pub padding: u32,
690}
691
692#[derive(Debug, Clone, Copy, Default)]
694#[repr(C)]
695pub struct FuseGetxattrOut {
696 pub size: u32,
698 pub padding: u32,
700}
701
702#[derive(Debug, Clone, Copy, Default)]
704#[repr(C)]
705pub struct FuseStatfsOut {
706 pub st: StatFs,
708}
709
710#[derive(Debug, Clone, Copy, Default)]
712#[repr(C)]
713pub struct FuseLseekOut {
714 pub offset: u64,
716}
717
718#[derive(Debug, Clone, Copy)]
720#[repr(C)]
721pub struct FuseDirent {
722 pub ino: u64,
724 pub off: u64,
726 pub namelen: u32,
728 pub typ: u32,
730 }
732
733impl FuseDirent {
734 #[must_use]
736 pub const fn size(namelen: usize) -> usize {
737 let base = size_of::<Self>() + namelen;
739 (base + 7) & !7
740 }
741}
742
743impl FuseOpcode {
748 #[must_use]
750 pub fn from_u32(value: u32) -> Option<Self> {
751 match value {
752 1 => Some(Self::Lookup),
753 2 => Some(Self::Forget),
754 3 => Some(Self::Getattr),
755 4 => Some(Self::Setattr),
756 5 => Some(Self::Readlink),
757 6 => Some(Self::Symlink),
758 8 => Some(Self::Mknod),
759 9 => Some(Self::Mkdir),
760 10 => Some(Self::Unlink),
761 11 => Some(Self::Rmdir),
762 12 => Some(Self::Rename),
763 13 => Some(Self::Link),
764 14 => Some(Self::Open),
765 15 => Some(Self::Read),
766 16 => Some(Self::Write),
767 17 => Some(Self::Statfs),
768 18 => Some(Self::Release),
769 20 => Some(Self::Fsync),
770 21 => Some(Self::Setxattr),
771 22 => Some(Self::Getxattr),
772 23 => Some(Self::Listxattr),
773 24 => Some(Self::Removexattr),
774 25 => Some(Self::Flush),
775 26 => Some(Self::Init),
776 27 => Some(Self::Opendir),
777 28 => Some(Self::Readdir),
778 29 => Some(Self::Releasedir),
779 30 => Some(Self::Fsyncdir),
780 31 => Some(Self::Getlk),
781 32 => Some(Self::Setlk),
782 33 => Some(Self::Setlkw),
783 34 => Some(Self::Access),
784 35 => Some(Self::Create),
785 36 => Some(Self::Interrupt),
786 37 => Some(Self::Bmap),
787 38 => Some(Self::Destroy),
788 39 => Some(Self::Ioctl),
789 40 => Some(Self::Poll),
790 41 => Some(Self::NotifyReply),
791 42 => Some(Self::BatchForget),
792 43 => Some(Self::Fallocate),
793 44 => Some(Self::Readdirplus),
794 45 => Some(Self::Rename2),
795 46 => Some(Self::Lseek),
796 47 => Some(Self::CopyFileRange),
797 48 => Some(Self::SetupMapping),
798 49 => Some(Self::RemoveMapping),
799 _ => None,
800 }
801 }
802}
803
804impl FuseInHeader {
809 pub const SIZE: usize = size_of::<Self>();
811}
812
813impl FuseOutHeader {
814 pub const SIZE: usize = size_of::<Self>();
816
817 #[must_use]
819 pub const fn success(unique: u64, len: u32) -> Self {
820 Self {
821 len,
822 error: 0,
823 unique,
824 }
825 }
826
827 #[must_use]
829 pub const fn error(unique: u64, errno: i32) -> Self {
830 Self {
831 len: Self::SIZE as u32,
832 error: -errno,
833 unique,
834 }
835 }
836}