kernfs

package
v0.0.0-...-522126a Latest Latest
Warning

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

Go to latest
Published: Dec 23, 2019 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package kernfs provides the tools to implement inode-based filesystems. Kernfs has two main features:

  1. The Inode interface, which maps VFS2's path-based filesystem operations to specific filesystem nodes. Kernfs uses the Inode interface to provide a blanket implementation for the vfs.FilesystemImpl. Kernfs also serves as the synchronization mechanism for all filesystem operations by holding a filesystem-wide lock across all operations.
  1. Various utility types which provide generic implementations for various parts of the Inode and vfs.FileDescription interfaces. Client filesystems based on kernfs can embed the appropriate set of these to avoid having to reimplement common filesystem operations. See inode_impl_util.go and fd_impl_util.go.

Reference Model:

Kernfs dentries represents named pointers to inodes. Dentries and inode have independent lifetimes and reference counts. A child dentry unconditionally holds a reference on its parent directory's dentry. A dentry also holds a reference on the inode it points to. Multiple dentries can point to the same inode (for example, in the case of hardlinks). File descriptors hold a reference to the dentry they're opened on.

Dentries are guaranteed to exist while holding Filesystem.mu for reading. Dropping dentries require holding Filesystem.mu for writing. To queue dentries for destruction from a read critical section, see Filesystem.deferDecRef.

Lock ordering:

kernfs.Filesystem.mu

kernfs.Dentry.dirMu
  vfs.VirtualFilesystem.mountMu
    vfs.Dentry.mu
kernfs.Filesystem.droppedDentriesMu
(inode implementation locks, if any)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Dentry

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

Dentry implements vfs.DentryImpl.

A kernfs dentry is similar to a dentry in a traditional filesystem: it's a named reference to an inode. A dentry generally lives as long as it's part of a mounted filesystem tree. Kernfs doesn't cache dentries once all references to them are removed. Dentries hold a single reference to the inode they point to, and child dentries hold a reference on their parent.

Must be initialized by Init prior to first use.

func (*Dentry) DecRef

func (d *Dentry) DecRef()

DecRef implements vfs.DentryImpl.DecRef.

func (*Dentry) Init

func (d *Dentry) Init(inode Inode)

Init initializes this dentry.

Precondition: Caller must hold a reference on inode.

Postcondition: Caller's reference on inode is transferred to the dentry.

func (*Dentry) InsertChild

func (d *Dentry) InsertChild(name string, child *vfs.Dentry)

InsertChild inserts child into the vfs dentry cache with the given name under this dentry. This does not update the directory inode, so calling this on it's own isn't sufficient to insert a child into a directory. InsertChild updates the link count on d if required.

Precondition: d must represent a directory inode.

func (*Dentry) VFSDentry

func (d *Dentry) VFSDentry() *vfs.Dentry

VFSDentry returns the generic vfs dentry for this kernfs dentry.

type DynamicBytesFD

type DynamicBytesFD struct {
	vfs.FileDescriptionDefaultImpl
	vfs.DynamicBytesFileDescriptionImpl
	// contains filtered or unexported fields
}

DynamicBytesFD implements vfs.FileDescriptionImpl for an FD backed by a DynamicBytesFile.

Must be initialized with Init before first use.

func (*DynamicBytesFD) Init

func (fd *DynamicBytesFD) Init(m *vfs.Mount, d *vfs.Dentry, data vfs.DynamicBytesSource, flags uint32)

Init initializes a DynamicBytesFD.

func (*DynamicBytesFD) PRead

func (fd *DynamicBytesFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts vfs.ReadOptions) (int64, error)

PRead implmenets vfs.FileDescriptionImpl.PRead.

func (*DynamicBytesFD) PWrite

func (fd *DynamicBytesFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error)

PWrite implements vfs.FileDescriptionImpl.PWrite.

func (*DynamicBytesFD) Read

Read implmenets vfs.FileDescriptionImpl.Read.

func (*DynamicBytesFD) Release

func (fd *DynamicBytesFD) Release()

Release implements vfs.FileDescriptionImpl.Release.

func (*DynamicBytesFD) Seek

func (fd *DynamicBytesFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error)

Seek implements vfs.FileDescriptionImpl.Seek.

func (*DynamicBytesFD) SetStat

SetStat implements vfs.FileDescriptionImpl.SetStat.

func (*DynamicBytesFD) Stat

func (fd *DynamicBytesFD) Stat(ctx context.Context, opts vfs.StatOptions) (linux.Statx, error)

Stat implements vfs.FileDescriptionImpl.Stat.

func (*DynamicBytesFD) Write

Write implements vfs.FileDescriptionImpl.Write.

type DynamicBytesFile

type DynamicBytesFile struct {
	InodeAttrs
	InodeNoopRefCount
	InodeNotDirectory
	InodeNotSymlink
	// contains filtered or unexported fields
}

DynamicBytesFile implements kernfs.Inode and represents a read-only file whose contents are backed by a vfs.DynamicBytesSource.

Must be initialized with Init before first use.

func (*DynamicBytesFile) Init

func (f *DynamicBytesFile) Init(creds *auth.Credentials, ino uint64, data vfs.DynamicBytesSource)

Init intializes a dynamic bytes file.

func (*DynamicBytesFile) Open

func (f *DynamicBytesFile) Open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, flags uint32) (*vfs.FileDescription, error)

Open implements Inode.Open.

func (*DynamicBytesFile) SetStat

SetStat implements Inode.SetStat.

type Filesystem

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

Filesystem mostly implements vfs.FilesystemImpl for a generic in-memory filesystem. Concrete implementations are expected to embed this in their own Filesystem type.

func (*Filesystem) GetDentryAt

func (fs *Filesystem) GetDentryAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.GetDentryOptions) (*vfs.Dentry, error)

GetDentryAt implements vfs.FilesystemImpl.GetDentryAt.

func (*Filesystem) GetxattrAt

func (fs *Filesystem) GetxattrAt(ctx context.Context, rp *vfs.ResolvingPath, name string) (string, error)

GetxattrAt implements vfs.FilesystemImpl.GetxattrAt.

func (*Filesystem) Init

func (fs *Filesystem) Init(vfsObj *vfs.VirtualFilesystem)

Init initializes a kernfs filesystem. This should be called from during vfs.FilesystemType.NewFilesystem for the concrete filesystem embedding kernfs.

func (*Filesystem) LinkAt

func (fs *Filesystem) LinkAt(ctx context.Context, rp *vfs.ResolvingPath, vd vfs.VirtualDentry) error

LinkAt implements vfs.FilesystemImpl.LinkAt.

func (*Filesystem) ListxattrAt

func (fs *Filesystem) ListxattrAt(ctx context.Context, rp *vfs.ResolvingPath) ([]string, error)

ListxattrAt implements vfs.FilesystemImpl.ListxattrAt.

func (*Filesystem) MkdirAt

func (fs *Filesystem) MkdirAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.MkdirOptions) error

MkdirAt implements vfs.FilesystemImpl.MkdirAt.

func (*Filesystem) MknodAt

func (fs *Filesystem) MknodAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.MknodOptions) error

MknodAt implements vfs.FilesystemImpl.MknodAt.

func (*Filesystem) NextIno

func (fs *Filesystem) NextIno() uint64

NextIno allocates a new inode number on this filesystem.

func (*Filesystem) OpenAt

OpenAt implements vfs.FilesystemImpl.OpenAt.

func (*Filesystem) PrependPath

func (fs *Filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDentry, b *fspath.Builder) error

PrependPath implements vfs.FilesystemImpl.PrependPath.

func (*Filesystem) ReadlinkAt

func (fs *Filesystem) ReadlinkAt(ctx context.Context, rp *vfs.ResolvingPath) (string, error)

ReadlinkAt implements vfs.FilesystemImpl.ReadlinkAt.

func (*Filesystem) Release

func (fs *Filesystem) Release()

Release implements vfs.FilesystemImpl.Release.

func (*Filesystem) RemovexattrAt

func (fs *Filesystem) RemovexattrAt(ctx context.Context, rp *vfs.ResolvingPath, name string) error

RemovexattrAt implements vfs.FilesystemImpl.RemovexattrAt.

func (*Filesystem) RenameAt

RenameAt implements vfs.FilesystemImpl.RenameAt.

func (*Filesystem) RmdirAt

func (fs *Filesystem) RmdirAt(ctx context.Context, rp *vfs.ResolvingPath) error

RmdirAt implements vfs.FilesystemImpl.RmdirAt.

func (*Filesystem) SetStatAt

func (fs *Filesystem) SetStatAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.SetStatOptions) error

SetStatAt implements vfs.FilesystemImpl.SetStatAt.

func (*Filesystem) SetxattrAt

func (fs *Filesystem) SetxattrAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.SetxattrOptions) error

SetxattrAt implements vfs.FilesystemImpl.SetxattrAt.

func (*Filesystem) StatAt

func (fs *Filesystem) StatAt(ctx context.Context, rp *vfs.ResolvingPath, opts vfs.StatOptions) (linux.Statx, error)

StatAt implements vfs.FilesystemImpl.StatAt.

func (*Filesystem) StatFSAt

func (fs *Filesystem) StatFSAt(ctx context.Context, rp *vfs.ResolvingPath) (linux.Statfs, error)

StatFSAt implements vfs.FilesystemImpl.StatFSAt.

func (*Filesystem) SymlinkAt

func (fs *Filesystem) SymlinkAt(ctx context.Context, rp *vfs.ResolvingPath, target string) error

SymlinkAt implements vfs.FilesystemImpl.SymlinkAt.

func (*Filesystem) Sync

func (fs *Filesystem) Sync(ctx context.Context) error

Sync implements vfs.FilesystemImpl.Sync.

func (*Filesystem) UnlinkAt

func (fs *Filesystem) UnlinkAt(ctx context.Context, rp *vfs.ResolvingPath) error

UnlinkAt implements vfs.FilesystemImpl.UnlinkAt.

func (*Filesystem) VFSFilesystem

func (fs *Filesystem) VFSFilesystem() *vfs.Filesystem

VFSFilesystem returns the generic vfs filesystem object.

type FilesystemType

type FilesystemType struct{}

FilesystemType implements vfs.FilesystemType.

type GenericDirectoryFD

type GenericDirectoryFD struct {
	vfs.FileDescriptionDefaultImpl
	vfs.DirectoryFileDescriptionDefaultImpl
	// contains filtered or unexported fields
}

GenericDirectoryFD implements vfs.FileDescriptionImpl for a generic directory inode that uses OrderChildren to track child nodes. GenericDirectoryFD is not compatible with dynamic directories.

Note that GenericDirectoryFD holds a lock over OrderedChildren while calling IterDirents callback. The IterDirents callback therefore cannot hash or unhash children, or recursively call IterDirents on the same underlying inode.

Must be initialize with Init before first use.

func (*GenericDirectoryFD) ConfigureMMap

func (fd *GenericDirectoryFD) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) error

ConfigureMMap implements vfs.FileDescriptionImpl.ConfigureMMap.

func (*GenericDirectoryFD) Init

func (fd *GenericDirectoryFD) Init(m *vfs.Mount, d *vfs.Dentry, children *OrderedChildren, flags uint32)

Init initializes a GenericDirectoryFD.

func (*GenericDirectoryFD) IterDirents

IterDirents implements vfs.FileDecriptionImpl.IterDirents. IterDirents holds o.mu when calling cb.

func (*GenericDirectoryFD) PRead

func (fd *GenericDirectoryFD) PRead(ctx context.Context, dst usermem.IOSequence, offset int64, opts vfs.ReadOptions) (int64, error)

PRead implmenets vfs.FileDescriptionImpl.PRead.

func (*GenericDirectoryFD) PWrite

func (fd *GenericDirectoryFD) PWrite(ctx context.Context, src usermem.IOSequence, offset int64, opts vfs.WriteOptions) (int64, error)

PWrite implements vfs.FileDescriptionImpl.PWrite.

func (*GenericDirectoryFD) Read

Read implmenets vfs.FileDescriptionImpl.Read.

func (*GenericDirectoryFD) Release

func (fd *GenericDirectoryFD) Release()

Release implements vfs.FileDecriptionImpl.Release.

func (*GenericDirectoryFD) Seek

func (fd *GenericDirectoryFD) Seek(ctx context.Context, offset int64, whence int32) (int64, error)

Seek implements vfs.FileDecriptionImpl.Seek.

func (*GenericDirectoryFD) SetStat

func (fd *GenericDirectoryFD) SetStat(ctx context.Context, opts vfs.SetStatOptions) error

SetStat implements vfs.FileDescriptionImpl.SetStat.

func (*GenericDirectoryFD) Stat

Stat implements vfs.FileDescriptionImpl.Stat.

func (*GenericDirectoryFD) VFSFileDescription

func (fd *GenericDirectoryFD) VFSFileDescription() *vfs.FileDescription

VFSFileDescription returns a pointer to the vfs.FileDescription representing this object.

func (*GenericDirectoryFD) Write

Write implements vfs.FileDescriptionImpl.Write.

type Inode

type Inode interface {

	// Open creates a file description for the filesystem object represented by
	// this inode. The returned file description should hold a reference on the
	// inode for its lifetime.
	//
	// Precondition: !rp.Done(). vfsd.Impl() must be a kernfs Dentry.
	Open(rp *vfs.ResolvingPath, vfsd *vfs.Dentry, flags uint32) (*vfs.FileDescription, error)
	// contains filtered or unexported methods
}

The Inode interface maps filesystem-level operations that operate on paths to equivalent operations on specific filesystem nodes.

The interface methods are groups into logical categories as sub interfaces below. Generally, an implementation for each sub interface can be provided by embedding an appropriate type from inode_impl_utils.go. The sub interfaces are purely organizational. Methods declared directly in the main interface have no generic implementations, and should be explicitly provided by the client filesystem.

Generally, implementations are not responsible for tasks that are common to all filesystems. These include:

- Checking that dentries passed to methods are of the appropriate file type. - Checking permissions. - Updating link and reference counts.

Specific responsibilities of implementations are documented below.

type InodeAttrs

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

InodeAttrs partially implements the Inode interface, specifically the inodeMetadata sub interface. InodeAttrs provides functionality related to inode attributes.

Must be initialized by Init prior to first use.

func (*InodeAttrs) CheckPermissions

func (a *InodeAttrs) CheckPermissions(creds *auth.Credentials, ats vfs.AccessTypes) error

CheckPermissions implements Inode.CheckPermissions.

func (a *InodeAttrs) DecLinks()

DecLinks implements Inode.DecLinks.

func (a *InodeAttrs) IncLinks(n uint32)

IncLinks implements Inode.IncLinks.

func (*InodeAttrs) Init

func (a *InodeAttrs) Init(creds *auth.Credentials, ino uint64, mode linux.FileMode)

Init initializes this InodeAttrs.

func (*InodeAttrs) Mode

func (a *InodeAttrs) Mode() linux.FileMode

Mode implements Inode.Mode.

func (*InodeAttrs) SetStat

func (a *InodeAttrs) SetStat(_ *vfs.Filesystem, opts vfs.SetStatOptions) error

SetStat implements Inode.SetStat.

func (*InodeAttrs) Stat

func (a *InodeAttrs) Stat(*vfs.Filesystem) linux.Statx

Stat partially implements Inode.Stat. Note that this function doesn't provide all the stat fields, and the embedder should consider extending the result with filesystem-specific fields.

type InodeDirectoryNoNewChildren

type InodeDirectoryNoNewChildren struct{}

InodeDirectoryNoNewChildren partially implements the Inode interface. InodeDirectoryNoNewChildren represents a directory inode which does not support creation of new children.

func (*InodeDirectoryNoNewChildren) NewDir

NewDir implements Inode.NewDir.

func (*InodeDirectoryNoNewChildren) NewFile

NewFile implements Inode.NewFile.

NewLink implements Inode.NewLink.

func (*InodeDirectoryNoNewChildren) NewNode

NewNode implements Inode.NewNode.

NewSymlink implements Inode.NewSymlink.

type InodeNoDynamicLookup

type InodeNoDynamicLookup struct{}

InodeNoDynamicLookup partially implements the Inode interface, specifically the inodeDynamicLookup sub interface. Directory inodes that do not support dymanic entries (i.e. entries that are not "hashed" into the vfs.Dentry.children) can embed this to provide no-op implementations for functions related to dynamic entries.

func (*InodeNoDynamicLookup) Lookup

func (*InodeNoDynamicLookup) Lookup(ctx context.Context, name string) (*vfs.Dentry, error)

Lookup implements Inode.Lookup.

func (*InodeNoDynamicLookup) Valid

Valid implements Inode.Valid.

type InodeNoopRefCount

type InodeNoopRefCount struct {
}

InodeNoopRefCount partially implements the Inode interface, specifically the inodeRefs sub interface. InodeNoopRefCount implements a simple reference count for inodes, performing no extra actions when references are obtained or released. This is suitable for simple file inodes that don't reference any resources.

func (*InodeNoopRefCount) DecRef

func (n *InodeNoopRefCount) DecRef()

DecRef implements Inode.DecRef.

func (*InodeNoopRefCount) Destroy

func (n *InodeNoopRefCount) Destroy()

Destroy implements Inode.Destroy.

func (*InodeNoopRefCount) IncRef

func (n *InodeNoopRefCount) IncRef()

IncRef implements Inode.IncRef.

func (*InodeNoopRefCount) TryIncRef

func (n *InodeNoopRefCount) TryIncRef() bool

TryIncRef implements Inode.TryIncRef.

type InodeNotDirectory

type InodeNotDirectory struct {
}

InodeNotDirectory partially implements the Inode interface, specifically the inodeDirectory and inodeDynamicDirectory sub interfaces. Inodes that do not represent directories can embed this to provide no-op implementations for directory-related functions.

func (*InodeNotDirectory) HasChildren

func (*InodeNotDirectory) HasChildren() bool

HasChildren implements Inode.HasChildren.

func (*InodeNotDirectory) Lookup

func (*InodeNotDirectory) Lookup(ctx context.Context, name string) (*vfs.Dentry, error)

Lookup implements Inode.Lookup.

func (*InodeNotDirectory) NewDir

NewDir implements Inode.NewDir.

func (*InodeNotDirectory) NewFile

NewFile implements Inode.NewFile.

NewLink implements Inode.NewLinkink.

func (*InodeNotDirectory) NewNode

NewNode implements Inode.NewNode.

NewSymlink implements Inode.NewSymlink.

func (*InodeNotDirectory) Rename

Rename implements Inode.Rename.

func (*InodeNotDirectory) RmDir

RmDir implements Inode.RmDir.

Unlink implements Inode.Unlink.

func (*InodeNotDirectory) Valid

Valid implements Inode.Valid.

type InodeNotSymlink struct{}

InodeNotSymlink partially implements the Inode interface, specifically the inodeSymlink sub interface. All inodes that are not symlinks may embed this to return the appropriate errors from symlink-related functions.

func (*InodeNotSymlink) Readlink(context.Context) (string, error)

Readlink implements Inode.Readlink.

type OrderedChildren

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

OrderedChildren partially implements the Inode interface. OrderedChildren can be embedded in directory inodes to keep track of the children in the directory, and can then be used to implement a generic directory FD -- see GenericDirectoryFD. OrderedChildren is not compatible with dynamic directories.

Must be initialize with Init before first use.

func (*OrderedChildren) DecRef

func (o *OrderedChildren) DecRef()

DecRef implements Inode.DecRef.

func (*OrderedChildren) Destroy

func (o *OrderedChildren) Destroy()

Destroy cleans up resources referenced by this OrderedChildren.

func (*OrderedChildren) HasChildren

func (o *OrderedChildren) HasChildren() bool

HasChildren implements Inode.HasChildren.

func (*OrderedChildren) Init

Init initializes an OrderedChildren.

func (*OrderedChildren) Insert

func (o *OrderedChildren) Insert(name string, child *vfs.Dentry) error

Insert inserts child into o. This ignores the writability of o, as this is not part of the vfs.FilesystemImpl interface, and is a lower-level operation.

func (*OrderedChildren) Populate

func (o *OrderedChildren) Populate(d *Dentry, children map[string]*Dentry) uint32

Populate inserts children into this OrderedChildren, and d's dentry cache. Populate returns the number of directories inserted, which the caller may use to update the link count for the parent directory.

Precondition: d.Impl() must be a kernfs Dentry. d must represent a directory inode. children must not contain any conflicting entries already in o.

func (*OrderedChildren) Rename

func (o *OrderedChildren) Rename(ctx context.Context, oldname, newname string, child, dstDir *vfs.Dentry) (*vfs.Dentry, error)

Rename implements Inode.Rename.

Precondition: Rename may only be called across two directory inodes with identical implementations of Rename. Practically, this means filesystems that implement Rename by embedding OrderedChildren for any directory implementation must use OrderedChildren for all directory implementations that will support Rename.

Postcondition: reference on any replaced dentry transferred to caller.

func (*OrderedChildren) RmDir

func (o *OrderedChildren) RmDir(ctx context.Context, name string, child *vfs.Dentry) error

Rmdir implements Inode.Rmdir.

func (o *OrderedChildren) Unlink(ctx context.Context, name string, child *vfs.Dentry) error

Unlink implements Inode.Unlink.

type OrderedChildrenOptions

type OrderedChildrenOptions struct {
	// Writable indicates whether vfs.FilesystemImpl methods implemented by
	// OrderedChildren may modify the tracked children. This applies to
	// operations related to rename, unlink and rmdir. If an OrderedChildren is
	// not writable, these operations all fail with EPERM.
	Writable bool
}

OrderedChildrenOptions contains initialization options for OrderedChildren.

Jump to

Keyboard shortcuts

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