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