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