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