gvisor/pkg/sentry/fs/file_operations.go

178 lines
6.9 KiB
Go

// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package fs
import (
"io"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/memmap"
"gvisor.dev/gvisor/pkg/usermem"
"gvisor.dev/gvisor/pkg/waiter"
)
// SpliceOpts define how a splice works.
type SpliceOpts struct {
// Length is the length of the splice operation.
Length int64
// SrcOffset indicates whether the existing source file offset should
// be used. If this is true, then the Start value below is used.
//
// When passed to FileOperations object, this should always be true as
// the offset will be provided by a layer above, unless the object in
// question is a pipe or socket. This value can be relied upon for such
// an indicator.
SrcOffset bool
// SrcStart is the start of the source file. This is used only if
// SrcOffset is false.
SrcStart int64
// Dup indicates that the contents should not be consumed from the
// source (e.g. in the case of a socket or a pipe), but duplicated.
Dup bool
// DstOffset indicates that the destination file offset should be used.
//
// See SrcOffset for additional information.
DstOffset bool
// DstStart is the start of the destination file. This is used only if
// DstOffset is false.
DstStart int64
}
// FileOperations are operations on a File that diverge per file system.
//
// Operations that take a *File may use only the following interfaces:
//
// - File.UniqueID: Operations may only read this value.
// - File.Dirent: Operations must not take or drop a reference.
// - File.Offset(): This value is guaranteed to not change for the
// duration of the operation.
// - File.Flags(): This value may change during the operation.
type FileOperations interface {
// Release release resources held by FileOperations.
Release(ctx context.Context)
// Waitable defines how this File can be waited on for read and
// write readiness.
waiter.Waitable
// Seek seeks to offset based on SeekWhence. Returns the new
// offset or no change in the offset and an error.
Seek(ctx context.Context, file *File, whence SeekWhence, offset int64) (int64, error)
// Readdir reads the directory entries of file and serializes them
// using serializer.
//
// Returns the new directory offset or no change in the offset and
// an error. The offset returned must not be less than file.Offset().
//
// Serialization of directory entries must not happen asynchronously.
Readdir(ctx context.Context, file *File, serializer DentrySerializer) (int64, error)
// Read reads from file into dst at offset and returns the number
// of bytes read which must be greater than or equal to 0. File
// systems that do not support reading at an offset, (i.e. pipefs,
// sockfs) may ignore the offset. These file systems are expected
// to construct Files with !FileFlags.Pread.
//
// Read may return a nil error and only partially fill dst (at or
// before EOF). If the file represents a symlink, Read reads the target
// value of the symlink.
//
// Read does not check permissions nor flags.
//
// Read must not be called if !FileFlags.Read.
Read(ctx context.Context, file *File, dst usermem.IOSequence, offset int64) (int64, error)
// WriteTo is a variant of read that takes another file as a
// destination. For a splice (copy or move from one file to another),
// first a WriteTo on the source is attempted, followed by a ReadFrom
// on the destination, following by a buffered copy with standard Read
// and Write operations.
//
// If dup is set, the data should be duplicated into the destination
// and retained.
//
// The same preconditions as Read apply.
WriteTo(ctx context.Context, file *File, dst io.Writer, count int64, dup bool) (int64, error)
// Write writes src to file at offset and returns the number of bytes
// written which must be greater than or equal to 0. Like Read, file
// systems that do not support writing at an offset (i.e. pipefs, sockfs)
// may ignore the offset. These file systems are expected to construct
// Files with !FileFlags.Pwrite.
//
// If only part of src could be written, Write must return an error
// indicating why (e.g. syserror.ErrWouldBlock).
//
// Write does not check permissions nor flags.
//
// Write must not be called if !FileFlags.Write.
Write(ctx context.Context, file *File, src usermem.IOSequence, offset int64) (int64, error)
// ReadFrom is a variant of write that takes a another file as a
// source. See WriteTo for details regarding how this is called.
//
// The same preconditions as Write apply; FileFlags.Write must be set.
ReadFrom(ctx context.Context, file *File, src io.Reader, count int64) (int64, error)
// Fsync writes buffered modifications of file and/or flushes in-flight
// operations to backing storage based on syncType. The range to sync is
// [start, end]. The end is inclusive so that the last byte of a maximally
// sized file can be synced.
Fsync(ctx context.Context, file *File, start, end int64, syncType SyncType) error
// Flush this file's buffers/state (on close(2)).
Flush(ctx context.Context, file *File) error
// ConfigureMMap mutates opts to implement mmap(2) for the file. Most
// implementations can either embed fsutil.FileNoMMap (if they don't support
// memory mapping) or call fsutil.GenericConfigureMMap with the appropriate
// memmap.Mappable.
ConfigureMMap(ctx context.Context, file *File, opts *memmap.MMapOpts) error
// UnstableAttr returns the "unstable" attributes of the inode represented
// by the file. Most implementations can embed
// fsutil.FileUseInodeUnstableAttr, which delegates to
// InodeOperations.UnstableAttr.
UnstableAttr(ctx context.Context, file *File) (UnstableAttr, error)
// Ioctl implements the ioctl(2) linux syscall.
//
// io provides access to the virtual memory space to which pointers in args
// refer.
//
// Preconditions:
// * The AddressSpace (if any) that io refers to is activated.
// * Must only be called from a task goroutine.
Ioctl(ctx context.Context, file *File, io usermem.IO, args arch.SyscallArguments) (uintptr, error)
}
// FifoSizer is an interface for setting and getting the size of a pipe.
type FifoSizer interface {
// FifoSize returns the pipe capacity in bytes.
FifoSize(ctx context.Context, file *File) (int64, error)
// SetFifoSize sets the new pipe capacity in bytes.
//
// The new size is returned (which may be capped).
SetFifoSize(size int64) (int64, error)
}