#![allow(
clippy::cast_sign_loss,
clippy::cast_possible_wrap,
clippy::cast_possible_truncation
)]
use std::mem::size_of;
pub const FUSE_KERNEL_VERSION: u32 = 7;
pub const FUSE_KERNEL_MINOR_VERSION: u32 = 38;
pub const FUSE_ROOT_ID: u64 = 1;
pub const FUSE_ASYNC_READ: u32 = 1 << 0;
pub const FUSE_POSIX_LOCKS: u32 = 1 << 1;
pub const FUSE_FILE_OPS: u32 = 1 << 2;
pub const FUSE_ATOMIC_O_TRUNC: u32 = 1 << 3;
pub const FUSE_EXPORT_SUPPORT: u32 = 1 << 4;
pub const FUSE_BIG_WRITES: u32 = 1 << 5;
pub const FUSE_DONT_MASK: u32 = 1 << 6;
pub const FUSE_SPLICE_WRITE: u32 = 1 << 7;
pub const FUSE_SPLICE_MOVE: u32 = 1 << 8;
pub const FUSE_SPLICE_READ: u32 = 1 << 9;
pub const FUSE_FLOCK_LOCKS: u32 = 1 << 10;
pub const FUSE_HAS_IOCTL_DIR: u32 = 1 << 11;
pub const FUSE_AUTO_INVAL_DATA: u32 = 1 << 12;
pub const FUSE_DO_READDIRPLUS: u32 = 1 << 13;
pub const FUSE_READDIRPLUS_AUTO: u32 = 1 << 14;
pub const FUSE_ASYNC_DIO: u32 = 1 << 15;
pub const FUSE_WRITEBACK_CACHE: u32 = 1 << 16;
pub const FUSE_NO_OPEN_SUPPORT: u32 = 1 << 17;
pub const FUSE_PARALLEL_DIROPS: u32 = 1 << 18;
pub const FUSE_HANDLE_KILLPRIV: u32 = 1 << 19;
pub const FUSE_POSIX_ACL: u32 = 1 << 20;
pub const FUSE_ABORT_ERROR: u32 = 1 << 21;
pub const FUSE_MAX_PAGES: u32 = 1 << 22;
pub const FUSE_CACHE_SYMLINKS: u32 = 1 << 23;
pub const FUSE_NO_OPENDIR_SUPPORT: u32 = 1 << 24;
pub const FUSE_EXPLICIT_INVAL_DATA: u32 = 1 << 25;
pub const FATTR_MODE: u32 = 1 << 0;
pub const FATTR_UID: u32 = 1 << 1;
pub const FATTR_GID: u32 = 1 << 2;
pub const FATTR_SIZE: u32 = 1 << 3;
pub const FATTR_ATIME: u32 = 1 << 4;
pub const FATTR_MTIME: u32 = 1 << 5;
pub const FATTR_FH: u32 = 1 << 6;
pub const FATTR_ATIME_NOW: u32 = 1 << 7;
pub const FATTR_MTIME_NOW: u32 = 1 << 8;
pub const FATTR_LOCKOWNER: u32 = 1 << 9;
pub const FATTR_CTIME: u32 = 1 << 10;
pub const FOPEN_DIRECT_IO: u32 = 1 << 0;
pub const FOPEN_KEEP_CACHE: u32 = 1 << 1;
pub const FOPEN_NONSEEKABLE: u32 = 1 << 2;
pub const FOPEN_CACHE_DIR: u32 = 1 << 3;
pub const FOPEN_STREAM: u32 = 1 << 4;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum FuseOpcode {
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,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseInHeader {
pub len: u32,
pub opcode: u32,
pub unique: u64,
pub nodeid: u64,
pub uid: u32,
pub gid: u32,
pub pid: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseOutHeader {
pub len: u32,
pub error: i32,
pub unique: u64,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseAttr {
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 padding: u32,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct StatFs {
pub blocks: u64,
pub bfree: u64,
pub bavail: u64,
pub files: u64,
pub ffree: u64,
pub bsize: u32,
pub namelen: u32,
pub frsize: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseInitIn {
pub major: u32,
pub minor: u32,
pub max_readahead: u32,
pub flags: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseGetattrIn {
pub getattr_flags: u32,
pub dummy: u32,
pub fh: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseSetattrIn {
pub valid: u32,
pub padding: u32,
pub fh: u64,
pub size: u64,
pub lock_owner: u64,
pub atime: u64,
pub mtime: u64,
pub ctime: u64,
pub atimensec: u32,
pub mtimensec: u32,
pub ctimensec: u32,
pub mode: u32,
pub unused4: u32,
pub uid: u32,
pub gid: u32,
pub unused5: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseMknodIn {
pub mode: u32,
pub rdev: u32,
pub umask: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseMkdirIn {
pub mode: u32,
pub umask: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseRenameIn {
pub newdir: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseRename2In {
pub newdir: u64,
pub flags: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseLinkIn {
pub oldnodeid: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseOpenIn {
pub flags: u32,
pub unused: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseCreateIn {
pub flags: u32,
pub mode: u32,
pub umask: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseReadIn {
pub fh: u64,
pub offset: u64,
pub size: u32,
pub read_flags: u32,
pub lock_owner: u64,
pub flags: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseWriteIn {
pub fh: u64,
pub offset: u64,
pub size: u32,
pub write_flags: u32,
pub lock_owner: u64,
pub flags: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseReleaseIn {
pub fh: u64,
pub flags: u32,
pub release_flags: u32,
pub lock_owner: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseFlushIn {
pub fh: u64,
pub unused: u32,
pub padding: u32,
pub lock_owner: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseFsyncIn {
pub fh: u64,
pub fsync_flags: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseSetxattrIn {
pub size: u32,
pub flags: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseGetxattrIn {
pub size: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseAccessIn {
pub mask: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseLseekIn {
pub fh: u64,
pub offset: u64,
pub whence: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseFallocateIn {
pub fh: u64,
pub offset: u64,
pub length: u64,
pub mode: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseForgetIn {
pub nlookup: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseForgetOne {
pub nodeid: u64,
pub nlookup: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseBatchForgetIn {
pub count: u32,
pub dummy: u32,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseInitOut {
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 padding: u16,
pub unused: [u32; 8],
}
impl Default for FuseInitOut {
fn default() -> Self {
Self {
major: FUSE_KERNEL_VERSION,
minor: FUSE_KERNEL_MINOR_VERSION,
max_readahead: 128 * 1024,
flags: FUSE_ASYNC_READ | FUSE_BIG_WRITES | FUSE_WRITEBACK_CACHE,
max_background: 16,
congestion_threshold: 12,
max_write: 128 * 1024,
time_gran: 1,
max_pages: 32,
padding: 0,
unused: [0; 8],
}
}
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseEntryOut {
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: FuseAttr,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseAttrOut {
pub attr_valid: u64,
pub attr_valid_nsec: u32,
pub dummy: u32,
pub attr: FuseAttr,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseOpenOut {
pub fh: u64,
pub open_flags: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseWriteOut {
pub size: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseGetxattrOut {
pub size: u32,
pub padding: u32,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseStatfsOut {
pub st: StatFs,
}
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct FuseLseekOut {
pub offset: u64,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct FuseDirent {
pub ino: u64,
pub off: u64,
pub namelen: u32,
pub typ: u32,
}
impl FuseDirent {
#[must_use]
pub const fn size(namelen: usize) -> usize {
let base = size_of::<Self>() + namelen;
(base + 7) & !7
}
}
impl FuseOpcode {
#[must_use]
pub fn from_u32(value: u32) -> Option<Self> {
match value {
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),
_ => None,
}
}
}
impl FuseInHeader {
pub const SIZE: usize = size_of::<Self>();
}
impl FuseOutHeader {
pub const SIZE: usize = size_of::<Self>();
#[must_use]
pub const fn success(unique: u64, len: u32) -> Self {
Self {
len,
error: 0,
unique,
}
}
#[must_use]
pub const fn error(unique: u64, errno: i32) -> Self {
Self {
len: Self::SIZE as u32,
error: -errno,
unique,
}
}
}