fuse/
protocol.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Defines the kernel interface of FUSE.
5//!
6//! This was derived from the official fuse.h from the Linux kernel sources. It represents
7//! FUSE protocol version 7.31.
8//!
9//! For more details, see fuse.h.
10#![allow(non_camel_case_types)]
11#![expect(unused_parens)]
12
13use bitfield_struct::bitfield;
14use zerocopy::FromBytes;
15use zerocopy::Immutable;
16use zerocopy::IntoBytes;
17use zerocopy::KnownLayout;
18
19/*
20 * Version negotiation:
21 *
22 * Both the kernel and userspace send the version they support in the
23 * INIT request and reply respectively.
24 *
25 * If the major versions match then both shall use the smallest
26 * of the two minor versions for communication.
27 *
28 * If the kernel supports a larger major version, then userspace shall
29 * reply with the major version it supports, ignore the rest of the
30 * INIT message and expect a new INIT message from the kernel with a
31 * matching major version.
32 *
33 * If the library supports a larger major version, then it shall fall
34 * back to the major protocol version sent by the kernel for
35 * communication and reply with that major version (and an arbitrary
36 * supported minor version).
37 */
38
39/** Version number of this interface */
40pub const FUSE_KERNEL_VERSION: u32 = 7;
41
42/** Minor version number of this interface */
43pub const FUSE_KERNEL_MINOR_VERSION: u32 = 31;
44
45/** The node ID of the root inode */
46pub const FUSE_ROOT_ID: u64 = 1;
47
48/* Make sure all structures are padded to 64bit boundary, so 32bit
49userspace works under 64bit kernels */
50
51#[repr(C)]
52#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
53pub struct fuse_attr {
54    pub ino: u64,
55    pub size: u64,
56    pub blocks: u64,
57    pub atime: u64,
58    pub mtime: u64,
59    pub ctime: u64,
60    pub atimensec: u32,
61    pub mtimensec: u32,
62    pub ctimensec: u32,
63    pub mode: u32,
64    pub nlink: u32,
65    pub uid: u32,
66    pub gid: u32,
67    pub rdev: u32,
68    pub blksize: u32,
69    pub padding: u32,
70}
71
72#[repr(C)]
73#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
74pub struct fuse_sx_time {
75    pub sec: i64,
76    pub nsec: u32,
77    pub _rsvd: u32,
78}
79
80#[repr(C)]
81#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
82pub struct fuse_statx {
83    pub mask: u32,
84    pub blksize: u32,
85    pub attributes: u64,
86    pub nlink: u32,
87    pub uid: u32,
88    pub gid: u32,
89    pub mode: u16,
90    pub _rsvd1: u16,
91    pub ino: u64,
92    pub size: u64,
93    pub blocks: u64,
94    pub attributes_mask: u64,
95    pub atime: fuse_sx_time,
96    pub btime: fuse_sx_time,
97    pub ctime: fuse_sx_time,
98    pub mtime: fuse_sx_time,
99    pub rdev_major: u32,
100    pub rdev_minor: u32,
101    pub dev_major: u32,
102    pub dev_minor: u32,
103    pub _rsvd2: [u64; 14],
104}
105
106#[repr(C)]
107#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
108pub struct fuse_kstatfs {
109    pub blocks: u64,
110    pub bfree: u64,
111    pub bavail: u64,
112    pub files: u64,
113    pub ffree: u64,
114    pub bsize: u32,
115    pub namelen: u32,
116    pub frsize: u32,
117    pub padding: u32,
118    pub spare: [u32; 6],
119}
120
121#[repr(C)]
122#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
123pub struct fuse_file_lock {
124    pub start: u64,
125    pub end: u64,
126    pub lock_type: u32,
127    pub pid: u32, /* tgid */
128}
129
130/**
131 * Bitmasks for fuse_setattr_in.valid
132 */
133pub const FATTR_MODE: u32 = (1 << 0);
134pub const FATTR_UID: u32 = (1 << 1);
135pub const FATTR_GID: u32 = (1 << 2);
136pub const FATTR_SIZE: u32 = (1 << 3);
137pub const FATTR_ATIME: u32 = (1 << 4);
138pub const FATTR_MTIME: u32 = (1 << 5);
139pub const FATTR_FH: u32 = (1 << 6);
140pub const FATTR_ATIME_NOW: u32 = (1 << 7);
141pub const FATTR_MTIME_NOW: u32 = (1 << 8);
142pub const FATTR_LOCKOWNER: u32 = (1 << 9);
143pub const FATTR_CTIME: u32 = (1 << 10);
144pub const FATTR_KILL_SUIDGID: u32 = (1 << 11);
145
146/**
147 * Flags returned by the OPEN request
148 *
149 * FOPEN_DIRECT_IO: bypass page cache for this open file
150 * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
151 * FOPEN_NONSEEKABLE: the file is not seekable
152 * FOPEN_CACHE_DIR: allow caching this directory
153 * FOPEN_STREAM: the file is stream-like (no file position at all)
154 */
155pub const FOPEN_DIRECT_IO: u32 = (1 << 0);
156pub const FOPEN_KEEP_CACHE: u32 = (1 << 1);
157pub const FOPEN_NONSEEKABLE: u32 = (1 << 2);
158pub const FOPEN_CACHE_DIR: u32 = (1 << 3);
159pub const FOPEN_STREAM: u32 = (1 << 4);
160
161/**
162 * INIT request/reply flags
163 *
164 * FUSE_ASYNC_READ: asynchronous read requests
165 * FUSE_POSIX_LOCKS: remote locking for POSIX file locks
166 * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported)
167 * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem
168 * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".."
169 * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB
170 * FUSE_DONT_MASK: don't apply umask to file mode on create operations
171 * FUSE_SPLICE_WRITE: kernel supports splice write on the device
172 * FUSE_SPLICE_MOVE: kernel supports splice move on the device
173 * FUSE_SPLICE_READ: kernel supports splice read on the device
174 * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
175 * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
176 * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
177 * FUSE_DO_READDIRPLUS: do READDIRPLUS (READDIR+LOOKUP in one)
178 * FUSE_READDIRPLUS_AUTO: adaptive readdirplus
179 * FUSE_ASYNC_DIO: asynchronous direct I/O submission
180 * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
181 * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens
182 * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir
183 * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc
184 * FUSE_POSIX_ACL: filesystem supports posix acls
185 * FUSE_ABORT_ERROR: reading the device after abort returns ECONNABORTED
186 * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages
187 * FUSE_CACHE_SYMLINKS: cache READLINK responses
188 * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir
189 * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit request
190 * FUSE_MAP_ALIGNMENT: map_alignment field is valid
191 */
192pub const FUSE_ASYNC_READ: u32 = (1 << 0);
193pub const FUSE_POSIX_LOCKS: u32 = (1 << 1);
194pub const FUSE_FILE_OPS: u32 = (1 << 2);
195pub const FUSE_ATOMIC_O_TRUNC: u32 = (1 << 3);
196pub const FUSE_EXPORT_SUPPORT: u32 = (1 << 4);
197pub const FUSE_BIG_WRITES: u32 = (1 << 5);
198pub const FUSE_DONT_MASK: u32 = (1 << 6);
199pub const FUSE_SPLICE_WRITE: u32 = (1 << 7);
200pub const FUSE_SPLICE_MOVE: u32 = (1 << 8);
201pub const FUSE_SPLICE_READ: u32 = (1 << 9);
202pub const FUSE_FLOCK_LOCKS: u32 = (1 << 10);
203pub const FUSE_HAS_IOCTL_DIR: u32 = (1 << 11);
204pub const FUSE_AUTO_INVAL_DATA: u32 = (1 << 12);
205pub const FUSE_DO_READDIRPLUS: u32 = (1 << 13);
206pub const FUSE_READDIRPLUS_AUTO: u32 = (1 << 14);
207pub const FUSE_ASYNC_DIO: u32 = (1 << 15);
208pub const FUSE_WRITEBACK_CACHE: u32 = (1 << 16);
209pub const FUSE_NO_OPEN_SUPPORT: u32 = (1 << 17);
210pub const FUSE_PARALLEL_DIROPS: u32 = (1 << 18);
211pub const FUSE_HANDLE_KILLPRIV: u32 = (1 << 19);
212pub const FUSE_POSIX_ACL: u32 = (1 << 20);
213pub const FUSE_ABORT_ERROR: u32 = (1 << 21);
214pub const FUSE_MAX_PAGES: u32 = (1 << 22);
215pub const FUSE_CACHE_SYMLINKS: u32 = (1 << 23);
216pub const FUSE_NO_OPENDIR_SUPPORT: u32 = (1 << 24);
217pub const FUSE_EXPLICIT_INVAL_DATA: u32 = (1 << 25);
218pub const FUSE_MAP_ALIGNMENT: u32 = (1 << 26);
219pub const FUSE_SUBMOUNTS: u32 = (1 << 27);
220pub const FUSE_HANDLE_KILLPRIV_V2: u32 = (1 << 28);
221
222/**
223 * CUSE INIT request/reply flags
224 *
225 * CUSE_UNRESTRICTED_IOCTL:  use unrestricted ioctl
226 */
227pub const CUSE_UNRESTRICTED_IOCTL: u32 = (1 << 0);
228
229/**
230 * Release flags
231 */
232pub const FUSE_RELEASE_FLUSH: u32 = (1 << 0);
233pub const FUSE_RELEASE_FLOCK_UNLOCK: u32 = (1 << 1);
234
235/**
236 * Getattr flags
237 */
238pub const FUSE_GETATTR_FH: u32 = (1 << 0);
239
240/**
241 * Lock flags
242 */
243pub const FUSE_LK_FLOCK: u32 = (1 << 0);
244
245/**
246 * WRITE flags
247 *
248 * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
249 * FUSE_WRITE_LOCKOWNER: lock_owner field is valid
250 * FUSE_WRITE_KILL_PRIV: kill suid and sgid bits
251 */
252pub const FUSE_WRITE_CACHE: u32 = (1 << 0);
253pub const FUSE_WRITE_LOCKOWNER: u32 = (1 << 1);
254pub const FUSE_WRITE_KILL_PRIV: u32 = (1 << 2);
255
256/**
257 * Read flags
258 */
259pub const FUSE_READ_LOCKOWNER: u32 = (1 << 1);
260
261/**
262 * Ioctl flags
263 *
264 * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine
265 * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed
266 * FUSE_IOCTL_RETRY: retry with new iovecs
267 * FUSE_IOCTL_32BIT: 32bit ioctl
268 * FUSE_IOCTL_DIR: is a directory
269 * FUSE_IOCTL_COMPAT_X32: x32 compat ioctl on 64bit machine (64bit time_t)
270 *
271 * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs
272 */
273pub const FUSE_IOCTL_COMPAT: u32 = (1 << 0);
274pub const FUSE_IOCTL_UNRESTRICTED: u32 = (1 << 1);
275pub const FUSE_IOCTL_RETRY: u32 = (1 << 2);
276pub const FUSE_IOCTL_32BIT: u32 = (1 << 3);
277pub const FUSE_IOCTL_DIR: u32 = (1 << 4);
278pub const FUSE_IOCTL_COMPAT_X32: u32 = (1 << 5);
279
280pub const FUSE_IOCTL_MAX_IOV: u32 = 256;
281
282/**
283 * Poll flags
284 *
285 * FUSE_POLL_SCHEDULE_NOTIFY: request poll notify
286 */
287pub const FUSE_POLL_SCHEDULE_NOTIFY: u32 = (1 << 0);
288
289/**
290 * Fsync flags
291 *
292 * FUSE_FSYNC_FDATASYNC: Sync data only, not metadata
293 */
294pub const FUSE_FSYNC_FDATASYNC: u32 = (1 << 0);
295
296pub const FUSE_LOOKUP: u32 = 1;
297pub const FUSE_FORGET: u32 = 2; /* no reply */
298pub const FUSE_GETATTR: u32 = 3;
299pub const FUSE_SETATTR: u32 = 4;
300pub const FUSE_READLINK: u32 = 5;
301pub const FUSE_SYMLINK: u32 = 6;
302pub const FUSE_MKNOD: u32 = 8;
303pub const FUSE_MKDIR: u32 = 9;
304pub const FUSE_UNLINK: u32 = 10;
305pub const FUSE_RMDIR: u32 = 11;
306pub const FUSE_RENAME: u32 = 12;
307pub const FUSE_LINK: u32 = 13;
308pub const FUSE_OPEN: u32 = 14;
309pub const FUSE_READ: u32 = 15;
310pub const FUSE_WRITE: u32 = 16;
311pub const FUSE_STATFS: u32 = 17;
312pub const FUSE_RELEASE: u32 = 18;
313pub const FUSE_FSYNC: u32 = 20;
314pub const FUSE_SETXATTR: u32 = 21;
315pub const FUSE_GETXATTR: u32 = 22;
316pub const FUSE_LISTXATTR: u32 = 23;
317pub const FUSE_REMOVEXATTR: u32 = 24;
318pub const FUSE_FLUSH: u32 = 25;
319pub const FUSE_INIT: u32 = 26;
320pub const FUSE_OPENDIR: u32 = 27;
321pub const FUSE_READDIR: u32 = 28;
322pub const FUSE_RELEASEDIR: u32 = 29;
323pub const FUSE_FSYNCDIR: u32 = 30;
324pub const FUSE_GETLK: u32 = 31;
325pub const FUSE_SETLK: u32 = 32;
326pub const FUSE_SETLKW: u32 = 33;
327pub const FUSE_ACCESS: u32 = 34;
328pub const FUSE_CREATE: u32 = 35;
329pub const FUSE_INTERRUPT: u32 = 36;
330pub const FUSE_BMAP: u32 = 37;
331pub const FUSE_DESTROY: u32 = 38;
332pub const FUSE_IOCTL: u32 = 39;
333pub const FUSE_POLL: u32 = 40;
334pub const FUSE_NOTIFY_REPLY: u32 = 41;
335pub const FUSE_BATCH_FORGET: u32 = 42;
336pub const FUSE_FALLOCATE: u32 = 43;
337pub const FUSE_READDIRPLUS: u32 = 44;
338pub const FUSE_RENAME2: u32 = 45;
339pub const FUSE_LSEEK: u32 = 46;
340pub const FUSE_COPY_FILE_RANGE: u32 = 47;
341pub const FUSE_SETUPMAPPING: u32 = 48;
342pub const FUSE_REMOVEMAPPING: u32 = 49;
343pub const FUSE_SYNCFS: u32 = 50;
344pub const FUSE_TMPFILE: u32 = 51;
345pub const FUSE_STATX: u32 = 52;
346/* Special Android FUSE operation */
347pub const FUSE_CANONICAL_PATH: u32 = 2016;
348
349/* CUSE specific operations */
350pub const CUSE_INIT: u32 = 4096;
351
352/* Reserved opcodes: helpful to detect structure endian-ness */
353pub const CUSE_INIT_BSWAP_RESERVED: u32 = 1048576; /* CUSE_INIT << 8 */
354pub const FUSE_INIT_BSWAP_RESERVED: u32 = 436207616; /* FUSE_INIT << 24 */
355
356pub const FUSE_NOTIFY_POLL: u32 = 1;
357pub const FUSE_NOTIFY_INVAL_INODE: u32 = 2;
358pub const FUSE_NOTIFY_INVAL_ENTRY: u32 = 3;
359pub const FUSE_NOTIFY_STORE: u32 = 4;
360pub const FUSE_NOTIFY_RETRIEVE: u32 = 5;
361pub const FUSE_NOTIFY_DELETE: u32 = 6;
362pub const FUSE_NOTIFY_CODE_MAX: u32 = 7;
363
364/* The read buffer is required to be at least 8k, but may be much larger */
365pub const FUSE_MIN_READ_BUFFER: u32 = 8192;
366
367pub const FUSE_COMPAT_ENTRY_OUT_SIZE: u32 = 120;
368
369#[repr(C)]
370#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
371pub struct fuse_entry_out {
372    pub nodeid: u64, /* Inode ID */
373    pub generation: u64, /* Inode generation: nodeid:gen must
374                     be unique for the fs's lifetime */
375    pub entry_valid: u64, /* Cache timeout for the name */
376    pub attr_valid: u64,  /* Cache timeout for the attributes */
377    pub entry_valid_nsec: u32,
378    pub attr_valid_nsec: u32,
379    pub attr: fuse_attr,
380}
381
382#[repr(C)]
383#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
384pub struct fuse_forget_in {
385    pub nlookup: u64,
386}
387
388#[repr(C)]
389#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
390pub struct fuse_forget_one {
391    pub nodeid: u64,
392    pub nlookup: u64,
393}
394
395#[repr(C)]
396#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
397pub struct fuse_batch_forget_in {
398    pub count: u32,
399    pub dummy: u32,
400}
401
402#[repr(C)]
403#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
404pub struct fuse_getattr_in {
405    pub getattr_flags: u32,
406    pub dummy: u32,
407    pub fh: u64,
408}
409
410pub const FUSE_COMPAT_ATTR_OUT_SIZE: u32 = 96;
411
412#[repr(C)]
413#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
414pub struct fuse_attr_out {
415    pub attr_valid: u64, /* Cache timeout for the attributes */
416    pub attr_valid_nsec: u32,
417    pub dummy: u32,
418    pub attr: fuse_attr,
419}
420
421pub const FUSE_COMPAT_MKNOD_IN_SIZE: u32 = 8;
422
423#[repr(C)]
424#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
425pub struct fuse_mknod_in {
426    pub mode: u32,
427    pub rdev: u32,
428    pub umask: u32,
429    pub padding: u32,
430}
431
432#[repr(C)]
433#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
434pub struct fuse_mkdir_in {
435    pub mode: u32,
436    pub umask: u32,
437}
438
439#[repr(C)]
440#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
441pub struct fuse_rename_in {
442    pub newdir: u64,
443}
444
445#[repr(C)]
446#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
447pub struct fuse_rename2_in {
448    pub newdir: u64,
449    pub flags: u32,
450    pub padding: u32,
451}
452
453#[repr(C)]
454#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
455pub struct fuse_link_in {
456    pub oldnodeid: u64,
457}
458
459#[repr(C)]
460#[derive(Clone, Copy, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
461pub struct fuse_setattr_in {
462    pub valid: u32,
463    pub padding: u32,
464    pub fh: u64,
465    pub size: u64,
466    pub lock_owner: u64,
467    pub atime: u64,
468    pub mtime: u64,
469    pub ctime: u64,
470    pub atimensec: u32,
471    pub mtimensec: u32,
472    pub ctimensec: u32,
473    pub mode: u32,
474    pub unused4: u32,
475    pub uid: u32,
476    pub gid: u32,
477    pub unused5: u32,
478}
479
480#[repr(C)]
481#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
482pub struct fuse_open_in {
483    pub flags: u32,
484    pub unused: u32,
485}
486
487#[repr(C)]
488#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
489pub struct fuse_create_in {
490    pub flags: u32,
491    pub mode: u32,
492    pub umask: u32,
493    pub padding: u32,
494}
495
496#[repr(C)]
497#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
498pub struct fuse_open_out {
499    pub fh: u64,
500    pub open_flags: u32,
501    pub padding: u32,
502}
503
504#[repr(C)]
505#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
506pub struct fuse_release_in {
507    pub fh: u64,
508    pub flags: u32,
509    pub release_flags: u32,
510    pub lock_owner: u64,
511}
512
513#[repr(C)]
514#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
515pub struct fuse_flush_in {
516    pub fh: u64,
517    pub unused: u32,
518    pub padding: u32,
519    pub lock_owner: u64,
520}
521
522#[repr(C)]
523#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
524pub struct fuse_read_in {
525    pub fh: u64,
526    pub offset: u64,
527    pub size: u32,
528    pub read_flags: u32,
529    pub lock_owner: u64,
530    pub flags: u32,
531    pub padding: u32,
532}
533
534pub const FUSE_COMPAT_WRITE_IN_SIZE: u32 = 24;
535
536#[repr(C)]
537#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
538pub struct fuse_write_in {
539    pub fh: u64,
540    pub offset: u64,
541    pub size: u32,
542    pub write_flags: u32,
543    pub lock_owner: u64,
544    pub flags: u32,
545    pub padding: u32,
546}
547
548#[repr(C)]
549#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
550pub struct fuse_write_out {
551    pub size: u32,
552    pub padding: u32,
553}
554
555pub const FUSE_COMPAT_STATFS_SIZE: u32 = 48;
556
557#[repr(C)]
558#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
559pub struct fuse_statfs_out {
560    pub st: fuse_kstatfs,
561}
562
563#[repr(C)]
564#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
565pub struct fuse_fsync_in {
566    pub fh: u64,
567    pub fsync_flags: u32,
568    pub padding: u32,
569}
570
571#[repr(C)]
572#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
573pub struct fuse_setxattr_in {
574    pub size: u32,
575    pub flags: u32,
576}
577
578#[repr(C)]
579#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
580pub struct fuse_getxattr_in {
581    pub size: u32,
582    pub padding: u32,
583}
584
585#[repr(C)]
586#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
587pub struct fuse_getxattr_out {
588    pub size: u32,
589    pub padding: u32,
590}
591
592#[repr(C)]
593#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
594pub struct fuse_lk_in {
595    pub fh: u64,
596    pub owner: u64,
597    pub lk: fuse_file_lock,
598    pub lk_flags: u32,
599    pub padding: u32,
600}
601
602#[repr(C)]
603#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
604pub struct fuse_lk_out {
605    pub lk: fuse_file_lock,
606}
607
608#[repr(C)]
609#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
610pub struct fuse_access_in {
611    pub mask: u32,
612    pub padding: u32,
613}
614
615#[repr(C)]
616#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
617pub struct fuse_init_in {
618    pub major: u32,
619    pub minor: u32,
620    pub max_readahead: u32,
621    pub flags: u32,
622}
623
624pub const FUSE_COMPAT_INIT_OUT_SIZE: u32 = 8;
625pub const FUSE_COMPAT_22_INIT_OUT_SIZE: u32 = 24;
626
627#[repr(C)]
628#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
629pub struct fuse_init_out {
630    pub major: u32,
631    pub minor: u32,
632    pub max_readahead: u32,
633    pub flags: u32,
634    pub max_background: u16,
635    pub congestion_threshold: u16,
636    pub max_write: u32,
637    pub time_gran: u32,
638    pub max_pages: u16,
639    pub map_alignment: u16,
640    pub unused: [u32; 8],
641}
642
643pub const CUSE_INIT_INFO_MAX: u32 = 4096;
644
645#[repr(C)]
646#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
647pub struct cuse_init_in {
648    pub major: u32,
649    pub minor: u32,
650    pub unused: u32,
651    pub flags: u32,
652}
653
654#[repr(C)]
655#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
656pub struct cuse_init_out {
657    pub major: u32,
658    pub minor: u32,
659    pub unused: u32,
660    pub flags: u32,
661    pub max_read: u32,
662    pub max_write: u32,
663    pub dev_major: u32, /* chardev major */
664    pub dev_minor: u32, /* chardev minor */
665    pub spare: [u32; 10],
666}
667
668#[repr(C)]
669#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
670pub struct fuse_interrupt_in {
671    pub unique: u64,
672}
673
674#[repr(C)]
675#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
676pub struct fuse_bmap_in {
677    pub block: u64,
678    pub blocksize: u32,
679    pub padding: u32,
680}
681
682#[repr(C)]
683#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
684pub struct fuse_bmap_out {
685    pub block: u64,
686}
687
688#[repr(C)]
689#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
690pub struct fuse_ioctl_in {
691    pub fh: u64,
692    pub flags: u32,
693    pub cmd: u32,
694    pub arg: u64,
695    pub in_size: u32,
696    pub out_size: u32,
697}
698
699#[repr(C)]
700#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
701pub struct fuse_ioctl_iovec {
702    pub base: u64,
703    pub len: u64,
704}
705
706#[repr(C)]
707#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
708pub struct fuse_ioctl_out {
709    pub result: i32,
710    pub flags: u32,
711    pub in_iovs: u32,
712    pub out_iovs: u32,
713}
714
715#[repr(C)]
716#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
717pub struct fuse_poll_in {
718    pub fh: u64,
719    pub kh: u64,
720    pub flags: u32,
721    pub events: u32,
722}
723
724#[repr(C)]
725#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
726pub struct fuse_poll_out {
727    pub revents: u32,
728    pub padding: u32,
729}
730
731#[repr(C)]
732#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
733pub struct fuse_notify_poll_wakeup_out {
734    pub kh: u64,
735}
736
737#[repr(C)]
738#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
739pub struct fuse_fallocate_in {
740    pub fh: u64,
741    pub offset: u64,
742    pub length: u64,
743    pub mode: u32,
744    pub padding: u32,
745}
746
747#[repr(C)]
748#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
749pub struct fuse_in_header {
750    pub len: u32,
751    pub opcode: u32,
752    pub unique: u64,
753    pub nodeid: u64,
754    pub uid: u32,
755    pub gid: u32,
756    pub pid: u32,
757    pub padding: u32,
758}
759
760#[repr(C)]
761#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
762pub struct fuse_out_header {
763    pub len: u32,
764    pub error: i32,
765    pub unique: u64,
766}
767
768#[repr(C)]
769#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
770pub struct fuse_dirent {
771    pub ino: u64,
772    pub off: u64,
773    pub namelen: u32,
774    pub file_type: u32,
775    // char name[];
776}
777
778pub fn fuse_dirent_align(x: usize) -> usize {
779    (((x) + size_of::<u64>() - 1) & !(size_of::<u64>() - 1))
780}
781#[repr(C)]
782#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
783pub struct fuse_direntplus {
784    pub entry_out: fuse_entry_out,
785    pub dirent: fuse_dirent,
786}
787
788#[repr(C)]
789#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
790pub struct fuse_notify_inval_inode_out {
791    pub ino: u64,
792    pub off: i64,
793    pub len: i64,
794}
795
796#[repr(C)]
797#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
798pub struct fuse_notify_inval_entry_out {
799    pub parent: u64,
800    pub namelen: u32,
801    pub padding: u32,
802}
803
804#[repr(C)]
805#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
806pub struct fuse_notify_delete_out {
807    pub parent: u64,
808    pub child: u64,
809    pub namelen: u32,
810    pub padding: u32,
811}
812
813#[repr(C)]
814#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
815pub struct fuse_notify_store_out {
816    pub nodeid: u64,
817    pub offset: u64,
818    pub size: u32,
819    pub padding: u32,
820}
821
822#[repr(C)]
823#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
824pub struct fuse_notify_retrieve_out {
825    pub notify_unique: u64,
826    pub nodeid: u64,
827    pub offset: u64,
828    pub size: u32,
829    pub padding: u32,
830}
831
832/* Matches the size of fuse_write_in */
833#[repr(C)]
834#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
835pub struct fuse_notify_retrieve_in {
836    pub dummy1: u64,
837    pub offset: u64,
838    pub size: u32,
839    pub dummy2: u32,
840    pub dummy3: u64,
841    pub dummy4: u64,
842}
843
844/* Device ioctls: */
845//  const FUSE_DEV_IOC_CLONE: u32 = _IOR(229, 0, u32);
846
847#[repr(C)]
848#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
849pub struct fuse_lseek_in {
850    pub fh: u64,
851    pub offset: u64,
852    pub whence: u32,
853    pub padding: u32,
854}
855
856#[repr(C)]
857#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
858pub struct fuse_lseek_out {
859    pub offset: u64,
860}
861
862#[repr(C)]
863#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
864pub struct fuse_copy_file_range_in {
865    pub fh_in: u64,
866    pub off_in: u64,
867    pub nodeid_out: u64,
868    pub fh_out: u64,
869    pub off_out: u64,
870    pub len: u64,
871    pub flags: u64,
872}
873
874pub const FUSE_SETUPMAPPING_FLAG_WRITE: u64 = (1 << 0);
875
876#[repr(C)]
877#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
878pub struct fuse_setupmapping_in {
879    /* An already open handle */
880    pub fh: u64,
881    /* Offset into the file to start the mapping */
882    pub foffset: u64,
883    /* Length of mapping required */
884    pub len: u64,
885    /* Flags, FUSE_SETUPMAPPING_FLAG_* */
886    pub flags: u64,
887    /* memory offset in to dax window */
888    pub moffset: u64,
889}
890
891#[repr(C)]
892#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
893pub struct fuse_removemapping_in {
894    /* number of fuse_removemapping_one follows */
895    pub count: u32,
896}
897
898#[repr(C)]
899#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
900pub struct fuse_removemapping_one {
901    /* Offset into the dax to start the unmapping */
902    pub moffset: u64,
903    /* Length of mapping required */
904    pub len: u64,
905}
906
907#[repr(C)]
908#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
909pub struct fuse_syncfs_in {
910    pub padding: u64,
911}
912
913#[bitfield(u32)]
914#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
915pub struct StatxFlags {
916    #[bits(13)]
917    _rsvd1: u32,
918    pub force_sync: bool,
919    pub dont_sync: bool,
920    #[bits(17)]
921    _rsvd2: u32,
922}
923
924#[repr(C)]
925#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
926pub struct fuse_statx_in {
927    pub getattr_flags: u32,
928    _rsvd: u32,
929    pub fh: u64,
930    pub flags: StatxFlags,
931    pub mask: u32,
932}
933
934#[repr(C)]
935#[derive(Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
936pub struct fuse_statx_out {
937    pub attr_valid: u64, /* Cache timeout for the attributes */
938    pub attr_valid_nsec: u32,
939    pub flags: StatxFlags,
940    pub _rsvd: [u64; 2],
941    pub statx: fuse_statx,
942}