use std::mem::size_of;
pub const FUSE_KERNEL_VERSION: u32 = 7;
pub const FUSE_KERNEL_MINOR_VERSION: u32 = 36;
pub const FUSE_ROOT_ID: u64 = 1;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Opcode {
Lookup = 1,
Forget = 2,
Getattr = 3,
Setattr = 4,
Readlink = 5,
Symlink = 6,
Mknod = 8,
Mkdir = 9,
Unlink = 10,
Rmdir = 11,
Rename = 12,
Link = 13,
Open = 14,
Read = 15,
Write = 16,
Statfs = 17,
Release = 18,
Fsync = 20,
Setxattr = 21,
Getxattr = 22,
Listxattr = 23,
Removexattr = 24,
Flush = 25,
Init = 26,
Opendir = 27,
Readdir = 28,
Releasedir = 29,
Fsyncdir = 30,
Getlk = 31,
Setlk = 32,
Setlkw = 33,
Access = 34,
Create = 35,
Interrupt = 36,
Bmap = 37,
Destroy = 38,
Ioctl = 39,
Poll = 40,
NotifyReply = 41,
BatchForget = 42,
Fallocate = 43,
Readdirplus = 44,
Rename2 = 45,
Lseek = 46,
CopyFileRange = 47,
SetupMapping = 48,
RemoveMapping = 49,
SyncFs = 50,
Tmpfile = 51,
Statx = 52,
}
impl Opcode {
pub fn from_u32(v: u32) -> Option<Self> {
match v {
1 => Some(Self::Lookup),
2 => Some(Self::Forget),
3 => Some(Self::Getattr),
4 => Some(Self::Setattr),
5 => Some(Self::Readlink),
6 => Some(Self::Symlink),
8 => Some(Self::Mknod),
9 => Some(Self::Mkdir),
10 => Some(Self::Unlink),
11 => Some(Self::Rmdir),
12 => Some(Self::Rename),
13 => Some(Self::Link),
14 => Some(Self::Open),
15 => Some(Self::Read),
16 => Some(Self::Write),
17 => Some(Self::Statfs),
18 => Some(Self::Release),
20 => Some(Self::Fsync),
21 => Some(Self::Setxattr),
22 => Some(Self::Getxattr),
23 => Some(Self::Listxattr),
24 => Some(Self::Removexattr),
25 => Some(Self::Flush),
26 => Some(Self::Init),
27 => Some(Self::Opendir),
28 => Some(Self::Readdir),
29 => Some(Self::Releasedir),
30 => Some(Self::Fsyncdir),
31 => Some(Self::Getlk),
32 => Some(Self::Setlk),
33 => Some(Self::Setlkw),
34 => Some(Self::Access),
35 => Some(Self::Create),
36 => Some(Self::Interrupt),
37 => Some(Self::Bmap),
38 => Some(Self::Destroy),
39 => Some(Self::Ioctl),
40 => Some(Self::Poll),
41 => Some(Self::NotifyReply),
42 => Some(Self::BatchForget),
43 => Some(Self::Fallocate),
44 => Some(Self::Readdirplus),
45 => Some(Self::Rename2),
46 => Some(Self::Lseek),
47 => Some(Self::CopyFileRange),
48 => Some(Self::SetupMapping),
49 => Some(Self::RemoveMapping),
50 => Some(Self::SyncFs),
51 => Some(Self::Tmpfile),
52 => Some(Self::Statx),
_ => None,
}
}
}
pub const FUSE_DONT_MASK: u32 = 1 << 6;
pub const FUSE_MAP_ALIGNMENT: u32 = 1 << 26;
pub const FUSE_SUBMOUNTS: u32 = 1 << 27;
pub const FUSE_HANDLE_KILLPRIV_V2: u32 = 1 << 28;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct InHeader {
pub len: u32,
pub opcode: u32,
pub unique: u64,
pub nodeid: u64,
pub uid: u32,
pub gid: u32,
pub pid: u32,
pub padding: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct OutHeader {
pub len: u32,
pub error: i32,
pub unique: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct InitIn {
pub major: u32,
pub minor: u32,
pub max_readahead: u32,
pub flags: u32,
pub flags2: u32,
pub unused: [u32; 11],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct InitOut {
pub major: u32,
pub minor: u32,
pub max_readahead: u32,
pub flags: u32,
pub max_background: u16,
pub congestion_threshold: u16,
pub max_write: u32,
pub time_gran: u32,
pub max_pages: u16,
pub map_alignment: u16,
pub flags2: u32,
pub max_stack_depth: u32,
pub unused: [u32; 6],
}
pub const FUSE_SETUPMAPPING_FLAG_WRITE: u64 = 1 << 0;
pub const FUSE_SETUPMAPPING_FLAG_READ: u64 = 1 << 1;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SetupMappingIn {
pub fh: u64,
pub foffset: u64,
pub len: u64,
pub flags: u64,
pub moffset: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct RemoveMappingIn {
pub count: u32,
pub _pad: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct RemoveMappingOne {
pub moffset: u64,
pub len: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct Attr {
pub ino: u64,
pub size: u64,
pub blocks: u64,
pub atime: u64,
pub mtime: u64,
pub ctime: u64,
pub atimensec: u32,
pub mtimensec: u32,
pub ctimensec: u32,
pub mode: u32,
pub nlink: u32,
pub uid: u32,
pub gid: u32,
pub rdev: u32,
pub blksize: u32,
pub flags: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct EntryOut {
pub nodeid: u64,
pub generation: u64,
pub entry_valid: u64,
pub attr_valid: u64,
pub entry_valid_nsec: u32,
pub attr_valid_nsec: u32,
pub attr: Attr,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct GetattrIn {
pub flags: u32,
pub _dummy: u32,
pub fh: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct AttrOut {
pub attr_valid: u64,
pub attr_valid_nsec: u32,
pub _pad: u32,
pub attr: Attr,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct OpenIn {
pub flags: u32,
pub open_flags: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct OpenOut {
pub fh: u64,
pub open_flags: u32,
pub _pad: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct ReadIn {
pub fh: u64,
pub offset: u64,
pub size: u32,
pub read_flags: u32,
pub lock_owner: u64,
pub flags: u32,
pub _pad: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct WriteIn {
pub fh: u64,
pub offset: u64,
pub size: u32,
pub write_flags: u32,
pub lock_owner: u64,
pub flags: u32,
pub _pad: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct WriteOut {
pub size: u32,
pub _pad: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct ReleaseIn {
pub fh: u64,
pub flags: u32,
pub release_flags: u32,
pub lock_owner: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct FsyncIn {
pub fh: u64,
pub fsync_flags: u32,
pub _pad: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct NotifyInvalInodeOut {
pub ino: i64,
pub off: i64,
pub len: i64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct NotifyInvalEntryOut {
pub parent: u64,
pub namelen: u32,
pub _pad: u32,
}
pub const FUSE_NOTIFY_INVAL_INODE: i32 = 2;
pub const FUSE_NOTIFY_INVAL_ENTRY: i32 = 3;
pub const FUSE_NOTIFY_DELETE: i32 = 6;
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct CreateIn {
pub flags: u32,
pub mode: u32,
pub umask: u32,
pub open_flags: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct MkdirIn {
pub mode: u32,
pub umask: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct ForgetIn {
pub nlookup: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct Kstatfs {
pub blocks: u64,
pub bfree: u64,
pub bavail: u64,
pub files: u64,
pub ffree: u64,
pub bsize: u32,
pub namelen: u32,
pub frsize: u32,
pub _pad: u32,
pub spare: [u32; 6],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct StatfsOut {
pub st: Kstatfs,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct DirentHeader {
pub ino: u64,
pub off: u64,
pub namelen: u32,
pub typ: u32,
}
pub const DT_UNKNOWN: u32 = 0;
pub const DT_FIFO: u32 = 1;
pub const DT_CHR: u32 = 2;
pub const DT_DIR: u32 = 4;
pub const DT_BLK: u32 = 6;
pub const DT_REG: u32 = 8;
pub const DT_LNK: u32 = 10;
pub const DT_SOCK: u32 = 12;
pub const fn align_up(n: usize, to: usize) -> usize {
(n + to - 1) & !(to - 1)
}
pub const S_IFMT: u32 = 0o170000;
pub const S_IFREG: u32 = 0o100000;
pub const S_IFDIR: u32 = 0o040000;
pub const S_IFLNK: u32 = 0o120000;
pub const S_IFIFO: u32 = 0o010000;
pub const S_IFBLK: u32 = 0o060000;
pub const S_IFCHR: u32 = 0o020000;
pub const S_IFSOCK: u32 = 0o140000;
const _: () = {
assert!(size_of::<InHeader>() == 40);
assert!(size_of::<OutHeader>() == 16);
assert!(size_of::<InitIn>() == 64);
assert!(size_of::<InitOut>() == 64);
assert!(size_of::<SetupMappingIn>() == 40);
assert!(size_of::<RemoveMappingOne>() == 16);
assert!(size_of::<Attr>() == 88);
assert!(size_of::<EntryOut>() == 128);
assert!(size_of::<AttrOut>() == 104);
assert!(size_of::<OpenIn>() == 8);
assert!(size_of::<OpenOut>() == 16);
assert!(size_of::<ReadIn>() == 40);
assert!(size_of::<WriteIn>() == 40);
assert!(size_of::<WriteOut>() == 8);
assert!(size_of::<ReleaseIn>() == 24);
assert!(size_of::<FsyncIn>() == 16);
assert!(size_of::<CreateIn>() == 16);
assert!(size_of::<MkdirIn>() == 8);
assert!(size_of::<NotifyInvalInodeOut>() == 24);
assert!(size_of::<NotifyInvalEntryOut>() == 16);
assert!(size_of::<ForgetIn>() == 8);
assert!(size_of::<Kstatfs>() == 80);
assert!(size_of::<StatfsOut>() == 80);
assert!(size_of::<DirentHeader>() == 24);
};