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