• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::mem;
6 
7 use bitflags::bitflags;
8 use data_model::DataInit;
9 use enumn::N;
10 
11 /// Version number of this interface.
12 pub const KERNEL_VERSION: u32 = 7;
13 
14 /// Oldest supported minor version of the fuse interface.
15 pub const OLDEST_SUPPORTED_KERNEL_MINOR_VERSION: u32 = 27;
16 
17 /// Minor version number of this interface.
18 pub const KERNEL_MINOR_VERSION: u32 = 31;
19 
20 /// The ID of the inode corresponding to the root directory of the file system.
21 pub const ROOT_ID: u64 = 1;
22 
23 // Bitmasks for `fuse_setattr_in.valid`.
24 const FATTR_MODE: u32 = 1;
25 const FATTR_UID: u32 = 2;
26 const FATTR_GID: u32 = 4;
27 const FATTR_SIZE: u32 = 8;
28 const FATTR_ATIME: u32 = 16;
29 const FATTR_MTIME: u32 = 32;
30 pub const FATTR_FH: u32 = 64;
31 const FATTR_ATIME_NOW: u32 = 128;
32 const FATTR_MTIME_NOW: u32 = 256;
33 pub const FATTR_LOCKOWNER: u32 = 512;
34 const FATTR_CTIME: u32 = 1024;
35 
36 bitflags! {
37     pub struct SetattrValid: u32 {
38         const MODE = FATTR_MODE;
39         const UID = FATTR_UID;
40         const GID = FATTR_GID;
41         const SIZE = FATTR_SIZE;
42         const ATIME = FATTR_ATIME;
43         const MTIME = FATTR_MTIME;
44         const ATIME_NOW = FATTR_ATIME_NOW;
45         const MTIME_NOW = FATTR_MTIME_NOW;
46         const CTIME = FATTR_CTIME;
47     }
48 }
49 
50 // Flags returned by the OPEN request.
51 
52 /// Bypass page cache for this open file.
53 const FOPEN_DIRECT_IO: u32 = 1;
54 
55 /// Don't invalidate the data cache on open.
56 const FOPEN_KEEP_CACHE: u32 = 2;
57 
58 /// The file is not seekable.
59 const FOPEN_NONSEEKABLE: u32 = 4;
60 
61 /// Allow caching the directory entries.
62 const FOPEN_CACHE_DIR: u32 = 8;
63 
64 /// This file is stream-like (i.e., no file position).
65 const FOPEN_STREAM: u32 = 16;
66 
67 bitflags! {
68     /// Options controlling the behavior of files opened by the server in response
69     /// to an open or create request.
70     pub struct OpenOptions: u32 {
71         const DIRECT_IO = FOPEN_DIRECT_IO;
72         const KEEP_CACHE = FOPEN_KEEP_CACHE;
73         const NONSEEKABLE = FOPEN_NONSEEKABLE;
74         const CACHE_DIR = FOPEN_CACHE_DIR;
75         const STREAM = FOPEN_STREAM;
76     }
77 }
78 
79 // INIT request/reply flags.
80 
81 /// Asynchronous read requests.
82 const ASYNC_READ: u32 = 1;
83 
84 /// Remote locking for POSIX file locks.
85 const POSIX_LOCKS: u32 = 2;
86 
87 /// Kernel sends file handle for fstat, etc... (not yet supported).
88 const FILE_OPS: u32 = 4;
89 
90 /// Handles the O_TRUNC open flag in the filesystem.
91 const ATOMIC_O_TRUNC: u32 = 8;
92 
93 /// FileSystem handles lookups of "." and "..".
94 const EXPORT_SUPPORT: u32 = 16;
95 
96 /// FileSystem can handle write size larger than 4kB.
97 const BIG_WRITES: u32 = 32;
98 
99 /// Don't apply umask to file mode on create operations.
100 const DONT_MASK: u32 = 64;
101 
102 /// Kernel supports splice write on the device.
103 const SPLICE_WRITE: u32 = 128;
104 
105 /// Kernel supports splice move on the device.
106 const SPLICE_MOVE: u32 = 256;
107 
108 /// Kernel supports splice read on the device.
109 const SPLICE_READ: u32 = 512;
110 
111 /// Remote locking for BSD style file locks.
112 const FLOCK_LOCKS: u32 = 1024;
113 
114 /// Kernel supports ioctl on directories.
115 const HAS_IOCTL_DIR: u32 = 2048;
116 
117 /// Automatically invalidate cached pages.
118 const AUTO_INVAL_DATA: u32 = 4096;
119 
120 /// Do READDIRPLUS (READDIR+LOOKUP in one).
121 const DO_READDIRPLUS: u32 = 8192;
122 
123 /// Adaptive readdirplus.
124 const READDIRPLUS_AUTO: u32 = 16384;
125 
126 /// Asynchronous direct I/O submission.
127 const ASYNC_DIO: u32 = 32768;
128 
129 /// Use writeback cache for buffered writes.
130 const WRITEBACK_CACHE: u32 = 65536;
131 
132 /// Kernel supports zero-message opens.
133 const NO_OPEN_SUPPORT: u32 = 131072;
134 
135 /// Allow parallel lookups and readdir.
136 const PARALLEL_DIROPS: u32 = 262144;
137 
138 /// Fs handles killing suid/sgid/cap on write/chown/trunc.
139 const HANDLE_KILLPRIV: u32 = 524288;
140 
141 /// FileSystem supports posix acls.
142 const POSIX_ACL: u32 = 1048576;
143 
144 /// Reading the device after an abort returns `ECONNABORTED`.
145 const ABORT_ERROR: u32 = 2097152;
146 
147 /// The reply to the `init` message contains the max number of request pages.
148 const MAX_PAGES: u32 = 4194304;
149 
150 /// Cache `readlink` responses.
151 const CACHE_SYMLINKS: u32 = 8388608;
152 
153 /// Kernel supports zero-message opens for directories.
154 const NO_OPENDIR_SUPPORT: u32 = 16777216;
155 
156 /// Kernel supports explicit cache invalidation.
157 const EXPLICIT_INVAL_DATA: u32 = 33554432;
158 
159 /// The `map_alignment` field of the `InitOut` struct is valid.
160 const MAP_ALIGNMENT: u32 = 67108864;
161 
162 bitflags! {
163     /// A bitfield passed in as a parameter to and returned from the `init` method of the
164     /// `FileSystem` trait.
165     pub struct FsOptions: u32 {
166         /// Indicates that the filesystem supports asynchronous read requests.
167         ///
168         /// If this capability is not requested/available, the kernel will ensure that there is at
169         /// most one pending read request per file-handle at any time, and will attempt to order
170         /// read requests by increasing offset.
171         ///
172         /// This feature is enabled by default when supported by the kernel.
173         const ASYNC_READ = ASYNC_READ;
174 
175         /// Indicates that the filesystem supports "remote" locking.
176         ///
177         /// This feature is not enabled by default and should only be set if the filesystem
178         /// implements the `getlk` and `setlk` methods of the `FileSystem` trait.
179         const POSIX_LOCKS = POSIX_LOCKS;
180 
181         /// Kernel sends file handle for fstat, etc... (not yet supported).
182         const FILE_OPS = FILE_OPS;
183 
184         /// Indicates that the filesystem supports the `O_TRUNC` open flag. If disabled, and an
185         /// application specifies `O_TRUNC`, fuse first calls `setattr` to truncate the file and
186         /// then calls `open` with `O_TRUNC` filtered out.
187         ///
188         /// This feature is enabled by default when supported by the kernel.
189         const ATOMIC_O_TRUNC = ATOMIC_O_TRUNC;
190 
191         /// Indicates that the filesystem supports lookups of "." and "..".
192         ///
193         /// This feature is disabled by default.
194         const EXPORT_SUPPORT = EXPORT_SUPPORT;
195 
196         /// FileSystem can handle write size larger than 4kB.
197         const BIG_WRITES = BIG_WRITES;
198 
199         /// Indicates that the kernel should not apply the umask to the file mode on create
200         /// operations.
201         ///
202         /// This feature is disabled by default.
203         const DONT_MASK = DONT_MASK;
204 
205         /// Indicates that the server should try to use `splice(2)` when writing to the fuse device.
206         /// This may improve performance.
207         ///
208         /// This feature is not currently supported.
209         const SPLICE_WRITE = SPLICE_WRITE;
210 
211         /// Indicates that the server should try to move pages instead of copying when writing to /
212         /// reading from the fuse device. This may improve performance.
213         ///
214         /// This feature is not currently supported.
215         const SPLICE_MOVE = SPLICE_MOVE;
216 
217         /// Indicates that the server should try to use `splice(2)` when reading from the fuse
218         /// device. This may improve performance.
219         ///
220         /// This feature is not currently supported.
221         const SPLICE_READ = SPLICE_READ;
222 
223         /// If set, then calls to `flock` will be emulated using POSIX locks and must
224         /// then be handled by the filesystem's `setlock()` handler.
225         ///
226         /// If not set, `flock` calls will be handled by the FUSE kernel module internally (so any
227         /// access that does not go through the kernel cannot be taken into account).
228         ///
229         /// This feature is disabled by default.
230         const FLOCK_LOCKS = FLOCK_LOCKS;
231 
232         /// Indicates that the filesystem supports ioctl's on directories.
233         ///
234         /// This feature is enabled by default when supported by the kernel.
235         const HAS_IOCTL_DIR = HAS_IOCTL_DIR;
236 
237         /// Traditionally, while a file is open the FUSE kernel module only asks the filesystem for
238         /// an update of the file's attributes when a client attempts to read beyond EOF. This is
239         /// unsuitable for e.g. network filesystems, where the file contents may change without the
240         /// kernel knowing about it.
241         ///
242         /// If this flag is set, FUSE will check the validity of the attributes on every read. If
243         /// the attributes are no longer valid (i.e., if the *attribute* timeout has expired) then
244         /// FUSE will first send another `getattr` request. If the new mtime differs from the
245         /// previous value, any cached file *contents* will be invalidated as well.
246         ///
247         /// This flag should always be set when available. If all file changes go through the
248         /// kernel, *attribute* validity should be set to a very large number to avoid unnecessary
249         /// `getattr()` calls.
250         ///
251         /// This feature is enabled by default when supported by the kernel.
252         const AUTO_INVAL_DATA = AUTO_INVAL_DATA;
253 
254         /// Indicates that the filesystem supports readdirplus.
255         ///
256         /// The feature is not enabled by default and should only be set if the filesystem
257         /// implements the `readdirplus` method of the `FileSystem` trait.
258         const DO_READDIRPLUS = DO_READDIRPLUS;
259 
260         /// Indicates that the filesystem supports adaptive readdirplus.
261         ///
262         /// If `DO_READDIRPLUS` is not set, this flag has no effect.
263         ///
264         /// If `DO_READDIRPLUS` is set and this flag is not set, the kernel will always issue
265         /// `readdirplus()` requests to retrieve directory contents.
266         ///
267         /// If `DO_READDIRPLUS` is set and this flag is set, the kernel will issue both `readdir()`
268         /// and `readdirplus()` requests, depending on how much information is expected to be
269         /// required.
270         ///
271         /// This feature is not enabled by default and should only be set if the file system
272         /// implements both the `readdir` and `readdirplus` methods of the `FileSystem` trait.
273         const READDIRPLUS_AUTO = READDIRPLUS_AUTO;
274 
275         /// Indicates that the filesystem supports asynchronous direct I/O submission.
276         ///
277         /// If this capability is not requested/available, the kernel will ensure that there is at
278         /// most one pending read and one pending write request per direct I/O file-handle at any
279         /// time.
280         ///
281         /// This feature is enabled by default when supported by the kernel.
282         const ASYNC_DIO = ASYNC_DIO;
283 
284         /// Indicates that writeback caching should be enabled. This means that individual write
285         /// request may be buffered and merged in the kernel before they are sent to the file
286         /// system.
287         ///
288         /// This feature is disabled by default.
289         const WRITEBACK_CACHE = WRITEBACK_CACHE;
290 
291         /// Indicates support for zero-message opens. If this flag is set in the `capable` parameter
292         /// of the `init` trait method, then the file system may return `ENOSYS` from the open() handler
293         /// to indicate success. Further attempts to open files will be handled in the kernel. (If
294         /// this flag is not set, returning ENOSYS will be treated as an error and signaled to the
295         /// caller).
296         ///
297         /// Setting (or not setting) the field in the `FsOptions` returned from the `init` method
298         /// has no effect.
299         const ZERO_MESSAGE_OPEN = NO_OPEN_SUPPORT;
300 
301         /// Indicates support for parallel directory operations. If this flag is unset, the FUSE
302         /// kernel module will ensure that lookup() and readdir() requests are never issued
303         /// concurrently for the same directory.
304         ///
305         /// This feature is enabled by default when supported by the kernel.
306         const PARALLEL_DIROPS = PARALLEL_DIROPS;
307 
308         /// Indicates that the file system is responsible for unsetting setuid and setgid bits when a
309         /// file is written, truncated, or its owner is changed.
310         ///
311         /// This feature is enabled by default when supported by the kernel.
312         const HANDLE_KILLPRIV = HANDLE_KILLPRIV;
313 
314         /// Indicates support for POSIX ACLs.
315         ///
316         /// If this feature is enabled, the kernel will cache and have responsibility for enforcing
317         /// ACLs. ACL will be stored as xattrs and passed to userspace, which is responsible for
318         /// updating the ACLs in the filesystem, keeping the file mode in sync with the ACL, and
319         /// ensuring inheritance of default ACLs when new filesystem nodes are created. Note that
320         /// this requires that the file system is able to parse and interpret the xattr
321         /// representation of ACLs.
322         ///
323         /// Enabling this feature implicitly turns on the `default_permissions` mount option (even
324         /// if it was not passed to mount(2)).
325         ///
326         /// This feature is disabled by default.
327         const POSIX_ACL = POSIX_ACL;
328 
329         /// Indicates that the kernel may cache responses to `readlink` calls.
330         const CACHE_SYMLINKS = CACHE_SYMLINKS;
331 
332         /// Indicates support for zero-message opens for directories. If this flag is set in the
333         /// `capable` parameter of the `init` trait method, then the file system may return `ENOSYS`
334         /// from the opendir() handler to indicate success. Further attempts to open directories
335         /// will be handled in the kernel. (If this flag is not set, returning ENOSYS will be
336         /// treated as an error and signaled to the caller).
337         ///
338         /// Setting (or not setting) the field in the `FsOptions` returned from the `init` method
339         /// has no effect.
340         const ZERO_MESSAGE_OPENDIR = NO_OPENDIR_SUPPORT;
341 
342         /// Indicates support for invalidating cached pages only on explicit request.
343         ///
344         /// If this flag is set in the `capable` parameter of the `init` trait method, then the FUSE
345         /// kernel module supports invalidating cached pages only on explicit request by the
346         /// filesystem.
347         ///
348         /// By setting this flag in the return value of the `init` trait method, the filesystem is
349         /// responsible for invalidating cached pages through explicit requests to the kernel.
350         ///
351         /// Note that setting this flag does not prevent the cached pages from being flushed by OS
352         /// itself and/or through user actions.
353         ///
354         /// Note that if both EXPLICIT_INVAL_DATA and AUTO_INVAL_DATA are set in the `capable`
355         /// parameter of the `init` trait method then AUTO_INVAL_DATA takes precedence.
356         ///
357         /// This feature is disabled by default.
358         const EXPLICIT_INVAL_DATA = EXPLICIT_INVAL_DATA;
359 
360         /// Indicates that the `map_alignment` field of the `InitOut` struct is valid.
361         ///
362         /// The `MAP_ALIGNMENT` field is used by the FUSE kernel driver to ensure that its DAX
363         /// mapping requests are pagesize-aligned. This field automatically set by the server and
364         /// this feature is enabled by default.
365         const MAP_ALIGNMENT = MAP_ALIGNMENT;
366 
367 
368         /// Indicates that the `max_pages` field of the `InitOut` struct is valid.
369         ///
370         /// This field is used by the kernel driver to determine the maximum number of pages that
371         /// may be used for any read or write requests.
372         const MAX_PAGES = MAX_PAGES;
373     }
374 }
375 
376 // Release flags.
377 pub const RELEASE_FLUSH: u32 = 1;
378 pub const RELEASE_FLOCK_UNLOCK: u32 = 2;
379 
380 // Getattr flags.
381 pub const GETATTR_FH: u32 = 1;
382 
383 // Lock flags.
384 pub const LK_FLOCK: u32 = 1;
385 
386 // Write flags.
387 
388 /// Delayed write from page cache, file handle is guessed.
389 pub const WRITE_CACHE: u32 = 1;
390 
391 /// `lock_owner` field is valid.
392 pub const WRITE_LOCKOWNER: u32 = 2;
393 
394 /// Kill the suid and sgid bits.
395 pub const WRITE_KILL_PRIV: u32 = 3;
396 
397 // Read flags.
398 pub const READ_LOCKOWNER: u32 = 2;
399 
400 // Ioctl flags.
401 
402 /// 32bit compat ioctl on 64bit machine
403 const IOCTL_COMPAT: u32 = 1;
404 
405 /// Not restricted to well-formed ioctls, retry allowed
406 const IOCTL_UNRESTRICTED: u32 = 2;
407 
408 /// Retry with new iovecs
409 const IOCTL_RETRY: u32 = 4;
410 
411 /// 32bit ioctl
412 const IOCTL_32BIT: u32 = 8;
413 
414 /// Is a directory
415 const IOCTL_DIR: u32 = 16;
416 
417 /// 32-bit compat ioctl on 64-bit machine with 64-bit time_t.
418 const IOCTL_COMPAT_X32: u32 = 32;
419 
420 /// Maximum of in_iovecs + out_iovecs
421 pub const IOCTL_MAX_IOV: usize = 256;
422 
423 bitflags! {
424     pub struct IoctlFlags: u32 {
425         /// 32bit compat ioctl on 64bit machine
426         const COMPAT = IOCTL_COMPAT;
427 
428         /// Not restricted to well-formed ioctls, retry allowed
429         const UNRESTRICTED = IOCTL_UNRESTRICTED;
430 
431         /// Retry with new iovecs
432         const RETRY = IOCTL_RETRY;
433 
434         /// 32bit ioctl
435         const IOCTL_32BIT = IOCTL_32BIT;
436 
437         /// Is a directory
438         const DIR = IOCTL_DIR;
439 
440         /// 32-bit compat ioctl on 64-bit machine with 64-bit time_t.
441         const COMPAT_X32 = IOCTL_COMPAT_X32;
442     }
443 }
444 
445 /// Request poll notify.
446 pub const POLL_SCHEDULE_NOTIFY: u32 = 1;
447 
448 /// The read buffer is required to be at least 8k, but may be much larger.
449 pub const FUSE_MIN_READ_BUFFER: u32 = 8192;
450 
451 pub const FUSE_COMPAT_ENTRY_OUT_SIZE: u32 = 120;
452 pub const FUSE_COMPAT_ATTR_OUT_SIZE: u32 = 96;
453 pub const FUSE_COMPAT_MKNOD_IN_SIZE: u32 = 8;
454 pub const FUSE_COMPAT_WRITE_IN_SIZE: u32 = 24;
455 pub const FUSE_COMPAT_STATFS_SIZE: u32 = 48;
456 pub const FUSE_COMPAT_INIT_OUT_SIZE: u32 = 8;
457 pub const FUSE_COMPAT_22_INIT_OUT_SIZE: u32 = 24;
458 
459 const SETUPMAPPING_FLAG_WRITE: u64 = 1;
460 const SETUPMAPPING_FLAG_READ: u64 = 2;
461 
462 bitflags! {
463     pub struct SetUpMappingFlags: u64 {
464         /// Create writable mapping.
465         const WRITE = SETUPMAPPING_FLAG_WRITE;
466         /// Create readable mapping.
467         const READ = SETUPMAPPING_FLAG_READ;
468     }
469 }
470 
471 // Message definitions follow.  It is safe to implement DataInit for all of these
472 // because they are POD types.
473 
474 #[repr(C)]
475 #[derive(Debug, Default, Copy, Clone)]
476 pub struct Attr {
477     pub ino: u64,
478     pub size: u64,
479     pub blocks: u64,
480     pub atime: u64,
481     pub mtime: u64,
482     pub ctime: u64,
483     pub atimensec: u32,
484     pub mtimensec: u32,
485     pub ctimensec: u32,
486     pub mode: u32,
487     pub nlink: u32,
488     pub uid: u32,
489     pub gid: u32,
490     pub rdev: u32,
491     pub blksize: u32,
492     pub padding: u32,
493 }
494 unsafe impl DataInit for Attr {}
495 
496 impl From<libc::stat64> for Attr {
from(st: libc::stat64) -> Attr497     fn from(st: libc::stat64) -> Attr {
498         Attr {
499             ino: st.st_ino,
500             size: st.st_size as u64,
501             blocks: st.st_blocks as u64,
502             atime: st.st_atime as u64,
503             mtime: st.st_mtime as u64,
504             ctime: st.st_ctime as u64,
505             atimensec: st.st_atime_nsec as u32,
506             mtimensec: st.st_mtime_nsec as u32,
507             ctimensec: st.st_ctime_nsec as u32,
508             mode: st.st_mode,
509             nlink: st.st_nlink as u32,
510             uid: st.st_uid,
511             gid: st.st_gid,
512             rdev: st.st_rdev as u32,
513             blksize: st.st_blksize as u32,
514             ..Default::default()
515         }
516     }
517 }
518 
519 #[repr(C)]
520 #[derive(Debug, Default, Copy, Clone)]
521 pub struct Kstatfs {
522     pub blocks: u64,
523     pub bfree: u64,
524     pub bavail: u64,
525     pub files: u64,
526     pub ffree: u64,
527     pub bsize: u32,
528     pub namelen: u32,
529     pub frsize: u32,
530     pub padding: u32,
531     pub spare: [u32; 6],
532 }
533 unsafe impl DataInit for Kstatfs {}
534 
535 impl From<libc::statvfs64> for Kstatfs {
from(st: libc::statvfs64) -> Self536     fn from(st: libc::statvfs64) -> Self {
537         Kstatfs {
538             blocks: st.f_blocks,
539             bfree: st.f_bfree,
540             bavail: st.f_bavail,
541             files: st.f_files,
542             ffree: st.f_ffree,
543             bsize: st.f_bsize as u32,
544             namelen: st.f_namemax as u32,
545             frsize: st.f_frsize as u32,
546             ..Default::default()
547         }
548     }
549 }
550 
551 #[repr(C)]
552 #[derive(Debug, Default, Copy, Clone)]
553 pub struct FileLock {
554     pub start: u64,
555     pub end: u64,
556     pub type_: u32,
557     pub pid: u32, /* tgid */
558 }
559 unsafe impl DataInit for FileLock {}
560 
561 #[repr(u32)]
562 #[derive(Debug, Copy, Clone, N)]
563 pub enum Opcode {
564     Lookup = 1,
565     Forget = 2, /* No Reply */
566     Getattr = 3,
567     Setattr = 4,
568     Readlink = 5,
569     Symlink = 6,
570     Mknod = 8,
571     Mkdir = 9,
572     Unlink = 10,
573     Rmdir = 11,
574     Rename = 12,
575     Link = 13,
576     Open = 14,
577     Read = 15,
578     Write = 16,
579     Statfs = 17,
580     Release = 18,
581     Fsync = 20,
582     Setxattr = 21,
583     Getxattr = 22,
584     Listxattr = 23,
585     Removexattr = 24,
586     Flush = 25,
587     Init = 26,
588     Opendir = 27,
589     Readdir = 28,
590     Releasedir = 29,
591     Fsyncdir = 30,
592     Getlk = 31,
593     Setlk = 32,
594     Setlkw = 33,
595     Access = 34,
596     Create = 35,
597     Interrupt = 36,
598     Bmap = 37,
599     Destroy = 38,
600     Ioctl = 39,
601     Poll = 40,
602     NotifyReply = 41,
603     BatchForget = 42,
604     Fallocate = 43,
605     Readdirplus = 44,
606     Rename2 = 45,
607     Lseek = 46,
608     CopyFileRange = 47,
609     SetUpMapping = 48,
610     RemoveMapping = 49,
611 
612     ChromeOsTmpfile = u32::MAX,
613 }
614 
615 #[repr(u32)]
616 #[derive(Debug, Copy, Clone, N)]
617 pub enum NotifyOpcode {
618     Poll = 1,
619     InvalInode = 2,
620     InvalEntry = 3,
621     Store = 4,
622     Retrieve = 5,
623     Delete = 6,
624     CodeMax = 7,
625 }
626 
627 #[repr(C)]
628 #[derive(Debug, Default, Copy, Clone)]
629 pub struct EntryOut {
630     pub nodeid: u64,      /* Inode ID */
631     pub generation: u64,  /* Inode generation: nodeid:gen must be unique for the fs's lifetime */
632     pub entry_valid: u64, /* Cache timeout for the name */
633     pub attr_valid: u64,  /* Cache timeout for the attributes */
634     pub entry_valid_nsec: u32,
635     pub attr_valid_nsec: u32,
636     pub attr: Attr,
637 }
638 unsafe impl DataInit for EntryOut {}
639 
640 #[repr(C)]
641 #[derive(Debug, Default, Copy, Clone)]
642 pub struct ForgetIn {
643     pub nlookup: u64,
644 }
645 unsafe impl DataInit for ForgetIn {}
646 
647 #[repr(C)]
648 #[derive(Debug, Default, Copy, Clone)]
649 pub struct ForgetOne {
650     pub nodeid: u64,
651     pub nlookup: u64,
652 }
653 unsafe impl DataInit for ForgetOne {}
654 
655 #[repr(C)]
656 #[derive(Debug, Default, Copy, Clone)]
657 pub struct BatchForgetIn {
658     pub count: u32,
659     pub dummy: u32,
660 }
661 unsafe impl DataInit for BatchForgetIn {}
662 
663 #[repr(C)]
664 #[derive(Debug, Default, Copy, Clone)]
665 pub struct GetattrIn {
666     pub flags: u32,
667     pub dummy: u32,
668     pub fh: u64,
669 }
670 unsafe impl DataInit for GetattrIn {}
671 
672 #[repr(C)]
673 #[derive(Debug, Default, Copy, Clone)]
674 pub struct AttrOut {
675     pub attr_valid: u64, /* Cache timeout for the attributes */
676     pub attr_valid_nsec: u32,
677     pub dummy: u32,
678     pub attr: Attr,
679 }
680 unsafe impl DataInit for AttrOut {}
681 
682 #[repr(C)]
683 #[derive(Debug, Default, Copy, Clone)]
684 pub struct MknodIn {
685     pub mode: u32,
686     pub rdev: u32,
687     pub umask: u32,
688     pub padding: u32,
689 }
690 unsafe impl DataInit for MknodIn {}
691 
692 #[repr(C)]
693 #[derive(Debug, Default, Copy, Clone)]
694 pub struct MkdirIn {
695     pub mode: u32,
696     pub umask: u32,
697 }
698 unsafe impl DataInit for MkdirIn {}
699 
700 #[repr(C)]
701 #[derive(Debug, Default, Copy, Clone)]
702 pub struct ChromeOsTmpfileIn {
703     pub mode: u32,
704     pub umask: u32,
705 }
706 unsafe impl DataInit for ChromeOsTmpfileIn {}
707 
708 #[repr(C)]
709 #[derive(Debug, Default, Copy, Clone)]
710 pub struct RenameIn {
711     pub newdir: u64,
712 }
713 unsafe impl DataInit for RenameIn {}
714 
715 #[repr(C)]
716 #[derive(Debug, Default, Copy, Clone)]
717 pub struct Rename2In {
718     pub newdir: u64,
719     pub flags: u32,
720     pub padding: u32,
721 }
722 unsafe impl DataInit for Rename2In {}
723 
724 #[repr(C)]
725 #[derive(Debug, Default, Copy, Clone)]
726 pub struct LinkIn {
727     pub oldnodeid: u64,
728 }
729 unsafe impl DataInit for LinkIn {}
730 
731 #[repr(C)]
732 #[derive(Debug, Default, Copy, Clone)]
733 pub struct SetattrIn {
734     pub valid: u32,
735     pub padding: u32,
736     pub fh: u64,
737     pub size: u64,
738     pub lock_owner: u64,
739     pub atime: u64,
740     pub mtime: u64,
741     pub ctime: u64,
742     pub atimensec: u32,
743     pub mtimensec: u32,
744     pub ctimensec: u32,
745     pub mode: u32,
746     pub unused4: u32,
747     pub uid: u32,
748     pub gid: u32,
749     pub unused5: u32,
750 }
751 unsafe impl DataInit for SetattrIn {}
752 
753 impl From<SetattrIn> for libc::stat64 {
from(s: SetattrIn) -> libc::stat64754     fn from(s: SetattrIn) -> libc::stat64 {
755         // Safe because we are zero-initializing a struct with only POD fields.
756         let mut out: libc::stat64 = unsafe { mem::zeroed() };
757         out.st_mode = s.mode;
758         out.st_uid = s.uid;
759         out.st_gid = s.gid;
760         out.st_size = s.size as i64;
761         out.st_atime = s.atime as libc::time_t;
762         out.st_mtime = s.mtime as libc::time_t;
763         out.st_ctime = s.ctime as libc::time_t;
764         out.st_atime_nsec = s.atimensec as libc::c_long;
765         out.st_mtime_nsec = s.mtimensec as libc::c_long;
766         out.st_ctime_nsec = s.ctimensec as libc::c_long;
767 
768         out
769     }
770 }
771 
772 #[repr(C)]
773 #[derive(Debug, Default, Copy, Clone)]
774 pub struct OpenIn {
775     pub flags: u32,
776     pub unused: u32,
777 }
778 unsafe impl DataInit for OpenIn {}
779 
780 #[repr(C)]
781 #[derive(Debug, Default, Copy, Clone)]
782 pub struct CreateIn {
783     pub flags: u32,
784     pub mode: u32,
785     pub umask: u32,
786     pub padding: u32,
787 }
788 unsafe impl DataInit for CreateIn {}
789 
790 #[repr(C)]
791 #[derive(Debug, Default, Copy, Clone)]
792 pub struct OpenOut {
793     pub fh: u64,
794     pub open_flags: u32,
795     pub padding: u32,
796 }
797 unsafe impl DataInit for OpenOut {}
798 
799 #[repr(C)]
800 #[derive(Debug, Default, Copy, Clone)]
801 pub struct ReleaseIn {
802     pub fh: u64,
803     pub flags: u32,
804     pub release_flags: u32,
805     pub lock_owner: u64,
806 }
807 unsafe impl DataInit for ReleaseIn {}
808 
809 #[repr(C)]
810 #[derive(Debug, Default, Copy, Clone)]
811 pub struct FlushIn {
812     pub fh: u64,
813     pub unused: u32,
814     pub padding: u32,
815     pub lock_owner: u64,
816 }
817 unsafe impl DataInit for FlushIn {}
818 
819 #[repr(C)]
820 #[derive(Debug, Default, Copy, Clone)]
821 pub struct ReadIn {
822     pub fh: u64,
823     pub offset: u64,
824     pub size: u32,
825     pub read_flags: u32,
826     pub lock_owner: u64,
827     pub flags: u32,
828     pub padding: u32,
829 }
830 unsafe impl DataInit for ReadIn {}
831 
832 #[repr(C)]
833 #[derive(Debug, Default, Copy, Clone)]
834 pub struct WriteIn {
835     pub fh: u64,
836     pub offset: u64,
837     pub size: u32,
838     pub write_flags: u32,
839     pub lock_owner: u64,
840     pub flags: u32,
841     pub padding: u32,
842 }
843 unsafe impl DataInit for WriteIn {}
844 
845 #[repr(C)]
846 #[derive(Debug, Default, Copy, Clone)]
847 pub struct WriteOut {
848     pub size: u32,
849     pub padding: u32,
850 }
851 unsafe impl DataInit for WriteOut {}
852 
853 #[repr(C)]
854 #[derive(Debug, Default, Copy, Clone)]
855 pub struct StatfsOut {
856     pub st: Kstatfs,
857 }
858 unsafe impl DataInit for StatfsOut {}
859 
860 #[repr(C)]
861 #[derive(Debug, Default, Copy, Clone)]
862 pub struct FsyncIn {
863     pub fh: u64,
864     pub fsync_flags: u32,
865     pub padding: u32,
866 }
867 unsafe impl DataInit for FsyncIn {}
868 
869 #[repr(C)]
870 #[derive(Debug, Default, Copy, Clone)]
871 pub struct SetxattrIn {
872     pub size: u32,
873     pub flags: u32,
874 }
875 unsafe impl DataInit for SetxattrIn {}
876 
877 #[repr(C)]
878 #[derive(Debug, Default, Copy, Clone)]
879 pub struct GetxattrIn {
880     pub size: u32,
881     pub padding: u32,
882 }
883 unsafe impl DataInit for GetxattrIn {}
884 
885 #[repr(C)]
886 #[derive(Debug, Default, Copy, Clone)]
887 pub struct GetxattrOut {
888     pub size: u32,
889     pub padding: u32,
890 }
891 unsafe impl DataInit for GetxattrOut {}
892 
893 #[repr(C)]
894 #[derive(Debug, Default, Copy, Clone)]
895 pub struct LkIn {
896     pub fh: u64,
897     pub owner: u64,
898     pub lk: FileLock,
899     pub lk_flags: u32,
900     pub padding: u32,
901 }
902 unsafe impl DataInit for LkIn {}
903 
904 #[repr(C)]
905 #[derive(Debug, Default, Copy, Clone)]
906 pub struct LkOut {
907     pub lk: FileLock,
908 }
909 unsafe impl DataInit for LkOut {}
910 
911 #[repr(C)]
912 #[derive(Debug, Default, Copy, Clone)]
913 pub struct AccessIn {
914     pub mask: u32,
915     pub padding: u32,
916 }
917 unsafe impl DataInit for AccessIn {}
918 
919 #[repr(C)]
920 #[derive(Debug, Default, Copy, Clone)]
921 pub struct InitIn {
922     pub major: u32,
923     pub minor: u32,
924     pub max_readahead: u32,
925     pub flags: u32,
926 }
927 unsafe impl DataInit for InitIn {}
928 
929 #[repr(C)]
930 #[derive(Debug, Default, Copy, Clone)]
931 pub struct InitOut {
932     pub major: u32,
933     pub minor: u32,
934     pub max_readahead: u32,
935     pub flags: u32,
936     pub max_background: u16,
937     pub congestion_threshold: u16,
938     pub max_write: u32,
939     pub time_gran: u32,
940     pub max_pages: u16,
941     pub map_alignment: u16,
942     pub unused: [u32; 8],
943 }
944 unsafe impl DataInit for InitOut {}
945 
946 #[repr(C)]
947 #[derive(Debug, Default, Copy, Clone)]
948 pub struct InterruptIn {
949     pub unique: u64,
950 }
951 unsafe impl DataInit for InterruptIn {}
952 
953 #[repr(C)]
954 #[derive(Debug, Default, Copy, Clone)]
955 pub struct BmapIn {
956     pub block: u64,
957     pub blocksize: u32,
958     pub padding: u32,
959 }
960 unsafe impl DataInit for BmapIn {}
961 
962 #[repr(C)]
963 #[derive(Debug, Default, Copy, Clone)]
964 pub struct BmapOut {
965     pub block: u64,
966 }
967 unsafe impl DataInit for BmapOut {}
968 
969 #[repr(C)]
970 #[derive(Debug, Default, Copy, Clone)]
971 pub struct IoctlIn {
972     pub fh: u64,
973     pub flags: u32,
974     pub cmd: u32,
975     pub arg: u64,
976     pub in_size: u32,
977     pub out_size: u32,
978 }
979 unsafe impl DataInit for IoctlIn {}
980 
981 /// Describes a region of memory in the address space of the process that made the ioctl syscall.
982 /// Similar to `libc::iovec` but uses `u64`s for the address and the length.
983 #[repr(C)]
984 #[derive(Debug, Default, Copy, Clone)]
985 pub struct IoctlIovec {
986     /// The start address of the memory region. This must be in the address space of the process
987     /// that made the ioctl syscall.
988     pub base: u64,
989 
990     /// The length of the memory region.
991     pub len: u64,
992 }
993 unsafe impl DataInit for IoctlIovec {}
994 
995 #[repr(C)]
996 #[derive(Debug, Default, Copy, Clone)]
997 pub struct IoctlOut {
998     pub result: i32,
999     pub flags: u32,
1000     pub in_iovs: u32,
1001     pub out_iovs: u32,
1002 }
1003 unsafe impl DataInit for IoctlOut {}
1004 
1005 #[repr(C)]
1006 #[derive(Debug, Default, Copy, Clone)]
1007 pub struct PollIn {
1008     pub fh: u64,
1009     pub kh: u64,
1010     pub flags: u32,
1011     pub events: u32,
1012 }
1013 unsafe impl DataInit for PollIn {}
1014 
1015 #[repr(C)]
1016 #[derive(Debug, Default, Copy, Clone)]
1017 pub struct PollOut {
1018     pub revents: u32,
1019     pub padding: u32,
1020 }
1021 unsafe impl DataInit for PollOut {}
1022 
1023 #[repr(C)]
1024 #[derive(Debug, Default, Copy, Clone)]
1025 pub struct NotifyPollWakeupOut {
1026     pub kh: u64,
1027 }
1028 unsafe impl DataInit for NotifyPollWakeupOut {}
1029 
1030 #[repr(C)]
1031 #[derive(Debug, Default, Copy, Clone)]
1032 pub struct FallocateIn {
1033     pub fh: u64,
1034     pub offset: u64,
1035     pub length: u64,
1036     pub mode: u32,
1037     pub padding: u32,
1038 }
1039 unsafe impl DataInit for FallocateIn {}
1040 
1041 #[repr(C)]
1042 #[derive(Debug, Default, Copy, Clone)]
1043 pub struct InHeader {
1044     pub len: u32,
1045     pub opcode: u32,
1046     pub unique: u64,
1047     pub nodeid: u64,
1048     pub uid: u32,
1049     pub gid: u32,
1050     pub pid: u32,
1051     pub padding: u32,
1052 }
1053 unsafe impl DataInit for InHeader {}
1054 
1055 #[repr(C)]
1056 #[derive(Debug, Default, Copy, Clone)]
1057 pub struct OutHeader {
1058     pub len: u32,
1059     pub error: i32,
1060     pub unique: u64,
1061 }
1062 unsafe impl DataInit for OutHeader {}
1063 
1064 #[repr(C)]
1065 #[derive(Debug, Default, Copy, Clone)]
1066 pub struct Dirent {
1067     pub ino: u64,
1068     pub off: u64,
1069     pub namelen: u32,
1070     pub type_: u32,
1071     // char name[];
1072 }
1073 unsafe impl DataInit for Dirent {}
1074 
1075 #[repr(C)]
1076 #[derive(Debug, Default, Copy, Clone)]
1077 pub struct Direntplus {
1078     pub entry_out: EntryOut,
1079     pub dirent: Dirent,
1080 }
1081 unsafe impl DataInit for Direntplus {}
1082 
1083 #[repr(C)]
1084 #[derive(Debug, Default, Copy, Clone)]
1085 pub struct NotifyInvalInodeOut {
1086     pub ino: u64,
1087     pub off: i64,
1088     pub len: i64,
1089 }
1090 unsafe impl DataInit for NotifyInvalInodeOut {}
1091 
1092 #[repr(C)]
1093 #[derive(Debug, Default, Copy, Clone)]
1094 pub struct NotifyInvalEntryOut {
1095     pub parent: u64,
1096     pub namelen: u32,
1097     pub padding: u32,
1098 }
1099 unsafe impl DataInit for NotifyInvalEntryOut {}
1100 
1101 #[repr(C)]
1102 #[derive(Debug, Default, Copy, Clone)]
1103 pub struct NotifyDeleteOut {
1104     pub parent: u64,
1105     pub child: u64,
1106     pub namelen: u32,
1107     pub padding: u32,
1108 }
1109 unsafe impl DataInit for NotifyDeleteOut {}
1110 
1111 #[repr(C)]
1112 #[derive(Debug, Default, Copy, Clone)]
1113 pub struct NotifyStoreOut {
1114     pub nodeid: u64,
1115     pub offset: u64,
1116     pub size: u32,
1117     pub padding: u32,
1118 }
1119 unsafe impl DataInit for NotifyStoreOut {}
1120 
1121 #[repr(C)]
1122 #[derive(Debug, Default, Copy, Clone)]
1123 pub struct Notify_Retrieve_Out {
1124     pub notify_unique: u64,
1125     pub nodeid: u64,
1126     pub offset: u64,
1127     pub size: u32,
1128     pub padding: u32,
1129 }
1130 unsafe impl DataInit for Notify_Retrieve_Out {}
1131 
1132 /* Matches the size of fuse_write_in */
1133 #[repr(C)]
1134 #[derive(Debug, Default, Copy, Clone)]
1135 pub struct NotifyRetrieveIn {
1136     pub dummy1: u64,
1137     pub offset: u64,
1138     pub size: u32,
1139     pub dummy2: u32,
1140     pub dummy3: u64,
1141     pub dummy4: u64,
1142 }
1143 unsafe impl DataInit for NotifyRetrieveIn {}
1144 
1145 #[repr(C)]
1146 #[derive(Debug, Default, Copy, Clone)]
1147 pub struct LseekIn {
1148     pub fh: u64,
1149     pub offset: u64,
1150     pub whence: u32,
1151     pub padding: u32,
1152 }
1153 unsafe impl DataInit for LseekIn {}
1154 
1155 #[repr(C)]
1156 #[derive(Debug, Default, Copy, Clone)]
1157 pub struct LseekOut {
1158     pub offset: u64,
1159 }
1160 unsafe impl DataInit for LseekOut {}
1161 
1162 #[repr(C)]
1163 #[derive(Debug, Default, Copy, Clone)]
1164 pub struct CopyFileRangeIn {
1165     pub fh_src: u64,
1166     pub off_src: u64,
1167     pub nodeid_dst: u64,
1168     pub fh_dst: u64,
1169     pub off_dst: u64,
1170     pub len: u64,
1171     pub flags: u64,
1172 }
1173 unsafe impl DataInit for CopyFileRangeIn {}
1174 
1175 #[repr(C)]
1176 #[derive(Debug, Default, Copy, Clone)]
1177 pub struct SetUpMappingIn {
1178     /* An already open handle */
1179     pub fh: u64,
1180     /* Offset into the file to start the mapping */
1181     pub foffset: u64,
1182     /* Length of mapping required */
1183     pub len: u64,
1184     /* Flags, FUSE_SETUPMAPPING_FLAG_* */
1185     pub flags: u64,
1186     /* Offset in Memory Window */
1187     pub moffset: u64,
1188 }
1189 unsafe impl DataInit for SetUpMappingIn {}
1190 
1191 #[repr(C)]
1192 #[derive(Debug, Default, Copy, Clone)]
1193 pub struct RemoveMappingIn {
1194     /* number of fuse_removemapping_one follows */
1195     pub count: u32,
1196 }
1197 unsafe impl DataInit for RemoveMappingIn {}
1198 
1199 #[repr(C)]
1200 #[derive(Debug, Default, Copy, Clone)]
1201 pub struct RemoveMappingOne {
1202     /* Offset into the dax window start the unmapping */
1203     pub moffset: u64,
1204     /* Length of mapping required */
1205     pub len: u64,
1206 }
1207 unsafe impl DataInit for RemoveMappingOne {}
1208