gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/lisafs/message.go (about)

     1  // Copyright 2021 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 lisafs
    16  
    17  import (
    18  	"fmt"
    19  	"math"
    20  	"os"
    21  	"strings"
    22  
    23  	"gvisor.dev/gvisor/pkg/abi/linux"
    24  	"gvisor.dev/gvisor/pkg/hostarch"
    25  	"gvisor.dev/gvisor/pkg/marshal/primitive"
    26  )
    27  
    28  // Messages have two parts:
    29  //  * A transport header used to decipher received messages.
    30  //  * A byte array referred to as "payload" which contains the actual message.
    31  // "dataLen" refers to the size of both combined.
    32  //
    33  // All messages must implement the following functions:
    34  //	* marshal.Marshallable.SizeBytes
    35  //	* marshal.Marshallable.Marshal{Unsafe/Bytes}
    36  //	* marshal.CheckedMarshallable.CheckedUnmarshal
    37  //	* fmt.Stringer.String
    38  //
    39  // There is no explicit interface definition for this because that definition
    40  // will not be used anywhere. If a concrete type is passed into a function
    41  // which receives it as an interface, the struct is moved to the heap. This
    42  // erodes memory performance. Message structs are be short lived - they are
    43  // initialized, marshalled into a buffer and not used after that. So heap
    44  // allocating these message structs is wasteful. Don't define Message interface
    45  // so it's not used. Instead use function arguments. See Client.SndRcvMessage.
    46  //
    47  // Unmarshalling code should use the Checked variant of the Unmarshal functions
    48  // because a malicious encoder could have manipulated payload bytes to make the
    49  // unchecked unmarshal variants panic due to the lack of bound checking.
    50  // Marshalling code does not need additional bound checking because the caller
    51  // itself initializes the struct being marshalled, so it is trusted.
    52  //
    53  // String() implementations must ensure that the message struct doesn't escape.
    54  // For instance, directly passing the struct to fmt.Sprintf() escapes it
    55  // because of the implicit conversion to any.
    56  
    57  type marshalFunc func([]byte) []byte
    58  type unmarshalFunc func([]byte) ([]byte, bool)
    59  type debugStringer func() string
    60  
    61  // MID (message ID) is used to identify messages to parse from payload.
    62  //
    63  // +marshal slice:MIDSlice
    64  type MID uint16
    65  
    66  // These constants are used to identify their corresponding message types.
    67  const (
    68  	// Error is only used in responses to pass errors to client.
    69  	Error MID = 0
    70  
    71  	// Mount is used to establish connection between the client and server mount
    72  	// point. lisafs requires that the client makes a successful Mount RPC before
    73  	// making other RPCs.
    74  	Mount MID = 1
    75  
    76  	// Channel requests to start a new communicational channel.
    77  	Channel MID = 2
    78  
    79  	// FStat requests the stat(2) results for a specified file.
    80  	FStat MID = 3
    81  
    82  	// SetStat requests to change file attributes. Note that there is no one
    83  	// corresponding Linux syscall. This is a conglomeration of fchmod(2),
    84  	// fchown(2), ftruncate(2) and futimesat(2).
    85  	SetStat MID = 4
    86  
    87  	// Walk requests to walk the specified path starting from the specified
    88  	// directory. Server-side path traversal is terminated preemptively on
    89  	// symlinks entries because they can cause non-linear traversal.
    90  	Walk MID = 5
    91  
    92  	// WalkStat is the same as Walk, except the following differences:
    93  	//  * If the first path component is "", then it also returns stat results
    94  	//    for the directory where the walk starts.
    95  	//  * Does not return Inode, just the Stat results for each path component.
    96  	WalkStat MID = 6
    97  
    98  	// OpenAt is analogous to openat(2). It does not perform any walk. It merely
    99  	// duplicates the control FD with the open flags passed.
   100  	OpenAt MID = 7
   101  
   102  	// OpenCreateAt is analogous to openat(2) with O_CREAT|O_EXCL added to flags.
   103  	// It also returns the newly created file inode.
   104  	OpenCreateAt MID = 8
   105  
   106  	// Close is analogous to close(2) but can work on multiple FDs.
   107  	Close MID = 9
   108  
   109  	// FSync is analogous to fsync(2) but can work on multiple FDs.
   110  	FSync MID = 10
   111  
   112  	// PWrite is analogous to pwrite(2).
   113  	PWrite MID = 11
   114  
   115  	// PRead is analogous to pread(2).
   116  	PRead MID = 12
   117  
   118  	// MkdirAt is analogous to mkdirat(2).
   119  	MkdirAt MID = 13
   120  
   121  	// MknodAt is analogous to mknodat(2).
   122  	MknodAt MID = 14
   123  
   124  	// SymlinkAt is analogous to symlinkat(2).
   125  	SymlinkAt MID = 15
   126  
   127  	// LinkAt is analogous to linkat(2).
   128  	LinkAt MID = 16
   129  
   130  	// FStatFS is analogous to fstatfs(2).
   131  	FStatFS MID = 17
   132  
   133  	// FAllocate is analogous to fallocate(2).
   134  	FAllocate MID = 18
   135  
   136  	// ReadLinkAt is analogous to readlinkat(2).
   137  	ReadLinkAt MID = 19
   138  
   139  	// Flush cleans up the file state. Its behavior is implementation
   140  	// dependent and might not even be supported in server implementations.
   141  	Flush MID = 20
   142  
   143  	// Connect is loosely analogous to connect(2).
   144  	Connect MID = 21
   145  
   146  	// UnlinkAt is analogous to unlinkat(2).
   147  	UnlinkAt MID = 22
   148  
   149  	// RenameAt is loosely analogous to renameat(2).
   150  	RenameAt MID = 23
   151  
   152  	// Getdents64 is analogous to getdents64(2).
   153  	Getdents64 MID = 24
   154  
   155  	// FGetXattr is analogous to fgetxattr(2).
   156  	FGetXattr MID = 25
   157  
   158  	// FSetXattr is analogous to fsetxattr(2).
   159  	FSetXattr MID = 26
   160  
   161  	// FListXattr is analogous to flistxattr(2).
   162  	FListXattr MID = 27
   163  
   164  	// FRemoveXattr is analogous to fremovexattr(2).
   165  	FRemoveXattr MID = 28
   166  
   167  	// BindAt is analogous to bind(2).
   168  	BindAt MID = 29
   169  
   170  	// Listen is analogous to listen(2).
   171  	Listen MID = 30
   172  
   173  	// Accept is analogous to accept4(2).
   174  	Accept MID = 31
   175  )
   176  
   177  const (
   178  	// NoUID is a sentinel used to indicate no valid UID.
   179  	NoUID UID = math.MaxUint32
   180  
   181  	// NoGID is a sentinel used to indicate no valid GID.
   182  	NoGID GID = math.MaxUint32
   183  )
   184  
   185  // MaxMessageSize is the recommended max message size that can be used by
   186  // connections. Server implementations may choose to use other values.
   187  func MaxMessageSize() uint32 {
   188  	// Return HugePageSize - PageSize so that when flipcall packet window is
   189  	// created with MaxMessageSize() + flipcall header size + channel header
   190  	// size, HugePageSize is allocated and can be backed by a single huge page
   191  	// if supported by the underlying memfd.
   192  	return uint32(hostarch.HugePageSize - os.Getpagesize())
   193  }
   194  
   195  // UID represents a user ID.
   196  //
   197  // +marshal
   198  type UID uint32
   199  
   200  // Ok returns true if uid is not NoUID.
   201  func (uid UID) Ok() bool {
   202  	return uid != NoUID
   203  }
   204  
   205  // GID represents a group ID.
   206  //
   207  // +marshal
   208  type GID uint32
   209  
   210  // Ok returns true if gid is not NoGID.
   211  func (gid GID) Ok() bool {
   212  	return gid != NoGID
   213  }
   214  
   215  // EmptyMessage is an empty message.
   216  type EmptyMessage struct{}
   217  
   218  // String implements fmt.Stringer.String.
   219  func (*EmptyMessage) String() string {
   220  	return "EmptyMessage{}"
   221  }
   222  
   223  // SizeBytes implements marshal.Marshallable.SizeBytes.
   224  func (*EmptyMessage) SizeBytes() int {
   225  	return 0
   226  }
   227  
   228  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   229  func (*EmptyMessage) MarshalBytes(dst []byte) []byte { return dst }
   230  
   231  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   232  func (*EmptyMessage) CheckedUnmarshal(src []byte) ([]byte, bool) { return src, true }
   233  
   234  // SizedString represents a string in memory. The marshalled string bytes are
   235  // preceded by a uint16 signifying the string length.
   236  type SizedString string
   237  
   238  // SizeBytes implements marshal.Marshallable.SizeBytes.
   239  func (s *SizedString) SizeBytes() int {
   240  	return (*primitive.Uint16)(nil).SizeBytes() + len(*s)
   241  }
   242  
   243  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   244  func (s *SizedString) MarshalBytes(dst []byte) []byte {
   245  	strLen := primitive.Uint16(len(*s))
   246  	dst = strLen.MarshalUnsafe(dst)
   247  	// Copy without any allocation.
   248  	return dst[copy(dst[:strLen], *s):]
   249  }
   250  
   251  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   252  func (s *SizedString) CheckedUnmarshal(src []byte) ([]byte, bool) {
   253  	var strLen primitive.Uint16
   254  	srcRemain, ok := strLen.CheckedUnmarshal(src)
   255  	if !ok || len(srcRemain) < int(strLen) {
   256  		return src, false
   257  	}
   258  	// Take the hit, this leads to an allocation + memcpy. No way around it.
   259  	*s = SizedString(srcRemain[:strLen])
   260  	return srcRemain[strLen:], true
   261  }
   262  
   263  // StringArray represents an array of SizedStrings in memory. The marshalled
   264  // array data is preceded by a uint16 signifying the array length.
   265  type StringArray []string
   266  
   267  // String implements fmt.Stringer.String. This ensures that the string slice is
   268  // not escaped so that callers that use a statically sized string array do not
   269  // incur an unnecessary allocation.
   270  func (s *StringArray) String() string {
   271  	var b strings.Builder
   272  	b.WriteString("[")
   273  	b.WriteString(strings.Join(*s, ", "))
   274  	b.WriteString("]")
   275  	return b.String()
   276  }
   277  
   278  // SizeBytes implements marshal.Marshallable.SizeBytes.
   279  func (s *StringArray) SizeBytes() int {
   280  	size := (*primitive.Uint16)(nil).SizeBytes()
   281  	for _, str := range *s {
   282  		sstr := SizedString(str)
   283  		size += sstr.SizeBytes()
   284  	}
   285  	return size
   286  }
   287  
   288  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   289  func (s *StringArray) MarshalBytes(dst []byte) []byte {
   290  	arrLen := primitive.Uint16(len(*s))
   291  	dst = arrLen.MarshalUnsafe(dst)
   292  	for _, str := range *s {
   293  		sstr := SizedString(str)
   294  		dst = sstr.MarshalBytes(dst)
   295  	}
   296  	return dst
   297  }
   298  
   299  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   300  func (s *StringArray) CheckedUnmarshal(src []byte) ([]byte, bool) {
   301  	var arrLen primitive.Uint16
   302  	srcRemain, ok := arrLen.CheckedUnmarshal(src)
   303  	if !ok {
   304  		return src, false
   305  	}
   306  
   307  	if cap(*s) < int(arrLen) {
   308  		*s = make([]string, arrLen)
   309  	} else {
   310  		*s = (*s)[:arrLen]
   311  	}
   312  
   313  	for i := primitive.Uint16(0); i < arrLen; i++ {
   314  		var sstr SizedString
   315  		srcRemain, ok = sstr.CheckedUnmarshal(srcRemain)
   316  		if !ok {
   317  			return src, false
   318  		}
   319  		(*s)[i] = string(sstr)
   320  	}
   321  	return srcRemain, true
   322  }
   323  
   324  // Inode represents an inode on the remote filesystem.
   325  //
   326  // +marshal slice:InodeSlice
   327  type Inode struct {
   328  	ControlFD FDID
   329  	Stat      linux.Statx
   330  }
   331  
   332  func (i *Inode) String() string {
   333  	return fmt.Sprintf("Inode{ControlFD: %d, Stat: %s}", i.ControlFD, i.Stat.String())
   334  }
   335  
   336  // MountReq is an empty request to Mount on the connection.
   337  type MountReq struct{ EmptyMessage }
   338  
   339  // String implements fmt.Stringer.String.
   340  func (*MountReq) String() string {
   341  	return "MountReq{}"
   342  }
   343  
   344  // MountResp represents a Mount response.
   345  type MountResp struct {
   346  	Root Inode
   347  	// MaxMessageSize is the maximum size of messages communicated between the
   348  	// client and server in bytes. This includes the communication header.
   349  	MaxMessageSize primitive.Uint32
   350  	// SupportedMs holds all the supported messages.
   351  	SupportedMs []MID
   352  }
   353  
   354  // String implements fmt.Stringer.String.
   355  func (m *MountResp) String() string {
   356  	return fmt.Sprintf("MountResp{Root: %s, MaxMessageSize: %d, SupportedMs: %+v}", m.Root.String(), m.MaxMessageSize, m.SupportedMs)
   357  }
   358  
   359  // SizeBytes implements marshal.Marshallable.SizeBytes.
   360  func (m *MountResp) SizeBytes() int {
   361  	return m.Root.SizeBytes() +
   362  		m.MaxMessageSize.SizeBytes() +
   363  		(*primitive.Uint16)(nil).SizeBytes() +
   364  		(len(m.SupportedMs) * (*MID)(nil).SizeBytes())
   365  }
   366  
   367  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   368  func (m *MountResp) MarshalBytes(dst []byte) []byte {
   369  	dst = m.Root.MarshalUnsafe(dst)
   370  	dst = m.MaxMessageSize.MarshalUnsafe(dst)
   371  	numSupported := primitive.Uint16(len(m.SupportedMs))
   372  	dst = numSupported.MarshalBytes(dst)
   373  	return MarshalUnsafeMIDSlice(m.SupportedMs, dst)
   374  }
   375  
   376  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   377  func (m *MountResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
   378  	m.SupportedMs = m.SupportedMs[:0]
   379  	if m.SizeBytes() > len(src) {
   380  		return src, false
   381  	}
   382  	srcRemain := m.Root.UnmarshalUnsafe(src)
   383  	srcRemain = m.MaxMessageSize.UnmarshalUnsafe(srcRemain)
   384  	var numSupported primitive.Uint16
   385  	srcRemain = numSupported.UnmarshalBytes(srcRemain)
   386  	if int(numSupported)*(*MID)(nil).SizeBytes() > len(srcRemain) {
   387  		return src, false
   388  	}
   389  	if cap(m.SupportedMs) < int(numSupported) {
   390  		m.SupportedMs = make([]MID, numSupported)
   391  	} else {
   392  		m.SupportedMs = m.SupportedMs[:numSupported]
   393  	}
   394  	return UnmarshalUnsafeMIDSlice(m.SupportedMs, srcRemain), true
   395  }
   396  
   397  // ChannelReq is an empty requent to create a Channel.
   398  type ChannelReq struct{ EmptyMessage }
   399  
   400  // String implements fmt.Stringer.String.
   401  func (*ChannelReq) String() string {
   402  	return "ChannelReq{}"
   403  }
   404  
   405  // ChannelResp is the response to the create channel request.
   406  //
   407  // +marshal boundCheck
   408  type ChannelResp struct {
   409  	dataOffset int64
   410  	dataLength uint64
   411  }
   412  
   413  // String implements fmt.Stringer.String.
   414  func (c *ChannelResp) String() string {
   415  	return fmt.Sprintf("ChannelResp{dataOffset: %d, dataLength: %d}", c.dataOffset, c.dataLength)
   416  }
   417  
   418  // ErrorResp is returned to represent an error while handling a request.
   419  //
   420  // +marshal
   421  type ErrorResp struct {
   422  	errno uint32
   423  }
   424  
   425  // String implements fmt.Stringer.String.
   426  func (e *ErrorResp) String() string {
   427  	return fmt.Sprintf("ErrorResp{errno: %d}", e.errno)
   428  }
   429  
   430  // StatReq requests the stat results for the specified FD.
   431  //
   432  // +marshal boundCheck
   433  type StatReq struct {
   434  	FD FDID
   435  }
   436  
   437  // String implements fmt.Stringer.String.
   438  func (s *StatReq) String() string {
   439  	return fmt.Sprintf("StatReq{FD: %d}", s.FD)
   440  }
   441  
   442  // SetStatReq is used to set attributeds on FDs.
   443  //
   444  // +marshal boundCheck
   445  type SetStatReq struct {
   446  	FD    FDID
   447  	Mask  uint32
   448  	Mode  uint32 // Only permissions part is settable.
   449  	UID   UID
   450  	GID   GID
   451  	Size  uint64
   452  	Atime linux.Timespec
   453  	Mtime linux.Timespec
   454  }
   455  
   456  // String implements fmt.Stringer.String.
   457  func (s *SetStatReq) String() string {
   458  	return fmt.Sprintf("SetStatReq{FD: %d, Mask: %#x, Mode: %d, UID: %d, GID: %d, Size: %d, Atime: %s, Mtime: %s}",
   459  		s.FD, s.Mask, s.Mode, s.UID, s.GID, s.Size, s.Atime.ToTime(), s.Mtime.ToTime())
   460  }
   461  
   462  // SetStatResp is used to communicate SetStat results. It contains a mask
   463  // representing the failed changes. It also contains the errno of the failed
   464  // set attribute operation. If multiple operations failed then any of those
   465  // errnos can be returned.
   466  //
   467  // +marshal boundCheck
   468  type SetStatResp struct {
   469  	FailureMask  uint32
   470  	FailureErrNo uint32
   471  }
   472  
   473  // String implements fmt.Stringer.String.
   474  func (s *SetStatResp) String() string {
   475  	return fmt.Sprintf("SetStatResp{FailureMask: %#x, FailureErrNo: %d}", s.FailureMask, s.FailureErrNo)
   476  }
   477  
   478  // WalkReq is used to request to walk multiple path components at once. This
   479  // is used for both Walk and WalkStat.
   480  type WalkReq struct {
   481  	DirFD FDID
   482  	Path  StringArray
   483  }
   484  
   485  // String implements fmt.Stringer.String.
   486  func (w *WalkReq) String() string {
   487  	return fmt.Sprintf("WalkReq{DirFD: %d, Path: %s}", w.DirFD, w.Path.String())
   488  }
   489  
   490  // SizeBytes implements marshal.Marshallable.SizeBytes.
   491  func (w *WalkReq) SizeBytes() int {
   492  	return w.DirFD.SizeBytes() + w.Path.SizeBytes()
   493  }
   494  
   495  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   496  func (w *WalkReq) MarshalBytes(dst []byte) []byte {
   497  	dst = w.DirFD.MarshalUnsafe(dst)
   498  	return w.Path.MarshalBytes(dst)
   499  }
   500  
   501  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   502  func (w *WalkReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
   503  	w.Path = w.Path[:0]
   504  	if w.SizeBytes() > len(src) {
   505  		return src, false
   506  	}
   507  	srcRemain := w.DirFD.UnmarshalUnsafe(src)
   508  	if srcRemain, ok := w.Path.CheckedUnmarshal(srcRemain); ok {
   509  		return srcRemain, true
   510  	}
   511  	return src, false
   512  }
   513  
   514  // WalkStatus is used to indicate the reason for partial/unsuccessful server
   515  // side Walk operations. Please note that partial/unsuccessful walk operations
   516  // do not necessarily fail the RPC. The RPC is successful with a failure hint
   517  // which can be used by the client to infer server-side state.
   518  type WalkStatus = primitive.Uint8
   519  
   520  const (
   521  	// WalkSuccess indicates that all path components were successfully walked.
   522  	WalkSuccess WalkStatus = iota
   523  
   524  	// WalkComponentDoesNotExist indicates that the walk was prematurely
   525  	// terminated because an intermediate path component does not exist on
   526  	// server. The results of all previous existing path components is returned.
   527  	WalkComponentDoesNotExist
   528  
   529  	// WalkComponentSymlink indicates that the walk was prematurely
   530  	// terminated because an intermediate path component was a symlink. It is not
   531  	// safe to resolve symlinks remotely (unaware of mount points).
   532  	WalkComponentSymlink
   533  )
   534  
   535  func walkStatusToString(ws WalkStatus) string {
   536  	switch ws {
   537  	case WalkSuccess:
   538  		return "Success"
   539  	case WalkComponentDoesNotExist:
   540  		return "ComponentDoesNotExist"
   541  	case WalkComponentSymlink:
   542  		return "ComponentSymlink"
   543  	default:
   544  		panic(fmt.Sprintf("Unknown WalkStatus: %d", ws))
   545  	}
   546  }
   547  
   548  // WalkResp is used to communicate the inodes walked by the server. In memory,
   549  // the inode array is preceded by a uint16 integer denoting array length.
   550  type WalkResp struct {
   551  	Status WalkStatus
   552  	Inodes []Inode
   553  }
   554  
   555  // String implements fmt.Stringer.String. This ensures that the Inode slice is
   556  // not escaped so that callers that use a statically sized Inode array do not
   557  // incur an unnecessary allocation.
   558  func (w *WalkResp) String() string {
   559  	var arrB strings.Builder
   560  	arrB.WriteString("[")
   561  	for i := range w.Inodes {
   562  		if i > 0 {
   563  			arrB.WriteString(", ")
   564  		}
   565  		arrB.WriteString(w.Inodes[i].String())
   566  	}
   567  	arrB.WriteString("]")
   568  	return fmt.Sprintf("WalkResp{Status: %s, Inodes: %s}", walkStatusToString(w.Status), arrB.String())
   569  }
   570  
   571  // SizeBytes implements marshal.Marshallable.SizeBytes.
   572  func (w *WalkResp) SizeBytes() int {
   573  	return w.Status.SizeBytes() +
   574  		(*primitive.Uint16)(nil).SizeBytes() + (len(w.Inodes) * (*Inode)(nil).SizeBytes())
   575  }
   576  
   577  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   578  func (w *WalkResp) MarshalBytes(dst []byte) []byte {
   579  	dst = w.Status.MarshalUnsafe(dst)
   580  
   581  	numInodes := primitive.Uint16(len(w.Inodes))
   582  	dst = numInodes.MarshalUnsafe(dst)
   583  
   584  	return MarshalUnsafeInodeSlice(w.Inodes, dst)
   585  }
   586  
   587  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   588  func (w *WalkResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
   589  	w.Inodes = w.Inodes[:0]
   590  	if w.SizeBytes() > len(src) {
   591  		return src, false
   592  	}
   593  	srcRemain := w.Status.UnmarshalUnsafe(src)
   594  
   595  	var numInodes primitive.Uint16
   596  	srcRemain = numInodes.UnmarshalUnsafe(srcRemain)
   597  	if int(numInodes)*(*Inode)(nil).SizeBytes() > len(srcRemain) {
   598  		return src, false
   599  	}
   600  	if cap(w.Inodes) < int(numInodes) {
   601  		w.Inodes = make([]Inode, numInodes)
   602  	} else {
   603  		w.Inodes = w.Inodes[:numInodes]
   604  	}
   605  	return UnmarshalUnsafeInodeSlice(w.Inodes, srcRemain), true
   606  }
   607  
   608  // WalkStatResp is used to communicate stat results for WalkStat. In memory,
   609  // the array data is preceded by a uint16 denoting the array length.
   610  type WalkStatResp struct {
   611  	Stats []linux.Statx
   612  }
   613  
   614  // String implements fmt.Stringer.String.
   615  func (w *WalkStatResp) String() string {
   616  	var arrB strings.Builder
   617  	arrB.WriteString("[")
   618  	for i := range w.Stats {
   619  		if i > 0 {
   620  			arrB.WriteString(", ")
   621  		}
   622  		arrB.WriteString(w.Stats[i].String())
   623  	}
   624  	arrB.WriteString("]")
   625  	return fmt.Sprintf("WalkStatResp{Stats: %s}", arrB.String())
   626  }
   627  
   628  // SizeBytes implements marshal.Marshallable.SizeBytes.
   629  func (w *WalkStatResp) SizeBytes() int {
   630  	return (*primitive.Uint16)(nil).SizeBytes() + (len(w.Stats) * linux.SizeOfStatx)
   631  }
   632  
   633  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   634  func (w *WalkStatResp) MarshalBytes(dst []byte) []byte {
   635  	numStats := primitive.Uint16(len(w.Stats))
   636  	dst = numStats.MarshalUnsafe(dst)
   637  
   638  	return linux.MarshalUnsafeStatxSlice(w.Stats, dst)
   639  }
   640  
   641  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   642  func (w *WalkStatResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
   643  	w.Stats = w.Stats[:0]
   644  	if w.SizeBytes() > len(src) {
   645  		return src, false
   646  	}
   647  	var numStats primitive.Uint16
   648  	srcRemain := numStats.UnmarshalUnsafe(src)
   649  
   650  	if int(numStats)*linux.SizeOfStatx > len(srcRemain) {
   651  		return src, false
   652  	}
   653  	if cap(w.Stats) < int(numStats) {
   654  		w.Stats = make([]linux.Statx, numStats)
   655  	} else {
   656  		w.Stats = w.Stats[:numStats]
   657  	}
   658  	return linux.UnmarshalUnsafeStatxSlice(w.Stats, srcRemain), true
   659  }
   660  
   661  // OpenAtReq is used to open existing FDs with the specified flags.
   662  //
   663  // +marshal boundCheck
   664  type OpenAtReq struct {
   665  	FD    FDID
   666  	Flags uint32
   667  	_     uint32 // Need to make struct packed.
   668  }
   669  
   670  // String implements fmt.Stringer.String.
   671  func (o *OpenAtReq) String() string {
   672  	return fmt.Sprintf("OpenAtReq{FD: %d, Flags: %#o}", o.FD, o.Flags)
   673  }
   674  
   675  // OpenAtResp is used to communicate the newly created FD.
   676  //
   677  // +marshal boundCheck
   678  type OpenAtResp struct {
   679  	OpenFD FDID
   680  }
   681  
   682  // String implements fmt.Stringer.String.
   683  func (o *OpenAtResp) String() string {
   684  	return fmt.Sprintf("OpenAtResp{OpenFD: %d}", o.OpenFD)
   685  }
   686  
   687  // +marshal
   688  type createCommon struct {
   689  	DirFD FDID
   690  	UID   UID
   691  	GID   GID
   692  	Mode  linux.FileMode
   693  	// The following are needed to make the struct packed.
   694  	_ uint16
   695  	_ uint32
   696  }
   697  
   698  // OpenCreateAtReq is used to make OpenCreateAt requests.
   699  type OpenCreateAtReq struct {
   700  	createCommon
   701  	Flags primitive.Uint32
   702  	Name  SizedString
   703  }
   704  
   705  // String implements fmt.Stringer.String.
   706  func (o *OpenCreateAtReq) String() string {
   707  	return fmt.Sprintf("OpenCreateAtReq{DirFD: %d, Mode: %s, UID: %d, GID: %d, Flags: %#o, Name: %s}", o.DirFD, o.Mode, o.UID, o.GID, o.Flags, o.Name)
   708  }
   709  
   710  // SizeBytes implements marshal.Marshallable.SizeBytes.
   711  func (o *OpenCreateAtReq) SizeBytes() int {
   712  	return o.createCommon.SizeBytes() + o.Flags.SizeBytes() + o.Name.SizeBytes()
   713  }
   714  
   715  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   716  func (o *OpenCreateAtReq) MarshalBytes(dst []byte) []byte {
   717  	dst = o.createCommon.MarshalUnsafe(dst)
   718  	dst = o.Flags.MarshalUnsafe(dst)
   719  	return o.Name.MarshalBytes(dst)
   720  }
   721  
   722  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   723  func (o *OpenCreateAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
   724  	o.Name = ""
   725  	if o.SizeBytes() > len(src) {
   726  		return src, false
   727  	}
   728  	srcRemain := o.createCommon.UnmarshalUnsafe(src)
   729  	srcRemain = o.Flags.UnmarshalUnsafe(srcRemain)
   730  	if srcRemain, ok := o.Name.CheckedUnmarshal(srcRemain); ok {
   731  		return srcRemain, true
   732  	}
   733  	return src, false
   734  }
   735  
   736  // OpenCreateAtResp is used to communicate successful OpenCreateAt results.
   737  //
   738  // +marshal boundCheck
   739  type OpenCreateAtResp struct {
   740  	Child Inode
   741  	NewFD FDID
   742  }
   743  
   744  // String implements fmt.Stringer.String.
   745  func (o *OpenCreateAtResp) String() string {
   746  	return fmt.Sprintf("OpenCreateAtResp{Child: %s, NewFD: %d}", o.Child.String(), o.NewFD)
   747  }
   748  
   749  // FdArray is a utility struct which implements a marshallable type for
   750  // communicating an array of FDIDs. In memory, the array data is preceded by a
   751  // uint16 denoting the array length.
   752  type FdArray []FDID
   753  
   754  // String implements fmt.Stringer.String. This ensures that the FDID slice is
   755  // not escaped so that callers that use a statically sized FDID array do not
   756  // incur an unnecessary allocation.
   757  func (f *FdArray) String() string {
   758  	var b strings.Builder
   759  	b.WriteString("[")
   760  	for i, fd := range *f {
   761  		if i > 0 {
   762  			b.WriteString(", ")
   763  		}
   764  		b.WriteString(fmt.Sprintf("%d", fd))
   765  	}
   766  	b.WriteString("]")
   767  	return b.String()
   768  }
   769  
   770  // SizeBytes implements marshal.Marshallable.SizeBytes.
   771  func (f *FdArray) SizeBytes() int {
   772  	return (*primitive.Uint16)(nil).SizeBytes() + (len(*f) * (*FDID)(nil).SizeBytes())
   773  }
   774  
   775  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   776  func (f *FdArray) MarshalBytes(dst []byte) []byte {
   777  	arrLen := primitive.Uint16(len(*f))
   778  	dst = arrLen.MarshalUnsafe(dst)
   779  	return MarshalUnsafeFDIDSlice(*f, dst)
   780  }
   781  
   782  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   783  func (f *FdArray) CheckedUnmarshal(src []byte) ([]byte, bool) {
   784  	*f = (*f)[:0]
   785  	if f.SizeBytes() > len(src) {
   786  		return src, false
   787  	}
   788  	var arrLen primitive.Uint16
   789  	srcRemain := arrLen.UnmarshalUnsafe(src)
   790  	if int(arrLen)*(*FDID)(nil).SizeBytes() > len(srcRemain) {
   791  		return src, false
   792  	}
   793  	if cap(*f) < int(arrLen) {
   794  		*f = make(FdArray, arrLen)
   795  	} else {
   796  		*f = (*f)[:arrLen]
   797  	}
   798  	return UnmarshalUnsafeFDIDSlice(*f, srcRemain), true
   799  }
   800  
   801  // CloseReq is used to close(2) FDs.
   802  type CloseReq struct {
   803  	FDs FdArray
   804  }
   805  
   806  // String implements fmt.Stringer.String.
   807  func (c *CloseReq) String() string {
   808  	return fmt.Sprintf("CloseReq{FDs: %s}", c.FDs.String())
   809  }
   810  
   811  // SizeBytes implements marshal.Marshallable.SizeBytes.
   812  func (c *CloseReq) SizeBytes() int {
   813  	return c.FDs.SizeBytes()
   814  }
   815  
   816  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   817  func (c *CloseReq) MarshalBytes(dst []byte) []byte {
   818  	return c.FDs.MarshalBytes(dst)
   819  }
   820  
   821  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   822  func (c *CloseReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
   823  	return c.FDs.CheckedUnmarshal(src)
   824  }
   825  
   826  // CloseResp is an empty response to CloseReq.
   827  type CloseResp struct{ EmptyMessage }
   828  
   829  // String implements fmt.Stringer.String.
   830  func (*CloseResp) String() string {
   831  	return "CloseResp{}"
   832  }
   833  
   834  // FsyncReq is used to fsync(2) FDs.
   835  type FsyncReq struct {
   836  	FDs FdArray
   837  }
   838  
   839  // String implements fmt.Stringer.String.
   840  func (f *FsyncReq) String() string {
   841  	return fmt.Sprintf("FsyncReq{FDs: %s}", f.FDs.String())
   842  }
   843  
   844  // SizeBytes implements marshal.Marshallable.SizeBytes.
   845  func (f *FsyncReq) SizeBytes() int {
   846  	return f.FDs.SizeBytes()
   847  }
   848  
   849  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   850  func (f *FsyncReq) MarshalBytes(dst []byte) []byte {
   851  	return f.FDs.MarshalBytes(dst)
   852  }
   853  
   854  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   855  func (f *FsyncReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
   856  	return f.FDs.CheckedUnmarshal(src)
   857  }
   858  
   859  // FsyncResp is an empty response to FsyncReq.
   860  type FsyncResp struct{ EmptyMessage }
   861  
   862  // String implements fmt.Stringer.String.
   863  func (*FsyncResp) String() string {
   864  	return "FsyncResp{}"
   865  }
   866  
   867  // PReadReq is used to pread(2) on an FD.
   868  //
   869  // +marshal boundCheck
   870  type PReadReq struct {
   871  	Offset uint64
   872  	FD     FDID
   873  	Count  uint32
   874  	_      uint32 // Need to make struct packed.
   875  }
   876  
   877  // String implements fmt.Stringer.String.
   878  func (r *PReadReq) String() string {
   879  	return fmt.Sprintf("PReadReq{Offset: %d, FD: %d, Count: %d}", r.Offset, r.FD, r.Count)
   880  }
   881  
   882  // PReadResp is used to return the result of pread(2).
   883  type PReadResp struct {
   884  	NumBytes primitive.Uint64
   885  	Buf      []byte
   886  }
   887  
   888  // String implements fmt.Stringer.String.
   889  func (r *PReadResp) String() string {
   890  	return fmt.Sprintf("PReadResp{NumBytes: %d, Buf: [...%d bytes...]}", r.NumBytes, len(r.Buf))
   891  }
   892  
   893  // SizeBytes implements marshal.Marshallable.SizeBytes.
   894  func (r *PReadResp) SizeBytes() int {
   895  	return r.NumBytes.SizeBytes() + int(r.NumBytes)
   896  }
   897  
   898  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   899  func (r *PReadResp) MarshalBytes(dst []byte) []byte {
   900  	dst = r.NumBytes.MarshalUnsafe(dst)
   901  	return dst[copy(dst[:r.NumBytes], r.Buf[:r.NumBytes]):]
   902  }
   903  
   904  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   905  func (r *PReadResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
   906  	srcRemain, ok := r.NumBytes.CheckedUnmarshal(src)
   907  	if !ok || uint32(r.NumBytes) > uint32(len(srcRemain)) || uint32(r.NumBytes) > uint32(len(r.Buf)) {
   908  		return src, false
   909  	}
   910  
   911  	// We expect the client to have already allocated r.Buf. r.Buf probably
   912  	// (optimally) points to usermem. Directly copy into that.
   913  	r.Buf = r.Buf[:r.NumBytes]
   914  	return srcRemain[copy(r.Buf, srcRemain[:r.NumBytes]):], true
   915  }
   916  
   917  // PWriteReq is used to pwrite(2) on an FD.
   918  type PWriteReq struct {
   919  	Offset   primitive.Uint64
   920  	FD       FDID
   921  	NumBytes primitive.Uint32
   922  	Buf      []byte
   923  }
   924  
   925  // String implements fmt.Stringer.String.
   926  func (w *PWriteReq) String() string {
   927  	return fmt.Sprintf("PWriteReq{Offset: %d, FD: %d, NumBytes: %d, Buf: [...%d bytes...]}", w.Offset, w.FD, w.NumBytes, len(w.Buf))
   928  }
   929  
   930  // SizeBytes implements marshal.Marshallable.SizeBytes.
   931  func (w *PWriteReq) SizeBytes() int {
   932  	return w.Offset.SizeBytes() + w.FD.SizeBytes() + w.NumBytes.SizeBytes() + int(w.NumBytes)
   933  }
   934  
   935  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   936  func (w *PWriteReq) MarshalBytes(dst []byte) []byte {
   937  	dst = w.Offset.MarshalUnsafe(dst)
   938  	dst = w.FD.MarshalUnsafe(dst)
   939  	dst = w.NumBytes.MarshalUnsafe(dst)
   940  	return dst[copy(dst[:w.NumBytes], w.Buf[:w.NumBytes]):]
   941  }
   942  
   943  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   944  func (w *PWriteReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
   945  	w.NumBytes = 0
   946  	if w.SizeBytes() > len(src) {
   947  		return src, false
   948  	}
   949  	srcRemain := w.Offset.UnmarshalUnsafe(src)
   950  	srcRemain = w.FD.UnmarshalUnsafe(srcRemain)
   951  	srcRemain = w.NumBytes.UnmarshalUnsafe(srcRemain)
   952  
   953  	// This is an optimization. Assuming that the server is making this call, it
   954  	// is safe to just point to src rather than allocating and copying.
   955  	if uint32(w.NumBytes) > uint32(len(srcRemain)) {
   956  		return src, false
   957  	}
   958  	w.Buf = srcRemain[:w.NumBytes]
   959  	return srcRemain[w.NumBytes:], true
   960  }
   961  
   962  // PWriteResp is used to return the result of pwrite(2).
   963  //
   964  // +marshal boundCheck
   965  type PWriteResp struct {
   966  	Count uint64
   967  }
   968  
   969  // String implements fmt.Stringer.String.
   970  func (w *PWriteResp) String() string {
   971  	return fmt.Sprintf("PWriteResp{Count: %d}", w.Count)
   972  }
   973  
   974  // MkdirAtReq is used to make MkdirAt requests.
   975  type MkdirAtReq struct {
   976  	createCommon
   977  	Name SizedString
   978  }
   979  
   980  // String implements fmt.Stringer.String.
   981  func (m *MkdirAtReq) String() string {
   982  	return fmt.Sprintf("MkdirAtReq{DirFD: %d, Mode: %s, UID: %d, GID: %d, Name: %s}", m.DirFD, m.Mode, m.UID, m.GID, m.Name)
   983  }
   984  
   985  // SizeBytes implements marshal.Marshallable.SizeBytes.
   986  func (m *MkdirAtReq) SizeBytes() int {
   987  	return m.createCommon.SizeBytes() + m.Name.SizeBytes()
   988  }
   989  
   990  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
   991  func (m *MkdirAtReq) MarshalBytes(dst []byte) []byte {
   992  	dst = m.createCommon.MarshalUnsafe(dst)
   993  	return m.Name.MarshalBytes(dst)
   994  }
   995  
   996  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
   997  func (m *MkdirAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
   998  	m.Name = ""
   999  	if m.SizeBytes() > len(src) {
  1000  		return src, false
  1001  	}
  1002  	srcRemain := m.createCommon.UnmarshalUnsafe(src)
  1003  	if srcRemain, ok := m.Name.CheckedUnmarshal(srcRemain); ok {
  1004  		return srcRemain, true
  1005  	}
  1006  	return src, false
  1007  }
  1008  
  1009  // MkdirAtResp is the response to a successful MkdirAt request.
  1010  //
  1011  // +marshal boundCheck
  1012  type MkdirAtResp struct {
  1013  	ChildDir Inode
  1014  }
  1015  
  1016  // String implements fmt.Stringer.String.
  1017  func (m *MkdirAtResp) String() string {
  1018  	return fmt.Sprintf("MkdirAtResp{ChildDir: %s}", m.ChildDir.String())
  1019  }
  1020  
  1021  // MknodAtReq is used to make MknodAt requests.
  1022  type MknodAtReq struct {
  1023  	createCommon
  1024  	Minor primitive.Uint32
  1025  	Major primitive.Uint32
  1026  	Name  SizedString
  1027  }
  1028  
  1029  // String implements fmt.Stringer.String.
  1030  func (m *MknodAtReq) String() string {
  1031  	return fmt.Sprintf("MknodAtReq{DirFD: %d, Mode: %s, UID: %d, GID: %d, Minor: %d, Major: %d, Name: %s}", m.DirFD, m.Mode, m.UID, m.GID, m.Minor, m.Major, m.Name)
  1032  }
  1033  
  1034  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1035  func (m *MknodAtReq) SizeBytes() int {
  1036  	return m.createCommon.SizeBytes() + m.Minor.SizeBytes() + m.Major.SizeBytes() + m.Name.SizeBytes()
  1037  }
  1038  
  1039  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1040  func (m *MknodAtReq) MarshalBytes(dst []byte) []byte {
  1041  	dst = m.createCommon.MarshalUnsafe(dst)
  1042  	dst = m.Minor.MarshalUnsafe(dst)
  1043  	dst = m.Major.MarshalUnsafe(dst)
  1044  	return m.Name.MarshalBytes(dst)
  1045  }
  1046  
  1047  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1048  func (m *MknodAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1049  	m.Name = ""
  1050  	if m.SizeBytes() > len(src) {
  1051  		return src, false
  1052  	}
  1053  	srcRemain := m.createCommon.UnmarshalUnsafe(src)
  1054  	srcRemain = m.Minor.UnmarshalUnsafe(srcRemain)
  1055  	srcRemain = m.Major.UnmarshalUnsafe(srcRemain)
  1056  	if srcRemain, ok := m.Name.CheckedUnmarshal(srcRemain); ok {
  1057  		return srcRemain, true
  1058  	}
  1059  	return src, false
  1060  }
  1061  
  1062  // MknodAtResp is the response to a successful MknodAt request.
  1063  //
  1064  // +marshal boundCheck
  1065  type MknodAtResp struct {
  1066  	Child Inode
  1067  }
  1068  
  1069  // String implements fmt.Stringer.String.
  1070  func (m *MknodAtResp) String() string {
  1071  	return fmt.Sprintf("MknodAtResp{Child: %s}", m.Child.String())
  1072  }
  1073  
  1074  // SymlinkAtReq is used to make SymlinkAt request.
  1075  type SymlinkAtReq struct {
  1076  	DirFD  FDID
  1077  	UID    UID
  1078  	GID    GID
  1079  	Name   SizedString
  1080  	Target SizedString
  1081  }
  1082  
  1083  // String implements fmt.Stringer.String.
  1084  func (s *SymlinkAtReq) String() string {
  1085  	return fmt.Sprintf("SymlinkAtReq{DirFD: %d, UID: %d, GID: %d, Name: %s, Target: %s}", s.DirFD, s.UID, s.GID, s.Name, s.Target)
  1086  }
  1087  
  1088  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1089  func (s *SymlinkAtReq) SizeBytes() int {
  1090  	return s.DirFD.SizeBytes() + s.UID.SizeBytes() + s.GID.SizeBytes() + s.Name.SizeBytes() + s.Target.SizeBytes()
  1091  }
  1092  
  1093  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1094  func (s *SymlinkAtReq) MarshalBytes(dst []byte) []byte {
  1095  	dst = s.DirFD.MarshalUnsafe(dst)
  1096  	dst = s.UID.MarshalUnsafe(dst)
  1097  	dst = s.GID.MarshalUnsafe(dst)
  1098  	dst = s.Name.MarshalBytes(dst)
  1099  	return s.Target.MarshalBytes(dst)
  1100  }
  1101  
  1102  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1103  func (s *SymlinkAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1104  	s.Name = ""
  1105  	s.Target = ""
  1106  	if s.SizeBytes() > len(src) {
  1107  		return src, false
  1108  	}
  1109  	srcRemain := s.DirFD.UnmarshalUnsafe(src)
  1110  	srcRemain = s.UID.UnmarshalUnsafe(srcRemain)
  1111  	srcRemain = s.GID.UnmarshalUnsafe(srcRemain)
  1112  	var ok bool
  1113  	if srcRemain, ok = s.Name.CheckedUnmarshal(srcRemain); !ok {
  1114  		return src, false
  1115  	}
  1116  	if srcRemain, ok = s.Target.CheckedUnmarshal(srcRemain); !ok {
  1117  		return src, false
  1118  	}
  1119  	return srcRemain, true
  1120  }
  1121  
  1122  // SymlinkAtResp is the response to a successful SymlinkAt request.
  1123  //
  1124  // +marshal boundCheck
  1125  type SymlinkAtResp struct {
  1126  	Symlink Inode
  1127  }
  1128  
  1129  // String implements fmt.Stringer.String.
  1130  func (s *SymlinkAtResp) String() string {
  1131  	return fmt.Sprintf("SymlinkAtResp{Symlink: %s}", s.Symlink.String())
  1132  }
  1133  
  1134  // LinkAtReq is used to make LinkAt requests.
  1135  type LinkAtReq struct {
  1136  	DirFD  FDID
  1137  	Target FDID
  1138  	Name   SizedString
  1139  }
  1140  
  1141  // String implements fmt.Stringer.String.
  1142  func (l *LinkAtReq) String() string {
  1143  	return fmt.Sprintf("LinkAtReq{DirFD: %d, Target: %d, Name: %s}", l.DirFD, l.Target, l.Name)
  1144  }
  1145  
  1146  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1147  func (l *LinkAtReq) SizeBytes() int {
  1148  	return l.DirFD.SizeBytes() + l.Target.SizeBytes() + l.Name.SizeBytes()
  1149  }
  1150  
  1151  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1152  func (l *LinkAtReq) MarshalBytes(dst []byte) []byte {
  1153  	dst = l.DirFD.MarshalUnsafe(dst)
  1154  	dst = l.Target.MarshalUnsafe(dst)
  1155  	return l.Name.MarshalBytes(dst)
  1156  }
  1157  
  1158  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1159  func (l *LinkAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1160  	l.Name = ""
  1161  	if l.SizeBytes() > len(src) {
  1162  		return src, false
  1163  	}
  1164  	srcRemain := l.DirFD.UnmarshalUnsafe(src)
  1165  	srcRemain = l.Target.UnmarshalUnsafe(srcRemain)
  1166  	if srcRemain, ok := l.Name.CheckedUnmarshal(srcRemain); ok {
  1167  		return srcRemain, true
  1168  	}
  1169  	return src, false
  1170  }
  1171  
  1172  // LinkAtResp is used to respond to a successful LinkAt request.
  1173  //
  1174  // +marshal boundCheck
  1175  type LinkAtResp struct {
  1176  	Link Inode
  1177  }
  1178  
  1179  // String implements fmt.Stringer.String.
  1180  func (l *LinkAtResp) String() string {
  1181  	return fmt.Sprintf("LinkAtResp{Link: %s}", l.Link.String())
  1182  }
  1183  
  1184  // FStatFSReq is used to request StatFS results for the specified FD.
  1185  //
  1186  // +marshal boundCheck
  1187  type FStatFSReq struct {
  1188  	FD FDID
  1189  }
  1190  
  1191  // String implements fmt.Stringer.String.
  1192  func (s *FStatFSReq) String() string {
  1193  	return fmt.Sprintf("FStatFSReq{FD: %d}", s.FD)
  1194  }
  1195  
  1196  // StatFS is responded to a successful FStatFS request.
  1197  //
  1198  // +marshal boundCheck
  1199  type StatFS struct {
  1200  	Type            uint64
  1201  	BlockSize       int64
  1202  	Blocks          uint64
  1203  	BlocksFree      uint64
  1204  	BlocksAvailable uint64
  1205  	Files           uint64
  1206  	FilesFree       uint64
  1207  	NameLength      uint64
  1208  }
  1209  
  1210  // String implements fmt.Stringer.String.
  1211  func (s *StatFS) String() string {
  1212  	return fmt.Sprintf("StatFS{Type: %d, BlockSize: %d, Blocks: %d, BlocksFree: %d, BlocksAvailable: %d, Files: %d, FilesFree: %d, NameLength: %d}",
  1213  		s.Type, s.BlockSize, s.Blocks, s.BlocksFree, s.BlocksAvailable, s.Files, s.FilesFree, s.NameLength)
  1214  }
  1215  
  1216  // FAllocateReq is used to request to fallocate(2) an FD. This has no response.
  1217  //
  1218  // +marshal boundCheck
  1219  type FAllocateReq struct {
  1220  	FD     FDID
  1221  	Mode   uint64
  1222  	Offset uint64
  1223  	Length uint64
  1224  }
  1225  
  1226  // String implements fmt.Stringer.String.
  1227  func (a *FAllocateReq) String() string {
  1228  	return fmt.Sprintf("FAllocateReq{FD: %d, Mode: %d, Offset: %d, Length: %d}", a.FD, a.Mode, a.Offset, a.Length)
  1229  }
  1230  
  1231  // FAllocateResp is an empty response to FAllocateReq.
  1232  type FAllocateResp struct{ EmptyMessage }
  1233  
  1234  // String implements fmt.Stringer.String.
  1235  func (*FAllocateResp) String() string {
  1236  	return "FAllocateResp{}"
  1237  }
  1238  
  1239  // ReadLinkAtReq is used to readlinkat(2) at the specified FD.
  1240  //
  1241  // +marshal boundCheck
  1242  type ReadLinkAtReq struct {
  1243  	FD FDID
  1244  }
  1245  
  1246  // String implements fmt.Stringer.String.
  1247  func (r *ReadLinkAtReq) String() string {
  1248  	return fmt.Sprintf("ReadLinkAtReq{FD: %d}", r.FD)
  1249  }
  1250  
  1251  // ReadLinkAtResp is used to communicate ReadLinkAt results.
  1252  type ReadLinkAtResp struct {
  1253  	Target SizedString
  1254  }
  1255  
  1256  // String implements fmt.Stringer.String.
  1257  func (r *ReadLinkAtResp) String() string {
  1258  	return fmt.Sprintf("ReadLinkAtResp{Target: %s}", r.Target)
  1259  }
  1260  
  1261  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1262  func (r *ReadLinkAtResp) SizeBytes() int {
  1263  	return r.Target.SizeBytes()
  1264  }
  1265  
  1266  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1267  func (r *ReadLinkAtResp) MarshalBytes(dst []byte) []byte {
  1268  	return r.Target.MarshalBytes(dst)
  1269  }
  1270  
  1271  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1272  func (r *ReadLinkAtResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1273  	return r.Target.CheckedUnmarshal(src)
  1274  }
  1275  
  1276  // FlushReq is used to make Flush requests.
  1277  //
  1278  // +marshal boundCheck
  1279  type FlushReq struct {
  1280  	FD FDID
  1281  }
  1282  
  1283  // String implements fmt.Stringer.String.
  1284  func (f *FlushReq) String() string {
  1285  	return fmt.Sprintf("FlushReq{FD: %d}", f.FD)
  1286  }
  1287  
  1288  // FlushResp is an empty response to FlushReq.
  1289  type FlushResp struct{ EmptyMessage }
  1290  
  1291  // String implements fmt.Stringer.String.
  1292  func (*FlushResp) String() string {
  1293  	return "FlushResp{}"
  1294  }
  1295  
  1296  // ConnectReq is used to make a Connect request.
  1297  //
  1298  // +marshal boundCheck
  1299  type ConnectReq struct {
  1300  	FD FDID
  1301  	// SockType is used to specify the socket type to connect to. As a special
  1302  	// case, SockType = 0 means that the socket type does not matter and the
  1303  	// requester will accept any socket type.
  1304  	SockType uint32
  1305  	_        uint32 // Need to make struct packed.
  1306  }
  1307  
  1308  // String implements fmt.Stringer.String.
  1309  func (c *ConnectReq) String() string {
  1310  	return fmt.Sprintf("ConnectReq{FD: %d, SockType: %d}", c.FD, c.SockType)
  1311  }
  1312  
  1313  // ConnectResp is an empty response to ConnectReq.
  1314  type ConnectResp struct{ EmptyMessage }
  1315  
  1316  // String implements fmt.Stringer.String.
  1317  func (*ConnectResp) String() string {
  1318  	return "ConnectResp{}"
  1319  }
  1320  
  1321  // BindAtReq is used to make BindAt requests.
  1322  type BindAtReq struct {
  1323  	createCommon
  1324  	SockType primitive.Uint32
  1325  	Name     SizedString
  1326  }
  1327  
  1328  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1329  func (b *BindAtReq) SizeBytes() int {
  1330  	return b.createCommon.SizeBytes() + b.SockType.SizeBytes() + b.Name.SizeBytes()
  1331  }
  1332  
  1333  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1334  func (b *BindAtReq) MarshalBytes(dst []byte) []byte {
  1335  	dst = b.createCommon.MarshalUnsafe(dst)
  1336  	dst = b.SockType.MarshalUnsafe(dst)
  1337  	return b.Name.MarshalBytes(dst)
  1338  }
  1339  
  1340  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1341  func (b *BindAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1342  	b.Name = ""
  1343  	if b.SizeBytes() > len(src) {
  1344  		return src, false
  1345  	}
  1346  	srcRemain := b.createCommon.UnmarshalUnsafe(src)
  1347  	srcRemain = b.SockType.UnmarshalUnsafe(srcRemain)
  1348  	if srcRemain, ok := b.Name.CheckedUnmarshal(srcRemain); ok {
  1349  		return srcRemain, ok
  1350  	}
  1351  	return src, false
  1352  }
  1353  
  1354  // String implements fmt.Stringer.String.
  1355  func (b *BindAtReq) String() string {
  1356  	return fmt.Sprintf("BindAtReq{DirFD: %d, Mode: %s, UID: %d, GID: %d, SockType: %d, Name: %q}", b.DirFD, b.Mode, b.UID, b.GID, b.SockType, b.Name)
  1357  }
  1358  
  1359  // BindAtResp is used to communicate BindAt response.
  1360  //
  1361  // +marshal boundCheck
  1362  type BindAtResp struct {
  1363  	Child         Inode
  1364  	BoundSocketFD FDID
  1365  }
  1366  
  1367  // String implements fmt.Stringer.String.
  1368  func (b *BindAtResp) String() string {
  1369  	return fmt.Sprintf("BindAtResp{Child: %s, BoundSocketFD: %d}", b.Child.String(), b.BoundSocketFD)
  1370  }
  1371  
  1372  // ListenReq is used to make Listen requests.
  1373  //
  1374  // +marshal boundCheck
  1375  type ListenReq struct {
  1376  	FD      FDID
  1377  	Backlog int32
  1378  	_       uint32
  1379  }
  1380  
  1381  // String implements fmt.Stringer.String.
  1382  func (l *ListenReq) String() string {
  1383  	return fmt.Sprintf("ListenReq{FD: %v, Backlog: %d}", l.FD, l.Backlog)
  1384  }
  1385  
  1386  // ListenResp is an empty response to ListenResp.
  1387  type ListenResp struct{ EmptyMessage }
  1388  
  1389  // String implements fmt.Stringer.String.
  1390  func (*ListenResp) String() string {
  1391  	return "ListenResp{}"
  1392  }
  1393  
  1394  // AcceptReq is used to make AcceptRequests.
  1395  //
  1396  // +marshal boundCheck
  1397  type AcceptReq struct {
  1398  	FD FDID
  1399  }
  1400  
  1401  // String implements fmt.Stringer.String.
  1402  func (a *AcceptReq) String() string {
  1403  	return fmt.Sprintf("AcceptReq{FD: %v}", a.FD)
  1404  }
  1405  
  1406  // AcceptResp is an empty response to AcceptResp.
  1407  type AcceptResp struct {
  1408  	PeerAddr SizedString
  1409  }
  1410  
  1411  // String implements fmt.Stringer.String.
  1412  func (a *AcceptResp) String() string {
  1413  	return fmt.Sprintf("AcceptResp{PeerAddr: %s}", a.PeerAddr)
  1414  }
  1415  
  1416  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1417  func (a *AcceptResp) SizeBytes() int {
  1418  	return a.PeerAddr.SizeBytes()
  1419  }
  1420  
  1421  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1422  func (a *AcceptResp) MarshalBytes(dst []byte) []byte {
  1423  	return a.PeerAddr.MarshalBytes(dst)
  1424  }
  1425  
  1426  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1427  func (a *AcceptResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1428  	return a.PeerAddr.CheckedUnmarshal(src)
  1429  }
  1430  
  1431  // UnlinkAtReq is used to make UnlinkAt request.
  1432  type UnlinkAtReq struct {
  1433  	DirFD FDID
  1434  	Flags primitive.Uint32
  1435  	Name  SizedString
  1436  }
  1437  
  1438  // String implements fmt.Stringer.String.
  1439  func (u *UnlinkAtReq) String() string {
  1440  	return fmt.Sprintf("UnlinkAtReq{DirFD: %d, Flags: %#x, Name: %s}", u.DirFD, u.Flags, u.Name)
  1441  }
  1442  
  1443  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1444  func (u *UnlinkAtReq) SizeBytes() int {
  1445  	return u.DirFD.SizeBytes() + u.Flags.SizeBytes() + u.Name.SizeBytes()
  1446  }
  1447  
  1448  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1449  func (u *UnlinkAtReq) MarshalBytes(dst []byte) []byte {
  1450  	dst = u.DirFD.MarshalUnsafe(dst)
  1451  	dst = u.Flags.MarshalUnsafe(dst)
  1452  	return u.Name.MarshalBytes(dst)
  1453  }
  1454  
  1455  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1456  func (u *UnlinkAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1457  	u.Name = ""
  1458  	if u.SizeBytes() > len(src) {
  1459  		return src, false
  1460  	}
  1461  	srcRemain := u.DirFD.UnmarshalUnsafe(src)
  1462  	srcRemain = u.Flags.UnmarshalUnsafe(srcRemain)
  1463  	if srcRemain, ok := u.Name.CheckedUnmarshal(srcRemain); ok {
  1464  		return srcRemain, true
  1465  	}
  1466  	return src, false
  1467  }
  1468  
  1469  // UnlinkAtResp is an empty response to UnlinkAtReq.
  1470  type UnlinkAtResp struct{ EmptyMessage }
  1471  
  1472  // String implements fmt.Stringer.String.
  1473  func (*UnlinkAtResp) String() string {
  1474  	return "UnlinkAtResp{}"
  1475  }
  1476  
  1477  // RenameAtReq is used to make RenameAt requests. Note that the request takes in
  1478  // the to-be-renamed file's FD instead of oldDir and oldName like renameat(2).
  1479  type RenameAtReq struct {
  1480  	OldDir  FDID
  1481  	NewDir  FDID
  1482  	OldName SizedString
  1483  	NewName SizedString
  1484  }
  1485  
  1486  // String implements fmt.Stringer.String.
  1487  func (r *RenameAtReq) String() string {
  1488  	return fmt.Sprintf("RenameAtReq{OldDir: %d, NewDir: %d, OldName: %s, NewName: %s}", r.OldDir, r.NewDir, r.OldName, r.NewName)
  1489  }
  1490  
  1491  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1492  func (r *RenameAtReq) SizeBytes() int {
  1493  	return r.OldDir.SizeBytes() + r.NewDir.SizeBytes() + r.OldName.SizeBytes() + r.NewName.SizeBytes()
  1494  }
  1495  
  1496  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1497  func (r *RenameAtReq) MarshalBytes(dst []byte) []byte {
  1498  	dst = r.OldDir.MarshalUnsafe(dst)
  1499  	dst = r.NewDir.MarshalUnsafe(dst)
  1500  	dst = r.OldName.MarshalBytes(dst)
  1501  	return r.NewName.MarshalBytes(dst)
  1502  }
  1503  
  1504  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1505  func (r *RenameAtReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1506  	r.OldName = ""
  1507  	r.NewName = ""
  1508  	if r.SizeBytes() > len(src) {
  1509  		return src, false
  1510  	}
  1511  	srcRemain := r.OldDir.UnmarshalUnsafe(src)
  1512  	srcRemain = r.NewDir.UnmarshalUnsafe(srcRemain)
  1513  	var ok bool
  1514  	if srcRemain, ok = r.OldName.CheckedUnmarshal(srcRemain); !ok {
  1515  		return src, false
  1516  	}
  1517  	if srcRemain, ok = r.NewName.CheckedUnmarshal(srcRemain); !ok {
  1518  		return src, false
  1519  	}
  1520  	return srcRemain, true
  1521  }
  1522  
  1523  // RenameAtResp is an empty response to RenameAtReq.
  1524  type RenameAtResp struct{ EmptyMessage }
  1525  
  1526  // String implements fmt.Stringer.String.
  1527  func (*RenameAtResp) String() string {
  1528  	return "RenameAtResp{}"
  1529  }
  1530  
  1531  // Getdents64Req is used to make Getdents64 requests.
  1532  //
  1533  // +marshal boundCheck
  1534  type Getdents64Req struct {
  1535  	DirFD FDID
  1536  	// Count is the number of bytes to read. A negative value of Count is used to
  1537  	// indicate that the implementation must lseek(0, SEEK_SET) before calling
  1538  	// getdents64(2). Implementations must use the absolute value of Count to
  1539  	// determine the number of bytes to read.
  1540  	Count int32
  1541  	_     uint32 // Need to make struct packed.
  1542  }
  1543  
  1544  // String implements fmt.Stringer.String.
  1545  func (g *Getdents64Req) String() string {
  1546  	return fmt.Sprintf("Getdents64Req{DirFD: %d, Count: %d}", g.DirFD, g.Count)
  1547  }
  1548  
  1549  // Dirent64 is analogous to struct linux_dirent64.
  1550  type Dirent64 struct {
  1551  	Ino      primitive.Uint64
  1552  	DevMinor primitive.Uint32
  1553  	DevMajor primitive.Uint32
  1554  	Off      primitive.Uint64
  1555  	Type     primitive.Uint8
  1556  	Name     SizedString
  1557  }
  1558  
  1559  // String implements fmt.Stringer.String.
  1560  func (d *Dirent64) String() string {
  1561  	return fmt.Sprintf("Dirent64{Ino: %d, DevMinor: %d, DevMajor: %d, Off: %d, Type: %d, Name: %s}", d.Ino, d.DevMinor, d.DevMajor, d.Off, d.Type, d.Name)
  1562  }
  1563  
  1564  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1565  func (d *Dirent64) SizeBytes() int {
  1566  	return d.Ino.SizeBytes() + d.DevMinor.SizeBytes() + d.DevMajor.SizeBytes() + d.Off.SizeBytes() + d.Type.SizeBytes() + d.Name.SizeBytes()
  1567  }
  1568  
  1569  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1570  func (d *Dirent64) MarshalBytes(dst []byte) []byte {
  1571  	dst = d.Ino.MarshalUnsafe(dst)
  1572  	dst = d.DevMinor.MarshalUnsafe(dst)
  1573  	dst = d.DevMajor.MarshalUnsafe(dst)
  1574  	dst = d.Off.MarshalUnsafe(dst)
  1575  	dst = d.Type.MarshalUnsafe(dst)
  1576  	return d.Name.MarshalBytes(dst)
  1577  }
  1578  
  1579  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1580  func (d *Dirent64) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1581  	d.Name = ""
  1582  	if d.SizeBytes() > len(src) {
  1583  		return src, false
  1584  	}
  1585  	srcRemain := d.Ino.UnmarshalUnsafe(src)
  1586  	srcRemain = d.DevMinor.UnmarshalUnsafe(srcRemain)
  1587  	srcRemain = d.DevMajor.UnmarshalUnsafe(srcRemain)
  1588  	srcRemain = d.Off.UnmarshalUnsafe(srcRemain)
  1589  	srcRemain = d.Type.UnmarshalUnsafe(srcRemain)
  1590  	if srcRemain, ok := d.Name.CheckedUnmarshal(srcRemain); ok {
  1591  		return srcRemain, true
  1592  	}
  1593  	return src, false
  1594  }
  1595  
  1596  // Getdents64Resp is used to communicate getdents64 results. In memory, the
  1597  // dirents array is preceded by a uint16 integer denoting array length.
  1598  type Getdents64Resp struct {
  1599  	Dirents []Dirent64
  1600  }
  1601  
  1602  // String implements fmt.Stringer.String.
  1603  func (g *Getdents64Resp) String() string {
  1604  	var b strings.Builder
  1605  	b.WriteString("[")
  1606  	for i, dirent := range g.Dirents {
  1607  		if i > 0 {
  1608  			b.WriteString(", ")
  1609  		}
  1610  		b.WriteString(dirent.String())
  1611  	}
  1612  	b.WriteString("]")
  1613  	return fmt.Sprintf("Getdents64Resp{Dirents: %s}", b.String())
  1614  }
  1615  
  1616  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1617  func (g *Getdents64Resp) SizeBytes() int {
  1618  	ret := (*primitive.Uint16)(nil).SizeBytes()
  1619  	for i := range g.Dirents {
  1620  		ret += g.Dirents[i].SizeBytes()
  1621  	}
  1622  	return ret
  1623  }
  1624  
  1625  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1626  func (g *Getdents64Resp) MarshalBytes(dst []byte) []byte {
  1627  	numDirents := primitive.Uint16(len(g.Dirents))
  1628  	dst = numDirents.MarshalUnsafe(dst)
  1629  	for i := range g.Dirents {
  1630  		dst = g.Dirents[i].MarshalBytes(dst)
  1631  	}
  1632  	return dst
  1633  }
  1634  
  1635  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1636  func (g *Getdents64Resp) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1637  	g.Dirents = g.Dirents[:0]
  1638  	if g.SizeBytes() > len(src) {
  1639  		return src, false
  1640  	}
  1641  	var numDirents primitive.Uint16
  1642  	srcRemain := numDirents.UnmarshalUnsafe(src)
  1643  	if cap(g.Dirents) < int(numDirents) {
  1644  		g.Dirents = make([]Dirent64, numDirents)
  1645  	} else {
  1646  		g.Dirents = g.Dirents[:numDirents]
  1647  	}
  1648  
  1649  	var ok bool
  1650  	for i := range g.Dirents {
  1651  		if srcRemain, ok = g.Dirents[i].CheckedUnmarshal(srcRemain); !ok {
  1652  			return src, false
  1653  		}
  1654  	}
  1655  	return srcRemain, true
  1656  }
  1657  
  1658  // FGetXattrReq is used to make FGetXattr requests. The response to this is
  1659  // just a SizedString containing the xattr value.
  1660  type FGetXattrReq struct {
  1661  	FD      FDID
  1662  	BufSize primitive.Uint32
  1663  	Name    SizedString
  1664  }
  1665  
  1666  // String implements fmt.Stringer.String.
  1667  func (g *FGetXattrReq) String() string {
  1668  	return fmt.Sprintf("FGetXattrReq{FD: %d, BufSize: %d, Name: %s}", g.FD, g.BufSize, g.Name)
  1669  }
  1670  
  1671  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1672  func (g *FGetXattrReq) SizeBytes() int {
  1673  	return g.FD.SizeBytes() + g.BufSize.SizeBytes() + g.Name.SizeBytes()
  1674  }
  1675  
  1676  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1677  func (g *FGetXattrReq) MarshalBytes(dst []byte) []byte {
  1678  	dst = g.FD.MarshalUnsafe(dst)
  1679  	dst = g.BufSize.MarshalUnsafe(dst)
  1680  	return g.Name.MarshalBytes(dst)
  1681  }
  1682  
  1683  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1684  func (g *FGetXattrReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1685  	g.Name = ""
  1686  	if g.SizeBytes() > len(src) {
  1687  		return src, false
  1688  	}
  1689  	srcRemain := g.FD.UnmarshalUnsafe(src)
  1690  	srcRemain = g.BufSize.UnmarshalUnsafe(srcRemain)
  1691  	if srcRemain, ok := g.Name.CheckedUnmarshal(srcRemain); ok {
  1692  		return srcRemain, true
  1693  	}
  1694  	return src, false
  1695  }
  1696  
  1697  // FGetXattrResp is used to respond to FGetXattr request.
  1698  type FGetXattrResp struct {
  1699  	Value SizedString
  1700  }
  1701  
  1702  // String implements fmt.Stringer.String.
  1703  func (g *FGetXattrResp) String() string {
  1704  	return fmt.Sprintf("FGetXattrResp{Value: %s}", g.Value)
  1705  }
  1706  
  1707  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1708  func (g *FGetXattrResp) SizeBytes() int {
  1709  	return g.Value.SizeBytes()
  1710  }
  1711  
  1712  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1713  func (g *FGetXattrResp) MarshalBytes(dst []byte) []byte {
  1714  	return g.Value.MarshalBytes(dst)
  1715  }
  1716  
  1717  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1718  func (g *FGetXattrResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1719  	return g.Value.CheckedUnmarshal(src)
  1720  }
  1721  
  1722  // FSetXattrReq is used to make FSetXattr requests. It has no response.
  1723  type FSetXattrReq struct {
  1724  	FD    FDID
  1725  	Flags primitive.Uint32
  1726  	Name  SizedString
  1727  	Value SizedString
  1728  }
  1729  
  1730  // String implements fmt.Stringer.String.
  1731  func (s *FSetXattrReq) String() string {
  1732  	return fmt.Sprintf("FSetXattrReq{FD: %d, Flags: %#x, Name: %s, Value: %s}", s.FD, s.Flags, s.Name, s.Value)
  1733  }
  1734  
  1735  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1736  func (s *FSetXattrReq) SizeBytes() int {
  1737  	return s.FD.SizeBytes() + s.Flags.SizeBytes() + s.Name.SizeBytes() + s.Value.SizeBytes()
  1738  }
  1739  
  1740  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1741  func (s *FSetXattrReq) MarshalBytes(dst []byte) []byte {
  1742  	dst = s.FD.MarshalUnsafe(dst)
  1743  	dst = s.Flags.MarshalUnsafe(dst)
  1744  	dst = s.Name.MarshalBytes(dst)
  1745  	return s.Value.MarshalBytes(dst)
  1746  }
  1747  
  1748  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1749  func (s *FSetXattrReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1750  	s.Name = ""
  1751  	s.Value = ""
  1752  	if s.SizeBytes() > len(src) {
  1753  		return src, false
  1754  	}
  1755  	srcRemain := s.FD.UnmarshalUnsafe(src)
  1756  	srcRemain = s.Flags.UnmarshalUnsafe(srcRemain)
  1757  	var ok bool
  1758  	if srcRemain, ok = s.Name.CheckedUnmarshal(srcRemain); !ok {
  1759  		return src, false
  1760  	}
  1761  	if srcRemain, ok = s.Value.CheckedUnmarshal(srcRemain); !ok {
  1762  		return src, false
  1763  	}
  1764  	return srcRemain, true
  1765  }
  1766  
  1767  // FSetXattrResp is an empty response to FSetXattrReq.
  1768  type FSetXattrResp struct{ EmptyMessage }
  1769  
  1770  // String implements fmt.Stringer.String.
  1771  func (*FSetXattrResp) String() string {
  1772  	return "FSetXattrResp{}"
  1773  }
  1774  
  1775  // FRemoveXattrReq is used to make FRemoveXattr requests. It has no response.
  1776  type FRemoveXattrReq struct {
  1777  	FD   FDID
  1778  	Name SizedString
  1779  }
  1780  
  1781  // String implements fmt.Stringer.String.
  1782  func (r *FRemoveXattrReq) String() string {
  1783  	return fmt.Sprintf("FRemoveXattrReq{FD: %d, Name: %s}", r.FD, r.Name)
  1784  }
  1785  
  1786  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1787  func (r *FRemoveXattrReq) SizeBytes() int {
  1788  	return r.FD.SizeBytes() + r.Name.SizeBytes()
  1789  }
  1790  
  1791  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1792  func (r *FRemoveXattrReq) MarshalBytes(dst []byte) []byte {
  1793  	dst = r.FD.MarshalUnsafe(dst)
  1794  	return r.Name.MarshalBytes(dst)
  1795  }
  1796  
  1797  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1798  func (r *FRemoveXattrReq) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1799  	r.Name = ""
  1800  	if r.SizeBytes() > len(src) {
  1801  		return src, false
  1802  	}
  1803  	srcRemain := r.FD.UnmarshalUnsafe(src)
  1804  	if srcRemain, ok := r.Name.CheckedUnmarshal(srcRemain); ok {
  1805  		return srcRemain, true
  1806  	}
  1807  	return src, false
  1808  }
  1809  
  1810  // FRemoveXattrResp is an empty response to FRemoveXattrReq.
  1811  type FRemoveXattrResp struct{ EmptyMessage }
  1812  
  1813  // String implements fmt.Stringer.String.
  1814  func (*FRemoveXattrResp) String() string {
  1815  	return "FRemoveXattrResp{}"
  1816  }
  1817  
  1818  // FListXattrReq is used to make FListXattr requests.
  1819  //
  1820  // +marshal boundCheck
  1821  type FListXattrReq struct {
  1822  	FD   FDID
  1823  	Size uint64
  1824  }
  1825  
  1826  // String implements fmt.Stringer.String.
  1827  func (l *FListXattrReq) String() string {
  1828  	return fmt.Sprintf("FListXattrReq{FD: %d, Size: %d}", l.FD, l.Size)
  1829  }
  1830  
  1831  // FListXattrResp is used to respond to FListXattr requests.
  1832  type FListXattrResp struct {
  1833  	Xattrs StringArray
  1834  }
  1835  
  1836  // String implements fmt.Stringer.String.
  1837  func (l *FListXattrResp) String() string {
  1838  	return fmt.Sprintf("FListXattrResp{Xattrs: %s}", l.Xattrs.String())
  1839  }
  1840  
  1841  // SizeBytes implements marshal.Marshallable.SizeBytes.
  1842  func (l *FListXattrResp) SizeBytes() int {
  1843  	return l.Xattrs.SizeBytes()
  1844  }
  1845  
  1846  // MarshalBytes implements marshal.Marshallable.MarshalBytes.
  1847  func (l *FListXattrResp) MarshalBytes(dst []byte) []byte {
  1848  	return l.Xattrs.MarshalBytes(dst)
  1849  }
  1850  
  1851  // CheckedUnmarshal implements marshal.CheckedMarshallable.CheckedUnmarshal.
  1852  func (l *FListXattrResp) CheckedUnmarshal(src []byte) ([]byte, bool) {
  1853  	return l.Xattrs.CheckedUnmarshal(src)
  1854  }