inet.af/netstack@v0.0.0-20220214151720-7585b01ddccf/abi/linux/fuse.go (about) 1 // Copyright 2020 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package linux 16 17 import ( 18 "inet.af/netstack/marshal/primitive" 19 ) 20 21 // FUSEOpcode is a FUSE operation code. 22 // 23 // +marshal 24 type FUSEOpcode uint32 25 26 // FUSEOpID is a FUSE operation ID. 27 // 28 // +marshal 29 type FUSEOpID uint64 30 31 // FUSE_ROOT_ID is the id of root inode. 32 const FUSE_ROOT_ID = 1 33 34 // Opcodes for FUSE operations. 35 // 36 // Analogous to the opcodes in include/linux/fuse.h. 37 const ( 38 FUSE_LOOKUP FUSEOpcode = 1 39 FUSE_FORGET = 2 /* no reply */ 40 FUSE_GETATTR = 3 41 FUSE_SETATTR = 4 42 FUSE_READLINK = 5 43 FUSE_SYMLINK = 6 44 _ 45 FUSE_MKNOD = 8 46 FUSE_MKDIR = 9 47 FUSE_UNLINK = 10 48 FUSE_RMDIR = 11 49 FUSE_RENAME = 12 50 FUSE_LINK = 13 51 FUSE_OPEN = 14 52 FUSE_READ = 15 53 FUSE_WRITE = 16 54 FUSE_STATFS = 17 55 FUSE_RELEASE = 18 56 _ 57 FUSE_FSYNC = 20 58 FUSE_SETXATTR = 21 59 FUSE_GETXATTR = 22 60 FUSE_LISTXATTR = 23 61 FUSE_REMOVEXATTR = 24 62 FUSE_FLUSH = 25 63 FUSE_INIT = 26 64 FUSE_OPENDIR = 27 65 FUSE_READDIR = 28 66 FUSE_RELEASEDIR = 29 67 FUSE_FSYNCDIR = 30 68 FUSE_GETLK = 31 69 FUSE_SETLK = 32 70 FUSE_SETLKW = 33 71 FUSE_ACCESS = 34 72 FUSE_CREATE = 35 73 FUSE_INTERRUPT = 36 74 FUSE_BMAP = 37 75 FUSE_DESTROY = 38 76 FUSE_IOCTL = 39 77 FUSE_POLL = 40 78 FUSE_NOTIFY_REPLY = 41 79 FUSE_BATCH_FORGET = 42 80 ) 81 82 const ( 83 // FUSE_MIN_READ_BUFFER is the minimum size the read can be for any FUSE filesystem. 84 // This is the minimum size Linux supports. See linux.fuse.h. 85 FUSE_MIN_READ_BUFFER uint32 = 8192 86 ) 87 88 // FUSEHeaderIn is the header read by the daemon with each request. 89 // 90 // +marshal 91 type FUSEHeaderIn struct { 92 // Len specifies the total length of the data, including this header. 93 Len uint32 94 95 // Opcode specifies the kind of operation of the request. 96 Opcode FUSEOpcode 97 98 // Unique specifies the unique identifier for this request. 99 Unique FUSEOpID 100 101 // NodeID is the ID of the filesystem object being operated on. 102 NodeID uint64 103 104 // UID is the UID of the requesting process. 105 UID uint32 106 107 // GID is the GID of the requesting process. 108 GID uint32 109 110 // PID is the PID of the requesting process. 111 PID uint32 112 113 _ uint32 114 } 115 116 // FUSEHeaderOut is the header written by the daemon when it processes 117 // a request and wants to send a reply (almost all operations require a 118 // reply; if they do not, this will be explicitly documented). 119 // 120 // +marshal 121 type FUSEHeaderOut struct { 122 // Len specifies the total length of the data, including this header. 123 Len uint32 124 125 // Error specifies the error that occurred (0 if none). 126 Error int32 127 128 // Unique specifies the unique identifier of the corresponding request. 129 Unique FUSEOpID 130 } 131 132 // FUSE_INIT flags, consistent with the ones in include/uapi/linux/fuse.h. 133 // Our taget version is 7.23 but we have few implemented in advance. 134 const ( 135 FUSE_ASYNC_READ = 1 << 0 136 FUSE_POSIX_LOCKS = 1 << 1 137 FUSE_FILE_OPS = 1 << 2 138 FUSE_ATOMIC_O_TRUNC = 1 << 3 139 FUSE_EXPORT_SUPPORT = 1 << 4 140 FUSE_BIG_WRITES = 1 << 5 141 FUSE_DONT_MASK = 1 << 6 142 FUSE_SPLICE_WRITE = 1 << 7 143 FUSE_SPLICE_MOVE = 1 << 8 144 FUSE_SPLICE_READ = 1 << 9 145 FUSE_FLOCK_LOCKS = 1 << 10 146 FUSE_HAS_IOCTL_DIR = 1 << 11 147 FUSE_AUTO_INVAL_DATA = 1 << 12 148 FUSE_DO_READDIRPLUS = 1 << 13 149 FUSE_READDIRPLUS_AUTO = 1 << 14 150 FUSE_ASYNC_DIO = 1 << 15 151 FUSE_WRITEBACK_CACHE = 1 << 16 152 FUSE_NO_OPEN_SUPPORT = 1 << 17 153 FUSE_MAX_PAGES = 1 << 22 // From FUSE 7.28 154 ) 155 156 // currently supported FUSE protocol version numbers. 157 const ( 158 FUSE_KERNEL_VERSION = 7 159 FUSE_KERNEL_MINOR_VERSION = 31 160 ) 161 162 // Constants relevant to FUSE operations. 163 const ( 164 FUSE_NAME_MAX = 1024 165 FUSE_PAGE_SIZE = 4096 166 FUSE_DIRENT_ALIGN = 8 167 ) 168 169 // FUSEInitIn is the request sent by the kernel to the daemon, 170 // to negotiate the version and flags. 171 // 172 // +marshal 173 type FUSEInitIn struct { 174 // Major version supported by kernel. 175 Major uint32 176 177 // Minor version supported by the kernel. 178 Minor uint32 179 180 // MaxReadahead is the maximum number of bytes to read-ahead 181 // decided by the kernel. 182 MaxReadahead uint32 183 184 // Flags of this init request. 185 Flags uint32 186 } 187 188 // FUSEInitOut is the reply sent by the daemon to the kernel 189 // for FUSEInitIn. We target FUSE 7.23; this struct supports 7.28. 190 // 191 // +marshal 192 type FUSEInitOut struct { 193 // Major version supported by daemon. 194 Major uint32 195 196 // Minor version supported by daemon. 197 Minor uint32 198 199 // MaxReadahead is the maximum number of bytes to read-ahead. 200 // Decided by the daemon, after receiving the value from kernel. 201 MaxReadahead uint32 202 203 // Flags of this init reply. 204 Flags uint32 205 206 // MaxBackground is the maximum number of pending background requests 207 // that the daemon wants. 208 MaxBackground uint16 209 210 // CongestionThreshold is the daemon-decided threshold for 211 // the number of the pending background requests. 212 CongestionThreshold uint16 213 214 // MaxWrite is the daemon's maximum size of a write buffer. 215 // Kernel adjusts it to the minimum (fuse/init.go:fuseMinMaxWrite). 216 // if the value from daemon is too small. 217 MaxWrite uint32 218 219 // TimeGran is the daemon's time granularity for mtime and ctime metadata. 220 // The unit is nanosecond. 221 // Value should be power of 10. 222 // 1 indicates full nanosecond granularity support. 223 TimeGran uint32 224 225 // MaxPages is the daemon's maximum number of pages for one write operation. 226 // Kernel adjusts it to the maximum (fuse/init.go:FUSE_MAX_MAX_PAGES). 227 // if the value from daemon is too large. 228 MaxPages uint16 229 230 _ uint16 231 232 _ [8]uint32 233 } 234 235 // FUSE_GETATTR_FH is currently the only flag of FUSEGetAttrIn.GetAttrFlags. 236 // If it is set, the file handle (FUSEGetAttrIn.Fh) is used to indicate the 237 // object instead of the node id attribute in the request header. 238 const FUSE_GETATTR_FH = (1 << 0) 239 240 // FUSEGetAttrIn is the request sent by the kernel to the daemon, 241 // to get the attribute of a inode. 242 // 243 // +marshal 244 type FUSEGetAttrIn struct { 245 // GetAttrFlags specifies whether getattr request is sent with a nodeid or 246 // with a file handle. 247 GetAttrFlags uint32 248 249 _ uint32 250 251 // Fh is the file handler when GetAttrFlags has FUSE_GETATTR_FH bit. If 252 // used, the operation is analogous to fstat(2). 253 Fh uint64 254 } 255 256 // FUSEAttr is the struct used in the reponse FUSEGetAttrOut. 257 // 258 // +marshal 259 type FUSEAttr struct { 260 // Ino is the inode number of this file. 261 Ino uint64 262 263 // Size is the size of this file. 264 Size uint64 265 266 // Blocks is the number of the 512B blocks allocated by this file. 267 Blocks uint64 268 269 // Atime is the time of last access. 270 Atime uint64 271 272 // Mtime is the time of last modification. 273 Mtime uint64 274 275 // Ctime is the time of last status change. 276 Ctime uint64 277 278 // AtimeNsec is the nano second part of Atime. 279 AtimeNsec uint32 280 281 // MtimeNsec is the nano second part of Mtime. 282 MtimeNsec uint32 283 284 // CtimeNsec is the nano second part of Ctime. 285 CtimeNsec uint32 286 287 // Mode contains the file type and mode. 288 Mode uint32 289 290 // Nlink is the number of the hard links. 291 Nlink uint32 292 293 // UID is user ID of the owner. 294 UID uint32 295 296 // GID is group ID of the owner. 297 GID uint32 298 299 // Rdev is the device ID if this is a special file. 300 Rdev uint32 301 302 // BlkSize is the block size for filesystem I/O. 303 BlkSize uint32 304 305 _ uint32 306 } 307 308 // FUSEGetAttrOut is the reply sent by the daemon to the kernel 309 // for FUSEGetAttrIn. 310 // 311 // +marshal 312 type FUSEGetAttrOut struct { 313 // AttrValid and AttrValidNsec describe the attribute cache duration 314 AttrValid uint64 315 316 // AttrValidNsec is the nanosecond part of the attribute cache duration 317 AttrValidNsec uint32 318 319 _ uint32 320 321 // Attr contains the metadata returned from the FUSE server 322 Attr FUSEAttr 323 } 324 325 // FUSEEntryOut is the reply sent by the daemon to the kernel 326 // for FUSE_MKNOD, FUSE_MKDIR, FUSE_SYMLINK, FUSE_LINK and 327 // FUSE_LOOKUP. 328 // 329 // +marshal 330 type FUSEEntryOut struct { 331 // NodeID is the ID for current inode. 332 NodeID uint64 333 334 // Generation is the generation number of inode. 335 // Used to identify an inode that have different ID at different time. 336 Generation uint64 337 338 // EntryValid indicates timeout for an entry. 339 EntryValid uint64 340 341 // AttrValid indicates timeout for an entry's attributes. 342 AttrValid uint64 343 344 // EntryValidNsec indicates timeout for an entry in nanosecond. 345 EntryValidNSec uint32 346 347 // AttrValidNsec indicates timeout for an entry's attributes in nanosecond. 348 AttrValidNSec uint32 349 350 // Attr contains the attributes of an entry. 351 Attr FUSEAttr 352 } 353 354 // CString represents a null terminated string which can be marshalled. 355 // 356 // +marshal dynamic 357 type CString string 358 359 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 360 func (s *CString) MarshalBytes(buf []byte) []byte { 361 copy(buf, *s) 362 buf[len(*s)] = 0 // null char 363 return buf[s.SizeBytes():] 364 } 365 366 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 367 func (s *CString) UnmarshalBytes(buf []byte) []byte { 368 panic("Unimplemented, CString is never unmarshalled") 369 } 370 371 // SizeBytes implements marshal.Marshallable.SizeBytes. 372 func (s *CString) SizeBytes() int { 373 // 1 extra byte for null-terminated string. 374 return len(*s) + 1 375 } 376 377 // FUSELookupIn is the request sent by the kernel to the daemon 378 // to look up a file name. 379 // 380 // +marshal dynamic 381 type FUSELookupIn struct { 382 // Name is a file name to be looked up. 383 Name CString 384 } 385 386 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 387 func (r *FUSELookupIn) UnmarshalBytes(buf []byte) []byte { 388 panic("Unimplemented, FUSELookupIn is never unmarshalled") 389 } 390 391 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 392 func (r *FUSELookupIn) MarshalBytes(buf []byte) []byte { 393 return r.Name.MarshalBytes(buf) 394 } 395 396 // SizeBytes implements marshal.Marshallable.SizeBytes. 397 func (r *FUSELookupIn) SizeBytes() int { 398 return r.Name.SizeBytes() 399 } 400 401 // MAX_NON_LFS indicates the maximum offset without large file support. 402 const MAX_NON_LFS = ((1 << 31) - 1) 403 404 // flags returned by OPEN request. 405 const ( 406 // FOPEN_DIRECT_IO indicates bypassing page cache for this opened file. 407 FOPEN_DIRECT_IO = 1 << 0 408 // FOPEN_KEEP_CACHE avoids invalidate of data cache on open. 409 FOPEN_KEEP_CACHE = 1 << 1 410 // FOPEN_NONSEEKABLE indicates the file cannot be seeked. 411 FOPEN_NONSEEKABLE = 1 << 2 412 ) 413 414 // FUSEOpenIn is the request sent by the kernel to the daemon, 415 // to negotiate flags and get file handle. 416 // 417 // +marshal 418 type FUSEOpenIn struct { 419 // Flags of this open request. 420 Flags uint32 421 422 _ uint32 423 } 424 425 // FUSEOpenOut is the reply sent by the daemon to the kernel 426 // for FUSEOpenIn. 427 // 428 // +marshal 429 type FUSEOpenOut struct { 430 // Fh is the file handler for opened file. 431 Fh uint64 432 433 // OpenFlag for the opened file. 434 OpenFlag uint32 435 436 _ uint32 437 } 438 439 // FUSE_READ flags, consistent with the ones in include/uapi/linux/fuse.h. 440 const ( 441 FUSE_READ_LOCKOWNER = 1 << 1 442 ) 443 444 // FUSEReadIn is the request sent by the kernel to the daemon 445 // for FUSE_READ. 446 // 447 // +marshal 448 type FUSEReadIn struct { 449 // Fh is the file handle in userspace. 450 Fh uint64 451 452 // Offset is the read offset. 453 Offset uint64 454 455 // Size is the number of bytes to read. 456 Size uint32 457 458 // ReadFlags for this FUSE_READ request. 459 // Currently only contains FUSE_READ_LOCKOWNER. 460 ReadFlags uint32 461 462 // LockOwner is the id of the lock owner if there is one. 463 LockOwner uint64 464 465 // Flags for the underlying file. 466 Flags uint32 467 468 _ uint32 469 } 470 471 // FUSEWriteIn is the first part of the payload of the 472 // request sent by the kernel to the daemon 473 // for FUSE_WRITE (struct for FUSE version >= 7.9). 474 // 475 // The second part of the payload is the 476 // binary bytes of the data to be written. 477 // 478 // +marshal 479 type FUSEWriteIn struct { 480 // Fh is the file handle in userspace. 481 Fh uint64 482 483 // Offset is the write offset. 484 Offset uint64 485 486 // Size is the number of bytes to write. 487 Size uint32 488 489 // ReadFlags for this FUSE_WRITE request. 490 WriteFlags uint32 491 492 // LockOwner is the id of the lock owner if there is one. 493 LockOwner uint64 494 495 // Flags for the underlying file. 496 Flags uint32 497 498 _ uint32 499 } 500 501 // FUSEWriteOut is the payload of the reply sent by the daemon to the kernel 502 // for a FUSE_WRITE request. 503 // 504 // +marshal 505 type FUSEWriteOut struct { 506 // Size is the number of bytes written. 507 Size uint32 508 509 _ uint32 510 } 511 512 // FUSEReleaseIn is the request sent by the kernel to the daemon 513 // when there is no more reference to a file. 514 // 515 // +marshal 516 type FUSEReleaseIn struct { 517 // Fh is the file handler for the file to be released. 518 Fh uint64 519 520 // Flags of the file. 521 Flags uint32 522 523 // ReleaseFlags of this release request. 524 ReleaseFlags uint32 525 526 // LockOwner is the id of the lock owner if there is one. 527 LockOwner uint64 528 } 529 530 // FUSECreateMeta contains all the static fields of FUSECreateIn, 531 // which is used for FUSE_CREATE. 532 // 533 // +marshal 534 type FUSECreateMeta struct { 535 // Flags of the creating file. 536 Flags uint32 537 538 // Mode is the mode of the creating file. 539 Mode uint32 540 541 // Umask is the current file mode creation mask. 542 Umask uint32 543 _ uint32 544 } 545 546 // FUSECreateIn contains all the arguments sent by the kernel to the daemon, to 547 // atomically create and open a new regular file. 548 // 549 // +marshal dynamic 550 type FUSECreateIn struct { 551 // CreateMeta contains mode, rdev and umash field for FUSE_MKNODS. 552 CreateMeta FUSECreateMeta 553 554 // Name is the name of the node to create. 555 Name CString 556 } 557 558 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 559 func (r *FUSECreateIn) MarshalBytes(buf []byte) []byte { 560 buf = r.CreateMeta.MarshalBytes(buf) 561 return r.Name.MarshalBytes(buf) 562 } 563 564 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 565 func (r *FUSECreateIn) UnmarshalBytes(buf []byte) []byte { 566 panic("Unimplemented, FUSECreateIn is never unmarshalled") 567 } 568 569 // SizeBytes implements marshal.Marshallable.SizeBytes. 570 func (r *FUSECreateIn) SizeBytes() int { 571 return r.CreateMeta.SizeBytes() + r.Name.SizeBytes() 572 } 573 574 // FUSEMknodMeta contains all the static fields of FUSEMknodIn, 575 // which is used for FUSE_MKNOD. 576 // 577 // +marshal 578 type FUSEMknodMeta struct { 579 // Mode of the inode to create. 580 Mode uint32 581 582 // Rdev encodes device major and minor information. 583 Rdev uint32 584 585 // Umask is the current file mode creation mask. 586 Umask uint32 587 588 _ uint32 589 } 590 591 // FUSEMknodIn contains all the arguments sent by the kernel 592 // to the daemon, to create a new file node. 593 // 594 // +marshal dynamic 595 type FUSEMknodIn struct { 596 // MknodMeta contains mode, rdev and umash field for FUSE_MKNODS. 597 MknodMeta FUSEMknodMeta 598 // Name is the name of the node to create. 599 Name CString 600 } 601 602 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 603 func (r *FUSEMknodIn) MarshalBytes(buf []byte) []byte { 604 buf = r.MknodMeta.MarshalBytes(buf) 605 return r.Name.MarshalBytes(buf) 606 } 607 608 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 609 func (r *FUSEMknodIn) UnmarshalBytes(buf []byte) []byte { 610 panic("Unimplemented, FUSEMknodIn is never unmarshalled") 611 } 612 613 // SizeBytes implements marshal.Marshallable.SizeBytes. 614 func (r *FUSEMknodIn) SizeBytes() int { 615 return r.MknodMeta.SizeBytes() + r.Name.SizeBytes() 616 } 617 618 // FUSESymlinkIn is the request sent by the kernel to the daemon, 619 // to create a symbolic link. 620 // 621 // +marshal dynamic 622 type FUSESymlinkIn struct { 623 // Name of symlink to create. 624 Name CString 625 626 // Target of the symlink. 627 Target CString 628 } 629 630 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 631 func (r *FUSESymlinkIn) MarshalBytes(buf []byte) []byte { 632 buf = r.Name.MarshalBytes(buf) 633 return r.Target.MarshalBytes(buf) 634 } 635 636 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 637 func (r *FUSESymlinkIn) UnmarshalBytes(buf []byte) []byte { 638 panic("Unimplemented, FUSEMknodIn is never unmarshalled") 639 } 640 641 // SizeBytes implements marshal.Marshallable.SizeBytes. 642 func (r *FUSESymlinkIn) SizeBytes() int { 643 return r.Name.SizeBytes() + r.Target.SizeBytes() 644 } 645 646 // FUSEEmptyIn is used by operations without request body. 647 // 648 // +marshal dynamic 649 type FUSEEmptyIn struct{} 650 651 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 652 func (r *FUSEEmptyIn) MarshalBytes(buf []byte) []byte { 653 return buf 654 } 655 656 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 657 func (r *FUSEEmptyIn) UnmarshalBytes(buf []byte) []byte { 658 panic("Unimplemented, FUSEEmptyIn is never unmarshalled") 659 } 660 661 // SizeBytes implements marshal.Marshallable.SizeBytes. 662 func (r *FUSEEmptyIn) SizeBytes() int { 663 return 0 664 } 665 666 // FUSEMkdirMeta contains all the static fields of FUSEMkdirIn, 667 // which is used for FUSE_MKDIR. 668 // 669 // +marshal 670 type FUSEMkdirMeta struct { 671 // Mode of the directory of create. 672 Mode uint32 673 // Umask is the user file creation mask. 674 Umask uint32 675 } 676 677 // FUSEMkdirIn contains all the arguments sent by the kernel 678 // to the daemon, to create a new directory. 679 // 680 // +marshal dynamic 681 type FUSEMkdirIn struct { 682 // MkdirMeta contains Mode and Umask of the directory to create. 683 MkdirMeta FUSEMkdirMeta 684 // Name of the directory to create. 685 Name CString 686 } 687 688 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 689 func (r *FUSEMkdirIn) MarshalBytes(buf []byte) []byte { 690 buf = r.MkdirMeta.MarshalBytes(buf) 691 return r.Name.MarshalBytes(buf) 692 } 693 694 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 695 func (r *FUSEMkdirIn) UnmarshalBytes(buf []byte) []byte { 696 panic("Unimplemented, FUSEMkdirIn is never unmarshalled") 697 } 698 699 // SizeBytes implements marshal.Marshallable.SizeBytes. 700 func (r *FUSEMkdirIn) SizeBytes() int { 701 return r.MkdirMeta.SizeBytes() + r.Name.SizeBytes() 702 } 703 704 // FUSERmDirIn is the request sent by the kernel to the daemon 705 // when trying to remove a directory. 706 // 707 // +marshal dynamic 708 type FUSERmDirIn struct { 709 // Name is a directory name to be removed. 710 Name CString 711 } 712 713 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 714 func (r *FUSERmDirIn) MarshalBytes(buf []byte) []byte { 715 return r.Name.MarshalBytes(buf) 716 } 717 718 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 719 func (r *FUSERmDirIn) UnmarshalBytes(buf []byte) []byte { 720 panic("Unimplemented, FUSERmDirIn is never unmarshalled") 721 } 722 723 // SizeBytes implements marshal.Marshallable.SizeBytes. 724 func (r *FUSERmDirIn) SizeBytes() int { 725 return r.Name.SizeBytes() 726 } 727 728 // FUSEDirents is a list of Dirents received from the FUSE daemon server. 729 // It is used for FUSE_READDIR. 730 // 731 // +marshal dynamic 732 type FUSEDirents struct { 733 Dirents []*FUSEDirent 734 } 735 736 // FUSEDirent is a Dirent received from the FUSE daemon server. 737 // It is used for FUSE_READDIR. 738 // 739 // +marshal dynamic 740 type FUSEDirent struct { 741 // Meta contains all the static fields of FUSEDirent. 742 Meta FUSEDirentMeta 743 // Name is the filename of the dirent. 744 Name string 745 } 746 747 // FUSEDirentMeta contains all the static fields of FUSEDirent. 748 // It is used for FUSE_READDIR. 749 // 750 // +marshal 751 type FUSEDirentMeta struct { 752 // Inode of the dirent. 753 Ino uint64 754 // Offset of the dirent. 755 Off uint64 756 // NameLen is the length of the dirent name. 757 NameLen uint32 758 // Type of the dirent. 759 Type uint32 760 } 761 762 // SizeBytes implements marshal.Marshallable.SizeBytes. 763 func (r *FUSEDirents) SizeBytes() int { 764 var sizeBytes int 765 for _, dirent := range r.Dirents { 766 sizeBytes += dirent.SizeBytes() 767 } 768 769 return sizeBytes 770 } 771 772 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 773 func (r *FUSEDirents) MarshalBytes(buf []byte) []byte { 774 panic("Unimplemented, FUSEDirents is never marshalled") 775 } 776 777 // UnmarshalBytes deserializes FUSEDirents from the src buffer. 778 func (r *FUSEDirents) UnmarshalBytes(src []byte) []byte { 779 for { 780 if len(src) <= (*FUSEDirentMeta)(nil).SizeBytes() { 781 break 782 } 783 784 // Its unclear how many dirents there are in src. Each dirent is dynamically 785 // sized and so we can't make assumptions about how many dirents we can allocate. 786 if r.Dirents == nil { 787 r.Dirents = make([]*FUSEDirent, 0) 788 } 789 790 // We have to allocate a struct for each dirent - there must be a better way 791 // to do this. Linux allocates 1 page to store all the dirents and then 792 // simply reads them from the page. 793 var dirent FUSEDirent 794 src = dirent.UnmarshalBytes(src) 795 r.Dirents = append(r.Dirents, &dirent) 796 } 797 return src 798 } 799 800 // SizeBytes implements marshal.Marshallable.SizeBytes. 801 func (r *FUSEDirent) SizeBytes() int { 802 dataSize := r.Meta.SizeBytes() + len(r.Name) 803 804 // Each Dirent must be padded such that its size is a multiple 805 // of FUSE_DIRENT_ALIGN. Similar to the fuse dirent alignment 806 // in linux/fuse.h. 807 return (dataSize + (FUSE_DIRENT_ALIGN - 1)) & ^(FUSE_DIRENT_ALIGN - 1) 808 } 809 810 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 811 func (r *FUSEDirent) MarshalBytes(buf []byte) []byte { 812 panic("Unimplemented, FUSEDirent is never marshalled") 813 } 814 815 // shiftNextDirent advances buf to the start of the next dirent, per 816 // FUSE ABI. buf should begin at the start of a dirent. 817 func (r *FUSEDirent) shiftNextDirent(buf []byte) []byte { 818 nextOff := r.SizeBytes() 819 if nextOff > len(buf) { // Handle overflow. 820 return buf[len(buf):] 821 } 822 return buf[nextOff:] 823 } 824 825 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 826 func (r *FUSEDirent) UnmarshalBytes(src []byte) []byte { 827 srcP := r.Meta.UnmarshalBytes(src) 828 829 if r.Meta.NameLen > FUSE_NAME_MAX { 830 // The name is too long and therefore invalid. We don't 831 // need to unmarshal the name since it'll be thrown away. 832 return r.shiftNextDirent(src) 833 } 834 835 buf := make([]byte, r.Meta.NameLen) 836 name := primitive.ByteSlice(buf) 837 name.UnmarshalBytes(srcP[:r.Meta.NameLen]) 838 r.Name = string(name) 839 return r.shiftNextDirent(src) 840 } 841 842 // FATTR_* consts are the attribute flags defined in include/uapi/linux/fuse.h. 843 // These should be or-ed together for setattr to know what has been changed. 844 const ( 845 FATTR_MODE = (1 << 0) 846 FATTR_UID = (1 << 1) 847 FATTR_GID = (1 << 2) 848 FATTR_SIZE = (1 << 3) 849 FATTR_ATIME = (1 << 4) 850 FATTR_MTIME = (1 << 5) 851 FATTR_FH = (1 << 6) 852 FATTR_ATIME_NOW = (1 << 7) 853 FATTR_MTIME_NOW = (1 << 8) 854 FATTR_LOCKOWNER = (1 << 9) 855 FATTR_CTIME = (1 << 10) 856 ) 857 858 // FUSESetAttrIn is the request sent by the kernel to the daemon, 859 // to set the attribute(s) of a file. 860 // 861 // +marshal 862 type FUSESetAttrIn struct { 863 // Valid indicates which attributes are modified by this request. 864 Valid uint32 865 866 _ uint32 867 868 // Fh is used to identify the file if FATTR_FH is set in Valid. 869 Fh uint64 870 871 // Size is the size that the request wants to change to. 872 Size uint64 873 874 // LockOwner is the owner of the lock that the request wants to change to. 875 LockOwner uint64 876 877 // Atime is the access time that the request wants to change to. 878 Atime uint64 879 880 // Mtime is the modification time that the request wants to change to. 881 Mtime uint64 882 883 // Ctime is the status change time that the request wants to change to. 884 Ctime uint64 885 886 // AtimeNsec is the nano second part of Atime. 887 AtimeNsec uint32 888 889 // MtimeNsec is the nano second part of Mtime. 890 MtimeNsec uint32 891 892 // CtimeNsec is the nano second part of Ctime. 893 CtimeNsec uint32 894 895 // Mode is the file mode that the request wants to change to. 896 Mode uint32 897 898 _ uint32 899 900 // UID is the user ID of the owner that the request wants to change to. 901 UID uint32 902 903 // GID is the group ID of the owner that the request wants to change to. 904 GID uint32 905 906 _ uint32 907 } 908 909 // FUSEUnlinkIn is the request sent by the kernel to the daemon 910 // when trying to unlink a node. 911 // 912 // +marshal dynamic 913 type FUSEUnlinkIn struct { 914 // Name of the node to unlink. 915 Name CString 916 } 917 918 // MarshalBytes implements marshal.Marshallable.MarshalBytes. 919 func (r *FUSEUnlinkIn) MarshalBytes(buf []byte) []byte { 920 return r.Name.MarshalBytes(buf) 921 } 922 923 // UnmarshalBytes implements marshal.Marshallable.UnmarshalBytes. 924 func (r *FUSEUnlinkIn) UnmarshalBytes(buf []byte) []byte { 925 panic("Unimplemented, FUSEUnlinkIn is never unmarshalled") 926 } 927 928 // SizeBytes implements marshal.Marshallable.SizeBytes. 929 func (r *FUSEUnlinkIn) SizeBytes() int { 930 return r.Name.SizeBytes() 931 }