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  }