1#![allow(missing_docs)]
8
9use std::fmt::{Debug, Formatter};
10use std::mem;
11
12use bitflags::bitflags;
13use vm_memory::ByteValued;
14
15pub use libc::{
16 blksize_t, dev_t, ino64_t, mode_t, nlink_t, off64_t, pread64, preadv64, pwrite64, pwritev64,
17 stat64, statvfs64,
18};
19
20pub const KERNEL_VERSION: u32 = 7;
22
23pub const KERNEL_MINOR_VERSION: u32 = 33;
25
26pub const KERNEL_MINOR_VERSION_INIT_OUT_SIZE: u32 = 5;
28
29pub const KERNEL_MINOR_VERSION_INIT_22_OUT_SIZE: u32 = 23;
31
32pub const KERNEL_MINOR_VERSION_LOOKUP_NEGATIVE_ENTRY_ZERO: u32 = 4;
34
35pub const ROOT_ID: u64 = 1;
37
38const FATTR_MODE: u32 = 0x1;
40const FATTR_UID: u32 = 0x2;
41const FATTR_GID: u32 = 0x4;
42const FATTR_SIZE: u32 = 0x8;
43const FATTR_ATIME: u32 = 0x10;
44const FATTR_MTIME: u32 = 0x20;
45pub const FATTR_FH: u32 = 0x40;
46const FATTR_ATIME_NOW: u32 = 0x80;
47const FATTR_MTIME_NOW: u32 = 0x100;
48pub const FATTR_LOCKOWNER: u32 = 0x200;
49const FATTR_CTIME: u32 = 0x400;
50const FATTR_KILL_SUIDGID: u32 = 0x800;
51
52bitflags! {
53 pub struct SetattrValid: u32 {
54 const MODE = FATTR_MODE;
55 const UID = FATTR_UID;
56 const GID = FATTR_GID;
57 const SIZE = FATTR_SIZE;
58 const ATIME = FATTR_ATIME;
59 const MTIME = FATTR_MTIME;
60 const ATIME_NOW = FATTR_ATIME_NOW;
61 const MTIME_NOW = FATTR_MTIME_NOW;
62 const CTIME = FATTR_CTIME;
63 const KILL_SUIDGID = FATTR_KILL_SUIDGID;
64 }
65}
66
67pub const FOPEN_IN_KILL_SUIDGID: u32 = 1;
71
72const FOPEN_DIRECT_IO: u32 = 1;
74
75const FOPEN_KEEP_CACHE: u32 = 2;
77
78const FOPEN_NONSEEKABLE: u32 = 4;
80
81const FOPEN_CACHE_DIR: u32 = 8;
83
84const FOPEN_STREAM: u32 = 16;
86
87bitflags! {
88 pub struct OpenOptions: u32 {
91 const DIRECT_IO = FOPEN_DIRECT_IO;
93 const KEEP_CACHE = FOPEN_KEEP_CACHE;
95 const NONSEEKABLE = FOPEN_NONSEEKABLE;
97 const CACHE_DIR = FOPEN_CACHE_DIR;
99 const STREAM = FOPEN_STREAM;
101 }
102}
103
104const ASYNC_READ: u64 = 0x1;
108
109const POSIX_LOCKS: u64 = 0x2;
111
112const FILE_OPS: u64 = 0x4;
114
115const ATOMIC_O_TRUNC: u64 = 0x8;
117
118const EXPORT_SUPPORT: u64 = 0x10;
120
121const BIG_WRITES: u64 = 0x20;
123
124const DONT_MASK: u64 = 0x40;
126
127const SPLICE_WRITE: u64 = 0x80;
129
130const SPLICE_MOVE: u64 = 0x100;
132
133const SPLICE_READ: u64 = 0x200;
135
136const FLOCK_LOCKS: u64 = 0x400;
138
139const HAS_IOCTL_DIR: u64 = 0x800;
141
142const AUTO_INVAL_DATA: u64 = 0x1000;
144
145const DO_READDIRPLUS: u64 = 0x2000;
147
148const READDIRPLUS_AUTO: u64 = 0x4000;
150
151const ASYNC_DIO: u64 = 0x8000;
153
154const WRITEBACK_CACHE: u64 = 0x1_0000;
156
157const NO_OPEN_SUPPORT: u64 = 0x2_0000;
159
160const PARALLEL_DIROPS: u64 = 0x4_0000;
162
163const HANDLE_KILLPRIV: u64 = 0x8_0000;
165
166const POSIX_ACL: u64 = 0x10_0000;
168
169const ABORT_ERROR: u64 = 0x20_0000;
171
172const MAX_PAGES: u64 = 0x40_0000;
174
175const CACHE_SYMLINKS: u64 = 0x80_0000;
177
178const NO_OPENDIR_SUPPORT: u64 = 0x100_0000;
180
181const EXPLICIT_INVAL_DATA: u64 = 0x200_0000;
183
184const MAP_ALIGNMENT: u64 = 0x400_0000;
187
188const SUBMOUNTS: u64 = 0x800_0000;
190
191const HANDLE_KILLPRIV_V2: u64 = 0x1000_0000;
193
194const INIT_EXT: u64 = 0x4000_0000;
196
197const PERFILE_DAX: u64 = 0x2_0000_0000;
199
200const HAS_RESEND: u64 = 1_u64 << 39;
202
203const FD_PASSTHROUGH: u64 = 0x8000_0000_0000_0000;
207
208pub const FUSE_ATTR_DAX: u32 = 1 << 1;
218
219bitflags! {
220 pub struct FsOptions: u64 {
223 const ASYNC_READ = ASYNC_READ;
231
232 const POSIX_LOCKS = POSIX_LOCKS;
237
238 const FILE_OPS = FILE_OPS;
240
241 const ATOMIC_O_TRUNC = ATOMIC_O_TRUNC;
247
248 const EXPORT_SUPPORT = EXPORT_SUPPORT;
252
253 const BIG_WRITES = BIG_WRITES;
255
256 const DONT_MASK = DONT_MASK;
261
262 const SPLICE_WRITE = SPLICE_WRITE;
267
268 const SPLICE_MOVE = SPLICE_MOVE;
273
274 const SPLICE_READ = SPLICE_READ;
279
280 const FLOCK_LOCKS = FLOCK_LOCKS;
288
289 const HAS_IOCTL_DIR = HAS_IOCTL_DIR;
293
294 const AUTO_INVAL_DATA = AUTO_INVAL_DATA;
310
311 const DO_READDIRPLUS = DO_READDIRPLUS;
316
317 const READDIRPLUS_AUTO = READDIRPLUS_AUTO;
331
332 const ASYNC_DIO = ASYNC_DIO;
340
341 const WRITEBACK_CACHE = WRITEBACK_CACHE;
347
348 const ZERO_MESSAGE_OPEN = NO_OPEN_SUPPORT;
357
358 const PARALLEL_DIROPS = PARALLEL_DIROPS;
364
365 const HANDLE_KILLPRIV = HANDLE_KILLPRIV;
370
371 const POSIX_ACL = POSIX_ACL;
385
386 const ABORT_ERROR = ABORT_ERROR;
393
394 const MAX_PAGES = MAX_PAGES;
401
402 const CACHE_SYMLINKS = CACHE_SYMLINKS;
408
409 const ZERO_MESSAGE_OPENDIR = NO_OPENDIR_SUPPORT;
420
421 const EXPLICIT_INVAL_DATA = EXPLICIT_INVAL_DATA;
430
431 const MAP_ALIGNMENT = MAP_ALIGNMENT;
438
439 const SUBMOUNTS = SUBMOUNTS;
441
442 const HANDLE_KILLPRIV_V2 = HANDLE_KILLPRIV_V2;
452
453 const FD_PASSTHROUGH = FD_PASSTHROUGH;
455
456 const INIT_EXT = INIT_EXT;
458
459 const PERFILE_DAX = PERFILE_DAX;
464
465 const HAS_RESEND = HAS_RESEND;
467 }
468}
469
470pub const RELEASE_FLUSH: u32 = 1;
472pub const RELEASE_FLOCK_UNLOCK: u32 = 2;
473
474pub const GETATTR_FH: u32 = 1;
476
477pub const LK_FLOCK: u32 = 1;
479
480pub const WRITE_CACHE: u32 = 1;
484
485pub const WRITE_LOCKOWNER: u32 = 2;
487
488pub const WRITE_KILL_PRIV: u32 = 4;
490
491pub const READ_LOCKOWNER: u32 = 2;
493
494const IOCTL_COMPAT: u32 = 1;
498
499const IOCTL_UNRESTRICTED: u32 = 2;
501
502const IOCTL_RETRY: u32 = 4;
504
505const IOCTL_32BIT: u32 = 8;
507
508const IOCTL_DIR: u32 = 16;
510
511const IOCTL_COMPAT_X32: u32 = 32;
513
514const IOCTL_MAX_IOV: u32 = 256;
516
517bitflags! {
518 pub struct IoctlFlags: u32 {
519 const IOCTL_COMPAT = IOCTL_COMPAT;
521
522 const IOCTL_UNRESTRICTED = IOCTL_UNRESTRICTED;
524
525 const IOCTL_RETRY = IOCTL_RETRY;
527
528 const IOCTL_32BIT = IOCTL_32BIT;
530
531 const IOCTL_DIR = IOCTL_DIR;
533
534 const IOCTL_COMPAT_X32 = IOCTL_COMPAT_X32;
536
537 const IOCTL_MAX_IOV = IOCTL_MAX_IOV;
539 }
540}
541
542pub const ATTR_SUBMOUNT: u32 = 1;
545
546pub const POLL_SCHEDULE_NOTIFY: u32 = 1;
548
549pub const FSYNC_FDATASYNC: u32 = 1;
553
554pub const FUSE_MIN_READ_BUFFER: u32 = 8192;
556
557pub const FUSE_COMPAT_ENTRY_OUT_SIZE: usize = 120;
558pub const FUSE_COMPAT_ATTR_OUT_SIZE: usize = 96;
559pub const FUSE_COMPAT_MKNOD_IN_SIZE: usize = 8;
560pub const FUSE_COMPAT_WRITE_IN_SIZE: usize = 24;
561pub const FUSE_COMPAT_STATFS_SIZE: usize = 48;
562pub const FUSE_COMPAT_INIT_OUT_SIZE: usize = 8;
563pub const FUSE_COMPAT_22_INIT_OUT_SIZE: usize = 24;
564
565#[repr(C)]
569#[derive(Debug, Default, Copy, Clone)]
570pub struct Attr {
571 pub ino: u64,
572 pub size: u64,
573 pub blocks: u64,
574 pub atime: u64,
575 pub mtime: u64,
576 pub ctime: u64,
577 pub atimensec: u32,
578 pub mtimensec: u32,
579 pub ctimensec: u32,
580 pub mode: u32,
581 pub nlink: u32,
582 pub uid: u32,
583 pub gid: u32,
584 pub rdev: u32,
585 pub blksize: u32,
586 pub flags: u32,
587}
588unsafe impl ByteValued for Attr {}
589
590impl From<stat64> for Attr {
591 fn from(st: stat64) -> Attr {
592 Attr::with_flags(st, 0)
593 }
594}
595
596impl Attr {
597 pub fn with_flags(st: stat64, flags: u32) -> Attr {
598 Attr {
599 ino: st.st_ino,
600 size: st.st_size as u64,
601 blocks: st.st_blocks as u64,
602 atime: st.st_atime as u64,
603 mtime: st.st_mtime as u64,
604 ctime: st.st_ctime as u64,
605 atimensec: st.st_atime_nsec as u32,
606 mtimensec: st.st_mtime_nsec as u32,
607 ctimensec: st.st_ctime_nsec as u32,
608 mode: st.st_mode,
609 #[allow(clippy::unnecessary_cast)]
613 nlink: st.st_nlink as u32,
614 uid: st.st_uid,
615 gid: st.st_gid,
616 rdev: st.st_rdev as u32,
617 blksize: st.st_blksize as u32,
618 flags,
619 }
620 }
621}
622
623impl From<Attr> for stat64 {
624 fn from(attr: Attr) -> stat64 {
625 let mut out: stat64 = unsafe { mem::zeroed() };
627 out.st_ino = attr.ino;
628 out.st_size = attr.size as i64;
629 out.st_blocks = attr.blocks as i64;
630 out.st_atime = attr.atime as i64;
631 out.st_mtime = attr.mtime as i64;
632 out.st_ctime = attr.ctime as i64;
633 out.st_atime_nsec = attr.atimensec as i64;
634 out.st_mtime_nsec = attr.mtimensec as i64;
635 out.st_ctime_nsec = attr.ctimensec as i64;
636 out.st_mode = attr.mode as mode_t;
637 out.st_nlink = attr.nlink as nlink_t;
638 out.st_uid = attr.uid;
639 out.st_gid = attr.gid;
640 out.st_rdev = attr.rdev as dev_t;
641 out.st_blksize = attr.blksize as blksize_t;
642
643 out
644 }
645}
646
647#[repr(C)]
648#[derive(Debug, Default, Copy, Clone)]
649pub struct Kstatfs {
650 pub blocks: u64,
651 pub bfree: u64,
652 pub bavail: u64,
653 pub files: u64,
654 pub ffree: u64,
655 pub bsize: u32,
656 pub namelen: u32,
657 pub frsize: u32,
658 pub padding: u32,
659 pub spare: [u32; 6],
660}
661unsafe impl ByteValued for Kstatfs {}
662
663impl From<statvfs64> for Kstatfs {
664 fn from(st: statvfs64) -> Self {
665 Kstatfs {
666 blocks: st.f_blocks,
667 bfree: st.f_bfree,
668 bavail: st.f_bavail,
669 files: st.f_files,
670 ffree: st.f_ffree,
671 bsize: st.f_bsize as u32,
672 namelen: st.f_namemax as u32,
673 frsize: st.f_frsize as u32,
674 ..Default::default()
675 }
676 }
677}
678
679#[repr(C)]
680#[derive(Debug, Default, Copy, Clone)]
681pub struct FileLock {
682 pub start: u64,
683 pub end: u64,
684 pub type_: u32,
685 pub pid: u32, }
687unsafe impl ByteValued for FileLock {}
688
689#[repr(u32)]
690#[derive(Debug, Copy, Clone)]
691pub enum Opcode {
692 Lookup = 1,
693 Forget = 2, Getattr = 3,
695 Setattr = 4,
696 Readlink = 5,
697 Symlink = 6,
698 Mknod = 8,
699 Mkdir = 9,
700 Unlink = 10,
701 Rmdir = 11,
702 Rename = 12,
703 Link = 13,
704 Open = 14,
705 Read = 15,
706 Write = 16,
707 Statfs = 17,
708 Release = 18,
709 Fsync = 20,
710 Setxattr = 21,
711 Getxattr = 22,
712 Listxattr = 23,
713 Removexattr = 24,
714 Flush = 25,
715 Init = 26,
716 Opendir = 27,
717 Readdir = 28,
718 Releasedir = 29,
719 Fsyncdir = 30,
720 Getlk = 31,
721 Setlk = 32,
722 Setlkw = 33,
723 Access = 34,
724 Create = 35,
725 Interrupt = 36,
726 Bmap = 37,
727 Destroy = 38,
728 Ioctl = 39,
729 Poll = 40,
730 NotifyReply = 41,
731 BatchForget = 42,
732 Fallocate = 43,
733 Readdirplus = 44,
734 Rename2 = 45,
735 Lseek = 46,
736 CopyFileRange = 47,
737 SetupMapping = 48,
738 RemoveMapping = 49,
739 MaxOpcode = 50,
740
741 CuseInitBswapReserved = 1_048_576, InitBswapReserved = 436_207_616, }
745
746impl From<u32> for Opcode {
747 fn from(op: u32) -> Opcode {
748 if op >= Opcode::MaxOpcode as u32 {
749 return Opcode::MaxOpcode;
750 }
751 unsafe { mem::transmute(op) }
752 }
753}
754
755#[repr(u32)]
756#[derive(Debug, Copy, Clone)]
757pub enum NotifyOpcode {
758 Poll = 1,
759 InvalInode = 2,
760 InvalEntry = 3,
761 Store = 4,
762 Retrieve = 5,
763 Delete = 6,
764 Resend = 7,
765 CodeMax = 8,
766}
767
768#[repr(C)]
769#[derive(Debug, Default, Copy, Clone)]
770pub struct EntryOut {
771 pub nodeid: u64, pub generation: u64, pub entry_valid: u64, pub attr_valid: u64, pub entry_valid_nsec: u32,
776 pub attr_valid_nsec: u32,
777 pub attr: Attr,
778}
779unsafe impl ByteValued for EntryOut {}
780
781#[repr(C)]
782#[derive(Debug, Default, Copy, Clone)]
783pub struct ForgetIn {
784 pub nlookup: u64,
785}
786unsafe impl ByteValued for ForgetIn {}
787
788#[repr(C)]
789#[derive(Debug, Default, Copy, Clone)]
790pub struct ForgetOne {
791 pub nodeid: u64,
792 pub nlookup: u64,
793}
794unsafe impl ByteValued for ForgetOne {}
795
796#[repr(C)]
797#[derive(Debug, Default, Copy, Clone)]
798pub struct BatchForgetIn {
799 pub count: u32,
800 pub dummy: u32,
801}
802unsafe impl ByteValued for BatchForgetIn {}
803
804#[repr(C)]
805#[derive(Debug, Default, Copy, Clone)]
806pub struct GetattrIn {
807 pub flags: u32,
808 pub dummy: u32,
809 pub fh: u64,
810}
811unsafe impl ByteValued for GetattrIn {}
812
813#[repr(C)]
814#[derive(Debug, Default, Copy, Clone)]
815pub struct AttrOut {
816 pub attr_valid: u64, pub attr_valid_nsec: u32,
818 pub dummy: u32,
819 pub attr: Attr,
820}
821unsafe impl ByteValued for AttrOut {}
822
823#[repr(C)]
824#[derive(Debug, Default, Copy, Clone)]
825pub struct MknodIn {
826 pub mode: u32,
827 pub rdev: u32,
828 pub umask: u32,
829 pub padding: u32,
830}
831unsafe impl ByteValued for MknodIn {}
832
833#[repr(C)]
834#[derive(Debug, Default, Copy, Clone)]
835pub struct MkdirIn {
836 pub mode: u32,
837 pub umask: u32,
838}
839unsafe impl ByteValued for MkdirIn {}
840
841#[repr(C)]
842#[derive(Debug, Default, Copy, Clone)]
843pub struct RenameIn {
844 pub newdir: u64,
845}
846unsafe impl ByteValued for RenameIn {}
847
848#[repr(C)]
849#[derive(Debug, Default, Copy, Clone)]
850pub struct Rename2In {
851 pub newdir: u64,
852 pub flags: u32,
853 pub padding: u32,
854}
855unsafe impl ByteValued for Rename2In {}
856
857#[repr(C)]
858#[derive(Debug, Default, Copy, Clone)]
859pub struct LinkIn {
860 pub oldnodeid: u64,
861}
862unsafe impl ByteValued for LinkIn {}
863
864#[repr(C)]
865#[derive(Debug, Default, Copy, Clone)]
866pub struct SetattrIn {
867 pub valid: u32,
868 pub padding: u32,
869 pub fh: u64,
870 pub size: u64,
871 pub lock_owner: u64,
872 pub atime: u64,
873 pub mtime: u64,
874 pub ctime: u64,
875 pub atimensec: u32,
876 pub mtimensec: u32,
877 pub ctimensec: u32,
878 pub mode: u32,
879 pub unused4: u32,
880 pub uid: u32,
881 pub gid: u32,
882 pub unused5: u32,
883}
884unsafe impl ByteValued for SetattrIn {}
885
886impl From<SetattrIn> for stat64 {
887 fn from(setattr: SetattrIn) -> stat64 {
888 let mut out: stat64 = unsafe { mem::zeroed() };
890 out.st_mode = setattr.mode as mode_t;
891 out.st_uid = setattr.uid;
892 out.st_gid = setattr.gid;
893 out.st_size = setattr.size as i64;
894 out.st_atime = setattr.atime as i64;
895 out.st_mtime = setattr.mtime as i64;
896 out.st_ctime = setattr.ctime as i64;
897 out.st_atime_nsec = i64::from(setattr.atimensec);
898 out.st_mtime_nsec = i64::from(setattr.mtimensec);
899 out.st_ctime_nsec = i64::from(setattr.ctimensec);
900
901 out
902 }
903}
904
905#[repr(C)]
906#[derive(Debug, Default, Copy, Clone)]
907pub struct OpenIn {
908 pub flags: u32,
909 pub fuse_flags: u32,
910}
911unsafe impl ByteValued for OpenIn {}
912
913#[repr(C)]
914#[derive(Debug, Default, Copy, Clone)]
915pub struct CreateIn {
916 pub flags: u32,
917 pub mode: u32,
918 pub umask: u32,
919 pub fuse_flags: u32,
920}
921unsafe impl ByteValued for CreateIn {}
922
923#[repr(C)]
924#[derive(Debug, Default, Copy, Clone)]
925pub struct OpenOut {
926 pub fh: u64,
927 pub open_flags: u32,
928 pub passthrough: u32,
929}
930unsafe impl ByteValued for OpenOut {}
931
932#[repr(C)]
933#[derive(Debug, Default, Copy, Clone)]
934pub struct ReleaseIn {
935 pub fh: u64,
936 pub flags: u32,
937 pub release_flags: u32,
938 pub lock_owner: u64,
939}
940unsafe impl ByteValued for ReleaseIn {}
941
942#[repr(C)]
943#[derive(Debug, Default, Copy, Clone)]
944pub struct FlushIn {
945 pub fh: u64,
946 pub unused: u32,
947 pub padding: u32,
948 pub lock_owner: u64,
949}
950unsafe impl ByteValued for FlushIn {}
951
952#[repr(C)]
953#[derive(Debug, Default, Copy, Clone)]
954pub struct ReadIn {
955 pub fh: u64,
956 pub offset: u64,
957 pub size: u32,
958 pub read_flags: u32,
959 pub lock_owner: u64,
960 pub flags: u32,
961 pub padding: u32,
962}
963unsafe impl ByteValued for ReadIn {}
964
965#[repr(C)]
966#[derive(Debug, Default, Copy, Clone)]
967pub struct WriteIn {
968 pub fh: u64,
969 pub offset: u64,
970 pub size: u32,
971 pub fuse_flags: u32,
972 pub lock_owner: u64,
973 pub flags: u32,
974 pub padding: u32,
975}
976unsafe impl ByteValued for WriteIn {}
977
978#[repr(C)]
979#[derive(Debug, Default, Copy, Clone)]
980pub struct WriteOut {
981 pub size: u32,
982 pub padding: u32,
983}
984unsafe impl ByteValued for WriteOut {}
985
986#[repr(C)]
987#[derive(Debug, Default, Copy, Clone)]
988pub struct StatfsOut {
989 pub st: Kstatfs,
990}
991unsafe impl ByteValued for StatfsOut {}
992
993#[repr(C)]
994#[derive(Debug, Default, Copy, Clone)]
995pub struct FsyncIn {
996 pub fh: u64,
997 pub fsync_flags: u32,
998 pub padding: u32,
999}
1000unsafe impl ByteValued for FsyncIn {}
1001
1002#[repr(C)]
1003#[derive(Debug, Default, Copy, Clone)]
1004pub struct SetxattrIn {
1005 pub size: u32,
1006 pub flags: u32,
1007}
1008unsafe impl ByteValued for SetxattrIn {}
1009
1010#[repr(C)]
1011#[derive(Debug, Default, Copy, Clone)]
1012pub struct GetxattrIn {
1013 pub size: u32,
1014 pub padding: u32,
1015}
1016unsafe impl ByteValued for GetxattrIn {}
1017
1018#[repr(C)]
1019#[derive(Debug, Default, Copy, Clone)]
1020pub struct GetxattrOut {
1021 pub size: u32,
1022 pub padding: u32,
1023}
1024unsafe impl ByteValued for GetxattrOut {}
1025
1026#[repr(C)]
1027#[derive(Debug, Default, Copy, Clone)]
1028pub struct LkIn {
1029 pub fh: u64,
1030 pub owner: u64,
1031 pub lk: FileLock,
1032 pub lk_flags: u32,
1033 pub padding: u32,
1034}
1035unsafe impl ByteValued for LkIn {}
1036
1037#[repr(C)]
1038#[derive(Debug, Default, Copy, Clone)]
1039pub struct LkOut {
1040 pub lk: FileLock,
1041}
1042unsafe impl ByteValued for LkOut {}
1043
1044#[repr(C)]
1045#[derive(Debug, Default, Copy, Clone)]
1046pub struct AccessIn {
1047 pub mask: u32,
1048 pub padding: u32,
1049}
1050unsafe impl ByteValued for AccessIn {}
1051
1052#[repr(C)]
1053#[derive(Debug, Default, Copy, Clone)]
1054pub struct InitIn {
1055 pub major: u32,
1056 pub minor: u32,
1057 pub max_readahead: u32,
1058 pub flags: u32,
1059}
1060unsafe impl ByteValued for InitIn {}
1061
1062#[repr(C)]
1064#[derive(Debug, Default, Copy, Clone)]
1065pub struct InitIn2 {
1066 pub flags2: u32,
1067 pub unused: [u32; 11],
1068}
1069unsafe impl ByteValued for InitIn2 {}
1070
1071#[repr(C)]
1072#[derive(Debug, Default, Copy, Clone)]
1073pub struct InitOut {
1074 pub major: u32,
1075 pub minor: u32,
1076 pub max_readahead: u32,
1077 pub flags: u32,
1078 pub max_background: u16,
1079 pub congestion_threshold: u16,
1080 pub max_write: u32,
1081 pub time_gran: u32,
1082 pub max_pages: u16,
1083 pub map_alignment: u16,
1084 pub flags2: u32,
1085 pub unused: [u32; 7],
1086}
1087unsafe impl ByteValued for InitOut {}
1088
1089#[repr(C)]
1090#[derive(Debug, Default, Copy, Clone)]
1091pub struct InterruptIn {
1092 pub unique: u64,
1093}
1094unsafe impl ByteValued for InterruptIn {}
1095
1096#[repr(C)]
1097#[derive(Debug, Default, Copy, Clone)]
1098pub struct BmapIn {
1099 pub block: u64,
1100 pub blocksize: u32,
1101 pub padding: u32,
1102}
1103unsafe impl ByteValued for BmapIn {}
1104
1105#[repr(C)]
1106#[derive(Debug, Default, Copy, Clone)]
1107pub struct BmapOut {
1108 pub block: u64,
1109}
1110unsafe impl ByteValued for BmapOut {}
1111
1112#[repr(C)]
1113#[derive(Debug, Default, Copy, Clone)]
1114pub struct IoctlIn {
1115 pub fh: u64,
1116 pub flags: u32,
1117 pub cmd: u32,
1118 pub arg: u64,
1119 pub in_size: u32,
1120 pub out_size: u32,
1121}
1122unsafe impl ByteValued for IoctlIn {}
1123
1124#[repr(C)]
1125#[derive(Debug, Default, Copy, Clone)]
1126pub struct IoctlIovec {
1127 pub base: u64,
1128 pub len: u64,
1129}
1130unsafe impl ByteValued for IoctlIovec {}
1131
1132#[repr(C)]
1133#[derive(Debug, Default, Copy, Clone)]
1134pub struct IoctlOut {
1135 pub result: i32,
1136 pub flags: u32,
1137 pub in_iovs: u32,
1138 pub out_iovs: u32,
1139}
1140unsafe impl ByteValued for IoctlOut {}
1141
1142#[repr(C)]
1143#[derive(Debug, Default, Copy, Clone)]
1144pub struct PollIn {
1145 pub fh: u64,
1146 pub kh: u64,
1147 pub flags: u32,
1148 pub events: u32,
1149}
1150unsafe impl ByteValued for PollIn {}
1151
1152#[repr(C)]
1153#[derive(Debug, Default, Copy, Clone)]
1154pub struct PollOut {
1155 pub revents: u32,
1156 pub padding: u32,
1157}
1158unsafe impl ByteValued for PollOut {}
1159
1160#[repr(C)]
1161#[derive(Debug, Default, Copy, Clone)]
1162pub struct NotifyPollWakeupOut {
1163 pub kh: u64,
1164}
1165unsafe impl ByteValued for NotifyPollWakeupOut {}
1166
1167#[repr(C)]
1168#[derive(Debug, Default, Copy, Clone)]
1169pub struct FallocateIn {
1170 pub fh: u64,
1171 pub offset: u64,
1172 pub length: u64,
1173 pub mode: u32,
1174 pub padding: u32,
1175}
1176unsafe impl ByteValued for FallocateIn {}
1177
1178#[repr(C)]
1179#[derive(Default, Copy, Clone)]
1180pub struct InHeader {
1181 pub len: u32,
1182 pub opcode: u32,
1183 pub unique: u64,
1184 pub nodeid: u64,
1185 pub uid: u32,
1186 pub gid: u32,
1187 pub pid: u32,
1188 pub padding: u32,
1189}
1190unsafe impl ByteValued for InHeader {}
1191
1192impl Debug for InHeader {
1193 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1194 write!(
1195 f,
1196 "InHeader {{ len: {}, opcode: {}, unique: {}, nodeid: 0x{:x}, uid: {}, gid: {}, pid: {}, padding: {} }}",
1197 self.len, self.opcode, self.unique, self.nodeid, self.uid, self.gid, self.pid, self.padding
1198 )
1199 }
1200}
1201
1202#[repr(C)]
1203#[derive(Debug, Default, Copy, Clone)]
1204pub struct OutHeader {
1205 pub len: u32,
1206 pub error: i32,
1207 pub unique: u64,
1208}
1209unsafe impl ByteValued for OutHeader {}
1210
1211#[repr(C)]
1212#[derive(Debug, Default, Copy, Clone)]
1213pub struct Dirent {
1214 pub ino: u64,
1215 pub off: u64,
1216 pub namelen: u32,
1217 pub type_: u32,
1218 }
1220unsafe impl ByteValued for Dirent {}
1221
1222#[repr(C)]
1223#[derive(Debug, Default, Copy, Clone)]
1224pub struct Direntplus {
1225 pub entry_out: EntryOut,
1226 pub dirent: Dirent,
1227}
1228unsafe impl ByteValued for Direntplus {}
1229
1230#[repr(C)]
1231#[derive(Debug, Default, Copy, Clone)]
1232pub struct NotifyInvalInodeOut {
1233 pub ino: u64,
1234 pub off: i64,
1235 pub len: i64,
1236}
1237unsafe impl ByteValued for NotifyInvalInodeOut {}
1238
1239#[repr(C)]
1240#[derive(Debug, Default, Copy, Clone)]
1241pub struct NotifyInvalEntryOut {
1242 pub parent: u64,
1243 pub namelen: u32,
1244 pub padding: u32,
1245}
1246unsafe impl ByteValued for NotifyInvalEntryOut {}
1247
1248#[repr(C)]
1249#[derive(Debug, Default, Copy, Clone)]
1250pub struct NotifyDeleteOut {
1251 pub parent: u64,
1252 pub child: u64,
1253 pub namelen: u32,
1254 pub padding: u32,
1255}
1256unsafe impl ByteValued for NotifyDeleteOut {}
1257
1258#[repr(C)]
1259#[derive(Debug, Default, Copy, Clone)]
1260pub struct NotifyStoreOut {
1261 pub nodeid: u64,
1262 pub offset: u64,
1263 pub size: u32,
1264 pub padding: u32,
1265}
1266unsafe impl ByteValued for NotifyStoreOut {}
1267
1268#[repr(C)]
1269#[derive(Debug, Default, Copy, Clone)]
1270pub struct Notify_Retrieve_Out {
1271 pub notify_unique: u64,
1272 pub nodeid: u64,
1273 pub offset: u64,
1274 pub size: u32,
1275 pub padding: u32,
1276}
1277unsafe impl ByteValued for Notify_Retrieve_Out {}
1278
1279#[repr(C)]
1281#[derive(Debug, Default, Copy, Clone)]
1282pub struct NotifyRetrieveIn {
1283 pub dummy1: u64,
1284 pub offset: u64,
1285 pub size: u32,
1286 pub dummy2: u32,
1287 pub dummy3: u64,
1288 pub dummy4: u64,
1289}
1290unsafe impl ByteValued for NotifyRetrieveIn {}
1291
1292#[repr(C)]
1293#[derive(Debug, Default, Copy, Clone)]
1294pub struct LseekIn {
1295 pub fh: u64,
1296 pub offset: u64,
1297 pub whence: u32,
1298 pub padding: u32,
1299}
1300unsafe impl ByteValued for LseekIn {}
1301
1302#[repr(C)]
1303#[derive(Debug, Default, Copy, Clone)]
1304pub struct LseekOut {
1305 pub offset: u64,
1306}
1307unsafe impl ByteValued for LseekOut {}
1308
1309#[repr(C)]
1310#[derive(Debug, Default, Copy, Clone)]
1311pub struct CopyFileRangeIn {
1313 pub fh_in: u64,
1314 pub offset_in: u64,
1315 pub nodeid_out: u64,
1316 pub fh_out: u64,
1317 pub offset_out: u64,
1318 pub len: u64,
1319 pub flags: u64,
1320}
1321unsafe impl ByteValued for CopyFileRangeIn {}
1322
1323#[cfg(test)]
1324mod tests {
1325
1326 use super::*;
1327
1328 #[test]
1329 fn test_struct_size() {
1330 assert_eq!(std::mem::size_of::<Attr>(), 88);
1331 assert_eq!(std::mem::size_of::<Kstatfs>(), 80);
1332 assert_eq!(std::mem::size_of::<FileLock>(), 24);
1333 assert_eq!(std::mem::size_of::<EntryOut>(), 128);
1334 assert_eq!(std::mem::size_of::<ForgetIn>(), 8);
1335 assert_eq!(std::mem::size_of::<ForgetOne>(), 16);
1336 assert_eq!(std::mem::size_of::<BatchForgetIn>(), 8);
1337 assert_eq!(std::mem::size_of::<GetattrIn>(), 16);
1338 assert_eq!(std::mem::size_of::<AttrOut>(), 104);
1339 assert_eq!(std::mem::size_of::<MknodIn>(), 16);
1340 assert_eq!(std::mem::size_of::<MkdirIn>(), 8);
1341 assert_eq!(std::mem::size_of::<InHeader>(), 40);
1342 assert_eq!(std::mem::size_of::<OutHeader>(), 16);
1343 }
1344
1345 #[test]
1346 fn test_byte_valued() {
1347 let buf = [
1348 0x1u8, 0x2u8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5u8, 0x6u8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
1349 ];
1350 let forget = match ForgetOne::from_slice(&buf) {
1351 Some(f) => f,
1352 None => {
1353 panic!("Failed to parse ForgetOne from buffer: {:?}", buf)
1354 }
1355 };
1356
1357 assert_eq!(forget.nodeid, 0x201u64);
1358 assert_eq!(forget.nlookup, 0x605u64);
1359
1360 let forget = ForgetOne {
1361 nodeid: 0x201u64,
1362 nlookup: 0x605u64,
1363 };
1364 let buf = forget.as_slice();
1365 assert_eq!(buf[0], 0x1u8);
1366 assert_eq!(buf[1], 0x2u8);
1367 assert_eq!(buf[8], 0x5u8);
1368 assert_eq!(buf[9], 0x6u8);
1369 }
1370}