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