github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/fs/file_operations.go (about)

     1  // Copyright 2018 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 fs
    16  
    17  import (
    18  	"io"
    19  
    20  	"github.com/SagerNet/gvisor/pkg/context"
    21  	"github.com/SagerNet/gvisor/pkg/sentry/arch"
    22  	"github.com/SagerNet/gvisor/pkg/sentry/memmap"
    23  	"github.com/SagerNet/gvisor/pkg/usermem"
    24  	"github.com/SagerNet/gvisor/pkg/waiter"
    25  )
    26  
    27  // SpliceOpts define how a splice works.
    28  type SpliceOpts struct {
    29  	// Length is the length of the splice operation.
    30  	Length int64
    31  
    32  	// SrcOffset indicates whether the existing source file offset should
    33  	// be used. If this is true, then the Start value below is used.
    34  	//
    35  	// When passed to FileOperations object, this should always be true as
    36  	// the offset will be provided by a layer above, unless the object in
    37  	// question is a pipe or socket. This value can be relied upon for such
    38  	// an indicator.
    39  	SrcOffset bool
    40  
    41  	// SrcStart is the start of the source file. This is used only if
    42  	// SrcOffset is false.
    43  	SrcStart int64
    44  
    45  	// Dup indicates that the contents should not be consumed from the
    46  	// source (e.g. in the case of a socket or a pipe), but duplicated.
    47  	Dup bool
    48  
    49  	// DstOffset indicates that the destination file offset should be used.
    50  	//
    51  	// See SrcOffset for additional information.
    52  	DstOffset bool
    53  
    54  	// DstStart is the start of the destination file. This is used only if
    55  	// DstOffset is false.
    56  	DstStart int64
    57  }
    58  
    59  // FileOperations are operations on a File that diverge per file system.
    60  //
    61  // Operations that take a *File may use only the following interfaces:
    62  //
    63  // - File.UniqueID:	Operations may only read this value.
    64  // - File.Dirent:	Operations must not take or drop a reference.
    65  // - File.Offset(): 	This value is guaranteed to not change for the
    66  //			duration of the operation.
    67  // - File.Flags():	This value may change during the operation.
    68  type FileOperations interface {
    69  	// Release release resources held by FileOperations.
    70  	Release(ctx context.Context)
    71  
    72  	// Waitable defines how this File can be waited on for read and
    73  	// write readiness.
    74  	waiter.Waitable
    75  
    76  	// Seek seeks to offset based on SeekWhence. Returns the new
    77  	// offset or no change in the offset and an error.
    78  	Seek(ctx context.Context, file *File, whence SeekWhence, offset int64) (int64, error)
    79  
    80  	// Readdir reads the directory entries of file and serializes them
    81  	// using serializer.
    82  	//
    83  	// Returns the new directory offset or no change in the offset and
    84  	// an error. The offset returned must not be less than file.Offset().
    85  	//
    86  	// Serialization of directory entries must not happen asynchronously.
    87  	Readdir(ctx context.Context, file *File, serializer DentrySerializer) (int64, error)
    88  
    89  	// Read reads from file into dst at offset and returns the number
    90  	// of bytes read which must be greater than or equal to 0. File
    91  	// systems that do not support reading at an offset, (i.e. pipefs,
    92  	// sockfs) may ignore the offset. These file systems are expected
    93  	// to construct Files with !FileFlags.Pread.
    94  	//
    95  	// Read may return a nil error and only partially fill dst (at or
    96  	// before EOF). If the file represents a symlink, Read reads the target
    97  	// value of the symlink.
    98  	//
    99  	// Read does not check permissions nor flags.
   100  	//
   101  	// Read must not be called if !FileFlags.Read.
   102  	Read(ctx context.Context, file *File, dst usermem.IOSequence, offset int64) (int64, error)
   103  
   104  	// WriteTo is a variant of read that takes another file as a
   105  	// destination. For a splice (copy or move from one file to another),
   106  	// first a WriteTo on the source is attempted, followed by a ReadFrom
   107  	// on the destination, following by a buffered copy with standard Read
   108  	// and Write operations.
   109  	//
   110  	// If dup is set, the data should be duplicated into the destination
   111  	// and retained.
   112  	//
   113  	// The same preconditions as Read apply.
   114  	WriteTo(ctx context.Context, file *File, dst io.Writer, count int64, dup bool) (int64, error)
   115  
   116  	// Write writes src to file at offset and returns the number of bytes
   117  	// written which must be greater than or equal to 0. Like Read, file
   118  	// systems that do not support writing at an offset (i.e. pipefs, sockfs)
   119  	// may ignore the offset. These file systems are expected to construct
   120  	// Files with !FileFlags.Pwrite.
   121  	//
   122  	// If only part of src could be written, Write must return an error
   123  	// indicating why (e.g. syserror.ErrWouldBlock).
   124  	//
   125  	// Write does not check permissions nor flags.
   126  	//
   127  	// Write must not be called if !FileFlags.Write.
   128  	Write(ctx context.Context, file *File, src usermem.IOSequence, offset int64) (int64, error)
   129  
   130  	// ReadFrom is a variant of write that takes a another file as a
   131  	// source. See WriteTo for details regarding how this is called.
   132  	//
   133  	// The same preconditions as Write apply; FileFlags.Write must be set.
   134  	ReadFrom(ctx context.Context, file *File, src io.Reader, count int64) (int64, error)
   135  
   136  	// Fsync writes buffered modifications of file and/or flushes in-flight
   137  	// operations to backing storage based on syncType. The range to sync is
   138  	// [start, end]. The end is inclusive so that the last byte of a maximally
   139  	// sized file can be synced.
   140  	Fsync(ctx context.Context, file *File, start, end int64, syncType SyncType) error
   141  
   142  	// Flush this file's buffers/state (on close(2)).
   143  	Flush(ctx context.Context, file *File) error
   144  
   145  	// ConfigureMMap mutates opts to implement mmap(2) for the file. Most
   146  	// implementations can either embed fsutil.FileNoMMap (if they don't support
   147  	// memory mapping) or call fsutil.GenericConfigureMMap with the appropriate
   148  	// memmap.Mappable.
   149  	ConfigureMMap(ctx context.Context, file *File, opts *memmap.MMapOpts) error
   150  
   151  	// UnstableAttr returns the "unstable" attributes of the inode represented
   152  	// by the file. Most implementations can embed
   153  	// fsutil.FileUseInodeUnstableAttr, which delegates to
   154  	// InodeOperations.UnstableAttr.
   155  	UnstableAttr(ctx context.Context, file *File) (UnstableAttr, error)
   156  
   157  	// Ioctl implements the ioctl(2) linux syscall.
   158  	//
   159  	// io provides access to the virtual memory space to which pointers in args
   160  	// refer.
   161  	//
   162  	// Preconditions:
   163  	// * The AddressSpace (if any) that io refers to is activated.
   164  	// * Must only be called from a task goroutine.
   165  	Ioctl(ctx context.Context, file *File, io usermem.IO, args arch.SyscallArguments) (uintptr, error)
   166  }
   167  
   168  // FifoSizer is an interface for setting and getting the size of a pipe.
   169  type FifoSizer interface {
   170  	// FifoSize returns the pipe capacity in bytes.
   171  	FifoSize(ctx context.Context, file *File) (int64, error)
   172  
   173  	// SetFifoSize sets the new pipe capacity in bytes.
   174  	//
   175  	// The new size is returned (which may be capped).
   176  	SetFifoSize(size int64) (int64, error)
   177  }