fs

package
Version: v0.0.0-...-de960bb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2022 License: Apache-2.0, MIT Imports: 32 Imported by: 39

README

This package provides an implementation of the Linux virtual filesystem.

[TOC]

Overview

  • An fs.Dirent caches an fs.Inode in memory at a path in the VFS, giving the fs.Inode a relative position with respect to other fs.Inodes.

  • If an fs.Dirent is referenced by two file descriptors, then those file descriptors are coherent with each other: they depend on the same fs.Inode.

  • A mount point is an fs.Dirent for which fs.Dirent.mounted is true. It exposes the root of a mounted filesystem.

  • The fs.Inode produced by a registered filesystem on mount(2) owns an fs.MountedFilesystem from which other fs.Inodes will be looked up. For a remote filesystem, the fs.MountedFilesystem owns the connection to that remote filesystem.

  • In general:

fs.Inode <------------------------------
|                                      |
|                                      |
produced by                            |
exactly one                            |
|                             responsible for the
|                             virtual identity of
v                                      |
fs.MountedFilesystem -------------------

Glossary:

  • VFS: virtual filesystem.

  • inode: a virtual file object holding a cached view of a file on a backing filesystem (includes metadata and page caches).

  • superblock: the virtual state of a mounted filesystem (e.g. the virtual inode number set).

  • mount namespace: a view of the mounts under a root (during path traversal, the VFS makes visible/follows the mount point that is in the current task's mount namespace).

Save and restore

An application's hard dependencies on filesystem state can be broken down into two categories:

  • The state necessary to execute a traversal on or view the virtual filesystem hierarchy, regardless of what files an application has open.

  • The state necessary to represent open files.

The first is always necessary to save and restore. An application may never have any open file descriptors, but across save and restore it should see a coherent view of any mount namespace. NOTE(b/63601033): Currently only one "initial" mount namespace is supported.

The second is so that system calls across save and restore are coherent with each other (e.g. so that unintended re-reads or overwrites do not occur).

Specifically this state is:

  • An fs.MountManager containing mount points.

  • A kernel.FDTable containing pointers to open files.

Anything else managed by the VFS that can be easily loaded into memory from a filesystem is synced back to those filesystems and is not saved. Examples are pages in page caches used for optimizations (i.e. readahead and writeback), and directory entries used to accelerate path lookups.

Mount points

Saving and restoring a mount point means saving and restoring:

  • The root of the mounted filesystem.

  • Mount flags, which control how the VFS interacts with the mounted filesystem.

  • Any relevant metadata about the mounted filesystem.

  • All fs.Inodes referenced by the application that reside under the mount point.

fs.MountedFilesystem is metadata about a filesystem that is mounted. It is referenced by every fs.Inode loaded into memory under the mount point including the fs.Inode of the mount point itself. The fs.MountedFilesystem maps file objects on the filesystem to a virtualized fs.Inode number and vice versa.

To restore all fs.Inodes under a given mount point, each fs.Inode leverages its dependency on an fs.MountedFilesystem. Since the fs.MountedFilesystem knows how an fs.Inode maps to a file object on a backing filesystem, this mapping can be trivially consulted by each fs.Inode when the fs.Inode is restored.

In detail, a mount point is saved in two steps:

  • First, after the kernel is paused but before state.Save, we walk all mount namespaces and install a mapping from fs.Inode numbers to file paths relative to the root of the mounted filesystem in each fs.MountedFilesystem. This is subsequently called the set of fs.Inode mappings.

  • Second, during state.Save, each fs.MountedFilesystem decides whether to save the set of fs.Inode mappings. In-memory filesystems, like tmpfs, have no need to save a set of fs.Inode mappings, since the fs.Inodes can be entirely encoded in state file. Each fs.MountedFilesystem also optionally saves the device name from when the filesystem was originally mounted. Each fs.Inode saves its virtual identifier and a reference to a fs.MountedFilesystem.

A mount point is restored in two steps:

  • First, before state.Load, all mount configurations are stored in a global fs.RestoreEnvironment. This tells us what mount points the user wants to restore and how to re-establish pointers to backing filesystems.

  • Second, during state.Load, each fs.MountedFilesystem optionally searches for a mount in the fs.RestoreEnvironment that matches its saved device name. The fs.MountedFilesystem then reestablishes a pointer to the root of the mounted filesystem. For example, the mount specification provides the network connection for a mounted remote filesystem client to communicate with its remote file server. The fs.MountedFilesystem also trivially loads its set of fs.Inode mappings. When an fs.Inode is encountered, the fs.Inode loads its virtual identifier and its reference a fs.MountedFilesystem. It uses the fs.MountedFilesystem to obtain the root of the mounted filesystem and the fs.Inode mappings to obtain the relative file path to its data. With these, the fs.Inode re-establishes a pointer to its file object.

A mount point can trivially restore its fs.Inodes in parallel since fs.Inodes have a restore dependency on their fs.MountedFilesystem and not on each other.

Open files

An fs.File references the following filesystem objects:

fs.File -> fs.Dirent -> fs.Inode -> fs.MountedFilesystem

The fs.Inode is restored using its fs.MountedFilesystem. The Mount points section above describes how this happens in detail. The fs.Dirent restores its pointer to an fs.Inode, pointers to parent and children fs.Dirents, and the basename of the file.

Otherwise an fs.File restores flags, an offset, and a unique identifier (only used internally).

It may use the fs.Inode, which it indirectly holds a reference on through the fs.Dirent, to reestablish an open file handle on the backing filesystem (e.g. to continue reading and writing).

Overlay

The overlay implementation in the fs package takes Linux overlayfs as a frame of reference but corrects for several POSIX consistency errors.

In Linux overlayfs, the struct inode used for reading and writing to the same file may be different. This is because the struct inode is dissociated with the process of copying up the file from the upper to the lower directory. Since flock(2) and fcntl(2) locks, inotify(7) watches, page caches, and a file's identity are all stored directly or indirectly off the struct inode, these properties of the struct inode may be stale after the first modification. This can lead to file locking bugs, missed inotify events, and inconsistent data in shared memory mappings of files, to name a few problems.

The fs package maintains a single fs.Inode to represent a directory entry in an overlay and defines operations on this fs.Inode which synchronize with the copy up process. This achieves several things:

  • File locks, inotify watches, and the identity of the file need not be copied at all.

  • Memory mappings of files coordinate with the copy up process so that if a file in the lower directory is memory mapped, all references to it are invalidated, forcing the application to re-fault on memory mappings of the file under the upper directory.

The fs.Inode holds metadata about files in the upper and/or lower directories via an fs.overlayEntry. The fs.overlayEntry implements the fs.Mappable interface. It multiplexes between upper and lower directory memory mappings and stores a copy of memory references so they can be transferred to the upper directory fs.Mappable when the file is copied up.

The lower filesystem in an overlay may contain another (nested) overlay, but the upper filesystem may not contain another overlay. In other words, nested overlays form a tree structure that only allows branching in the lower filesystem.

Caching decisions in the overlay are delegated to the upper filesystem, meaning that the Keep and Revalidate methods on the overlay return the same values as the upper filesystem. A small wrinkle is that the lower filesystem is not allowed to return true from Revalidate, as the overlay can not reload inodes from the lower filesystem. A lower filesystem that does return true from Revalidate will trigger a panic.

The fs.Inode also holds a reference to a fs.MountedFilesystem that normalizes across the mounted filesystem state of the upper and lower directories.

When a file is copied from the lower to the upper directory, attempts to interact with the file block until the copy completes. All copying synchronizes with rename(2).

Future Work

Overlay

When a file is copied from a lower directory to an upper directory, several locks are taken: the global renamuMu and the copyMu of the fs.Inode being copied. This blocks operations on the file, including fault handling of memory mappings. Performance could be improved by copying files into a temporary directory that resides on the same filesystem as the upper directory and doing an atomic rename, holding locks only during the rename operation.

Additionally files are copied up synchronously. For large files, this causes a noticeable latency. Performance could be improved by pipelining copies at non-overlapping file offsets.

Documentation

Overview

Package fs implements a virtual filesystem layer.

Specific filesystem implementations must implement the InodeOperations interface (inode.go).

The MountNamespace (mounts.go) is used to create a collection of mounts in a filesystem rooted at a given Inode.

MountSources (mount.go) form a tree, with each mount holding pointers to its parent and children.

Dirents (dirents.go) wrap Inodes in a caching layer.

When multiple locks are to be held at the same time, they should be acquired in the following order.

Either:

File.mu
  Locks in FileOperations implementations
    goto Dirent-Locks

Or:

MountNamespace.mu
  goto Dirent-Locks

Dirent-Locks:

renameMu
  Dirent.dirMu
    Dirent.mu
      DirentCache.mu
      Inode.Watches.mu (see `Inotify` for other lock ordering)
      MountSource.mu
      Inode.appendMu
        Locks in InodeOperations implementations or overlayEntry

If multiple Dirent or MountSource locks must be taken, locks in the parent must be taken before locks in their children.

If locks must be taken on multiple unrelated Dirents, renameMu must be taken first. See lockForRename.

Index

Constants

View Source
const (
	// CtxRoot is a Context.Value key for a Dirent.
	CtxRoot contextID = iota

	// CtxDirentCacheLimiter is a Context.Value key for DirentCacheLimiter.
	CtxDirentCacheLimiter
)
View Source
const (
	// XattrOverlayPrefix is the prefix for extended attributes that affect
	// the behavior of an overlay.
	XattrOverlayPrefix = "trusted.overlay."

	// XattrOverlayWhiteoutPrefix is the prefix for extended attributes
	// that indicate that a whiteout exists.
	XattrOverlayWhiteoutPrefix = XattrOverlayPrefix + "whiteout."
)
View Source
const DefaultDirentCacheSize uint64 = 1000

DefaultDirentCacheSize is the number of Dirents that the VFS can hold an extra reference on.

View Source
const DefaultTraversalLimit = 10

DefaultTraversalLimit provides a sensible default traversal limit that may be passed to FindInode and FindLink. You may want to provide other options in individual syscall implementations, but for internal functions this will be sane.

View Source
const FileMaxOffset = math.MaxInt64

FileMaxOffset is the maximum possible file offset.

Variables

View Source
var (
	// ErrResolveViaReadlink is a special error value returned by
	// InodeOperations.Getlink() to indicate that a link should be
	// resolved automatically by walking to the path returned by
	// InodeOperations.Readlink().
	ErrResolveViaReadlink = errors.New("link should be resolved via Readlink()")
)
View Source
var RootOwner = FileOwner{
	UID: auth.RootKUID,
	GID: auth.RootKGID,
}

RootOwner corresponds to KUID/KGID 0/0.

Functions

func Async

func Async(f func())

Async executes a function asynchronously.

Async must not be called recursively. +checklocksignore

func AsyncBarrier

func AsyncBarrier()

AsyncBarrier waits for all outstanding asynchronous work to complete.

func AsyncErrorBarrier

func AsyncErrorBarrier() error

AsyncErrorBarrier waits for all outstanding asynchronous work to complete, or the first async error to arrive. Other unfinished async executions will continue in the background. Other past and future async errors are ignored.

func AsyncWithContext

func AsyncWithContext(ctx context.Context, f func(context.Context))

AsyncWithContext is just like Async, except that it calls the asynchronous function with the given context as argument. This function exists to avoid needing to allocate an extra function on the heap in a hot path. +checklocksignore

func CatchError

func CatchError(f func() error) func()

CatchError tries to capture the potential async error returned by the function. At most one async error will be captured globally so excessive errors will be dropped.

func ContextCanAccessFile

func ContextCanAccessFile(ctx context.Context, inode *Inode, reqPerms PermMask) bool

ContextCanAccessFile determines whether `file` can be accessed in the requested way (for reading, writing, or execution) using the caller's credentials and user namespace, as does Linux's fs/namei.c:generic_permission.

func DirentReaddir

func DirentReaddir(ctx context.Context, d *Dirent, it DirIterator, root *Dirent, dirCtx *DirCtx, offset int64) (int64, error)

DirentReaddir serializes the directory entries of d including "." and "..".

Arguments:

- d:		the Dirent of the directory being read; required to provide "." and "..".
- it:	the directory iterator; which represents an open directory handle.
- root: 	fs root; if d is equal to the root, then '..' will refer to d.
- ctx: 	context provided to file systems in order to select and serialize entries.
- offset:	the current directory offset.

Returns the offset of the *next* element which was not serialized.

func GenericMountSourceOptions

func GenericMountSourceOptions(data string) map[string]string

GenericMountSourceOptions splits a string containing comma separated tokens of the format 'key=value' or 'key' into a map of keys and values. For example:

data = "key0=value0,key1,key2=value2" -> map{'key0':'value0','key1':”,'key2':'value2'}

If data contains duplicate keys, then the last token wins.

func GenericReaddir

func GenericReaddir(ctx *DirCtx, s *SortedDentryMap) (int, error)

GenericReaddir serializes DentAttrs based on a SortedDentryMap that must contain _all_ up-to-date DentAttrs under a directory. If ctx.DirCursor is not nil, it is updated to the name of the last DentAttr that was successfully serialized.

Returns the number of entries serialized.

func IsAnonymous

func IsAnonymous(s StableAttr) bool

IsAnonymous returns true if StableAttr.Type matches any type of anonymous.

func IsCharDevice

func IsCharDevice(s StableAttr) bool

IsCharDevice returns true if StableAttr.Type matches a character device.

func IsDir

func IsDir(s StableAttr) bool

IsDir returns true if StableAttr.Type matches any type of directory.

func IsFile

func IsFile(s StableAttr) bool

IsFile returns true if StableAttr.Type matches any type of file.

func IsPipe

func IsPipe(s StableAttr) bool

IsPipe returns true if StableAttr.Type matches any type of pipe.

func IsRegular

func IsRegular(s StableAttr) bool

IsRegular returns true if StableAttr.Type matches a regular file.

func IsSocket

func IsSocket(s StableAttr) bool

IsSocket returns true if StableAttr.Type matches any type of socket.

func IsSubpath

func IsSubpath(subpath, path string) (string, bool)

IsSubpath checks whether the first path is a (strict) descendent of the second. If it is a subpath, then true is returned along with a clean relative path from the second path to the first. Otherwise false is returned.

func IsSymlink(s StableAttr) bool

IsSymlink returns true if StableAttr.Type matches a symlink.

func OffsetPageEnd

func OffsetPageEnd(offset int64) uint64

OffsetPageEnd returns the file offset rounded up to the nearest page boundary. OffsetPageEnd panics if rounding up causes overflow, which shouldn't be possible given that offset is an int64.

func ReadEndOffset

func ReadEndOffset(offset int64, length int64, size int64) int64

ReadEndOffset returns an exclusive end offset for a read operation so that the read does not overflow an int64 nor size.

Parameters:

- offset: the starting offset of the read.
- length: the number of bytes to read.
- size:   the size of the file.

Postconditions: The returned offset is >= offset.

func RegisterFilesystem

func RegisterFilesystem(f Filesystem)

RegisterFilesystem registers a new file system that is visible to mount and the /proc/filesystems list. Packages implementing Filesystem should call RegisterFilesystem in init().

func Rename

func Rename(ctx context.Context, root *Dirent, oldParent *Dirent, oldName string, newParent *Dirent, newName string) error

Rename atomically converts the child of oldParent named oldName to a child of newParent named newName.

func SaveFileFsyncError

func SaveFileFsyncError(err error) error

SaveFileFsyncError converts an fs.File.Fsync error to an error that indicates that the fs.File was not synced sufficiently to be saved.

func SaveInodeMappings

func SaveInodeMappings()

SaveInodeMappings saves a mapping of path -> inode ID for every user-reachable Dirent.

The entire kernel must be frozen to call this, and filesystem state must not change between SaveInodeMappings and state.Save, otherwise the saved state of any MountSource may be incoherent.

func SetRestoreEnvironment

func SetRestoreEnvironment(r RestoreEnvironment)

SetRestoreEnvironment sets the RestoreEnvironment. Must be called before state.Load and only once.

func Splice

func Splice(ctx context.Context, dst *File, src *File, opts SpliceOpts) (int64, error)

Splice moves data to this file, directly from another.

Offsets are updated only if DstOffset and SrcOffset are set. +checklocksignore

func SplitFirst

func SplitFirst(path string) (current, remainder string)

SplitFirst splits the given path into a first directory and the remainder.

If remainder is empty, then the path is a single element.

func SplitLast

func SplitLast(path string) (dir, file string)

SplitLast splits the given path into a directory and a file.

The "absoluteness" of the path is preserved, but dir is always stripped of trailing slashes.

func ToDirentType

func ToDirentType(nodeType InodeType) uint8

ToDirentType converts an InodeType to a linux dirent type field.

func TrimTrailingSlashes

func TrimTrailingSlashes(dir string) (trimmed string, changed bool)

TrimTrailingSlashes trims any trailing slashes.

The returned boolean indicates whether any changes were made.

func WithRoot

func WithRoot(ctx context.Context, root *Dirent) context.Context

WithRoot returns a copy of ctx with the given root.

func WriteEndOffset

func WriteEndOffset(offset int64, length int64) int64

WriteEndOffset returns an exclusive end offset for a write operation so that the write does not overflow an int64.

Parameters:

- offset: the starting offset of the write.
- length: the number of bytes to write.

Postconditions: The returned offset is >= offset.

func XattrOverlayWhiteout

func XattrOverlayWhiteout(name string) string

XattrOverlayWhiteout returns an extended attribute that indicates a whiteout exists for name. It is supported by directories that wish to mask the existence of name.

Types

type AttrMask

type AttrMask struct {
	Type             bool
	DeviceID         bool
	InodeID          bool
	BlockSize        bool
	Size             bool
	Usage            bool
	Perms            bool
	UID              bool
	GID              bool
	AccessTime       bool
	ModificationTime bool
	StatusChangeTime bool
	Links            bool
}

AttrMask contains fields to mask StableAttr and UnstableAttr.

+stateify savable

func (AttrMask) Empty

func (a AttrMask) Empty() bool

Empty returns true if all fields in AttrMask are false.

type CollectEntriesSerializer

type CollectEntriesSerializer struct {
	Entries map[string]DentAttr
	Order   []string
}

CollectEntriesSerializer copies DentAttrs to Entries. The order in which entries are encountered is preserved in Order.

func (*CollectEntriesSerializer) CopyOut

func (c *CollectEntriesSerializer) CopyOut(name string, attr DentAttr) error

CopyOut implements DentrySerializer.CopyOut.

func (*CollectEntriesSerializer) Written

func (c *CollectEntriesSerializer) Written() int

Written implements DentrySerializer.Written.

type DentAttr

type DentAttr struct {
	// Type is the InodeType of an Inode.
	Type InodeType

	// InodeID uniquely identifies an Inode on a device.
	InodeID uint64
}

DentAttr is the metadata of a directory entry. It is a subset of StableAttr.

+stateify savable

func GenericDentAttr

func GenericDentAttr(nt InodeType, device *device.Device) DentAttr

GenericDentAttr returns a generic DentAttr where:

Type == nt InodeID == the inode id of a new inode on device.

type DentrySerializer

type DentrySerializer interface {
	// CopyOut serializes a directory entry based on its name and attributes.
	CopyOut(name string, attributes DentAttr) error

	// Written returns the number of bytes written.
	Written() int
}

DentrySerializer serializes a directory entry.

type DirCtx

type DirCtx struct {
	// Serializer is used to serialize the node attributes.
	Serializer DentrySerializer

	// DirCursor is the directory cursor.
	DirCursor *string
	// contains filtered or unexported fields
}

DirCtx is used in FileOperations.IterateDir to emit directory entries. It is not thread-safe.

func (*DirCtx) DentAttrs

func (c *DirCtx) DentAttrs() map[string]DentAttr

DentAttrs returns a map of DentAttrs corresponding to the emitted directory entries.

func (*DirCtx) DirEmit

func (c *DirCtx) DirEmit(name string, attr DentAttr) error

DirEmit is called for each directory entry.

type DirIterator

type DirIterator interface {
	// IterateDir emits directory entries by calling dirCtx.EmitDir, beginning
	// with the entry at offset and returning the next directory offset.
	//
	// Entries for "." and ".." must *not* be included.
	//
	// If the offset returned is the same as the argument offset, then
	// nothing has been serialized.  This is equivalent to reaching EOF.
	// In this case serializer.Written() should return 0.
	//
	// The order of entries to emit must be consistent between Readdir
	// calls, and must start with the given offset.
	//
	// The caller must ensure that this operation is permitted.
	IterateDir(ctx context.Context, d *Dirent, dirCtx *DirCtx, offset int) (int, error)
}

DirIterator is an open directory containing directory entries that can be read.

type Dirent

type Dirent struct {
	// AtomicRefCount is our reference count.
	refs.AtomicRefCount

	// Inode is the underlying file object.
	//
	// Inode is exported currently to assist in implementing overlay Inodes (where a
	// Inode.InodeOperations.Lookup may need to merge the Inode contained in a positive Dirent with
	// another Inode). This is normally done before the Dirent is parented (there are
	// no external references to it).
	//
	// Other objects in the VFS may take a reference to this Inode but only while holding
	// a reference to this Dirent.
	Inode *Inode
	// contains filtered or unexported fields
}

Dirent holds an Inode in memory.

A Dirent may be negative or positive:

A negative Dirent contains a nil Inode and indicates that a path does not exist. This is a convention taken from the Linux dcache, see fs/dcache.c. A negative Dirent remains cached until a create operation replaces it with a positive Dirent. A negative Dirent always has one reference owned by its parent and takes _no_ reference on its parent. This ensures that its parent can be unhashed regardless of negative children.

A positive Dirent contains a non-nil Inode. It remains cached for as long as there remain references to it. A positive Dirent always takes a reference on its parent.

A Dirent may be a root Dirent (parent is nil) or be parented (non-nil parent).

Dirents currently do not attempt to free entries that lack application references under memory pressure.

+stateify savable

func NewDirent

func NewDirent(ctx context.Context, inode *Inode, name string) *Dirent

NewDirent returns a new root Dirent, taking the caller's reference on inode. The caller holds the only reference to the Dirent. Parents may call hashChild to parent this Dirent.

func NewNegativeDirent

func NewNegativeDirent(name string) *Dirent

NewNegativeDirent returns a new root negative Dirent. Otherwise same as NewDirent.

func NewTransientDirent

func NewTransientDirent(inode *Inode) *Dirent

NewTransientDirent creates a transient Dirent that shouldn't actually be visible to users.

An Inode is required.

func RootFromContext

func RootFromContext(ctx context.Context) *Dirent

RootFromContext returns the root of the virtual filesystem observed by ctx, or nil if ctx is not associated with a virtual filesystem. If RootFromContext returns a non-nil fs.Dirent, a reference is taken on it.

func (*Dirent) BaseName

func (d *Dirent) BaseName() string

BaseName returns the base name of the dirent.

func (*Dirent) Bind

func (d *Dirent) Bind(ctx context.Context, root *Dirent, name string, data transport.BoundEndpoint, perms FilePermissions) (*Dirent, error)

Bind satisfies the InodeOperations interface; otherwise same as GetFile.

func (*Dirent) Create

func (d *Dirent) Create(ctx context.Context, root *Dirent, name string, flags FileFlags, perms FilePermissions) (*File, error)

Create creates a new regular file in this directory.

func (*Dirent) CreateDirectory

func (d *Dirent) CreateDirectory(ctx context.Context, root *Dirent, name string, perms FilePermissions) error

CreateDirectory creates a new directory under this dirent.

func (*Dirent) CreateFifo

func (d *Dirent) CreateFifo(ctx context.Context, root *Dirent, name string, perms FilePermissions) error

CreateFifo creates a new named pipe under this dirent.

func (d *Dirent) CreateHardLink(ctx context.Context, root *Dirent, target *Dirent, name string) error

CreateHardLink creates a new hard link in this directory.

func (d *Dirent) CreateLink(ctx context.Context, root *Dirent, oldname, newname string) error

CreateLink creates a new link in this directory.

func (*Dirent) DecRef

func (d *Dirent) DecRef(ctx context.Context)

DecRef decreases the Dirent's refcount and drops its reference on its mount.

DecRef implements RefCounter.DecRef with destructor d.destroy.

func (*Dirent) FullName

func (d *Dirent) FullName(root *Dirent) (string, bool)

FullName returns the fully-qualified name and a boolean value representing whether this Dirent was a descendant of root. If the root argument is nil it is assumed to be the root of the Dirent tree.

func (*Dirent) GetDotAttrs

func (d *Dirent) GetDotAttrs(root *Dirent) (DentAttr, DentAttr)

GetDotAttrs returns the DentAttrs corresponding to "." and ".." directories.

func (*Dirent) IncRef

func (d *Dirent) IncRef()

IncRef increases the Dirent's refcount as well as its mount's refcount.

IncRef implements RefCounter.IncRef.

func (*Dirent) InotifyEvent

func (d *Dirent) InotifyEvent(events, cookie uint32)

InotifyEvent notifies all watches on the inode for this dirent and its parent of potential events. The events may not actually propagate up to the user, depending on the event masks. InotifyEvent automatically provides the name of the current dirent as the subject of the event as required, and adds the IN_ISDIR flag for dirents that refer to directories.

func (*Dirent) IsNegative

func (d *Dirent) IsNegative() bool

IsNegative returns true if d represents a path that does not exist.

func (*Dirent) IsRoot

func (d *Dirent) IsRoot() bool

IsRoot returns true if d is a root Dirent.

func (*Dirent) MayDelete

func (d *Dirent) MayDelete(ctx context.Context, root *Dirent, name string) error

MayDelete determines whether `name`, a child of `d`, can be deleted or renamed by `ctx`.

Compare Linux kernel fs/namei.c:may_delete.

func (*Dirent) MountRoot

func (d *Dirent) MountRoot() *Dirent

MountRoot finds and returns the mount-root for a given dirent.

func (*Dirent) Remove

func (d *Dirent) Remove(ctx context.Context, root *Dirent, name string, dirPath bool) error

Remove removes the given file or symlink. The root dirent is used to resolve name, and must not be nil.

func (*Dirent) RemoveDirectory

func (d *Dirent) RemoveDirectory(ctx context.Context, root *Dirent, name string) error

RemoveDirectory removes the given directory. The root dirent is used to resolve name, and must not be nil.

func (*Dirent) SyncAll

func (d *Dirent) SyncAll(ctx context.Context)

SyncAll iterates through mount points under d and writes back their buffered modifications to filesystems.

func (*Dirent) TryIncRef

func (d *Dirent) TryIncRef() bool

TryIncRef implements RefCounter.TryIncRef.

func (*Dirent) Walk

func (d *Dirent) Walk(ctx context.Context, root *Dirent, name string) (*Dirent, error)

Walk walks to a new dirent, and will not walk higher than the given root Dirent, which must not be nil.

type DirentCache

type DirentCache struct {
	// contains filtered or unexported fields
}

DirentCache is an LRU cache of Dirents. The Dirent's refCount is incremented when it is added to the cache, and decremented when it is removed.

A nil DirentCache corresponds to a cache with size 0. All methods can be called, but nothing is actually cached.

+stateify savable

func NewDirentCache

func NewDirentCache(maxSize uint64) *DirentCache

NewDirentCache returns a new DirentCache with the given maxSize.

func (*DirentCache) Add

func (c *DirentCache) Add(d *Dirent)

Add adds the element to the cache and increments the refCount. If the argument is already in the cache, it is moved to the front. An element is removed from the back if the cache is over capacity.

func (*DirentCache) Invalidate

func (c *DirentCache) Invalidate()

Invalidate removes all Dirents from the cache, calling DecRef on each.

func (*DirentCache) Remove

func (c *DirentCache) Remove(d *Dirent)

Remove removes the element from the cache and decrements its refCount. It also sets the previous and next elements to nil, which allows us to determine if a given element is in the cache.

func (*DirentCache) Size

func (c *DirentCache) Size() uint64

Size returns the number of elements in the cache.

type DirentCacheLimiter

type DirentCacheLimiter struct {
	// contains filtered or unexported fields
}

DirentCacheLimiter acts as a global limit for all dirent caches in the process.

+stateify savable

func DirentCacheLimiterFromContext

func DirentCacheLimiterFromContext(ctx context.Context) *DirentCacheLimiter

DirentCacheLimiterFromContext returns the DirentCacheLimiter used by ctx, or nil if ctx does not have a dirent cache limiter.

func NewDirentCacheLimiter

func NewDirentCacheLimiter(max uint64) *DirentCacheLimiter

NewDirentCacheLimiter creates a new DirentCacheLimiter.

type DirentOperations

type DirentOperations interface {
	// Revalidate is called during lookup each time we encounter a Dirent
	// in the cache. Implementations may update stale properties of the
	// child Inode. If Revalidate returns true, then the entire Inode will
	// be reloaded.
	//
	// Revalidate will never be called on a Inode that is mounted.
	Revalidate(ctx context.Context, name string, parent, child *Inode) bool

	// Keep returns true if the Dirent should be kept in memory for as long
	// as possible beyond any active references.
	Keep(dirent *Dirent) bool

	// CacheReaddir returns true if directory entries returned by
	// FileOperations.Readdir may be cached for future use.
	//
	// Postconditions: This method must always return the same value.
	CacheReaddir() bool
}

DirentOperations provide file systems greater control over how long a Dirent stays pinned in core. Implementations must not take Dirent.mu.

type ErrCorruption

type ErrCorruption struct {
	// Err is the wrapped error.
	Err error
}

ErrCorruption indicates a failed restore due to external file system state in corruption.

func (ErrCorruption) Error

func (e ErrCorruption) Error() string

Error returns a sensible description of the restore error.

type ErrSaveRejection

type ErrSaveRejection struct {
	// Err is the wrapped error.
	Err error
}

ErrSaveRejection indicates a failed save due to unsupported file system state such as dangling open fd, etc.

func (*ErrSaveRejection) Error

func (e *ErrSaveRejection) Error() string

Error returns a sensible description of the save rejection error.

type Event

type Event struct {
	// contains filtered or unexported fields
}

Event represents a struct inotify_event from linux.

+stateify savable

func (*Event) CopyTo

func (e *Event) CopyTo(ctx context.Context, buf []byte, dst usermem.IOSequence) (int64, error)

CopyTo serializes this event to dst. buf is used as a scratch buffer to construct the output. We use a buffer allocated ahead of time for performance. buf must be at least inotifyEventBaseSize bytes.

type FifoSizer

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)
}

FifoSizer is an interface for setting and getting the size of a pipe.

type File

type File struct {
	refs.AtomicRefCount

	// UniqueID is the globally unique identifier of the File.
	UniqueID uint64

	// Dirent is the Dirent backing this File. This encodes the name
	// of the File via Dirent.FullName() as well as its identity via the
	// Dirent's Inode. The Dirent is non-nil.
	//
	// A File holds a reference to this Dirent. Using the returned Dirent is
	// only safe as long as a reference on the File is held. The association
	// between a File and a Dirent is immutable.
	//
	// Files that are not parented in a filesystem return a root Dirent
	// that holds a reference to their Inode.
	//
	// The name of the Dirent may reflect parentage if the Dirent is not a
	// root Dirent or the identity of the File on a pseudo filesystem (pipefs,
	// sockfs, etc).
	//
	// Multiple Files may hold a reference to the same Dirent. This is the
	// common case for Files that are parented and maintain consistency with
	// other files via the Dirent cache.
	Dirent *Dirent

	// FileOperations implements file system specific behavior for this File.
	FileOperations FileOperations `state:"wait"`
	// contains filtered or unexported fields
}

File is an open file handle. It is thread-safe.

File provides stronger synchronization guarantees than Linux. Linux synchronizes lseek(2), read(2), and write(2) with respect to the file offset for regular files and only for those interfaces. See fs/read_write.c:fdget_pos, fs.read_write.c:fdput_pos and FMODE_ATOMIC_POS.

In contrast, File synchronizes any operation that could take a long time under a single abortable mutex which also synchronizes lseek(2), read(2), and write(2).

FIXME(b/38451980): Split synchronization from cancellation.

+stateify savable

func NewFile

func NewFile(ctx context.Context, dirent *Dirent, flags FileFlags, fops FileOperations) *File

NewFile returns a File. It takes a reference on the Dirent and owns the lifetime of the FileOperations. Files that do not support reading and writing at an arbitrary offset should set flags.Pread and flags.Pwrite to false respectively.

func (*File) Async

func (f *File) Async(newAsync func() FileAsync) (FileAsync, error)

Async gets the stored FileAsync or creates a new one with the supplied function. If the supplied function is nil, no FileAsync is created and the current value is returned.

func (*File) ConfigureMMap

func (f *File) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) error

ConfigureMMap calls f.FileOperations.ConfigureMMap with f as the File.

Returns linuxerr.ErrInterrupted if interrupted.

func (*File) DecRef

func (f *File) DecRef(ctx context.Context)

DecRef destroys the File when it is no longer referenced.

func (*File) DeviceID

func (f *File) DeviceID() uint64

DeviceID implements memmap.MappingIdentity.DeviceID.

func (*File) EventRegister

func (f *File) EventRegister(e *waiter.Entry) error

EventRegister implements waiter.Waitable.EventRegister.

func (*File) EventUnregister

func (f *File) EventUnregister(e *waiter.Entry)

EventUnregister implements waiter.Waitable.EventUnregister.

func (*File) Flags

func (f *File) Flags() FileFlags

Flags atomically loads the File's flags.

func (*File) Flush

func (f *File) Flush(ctx context.Context) error

Flush calls f.FileOperations.Flush with f as the File.

Returns linuxerr.ErrInterrupted if syncing was interrupted.

func (*File) Fsync

func (f *File) Fsync(ctx context.Context, start int64, end int64, syncType SyncType) error

Fsync calls f.FileOperations.Fsync with f as the File.

Returns linuxerr.ErrInterrupted if syncing was interrupted.

func (*File) InodeID

func (f *File) InodeID() uint64

InodeID implements memmap.MappingIdentity.InodeID.

func (*File) MappedName

func (f *File) MappedName(ctx context.Context) string

MappedName implements memmap.MappingIdentity.MappedName.

func (*File) Msync

func (f *File) Msync(ctx context.Context, mr memmap.MappableRange) error

Msync implements memmap.MappingIdentity.Msync.

func (*File) Offset

func (f *File) Offset() int64

Offset atomically loads the File's offset.

func (*File) Preadv

func (f *File) Preadv(ctx context.Context, dst usermem.IOSequence, offset int64) (int64, error)

Preadv calls f.FileOperations.Read with f as the File. It does not advance the file offset. If !f.Flags().Pread, Preadv should not be called.

Otherwise same as Readv.

func (*File) Pwritev

func (f *File) Pwritev(ctx context.Context, src usermem.IOSequence, offset int64) (int64, error)

Pwritev calls f.FileOperations.Write with f as the File. It does not advance the file offset. If !f.Flags().Pwritev, Pwritev should not be called.

Otherwise same as Writev.

func (*File) Readdir

func (f *File) Readdir(ctx context.Context, serializer DentrySerializer) error

Readdir reads the directory entries of this File and writes them out to the DentrySerializer until entries can no longer be written. If even a single directory entry is written then Readdir returns a nil error and the directory offset is advanced.

Readdir unconditionally updates the access time on the File's Inode, see fs/readdir.c:iterate_dir.

Returns linuxerr.ErrInterrupted if reading was interrupted.

func (*File) Readiness

func (f *File) Readiness(mask waiter.EventMask) waiter.EventMask

Readiness implements waiter.Waitable.Readiness.

func (*File) Readv

func (f *File) Readv(ctx context.Context, dst usermem.IOSequence) (int64, error)

Readv calls f.FileOperations.Read with f as the File, advancing the file offset if f.FileOperations.Read returns bytes read > 0.

Returns linuxerr.ErrInterrupted if reading was interrupted.

func (*File) Seek

func (f *File) Seek(ctx context.Context, whence SeekWhence, offset int64) (int64, error)

Seek calls f.FileOperations.Seek with f as the File, updating the file offset to the value returned by f.FileOperations.Seek if the operation is successful.

Returns linuxerr.ErrInterrupted if seeking was interrupted.

func (*File) SetFlags

func (f *File) SetFlags(newFlags SettableFileFlags)

SetFlags atomically changes the File's flags to the values contained in newFlags. See SettableFileFlags for values that can be set.

func (*File) UnstableAttr

func (f *File) UnstableAttr(ctx context.Context) (UnstableAttr, error)

UnstableAttr calls f.FileOperations.UnstableAttr with f as the File.

Returns linuxerr.ErrInterrupted if interrupted.

func (*File) Writev

func (f *File) Writev(ctx context.Context, src usermem.IOSequence) (int64, error)

Writev calls f.FileOperations.Write with f as the File, advancing the file offset if f.FileOperations.Write returns bytes written > 0.

Writev positions the write offset at EOF if f.Flags().Append. This is unavoidably racy for network file systems. Writev also truncates src to avoid overrunning the current file size limit if necessary.

Returns linuxerr.ErrInterrupted if writing was interrupted.

type FileAsync

type FileAsync interface {
	Register(w waiter.Waitable) error
	Unregister(w waiter.Waitable)
}

A FileAsync sends signals to its owner when w is ready for IO.

type FileFlags

type FileFlags struct {
	// Direct indicates that I/O should be done directly.
	Direct bool

	// NonBlocking indicates that I/O should not block.
	NonBlocking bool

	// DSync indicates that each write will flush data and metadata required to
	// read the file's contents.
	DSync bool

	// Sync indicates that each write will flush data and all file metadata.
	Sync bool

	// Append indicates this file is append only.
	Append bool

	// Read indicates this file is readable.
	Read bool

	// Write indicates this file is writeable.
	Write bool

	// Pread indicates this file is readable at an arbitrary offset.
	Pread bool

	// Pwrite indicates this file is writable at an arbitrary offset.
	Pwrite bool

	// Directory indicates that this file must be a directory.
	Directory bool

	// Async indicates that this file sends signals on IO events.
	Async bool

	// LargeFile indicates that this file should be opened even if it has
	// size greater than linux's off_t. When running in 64-bit mode,
	// Linux sets this flag for all files. Since gVisor is only compatible
	// with 64-bit Linux, it also sets this flag for all files.
	LargeFile bool

	// NonSeekable indicates that file.offset isn't used.
	NonSeekable bool

	// Truncate indicates that the file should be truncated before opened.
	// This is only applicable if the file is regular.
	Truncate bool
}

FileFlags encodes file flags.

+stateify savable

func (FileFlags) Settable

func (f FileFlags) Settable() SettableFileFlags

Settable returns the subset of f that are settable.

func (FileFlags) ToLinux

func (f FileFlags) ToLinux() (mask uint)

ToLinux converts a FileFlags object to a Linux representation.

type FileOperations

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. linuxerr.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)
}

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 FileOwner

type FileOwner struct {
	UID auth.KUID
	GID auth.KGID
}

FileOwner represents ownership of a file.

+stateify savable

func FileOwnerFromContext

func FileOwnerFromContext(ctx context.Context) FileOwner

FileOwnerFromContext returns a FileOwner using the effective user and group IDs used by ctx.

type FilePermissions

type FilePermissions struct {
	User  PermMask
	Group PermMask
	Other PermMask

	// Sticky, if set on directories, restricts renaming and deletion of
	// files in those directories to the directory owner, file owner, or
	// CAP_FOWNER. The sticky bit is ignored when set on other files.
	Sticky bool

	// SetUID executables can call UID-setting syscalls without CAP_SETUID.
	SetUID bool

	// SetGID executables can call GID-setting syscalls without CAP_SETGID.
	SetGID bool
}

FilePermissions represents the permissions of a file, with Read/Write/Execute bits for user, group, and other.

+stateify savable

func FilePermsFromMode

func FilePermsFromMode(mode linux.FileMode) (fp FilePermissions)

FilePermsFromMode converts a system file mode to a FilePermissions struct.

func FilePermsFromP9

func FilePermsFromP9(mode p9.FileMode) FilePermissions

FilePermsFromP9 converts a p9.FileMode to a FilePermissions struct.

func (FilePermissions) AnyExecute

func (f FilePermissions) AnyExecute() bool

AnyExecute returns true if any of U/G/O have the execute bit set.

func (FilePermissions) AnyRead

func (f FilePermissions) AnyRead() bool

AnyRead returns true if any of U/G/O have the read bit set.

func (FilePermissions) AnyWrite

func (f FilePermissions) AnyWrite() bool

AnyWrite returns true if any of U/G/O have the write bit set.

func (*FilePermissions) DropSetUIDAndMaybeGID

func (f *FilePermissions) DropSetUIDAndMaybeGID()

DropSetUIDAndMaybeGID turns off setuid, and turns off setgid if f allows group execution.

func (FilePermissions) HasSetUIDOrGID

func (f FilePermissions) HasSetUIDOrGID() bool

HasSetUIDOrGID returns true if either the setuid or setgid bit is set.

func (FilePermissions) LinuxMode

func (f FilePermissions) LinuxMode() linux.FileMode

LinuxMode returns the linux mode_t representation of these permissions.

func (FilePermissions) OSMode

func (f FilePermissions) OSMode() os.FileMode

OSMode returns the Go runtime's OS independent os.FileMode representation of these permissions.

type Filesystem

type Filesystem interface {
	// Name is the unique identifier of the file system. It corresponds to the
	// filesystemtype argument of sys_mount and will appear in the output of
	// /proc/filesystems.
	Name() string

	// Flags indicate common properties of the file system.
	Flags() FilesystemFlags

	// Mount generates a mountable Inode backed by device and configured
	// using file system independent flags and file system dependent
	// data options.
	//
	// Mount may return arbitrary errors. They do not need syserr translations.
	Mount(ctx context.Context, device string, flags MountSourceFlags, data string, dataObj interface{}) (*Inode, error)

	// AllowUserMount determines whether mount(2) is allowed to mount a
	// file system of this type.
	AllowUserMount() bool

	// AllowUserList determines whether this filesystem is listed in
	// /proc/filesystems
	AllowUserList() bool
}

Filesystem is a mountable file system.

func FindFilesystem

func FindFilesystem(name string) (Filesystem, bool)

FindFilesystem returns a Filesystem registered at name or (nil, false) if name is not a file system type that can be found in /proc/filesystems.

func GetFilesystems

func GetFilesystems() []Filesystem

GetFilesystems returns the set of registered filesystems in a consistent order.

type FilesystemFlags

type FilesystemFlags int

FilesystemFlags matches include/linux/fs.h:file_system_type.fs_flags.

const (
	// FilesystemRequiresDev indicates that the file system requires a device name
	// on mount. It is used to construct the output of /proc/filesystems.
	FilesystemRequiresDev FilesystemFlags = 1
)

type Info

type Info struct {
	// Type is the filesystem type magic value.
	Type uint64

	// TotalBlocks is the total data blocks in the filesystem.
	TotalBlocks uint64

	// FreeBlocks is the number of free blocks available.
	FreeBlocks uint64

	// TotalFiles is the total file nodes in the filesystem.
	TotalFiles uint64

	// FreeFiles is the number of free file nodes.
	FreeFiles uint64
}

Info defines attributes of a filesystem.

type Inode

type Inode struct {
	// AtomicRefCount is our reference count.
	refs.AtomicRefCount

	// InodeOperations is the file system specific behavior of the Inode.
	InodeOperations InodeOperations

	// StableAttr are stable cached attributes of the Inode.
	StableAttr StableAttr

	// LockCtx is the file lock context. It manages its own sychronization and tracks
	// regions of the Inode that have locks held.
	LockCtx LockCtx

	// Watches is the set of inotify watches for this inode.
	Watches *Watches

	// MountSource is the mount source this Inode is a part of.
	MountSource *MountSource
	// contains filtered or unexported fields
}

Inode is a file system object that can be simultaneously referenced by different components of the VFS (Dirent, fs.File, etc).

+stateify savable

func NewInode

func NewInode(ctx context.Context, iops InodeOperations, msrc *MountSource, sattr StableAttr) *Inode

NewInode constructs an Inode from InodeOperations, a MountSource, and stable attributes.

NewInode takes a reference on msrc.

func NewMockInode

func NewMockInode(ctx context.Context, msrc *MountSource, sattr StableAttr) *Inode

NewMockInode returns a mock *Inode using MockInodeOperations.

func NewOverlayRoot

func NewOverlayRoot(ctx context.Context, upper *Inode, lower *Inode, flags MountSourceFlags) (*Inode, error)

NewOverlayRoot produces the root of an overlay.

Preconditions:

- upper and lower must be non-nil.
- upper must not be an overlay.
- lower should not expose character devices, pipes, or sockets, because
  copying up these types of files is not supported.
- lower must not require that file objects be revalidated.
- lower must not have dynamic file/directory content.

func NewOverlayRootFile

func NewOverlayRootFile(ctx context.Context, upperMS *MountSource, lower *Inode, flags MountSourceFlags) (*Inode, error)

NewOverlayRootFile produces the root of an overlay that points to a file.

Preconditions:

- lower must be non-nil.
- lower should not expose character devices, pipes, or sockets, because
  copying up these types of files is not supported. Neither it can be a dir.
- lower must not require that file objects be revalidated.
- lower must not have dynamic file/directory content.

func NewTestOverlayDir

func NewTestOverlayDir(ctx context.Context, upper, lower *Inode, revalidate bool) *Inode

NewTestOverlayDir returns an overlay Inode for tests.

If `revalidate` is true, then the upper filesystem will require revalidation.

func (i *Inode) AddLink()

AddLink calls i.InodeOperations.AddLink.

func (*Inode) Allocate

func (i *Inode) Allocate(ctx context.Context, d *Dirent, offset int64, length int64) error

Allocate calls i.InodeOperations.Allocate with i as the Inode.

func (*Inode) Bind

func (i *Inode) Bind(ctx context.Context, parent *Dirent, name string, data transport.BoundEndpoint, perm FilePermissions) (*Dirent, error)

Bind calls i.InodeOperations.Bind with i as the directory.

func (*Inode) BoundEndpoint

func (i *Inode) BoundEndpoint(path string) transport.BoundEndpoint

BoundEndpoint calls i.InodeOperations.BoundEndpoint with i as the Inode.

func (*Inode) CheckCapability

func (i *Inode) CheckCapability(ctx context.Context, cp linux.Capability) bool

CheckCapability checks whether `ctx` has capability `cp` with respect to operations on this Inode.

Compare Linux's kernel/capability.c:capable_wrt_inode_uidgid().

func (*Inode) CheckOwnership

func (i *Inode) CheckOwnership(ctx context.Context) bool

CheckOwnership checks whether `ctx` owns this Inode or may act as its owner. Compare Linux's fs/inode.c:inode_owner_or_capable().

func (*Inode) CheckPermission

func (i *Inode) CheckPermission(ctx context.Context, p PermMask) error

CheckPermission will check if the caller may access this file in the requested way for reading, writing, or executing.

CheckPermission is like Linux's fs/namei.c:inode_permission. It

- checks file system mount flags,
- and utilizes InodeOperations.Check to check capabilities and modes.

func (*Inode) Create

func (i *Inode) Create(ctx context.Context, d *Dirent, name string, flags FileFlags, perm FilePermissions) (*File, error)

Create calls i.InodeOperations.Create with i as the directory.

func (*Inode) CreateDirectory

func (i *Inode) CreateDirectory(ctx context.Context, d *Dirent, name string, perm FilePermissions) error

CreateDirectory calls i.InodeOperations.CreateDirectory with i as the directory.

func (*Inode) CreateFifo

func (i *Inode) CreateFifo(ctx context.Context, d *Dirent, name string, perm FilePermissions) error

CreateFifo calls i.InodeOperations.CreateFifo with i as the directory.

func (i *Inode) CreateHardLink(ctx context.Context, d *Dirent, target *Dirent, name string) error

CreateHardLink calls i.InodeOperations.CreateHardLink with i as the directory.

func (i *Inode) CreateLink(ctx context.Context, d *Dirent, oldname string, newname string) error

CreateLink calls i.InodeOperations.CreateLink with i as the directory.

func (*Inode) DecRef

func (i *Inode) DecRef(ctx context.Context)

DecRef drops a reference on the Inode.

func (i *Inode) DropLink()

DropLink calls i.InodeOperations.DropLink.

func (*Inode) GetFile

func (i *Inode) GetFile(ctx context.Context, d *Dirent, flags FileFlags) (*File, error)

GetFile calls i.InodeOperations.GetFile with the given arguments.

func (*Inode) GetXattr

func (i *Inode) GetXattr(ctx context.Context, name string, size uint64) (string, error)

GetXattr calls i.InodeOperations.GetXattr with i as the Inode.

func (i *Inode) Getlink(ctx context.Context) (*Dirent, error)

Getlink calls i.InodeOperations.Getlink.

func (*Inode) IsVirtual

func (i *Inode) IsVirtual() bool

IsVirtual calls i.InodeOperations.IsVirtual.

func (*Inode) ListXattr

func (i *Inode) ListXattr(ctx context.Context, size uint64) (map[string]struct{}, error)

ListXattr calls i.InodeOperations.ListXattr with i as the Inode.

func (*Inode) Lookup

func (i *Inode) Lookup(ctx context.Context, name string) (*Dirent, error)

Lookup calls i.InodeOperations.Lookup with i as the directory.

func (*Inode) Mappable

func (i *Inode) Mappable() memmap.Mappable

Mappable calls i.InodeOperations.Mappable.

func (i *Inode) Readlink(ctx context.Context) (string, error)

Readlink calls i.InodeOperations.Readlnk with i as the Inode.

func (*Inode) Remove

func (i *Inode) Remove(ctx context.Context, d *Dirent, remove *Dirent) error

Remove calls i.InodeOperations.Remove/RemoveDirectory with i as the directory.

func (*Inode) RemoveXattr

func (i *Inode) RemoveXattr(ctx context.Context, d *Dirent, name string) error

RemoveXattr calls i.InodeOperations.RemoveXattr with i as the Inode.

func (*Inode) Rename

func (i *Inode) Rename(ctx context.Context, oldParent *Dirent, renamed *Dirent, newParent *Dirent, newName string, replacement bool) error

Rename calls i.InodeOperations.Rename with the given arguments.

func (*Inode) SetOwner

func (i *Inode) SetOwner(ctx context.Context, d *Dirent, o FileOwner) error

SetOwner calls i.InodeOperations.SetOwner with i as the Inode.

func (*Inode) SetPermissions

func (i *Inode) SetPermissions(ctx context.Context, d *Dirent, f FilePermissions) bool

SetPermissions calls i.InodeOperations.SetPermissions with i as the Inode.

func (*Inode) SetTimestamps

func (i *Inode) SetTimestamps(ctx context.Context, d *Dirent, ts TimeSpec) error

SetTimestamps calls i.InodeOperations.SetTimestamps with i as the Inode.

func (*Inode) SetXattr

func (i *Inode) SetXattr(ctx context.Context, d *Dirent, name, value string, flags uint32) error

SetXattr calls i.InodeOperations.SetXattr with i as the Inode.

func (*Inode) StatFS

func (i *Inode) StatFS(ctx context.Context) (Info, error)

StatFS calls i.InodeOperations.StatFS.

func (*Inode) TestHasLowerFS

func (i *Inode) TestHasLowerFS() bool

TestHasLowerFS returns true if i is an overlay Inode and it has a pointer to an Inode on a lower filesystem.

func (*Inode) TestHasUpperFS

func (i *Inode) TestHasUpperFS() bool

TestHasUpperFS returns true if i is an overlay Inode and it has a pointer to an Inode on an upper filesystem.

func (*Inode) Truncate

func (i *Inode) Truncate(ctx context.Context, d *Dirent, size int64) error

Truncate calls i.InodeOperations.Truncate with i as the Inode.

func (*Inode) UnstableAttr

func (i *Inode) UnstableAttr(ctx context.Context) (UnstableAttr, error)

UnstableAttr calls i.InodeOperations.UnstableAttr with i as the Inode.

func (*Inode) WriteOut

func (i *Inode) WriteOut(ctx context.Context) error

WriteOut calls i.InodeOperations.WriteOut with i as the Inode.

type InodeMappings

type InodeMappings map[uint64]string

InodeMappings defines a fmt.Stringer MountSource Inode mappings.

func (InodeMappings) String

func (i InodeMappings) String() string

String implements fmt.Stringer.String.

type InodeOperations

type InodeOperations interface {
	// Release releases all private file system data held by this object.
	// Once Release is called, this object is dead (no other methods will
	// ever be called).
	Release(context.Context)

	// Lookup loads an Inode at name under dir into a Dirent. The name
	// is a valid component path: it contains no "/"s nor is the empty
	// string.
	//
	// Lookup may return one of:
	//
	//	* A nil Dirent and a non-nil error. If the reason that Lookup failed
	//   was because the name does not exist under Inode, then must return
	//   linuxerr.ENOENT.
	//
	//	* If name does not exist under dir and the file system wishes this
	//   fact to be cached, a non-nil Dirent containing a nil Inode and a
	//   nil error. This is a negative Dirent and must have exactly one
	//   reference (at-construction reference).
	//
	//	* If name does exist under this dir, a non-nil Dirent containing a
	//   non-nil Inode, and a nil error. File systems that take extra
	//   references on this Dirent should implement DirentOperations.
	Lookup(ctx context.Context, dir *Inode, name string) (*Dirent, error)

	// Create creates an Inode at name under dir and returns a new File
	// whose Dirent backs the new Inode. Implementations must ensure that
	// name does not already exist. Create may return one of:
	//
	//	* A nil File and a non-nil error.
	//
	//	* A non-nil File and a nil error. File.Dirent will be a new Dirent,
	// with a single reference held by File. File systems that take extra
	// references on this Dirent should implement DirentOperations.
	//
	// The caller must ensure that this operation is permitted.
	Create(ctx context.Context, dir *Inode, name string, flags FileFlags, perm FilePermissions) (*File, error)

	// CreateDirectory creates a new directory under this dir.
	// CreateDirectory should otherwise do the same as Create.
	//
	// The caller must ensure that this operation is permitted.
	CreateDirectory(ctx context.Context, dir *Inode, name string, perm FilePermissions) error

	// CreateLink creates a symbolic link under dir between newname
	// and oldname. CreateLink should otherwise do the same as Create.
	//
	// The caller must ensure that this operation is permitted.
	CreateLink(ctx context.Context, dir *Inode, oldname string, newname string) error

	// CreateHardLink creates a hard link under dir between the target
	// Inode and name.
	//
	// The caller must ensure this operation is permitted.
	CreateHardLink(ctx context.Context, dir *Inode, target *Inode, name string) error

	// CreateFifo creates a new named pipe under dir at name.
	//
	// The caller must ensure that this operation is permitted.
	CreateFifo(ctx context.Context, dir *Inode, name string, perm FilePermissions) error

	// Remove removes the given named non-directory under dir.
	//
	// The caller must ensure that this operation is permitted.
	Remove(ctx context.Context, dir *Inode, name string) error

	// RemoveDirectory removes the given named directory under dir.
	//
	// The caller must ensure that this operation is permitted.
	//
	// RemoveDirectory should check that the directory to be
	// removed is empty.
	RemoveDirectory(ctx context.Context, dir *Inode, name string) error

	// Rename atomically renames oldName under oldParent to newName under
	// newParent where oldParent and newParent are directories. inode is
	// the Inode of this InodeOperations.
	//
	// If replacement is true, then newName already exists and this call
	// will replace it with oldName.
	//
	// Implementations are responsible for rejecting renames that replace
	// non-empty directories.
	Rename(ctx context.Context, inode *Inode, oldParent *Inode, oldName string, newParent *Inode, newName string, replacement bool) error

	// Bind binds a new socket under dir at the given name.
	//
	// The caller must ensure that this operation is permitted.
	Bind(ctx context.Context, dir *Inode, name string, data transport.BoundEndpoint, perm FilePermissions) (*Dirent, error)

	// BoundEndpoint returns the socket endpoint at path stored in
	// or generated by an Inode.
	//
	// The path is only relevant for generated endpoint because stored
	// endpoints already know their path. It is ok for the endpoint to
	// hold onto their path because the only way to change a bind
	// address is to rebind the socket.
	//
	// This is valid iff the type of the Inode is a Socket, which
	// generally implies that this Inode was created via CreateSocket.
	//
	// If there is no socket endpoint available, nil will be returned.
	BoundEndpoint(inode *Inode, path string) transport.BoundEndpoint

	// GetFile returns a new open File backed by a Dirent and FileFlags.
	//
	// Special Inode types may block using ctx.Sleeper. RegularFiles,
	// Directories, and Symlinks must not block (see doCopyUp).
	//
	// The returned File will uniquely back an application fd.
	GetFile(ctx context.Context, d *Dirent, flags FileFlags) (*File, error)

	// UnstableAttr returns the most up-to-date "unstable" attributes of
	// an Inode, where "unstable" means that they change in response to
	// file system events.
	UnstableAttr(ctx context.Context, inode *Inode) (UnstableAttr, error)

	// GetXattr retrieves the value of extended attribute specified by name.
	// Inodes that do not support extended attributes return EOPNOTSUPP. Inodes
	// that support extended attributes but don't have a value at name return
	// ENODATA.
	//
	// If this is called through the getxattr(2) syscall, size indicates the
	// size of the buffer that the application has allocated to hold the
	// attribute value. If the value is larger than size, implementations may
	// return ERANGE to indicate that the buffer is too small, but they are also
	// free to ignore the hint entirely (i.e. the value returned may be larger
	// than size). All size checking is done independently at the syscall layer.
	GetXattr(ctx context.Context, inode *Inode, name string, size uint64) (string, error)

	// SetXattr sets the value of extended attribute specified by name. Inodes
	// that do not support extended attributes return EOPNOTSUPP.
	SetXattr(ctx context.Context, inode *Inode, name, value string, flags uint32) error

	// ListXattr returns the set of all extended attributes names that
	// have values. Inodes that do not support extended attributes return
	// EOPNOTSUPP.
	//
	// If this is called through the listxattr(2) syscall, size indicates the
	// size of the buffer that the application has allocated to hold the
	// attribute list. If the list would be larger than size, implementations may
	// return ERANGE to indicate that the buffer is too small, but they are also
	// free to ignore the hint entirely. All size checking is done independently
	// at the syscall layer.
	ListXattr(ctx context.Context, inode *Inode, size uint64) (map[string]struct{}, error)

	// RemoveXattr removes an extended attribute specified by name. Inodes that
	// do not support extended attributes return EOPNOTSUPP.
	RemoveXattr(ctx context.Context, inode *Inode, name string) error

	// Check determines whether an Inode can be accessed with the
	// requested permission mask using the context (which gives access
	// to Credentials and UserNamespace).
	Check(ctx context.Context, inode *Inode, p PermMask) bool

	// SetPermissions sets new permissions for an Inode.  Returns false
	// if it was not possible to set the new permissions.
	//
	// The caller must ensure that this operation is permitted.
	SetPermissions(ctx context.Context, inode *Inode, f FilePermissions) bool

	// SetOwner sets the ownership for this file.
	//
	// If either UID or GID are set to auth.NoID, its value will not be
	// changed.
	//
	// The caller must ensure that this operation is permitted.
	SetOwner(ctx context.Context, inode *Inode, owner FileOwner) error

	// SetTimestamps sets the access and modification timestamps of an
	// Inode according to the access and modification times in the TimeSpec.
	//
	// If either ATimeOmit or MTimeOmit is set, then the corresponding
	// timestamp is not updated.
	//
	// If either ATimeSetSystemTime or MTimeSetSystemTime is true, that
	// timestamp is set to the current time instead.
	//
	// The caller must ensure that this operation is permitted.
	SetTimestamps(ctx context.Context, inode *Inode, ts TimeSpec) error

	// Truncate changes the size of an Inode. Truncate should not check
	// permissions internally, as it is used for both sys_truncate and
	// sys_ftruncate.
	//
	// Implementations need not check that length >= 0.
	Truncate(ctx context.Context, inode *Inode, size int64) error

	// Allocate allows the caller to reserve disk space for the inode.
	// It's equivalent to fallocate(2) with 'mode=0'.
	Allocate(ctx context.Context, inode *Inode, offset int64, length int64) error

	// WriteOut writes cached Inode state to a backing filesystem in a
	// synchronous manner.
	//
	// File systems that do not cache metadata or data via an Inode
	// implement WriteOut as a no-op. File systems that are entirely in
	// memory also implement WriteOut as a no-op. Otherwise file systems
	// call Inode.Sync to write back page cached data and cached metadata
	// followed by syncing writeback handles.
	//
	// It derives from include/linux/fs.h:super_operations->write_inode.
	WriteOut(ctx context.Context, inode *Inode) error

	// Readlink reads the symlink path of an Inode.
	//
	// Readlink is permitted to return a different path depending on ctx,
	// the request originator.
	//
	// The caller must ensure that this operation is permitted.
	//
	// Readlink should check that Inode is a symlink and its content is
	// at least readable.
	Readlink(ctx context.Context, inode *Inode) (string, error)

	// Getlink resolves a symlink to a target *Dirent.
	//
	// Filesystems that can resolve the link by walking to the path returned
	// by Readlink should return (nil, ErrResolveViaReadlink), which
	// triggers link resolution via Realink and Lookup.
	//
	// Some links cannot be followed by Lookup. In this case, Getlink can
	// return the Dirent of the link target. The caller holds a reference
	// to the Dirent. Filesystems that return a non-nil *Dirent from Getlink
	// cannot participate in an overlay because it is impossible for the
	// overlay to ascertain whether or not the *Dirent should contain an
	// overlayEntry.
	//
	// Any error returned from Getlink other than ErrResolveViaReadlink
	// indicates the caller's inability to traverse this Inode as a link
	// (e.g. linuxerr.ENOLINK indicates that the Inode is not a link,
	// syscall.EPERM indicates that traversing the link is not allowed, etc).
	Getlink(context.Context, *Inode) (*Dirent, error)

	// Mappable returns a memmap.Mappable that provides memory mappings of the
	// Inode's data. Mappable may return nil if this is not supported. The
	// returned Mappable must remain valid until InodeOperations.Release is
	// called.
	Mappable(*Inode) memmap.Mappable

	// AddLink increments the hard link count of an Inode.
	//
	// Remove in favor of Inode.IncLink.
	AddLink()

	// DropLink decrements the hard link count of an Inode.
	//
	// Remove in favor of Inode.DecLink.
	DropLink()

	// NotifyStatusChange sets the status change time to the current time.
	//
	// Remove in favor of updating the Inode's cached status change time.
	NotifyStatusChange(ctx context.Context)

	// IsVirtual indicates whether or not this corresponds to a virtual
	// resource.
	//
	// If IsVirtual returns true, then caching will be disabled for this
	// node, and fs.Dirent.Freeze() will not stop operations on the node.
	//
	// Remove in favor of freezing specific mounts.
	IsVirtual() bool

	// StatFS returns a filesystem Info implementation or an error.  If
	// the filesystem does not support this operation (maybe in the future
	// it will), then ENOSYS should be returned.
	StatFS(context.Context) (Info, error)
}

InodeOperations are operations on an Inode that diverge per file system.

Objects that implement InodeOperations may cache file system "private" data that is useful for implementing these methods. In contrast, Inode contains state that is common to all Inodes; this state may be optionally used by InodeOperations. An object that implements InodeOperations may not take a reference on an Inode.

type InodeType

type InodeType int

InodeType enumerates types of Inodes.

const (
	// RegularFile is a regular file.
	RegularFile InodeType = iota

	// SpecialFile is a file that doesn't support SeekEnd. It is used for
	// things like proc files.
	SpecialFile

	// Directory is a directory.
	Directory

	// SpecialDirectory is a directory that *does* support SeekEnd. It's
	// the opposite of the SpecialFile scenario above. It similarly
	// supports proc files.
	SpecialDirectory

	// Symlink is a symbolic link.
	Symlink

	// Pipe is a pipe (named or regular).
	Pipe

	// Socket is a socket.
	Socket

	// CharacterDevice is a character device.
	CharacterDevice

	// BlockDevice is a block device.
	BlockDevice

	// Anonymous is an anonymous type when none of the above apply.
	// Epoll fds and event-driven fds fit this category.
	Anonymous
)

func ToInodeType

func ToInodeType(linuxFileType linux.FileMode) InodeType

ToInodeType coverts a linux file type to InodeType.

func (InodeType) LinuxType

func (n InodeType) LinuxType() uint32

LinuxType returns the linux file type for this inode type.

func (InodeType) String

func (n InodeType) String() string

String returns a human-readable representation of the InodeType.

type Inotify

type Inotify struct {
	waiter.Queue
	// contains filtered or unexported fields
}

Inotify represents an inotify instance created by inotify_init(2) or inotify_init1(2). Inotify implements the FileOperations interface.

Lock ordering:

Inotify.mu -> Inode.Watches.mu -> Watch.mu -> Inotify.evMu

+stateify savable

func NewInotify

func NewInotify(ctx context.Context) *Inotify

NewInotify constructs a new Inotify instance.

func (*Inotify) AddWatch

func (i *Inotify) AddWatch(target *Dirent, mask uint32) int32

AddWatch constructs a new inotify watch and adds it to the target dirent. It returns the watch descriptor returned by inotify_add_watch(2).

func (*Inotify) ConfigureMMap

func (*Inotify) ConfigureMMap(context.Context, *File, *memmap.MMapOpts) error

ConfigureMMap implements FileOperations.ConfigureMMap.

func (*Inotify) EventRegister

func (i *Inotify) EventRegister(e *waiter.Entry) error

EventRegister implements waiter.Waitable.

func (*Inotify) Flush

func (*Inotify) Flush(context.Context, *File) error

Flush implements FileOperations.Flush.

func (*Inotify) Fsync

Fsync implements FileOperations.Fsync.

func (*Inotify) Ioctl

func (i *Inotify) Ioctl(ctx context.Context, _ *File, io usermem.IO, args arch.SyscallArguments) (uintptr, error)

Ioctl implements fs.FileOperations.Ioctl.

func (*Inotify) Read

func (i *Inotify) Read(ctx context.Context, _ *File, dst usermem.IOSequence, _ int64) (int64, error)

Read implements FileOperations.Read.

func (*Inotify) ReadFrom

func (*Inotify) ReadFrom(context.Context, *File, io.Reader, int64) (int64, error)

ReadFrom implements FileOperations.ReadFrom.

func (*Inotify) Readdir

Readdir implements FileOperatons.Readdir.

func (*Inotify) Readiness

func (i *Inotify) Readiness(mask waiter.EventMask) waiter.EventMask

Readiness implements waiter.Waitable.Readiness.

Readiness indicates whether there are pending events for an inotify instance.

func (*Inotify) Release

func (i *Inotify) Release(ctx context.Context)

Release implements FileOperations.Release. Release removes all watches and frees all resources for an inotify instance.

func (*Inotify) RmWatch

func (i *Inotify) RmWatch(ctx context.Context, wd int32) error

RmWatch implements watcher.Watchable.RmWatch.

RmWatch looks up an inotify watch for the given 'wd' and configures the target dirent to stop sending events to this inotify instance.

func (*Inotify) Seek

Seek implements FileOperations.Seek.

func (*Inotify) UnstableAttr

func (i *Inotify) UnstableAttr(ctx context.Context, file *File) (UnstableAttr, error)

UnstableAttr implements FileOperations.UnstableAttr.

func (*Inotify) Write

Write implements FileOperations.Write.

func (*Inotify) WriteTo

func (*Inotify) WriteTo(context.Context, *File, io.Writer, int64, bool) (int64, error)

WriteTo implements FileOperations.WriteTo.

type LockCtx

type LockCtx struct {
	// Posix is a set of POSIX-style regional advisory locks, see fcntl(2).
	Posix lock.Locks

	// BSD is a set of BSD-style advisory file wide locks, see flock(2).
	BSD lock.Locks
}

LockCtx is an Inode's lock context and contains different personalities of locks; both Posix and BSD style locks are supported.

Note that in Linux fcntl(2) and flock(2) locks are _not_ cooperative, because race and deadlock conditions make merging them prohibitive. We do the same and keep them oblivious to each other but provide a "context" as a convenient container.

+stateify savable

type MockInodeOperations

type MockInodeOperations struct {
	InodeOperations

	UAttr UnstableAttr
	// contains filtered or unexported fields
}

MockInodeOperations implements InodeOperations for testing Inodes.

func NewMockInodeOperations

func NewMockInodeOperations(ctx context.Context) *MockInodeOperations

NewMockInodeOperations returns a *MockInodeOperations.

func (*MockInodeOperations) Allocate

func (n *MockInodeOperations) Allocate(ctx context.Context, inode *Inode, offset, length int64) error

Allocate implements fs.InodeOperations.Allocate.

func (*MockInodeOperations) Check

func (n *MockInodeOperations) Check(ctx context.Context, inode *Inode, p PermMask) bool

Check implements fs.InodeOperations.Check.

func (*MockInodeOperations) Create

func (n *MockInodeOperations) Create(ctx context.Context, dir *Inode, p string, flags FileFlags, perms FilePermissions) (*File, error)

Create implements fs.InodeOperations.Create.

func (*MockInodeOperations) CreateDirectory

CreateDirectory implements fs.InodeOperations.CreateDirectory.

func (n *MockInodeOperations) CreateLink(_ context.Context, dir *Inode, oldname string, newname string) error

CreateLink implements fs.InodeOperations.CreateLink.

Getlink implements fs.InodeOperations.Getlink.

func (*MockInodeOperations) IsVirtual

func (n *MockInodeOperations) IsVirtual() bool

IsVirtual implements fs.InodeOperations.IsVirtual.

func (*MockInodeOperations) Lookup

func (n *MockInodeOperations) Lookup(ctx context.Context, dir *Inode, p string) (*Dirent, error)

Lookup implements fs.InodeOperations.Lookup.

func (*MockInodeOperations) Release

func (n *MockInodeOperations) Release(context.Context)

Release implements fs.InodeOperations.Release.

func (*MockInodeOperations) Remove

Remove implements fs.InodeOperations.Remove.

func (*MockInodeOperations) RemoveDirectory

func (n *MockInodeOperations) RemoveDirectory(context.Context, *Inode, string) error

RemoveDirectory implements fs.InodeOperations.RemoveDirectory.

func (*MockInodeOperations) Rename

func (n *MockInodeOperations) Rename(ctx context.Context, inode *Inode, oldParent *Inode, oldName string, newParent *Inode, newName string, replacement bool) error

Rename implements fs.InodeOperations.Rename.

func (*MockInodeOperations) SetOwner

SetOwner implements fs.InodeOperations.SetOwner.

func (*MockInodeOperations) SetPermissions

SetPermissions implements fs.InodeOperations.SetPermissions.

func (*MockInodeOperations) SetTimestamps

func (n *MockInodeOperations) SetTimestamps(context.Context, *Inode, TimeSpec) error

SetTimestamps implements fs.InodeOperations.SetTimestamps.

func (*MockInodeOperations) Truncate

func (n *MockInodeOperations) Truncate(ctx context.Context, inode *Inode, size int64) error

Truncate implements fs.InodeOperations.Truncate.

func (*MockInodeOperations) UnstableAttr

UnstableAttr implements fs.InodeOperations.UnstableAttr.

func (*MockInodeOperations) WriteOut

WriteOut implements fs.InodeOperations.WriteOut.

type MockMountSourceOps

type MockMountSourceOps struct {
	MountSourceOperations
	// contains filtered or unexported fields
}

MockMountSourceOps implements fs.MountSourceOperations.

func (*MockMountSourceOps) CacheReaddir

func (n *MockMountSourceOps) CacheReaddir() bool

CacheReaddir implements fs.MountSourceOperations.CacheReaddir.

func (*MockMountSourceOps) Keep

func (n *MockMountSourceOps) Keep(dirent *Dirent) bool

Keep implements fs.MountSourceOperations.Keep.

func (*MockMountSourceOps) Revalidate

func (n *MockMountSourceOps) Revalidate(context.Context, string, *Inode, *Inode) bool

Revalidate implements fs.MountSourceOperations.Revalidate.

type Mount

type Mount struct {
	// ID is a unique id for this mount. It may be invalidMountID if this is
	// used to cache a dirent that was mounted over.
	ID uint64

	// ParentID is the parent's mount unique id. It may be invalidMountID if this
	// is the root mount or if this is used to cache a dirent that was mounted
	// over.
	ParentID uint64
	// contains filtered or unexported fields
}

Mount represents a mount in the file system. It holds the root dirent for the mount. It also points back to the dirent or mount where it was mounted over, so that it can be restored when unmounted. The chained mount can be either:

- Mount: when it's mounted on top of another mount point.
- Dirent: when it's mounted on top of a dirent. In this case the mount is
  called an "undo" mount and only 'root' is set. All other fields are
  either invalid or nil.

+stateify savable

func (*Mount) IsRoot

func (m *Mount) IsRoot() bool

IsRoot returns true if the mount has no parent.

func (*Mount) IsUndo

func (m *Mount) IsUndo() bool

IsUndo returns true if 'm' is an undo mount that should be used to restore the original dirent during unmount only and it's not a valid mount.

func (*Mount) Root

func (m *Mount) Root() *Dirent

Root returns the root dirent of this mount.

This may return nil if the mount has already been free. Callers must handle this case appropriately. If non-nil, callers must call DecRef on the returned *Dirent.

type MountArgs

type MountArgs struct {
	// Dev corresponds to the devname argumnent of Mount.
	Dev string

	// Flags corresponds to the flags argument of Mount.
	Flags MountSourceFlags

	// DataString corresponds to the data argument of Mount.
	DataString string

	// DataObj corresponds to the data interface argument of Mount.
	DataObj interface{}
}

MountArgs holds arguments to Mount.

type MountNamespace

type MountNamespace struct {
	refs.AtomicRefCount
	// contains filtered or unexported fields
}

MountNamespace defines a VFS root. It contains collection of Mounts that are mounted inside the Dirent tree rooted at the Root Dirent. It provides methods for traversing the Dirent, and for mounting/unmounting in the tree.

Note that this does not correspond to a "mount namespace" in the Linux. It is more like a unique VFS instance.

It's possible for different processes to have different MountNamespaces. In this case, the file systems exposed to the processes are completely distinct.

+stateify savable

func NewMountNamespace

func NewMountNamespace(ctx context.Context, root *Inode) (*MountNamespace, error)

NewMountNamespace returns a new MountNamespace, with the provided node at the root, and the given cache size. A root must always be provided.

func (*MountNamespace) AllMountsUnder

func (mns *MountNamespace) AllMountsUnder(parent *Mount) []*Mount

AllMountsUnder returns a slice of all mounts under the parent, including itself.

func (*MountNamespace) DecRef

func (mns *MountNamespace) DecRef(ctx context.Context)

DecRef implements RefCounter.DecRef with destructor mns.destroy.

func (*MountNamespace) FindInode

func (mns *MountNamespace) FindInode(ctx context.Context, root, wd *Dirent, path string, remainingTraversals *uint) (*Dirent, error)

FindInode is identical to FindLink except the return value is resolved.

func (mns *MountNamespace) FindLink(ctx context.Context, root, wd *Dirent, path string, remainingTraversals *uint) (*Dirent, error)

FindLink returns an Dirent from a given node, which may be a symlink.

The root argument is treated as the root directory, and FindLink will not return anything above that. The wd dirent provides the starting directory, and may be nil which indicates the root should be used. You must call DecRef on the resulting Dirent when you are no longer using the object.

If wd is nil, then the root will be used as the working directory. If the path is absolute, this has no functional impact.

Precondition: root must be non-nil. Precondition: the path must be non-empty.

func (*MountNamespace) FindMount

func (mns *MountNamespace) FindMount(d *Dirent) *Mount

FindMount returns the mount that 'd' belongs to. It walks the dirent back until a mount is found. It may return nil if no mount was found.

func (*MountNamespace) FlushMountSourceRefs

func (mns *MountNamespace) FlushMountSourceRefs()

FlushMountSourceRefs flushes extra references held by MountSources for all active mount points; see fs/mount.go:MountSource.FlushDirentRefs.

func (*MountNamespace) Mount

func (mns *MountNamespace) Mount(ctx context.Context, mountPoint *Dirent, inode *Inode) error

Mount mounts a `inode` over the subtree at `node`.

func (*MountNamespace) Root

func (mns *MountNamespace) Root() *Dirent

Root returns the MountNamespace's root Dirent and increments its reference count. The caller must call DecRef when finished.

func (*MountNamespace) SyncAll

func (mns *MountNamespace) SyncAll(ctx context.Context)

SyncAll calls Dirent.SyncAll on the root.

func (*MountNamespace) Unmount

func (mns *MountNamespace) Unmount(ctx context.Context, node *Dirent, detachOnly bool) error

Unmount ensures no references to the MountSource remain and removes `node` from this subtree. The subtree formerly mounted in `node`'s place will be restored. node's MountSource will be destroyed as soon as the last reference to `node` is dropped, as no references to Dirents within will remain.

If detachOnly is set, Unmount merely removes `node` from the subtree, but allows existing references to the MountSource remain. E.g. if an open file still refers to Dirents in MountSource, the Unmount will succeed anyway and MountSource will be destroyed at a later time when all references to Dirents within are dropped.

The caller must hold a reference to node from walking to it.

func (*MountNamespace) UserNamespace

func (mns *MountNamespace) UserNamespace() *auth.UserNamespace

UserNamespace returns the user namespace associated with this mount manager.

type MountSource

type MountSource struct {
	refs.AtomicRefCount

	// MountSourceOperations defines filesystem specific behavior.
	MountSourceOperations

	// FilesystemType is the type of the filesystem backing this mount.
	FilesystemType string

	// Flags are the flags that this filesystem was mounted with.
	Flags MountSourceFlags
	// contains filtered or unexported fields
}

MountSource represents a source of file objects.

MountSource corresponds to struct super_block in Linux.

A mount source may represent a physical device (or a partition of a physical device) or a virtual source of files such as procfs for a specific PID namespace. There should be only one mount source per logical device. E.g. there should be only procfs mount source for a given PID namespace.

A mount source represents files as inodes. Every inode belongs to exactly one mount source. Each file object may only be represented using one inode object in a sentry instance.

TODO(b/63601033): Move Flags out of MountSource to Mount.

+stateify savable

func NewCachingMountSource

func NewCachingMountSource(ctx context.Context, filesystem Filesystem, flags MountSourceFlags) *MountSource

NewCachingMountSource returns a generic mount that will cache dirents aggressively.

func NewMockMountSource

func NewMockMountSource(cache *DirentCache) *MountSource

NewMockMountSource returns a new *MountSource using MockMountSourceOps.

func NewMountSource

func NewMountSource(ctx context.Context, mops MountSourceOperations, filesystem Filesystem, flags MountSourceFlags) *MountSource

NewMountSource returns a new MountSource. Filesystem may be nil if there is no filesystem backing the mount.

func NewNonCachingMountSource

func NewNonCachingMountSource(ctx context.Context, filesystem Filesystem, flags MountSourceFlags) *MountSource

NewNonCachingMountSource returns a generic mount that will never cache dirents.

func NewPseudoMountSource

func NewPseudoMountSource(ctx context.Context) *MountSource

NewPseudoMountSource returns a "pseudo" mount source that is not backed by an actual filesystem. It is always non-caching.

func NewRevalidatingMountSource

func NewRevalidatingMountSource(ctx context.Context, filesystem Filesystem, flags MountSourceFlags) *MountSource

NewRevalidatingMountSource returns a generic mount that will cache dirents, but will revalidate them on each lookup and always perform uncached readdir.

func (*MountSource) DecDirentRefs

func (msrc *MountSource) DecDirentRefs()

DecDirentRefs decrements direntRefs.

func (*MountSource) DecRef

func (msrc *MountSource) DecRef(ctx context.Context)

DecRef drops a reference on the MountSource.

func (*MountSource) DirentRefs

func (msrc *MountSource) DirentRefs() uint64

DirentRefs returns the current mount direntRefs.

func (*MountSource) FlushDirentRefs

func (msrc *MountSource) FlushDirentRefs()

FlushDirentRefs drops all references held by the MountSource on Dirents.

func (*MountSource) IncDirentRefs

func (msrc *MountSource) IncDirentRefs()

IncDirentRefs increases direntRefs.

func (*MountSource) SetDirentCacheLimiter

func (msrc *MountSource) SetDirentCacheLimiter(l *DirentCacheLimiter)

SetDirentCacheLimiter sets the limiter objcet to the dirent cache associated with this mount source.

func (*MountSource) SetDirentCacheMaxSize

func (msrc *MountSource) SetDirentCacheMaxSize(max uint64)

SetDirentCacheMaxSize sets the max size to the dirent cache associated with this mount source.

type MountSourceFlags

type MountSourceFlags struct {
	// ReadOnly corresponds to mount(2)'s "MS_RDONLY" and indicates that
	// the filesystem should be mounted read-only.
	ReadOnly bool

	// NoAtime corresponds to mount(2)'s "MS_NOATIME" and indicates that
	// the filesystem should not update access time in-place.
	NoAtime bool

	// ForcePageCache causes all filesystem I/O operations to use the page
	// cache, even when the platform supports direct mapped I/O. This
	// doesn't correspond to any Linux mount options.
	ForcePageCache bool

	// NoExec corresponds to mount(2)'s "MS_NOEXEC" and indicates that
	// binaries from this file system can't be executed.
	NoExec bool
}

MountSourceFlags represents all mount option flags as a struct.

+stateify savable

type MountSourceOperations

type MountSourceOperations interface {
	// DirentOperations provide optional extra management of Dirents.
	DirentOperations

	// Destroy destroys the MountSource.
	Destroy(ctx context.Context)

	// ResetInodeMappings clears all mappings of Inodes before SaveInodeMapping
	// is called.
	ResetInodeMappings()

	// SaveInodeMappings is called during saving to store, for each reachable
	// Inode in the mounted filesystem, a mapping of Inode.StableAttr.InodeID
	// to the Inode's path relative to its mount point. If an Inode is
	// reachable at more than one path due to hard links, it is unspecified
	// which path is mapped. Filesystems that do not use this information to
	// restore inodes can make SaveInodeMappings a no-op.
	SaveInodeMapping(inode *Inode, path string)
}

MountSourceOperations contains filesystem specific operations.

type PermMask

type PermMask struct {
	// Read indicates reading is permitted.
	Read bool

	// Write indicates writing is permitted.
	Write bool

	// Execute indicates execution is permitted.
	Execute bool
}

PermMask are file access permissions.

+stateify savable

func PermsFromMode

func PermsFromMode(mode linux.FileMode) (perms PermMask)

PermsFromMode takes the Other permissions (last 3 bits) of a FileMode and returns a set of PermMask.

func (PermMask) Mode

func (p PermMask) Mode() (mode os.FileMode)

Mode returns the system mode (unix.S_IXOTH, etc.) for these permissions in the "other" bits.

func (PermMask) OnlyRead

func (p PermMask) OnlyRead() bool

OnlyRead returns true when only the read bit is set.

func (PermMask) String

func (p PermMask) String() string

String implements the fmt.Stringer interface for PermMask.

func (PermMask) SupersetOf

func (p PermMask) SupersetOf(other PermMask) bool

SupersetOf returns true iff the permissions in p are a superset of the permissions in other.

type RestoreEnvironment

type RestoreEnvironment struct {
	// MountSources maps Filesystem.Name() to mount arguments.
	MountSources map[string][]MountArgs

	// ValidateFileSize indicates file size should not change across S/R.
	ValidateFileSize bool

	// ValidateFileTimestamp indicates file modification timestamp should
	// not change across S/R.
	ValidateFileTimestamp bool
}

RestoreEnvironment is the restore environment for file systems. It consists of things that change across save and restore and therefore cannot be saved in the object graph.

func CurrentRestoreEnvironment

func CurrentRestoreEnvironment() (RestoreEnvironment, bool)

CurrentRestoreEnvironment returns the current, read-only RestoreEnvironment. If no RestoreEnvironment was ever set, returns (_, false).

type SeekWhence

type SeekWhence int

SeekWhence determines seek direction.

const (
	// SeekSet sets the absolute offset.
	SeekSet SeekWhence = iota

	// SeekCurrent sets relative to the current position.
	SeekCurrent

	// SeekEnd sets relative to the end of the file.
	SeekEnd
)

func (SeekWhence) String

func (s SeekWhence) String() string

String returns a human readable string for whence.

type SettableFileFlags

type SettableFileFlags struct {
	// Direct indicates that I/O should be done directly.
	Direct bool

	// NonBlocking indicates that I/O should not block.
	NonBlocking bool

	// Append indicates this file is append only.
	Append bool

	// Async indicates that this file sends signals on IO events.
	Async bool
}

SettableFileFlags is a subset of FileFlags above that can be changed via fcntl(2) using the F_SETFL command.

type SimpleMountSourceOperations

type SimpleMountSourceOperations struct {
	// contains filtered or unexported fields
}

SimpleMountSourceOperations implements MountSourceOperations.

+stateify savable

func (*SimpleMountSourceOperations) CacheReaddir

func (smo *SimpleMountSourceOperations) CacheReaddir() bool

CacheReaddir implements MountSourceOperations.CacheReaddir.

func (*SimpleMountSourceOperations) Destroy

Destroy implements MountSourceOperations.Destroy.

func (*SimpleMountSourceOperations) Keep

Keep implements MountSourceOperations.Keep.

func (*SimpleMountSourceOperations) ResetInodeMappings

func (*SimpleMountSourceOperations) ResetInodeMappings()

ResetInodeMappings implements MountSourceOperations.ResetInodeMappings.

func (*SimpleMountSourceOperations) Revalidate

Revalidate implements MountSourceOperations.Revalidate.

func (*SimpleMountSourceOperations) SaveInodeMapping

func (*SimpleMountSourceOperations) SaveInodeMapping(*Inode, string)

SaveInodeMapping implements MountSourceOperations.SaveInodeMapping.

type SortedDentryMap

type SortedDentryMap struct {
	// contains filtered or unexported fields
}

SortedDentryMap is a sorted map of names and fs.DentAttr entries.

+stateify savable

func NewSortedDentryMap

func NewSortedDentryMap(entries map[string]DentAttr) *SortedDentryMap

NewSortedDentryMap maintains entries in name sorted order.

func (*SortedDentryMap) Add

func (s *SortedDentryMap) Add(name string, entry DentAttr)

Add adds an entry with the given name to the map, preserving sort order. If name already exists in the map, its entry will be overwritten.

func (*SortedDentryMap) Contains

func (s *SortedDentryMap) Contains(name string) bool

Contains reports whether the map contains an entry with the given name.

func (*SortedDentryMap) GetAll

func (s *SortedDentryMap) GetAll() ([]string, map[string]DentAttr)

GetAll returns all names and entries in s. Callers should not modify the returned values.

func (*SortedDentryMap) GetNext

func (s *SortedDentryMap) GetNext(cursor string) ([]string, map[string]DentAttr)

GetNext returns names after cursor in s and all entries.

func (*SortedDentryMap) Remove

func (s *SortedDentryMap) Remove(name string)

Remove removes an entry with the given name from the map, preserving sort order.

type SpliceOpts

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
}

SpliceOpts define how a splice works.

type StableAttr

type StableAttr struct {
	// Type is the InodeType of a InodeOperations.
	Type InodeType

	// DeviceID is the device on which a InodeOperations resides.
	DeviceID uint64

	// InodeID uniquely identifies InodeOperations on its device.
	InodeID uint64

	// BlockSize is the block size of data backing this InodeOperations.
	BlockSize int64

	// DeviceFileMajor is the major device number of this Node, if it is a
	// device file.
	DeviceFileMajor uint16

	// DeviceFileMinor is the minor device number of this Node, if it is a
	// device file.
	DeviceFileMinor uint32
}

StableAttr contains Inode attributes that will be stable throughout the lifetime of the Inode.

+stateify savable

type SyncType

type SyncType int

SyncType enumerates ways in which a File can be synced.

const (
	// SyncAll indicates that modified in-memory metadata and data should
	// be written to backing storage. SyncAll implies SyncBackingStorage.
	SyncAll SyncType = iota

	// SyncData indicates that along with modified in-memory data, only
	// metadata needed to access that data needs to be written.
	//
	// For example, changes to access time or modification time do not
	// need to be written because they are not necessary for a data read
	// to be handled correctly, unlike the file size.
	//
	// The aim of SyncData is to reduce disk activity for applications
	// that do not require all metadata to be synchronized with the disk,
	// see fdatasync(2). File systems that implement SyncData as SyncAll
	// do not support this optimization.
	//
	// SyncData implies SyncBackingStorage.
	SyncData

	// SyncBackingStorage indicates that in-flight write operations to
	// backing storage should be flushed.
	SyncBackingStorage
)

type TimeSpec

type TimeSpec struct {
	ATime              ktime.Time
	ATimeOmit          bool
	ATimeSetSystemTime bool
	MTime              ktime.Time
	MTimeOmit          bool
	MTimeSetSystemTime bool
}

TimeSpec contains access and modification timestamps. If either ATimeOmit or MTimeOmit is true, then the corresponding timestamp should not be updated. If either ATimeSetSystemTime or MTimeSetSystemTime are set then the corresponding timestamp should be ignored and the time will be set to the current system time.

type UnstableAttr

type UnstableAttr struct {
	// Size is the file size in bytes.
	Size int64

	// Usage is the actual data usage in bytes.
	Usage int64

	// Perms is the protection (read/write/execute for user/group/other).
	Perms FilePermissions

	// Owner describes the ownership of this file.
	Owner FileOwner

	// AccessTime is the time of last access
	AccessTime ktime.Time

	// ModificationTime is the time of last modification.
	ModificationTime ktime.Time

	// StatusChangeTime is the time of last attribute modification.
	StatusChangeTime ktime.Time

	// Links is the number of hard links.
	Links uint64
}

UnstableAttr contains Inode attributes that may change over the lifetime of the Inode.

+stateify savable

func WithCurrentTime

func WithCurrentTime(ctx context.Context, u UnstableAttr) UnstableAttr

WithCurrentTime returns u with AccessTime == ModificationTime == current time.

func (*UnstableAttr) SetOwner

func (ua *UnstableAttr) SetOwner(ctx context.Context, owner FileOwner)

SetOwner sets the owner and group if they are valid.

This method is NOT thread-safe. Callers must prevent concurrent calls.

func (*UnstableAttr) SetPermissions

func (ua *UnstableAttr) SetPermissions(ctx context.Context, p FilePermissions)

SetPermissions sets the permissions.

This method is NOT thread-safe. Callers must prevent concurrent calls.

func (*UnstableAttr) SetTimestamps

func (ua *UnstableAttr) SetTimestamps(ctx context.Context, ts TimeSpec)

SetTimestamps sets the timestamps according to the TimeSpec.

This method is NOT thread-safe. Callers must prevent concurrent calls.

type Watch

type Watch struct {
	// contains filtered or unexported fields
}

Watch represent a particular inotify watch created by inotify_add_watch.

While a watch is active, it ensures the target inode is pinned in memory by holding an extra ref on each dirent known (by inotify) to point to the inode. These are known as pins. For a full discussion, see fs/g3doc/inotify.md.

+stateify savable

func (*Watch) ID

func (w *Watch) ID() uint64

ID returns the id of the inotify instance that owns this watch.

func (*Watch) Notify

func (w *Watch) Notify(name string, events uint32, cookie uint32)

Notify queues a new event on this watch.

func (w *Watch) NotifyParentAfterUnlink() bool

NotifyParentAfterUnlink indicates whether the parent of the watched object should continue to be be notified of events after the target has been unlinked.

func (*Watch) Pin

func (w *Watch) Pin(d *Dirent)

Pin acquires a new ref on dirent, which pins the dirent in memory while the watch is active. Calling Pin for a second time on the same dirent for the same watch is a no-op.

func (*Watch) TargetDestroyed

func (w *Watch) TargetDestroyed()

TargetDestroyed notifies the owner of the watch that the watch target is gone. The owner should release its own references to the watcher upon receiving this notification.

func (*Watch) Unpin

func (w *Watch) Unpin(ctx context.Context, d *Dirent)

Unpin drops any extra refs held on dirent due to a previous Pin call. Calling Unpin multiple times for the same dirent, or on a dirent without a corresponding Pin call is a no-op.

type Watches

type Watches struct {
	// contains filtered or unexported fields
}

Watches is the collection of inotify watches on an inode.

+stateify savable

func (*Watches) Add

func (w *Watches) Add(watch *Watch)

Add adds watch into this set of watches. The watch being added must be unique - its ID() should not collide with any existing watches.

func (*Watches) Lookup

func (w *Watches) Lookup(id uint64) *Watch

Lookup returns a matching watch with the given id. Returns nil if no such watch exists. Note that the result returned by this method only remains valid if the inotify instance owning the watch is locked, preventing modification of the returned watch and preventing the replacement of the watch by another one from the same instance (since there may be at most one watch per instance, per target).

func (*Watches) MarkUnlinked

func (w *Watches) MarkUnlinked()

MarkUnlinked indicates the target for this set of watches to be unlinked. This has implications for the IN_EXCL_UNLINK flag.

func (*Watches) Notify

func (w *Watches) Notify(name string, events, cookie uint32)

Notify queues a new event with all watches in this set.

func (*Watches) Remove

func (w *Watches) Remove(id uint64)

Remove removes a watch with the given id from this set of watches. The caller is responsible for generating any watch removal event, as appropriate. The provided id must match an existing watch in this collection.

func (*Watches) Unpin

func (w *Watches) Unpin(ctx context.Context, d *Dirent)

Unpin unpins dirent from all watches in this set.

Directories

Path Synopsis
Package anon implements an anonymous inode, useful for implementing inodes for pseudo filesystems.
Package anon implements an anonymous inode, useful for implementing inodes for pseudo filesystems.
Package dev provides a filesystem with simple devices.
Package dev provides a filesystem with simple devices.
Package fdpipe implements common namedpipe opening and accessing logic.
Package fdpipe implements common namedpipe opening and accessing logic.
Package filetest provides a test implementation of an fs.File.
Package filetest provides a test implementation of an fs.File.
Package fsutil provides utilities for implementing fs.InodeOperations and fs.FileOperations: - For embeddable utilities, see inode.go and file.go.
Package fsutil provides utilities for implementing fs.InodeOperations and fs.FileOperations: - For embeddable utilities, see inode.go and file.go.
Package gofer implements a remote 9p filesystem.
Package gofer implements a remote 9p filesystem.
Package host supports file descriptors imported directly.
Package host supports file descriptors imported directly.
Package lock is the API for POSIX-style advisory regional file locks and BSD-style full file locks.
Package lock is the API for POSIX-style advisory regional file locks and BSD-style full file locks.
Package proc implements a partial in-memory file system for procfs.
Package proc implements a partial in-memory file system for procfs.
device
Package device contains the proc device to avoid dependency loops.
Package device contains the proc device to avoid dependency loops.
seqfile
Package seqfile provides dynamic ordered files.
Package seqfile provides dynamic ordered files.
Package ramfs provides the fundamentals for a simple in-memory filesystem.
Package ramfs provides the fundamentals for a simple in-memory filesystem.
Package sys implements a sysfs filesystem.
Package sys implements a sysfs filesystem.
Package timerfd implements the semantics of Linux timerfd objects as described by timerfd_create(2).
Package timerfd implements the semantics of Linux timerfd objects as described by timerfd_create(2).
Package tmpfs is a filesystem implementation backed by memory.
Package tmpfs is a filesystem implementation backed by memory.
Package tty provide pseudoterminals via a devpts filesystem.
Package tty provide pseudoterminals via a devpts filesystem.
Package user contains methods for resolving filesystem paths based on the user and their environment.
Package user contains methods for resolving filesystem paths based on the user and their environment.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL