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