node

package
v0.0.0-...-bbc9ce3 Latest Latest
Warning

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

Go to latest
Published: Dec 6, 2021 License: BSD-2-Clause Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// This file size cap is a fundamental limit of FAT filesystems
	MaxSizeFile = int64(0xFFFFFFFF)

	// All direntries must be indexable by a 16-bit integer (for historical reasons)
	MaxSizeDirectory = int64((1 << 16) * direntry.DirentrySize)
)

Variables

View Source
var (
	// ErrNoSpace indicates the requested operation requires more space than is available
	ErrNoSpace = fs.ErrNoSpace

	// ErrBadArgument indicates the argument passed to a node was invalid
	ErrBadArgument = fs.ErrInvalidArgs
)

Functions

func Allocate

func Allocate(n DirectoryNode, entry *direntry.Dirent) (direntryIndex int, err error)

Allocate allocates space for a dirent in the directory, placing entry into directory on disk. Also relocates the "last free" marker if necessary.

Returns the index of the direntry allocated. Returns an error if the entry cannot be serialized, there isn't enough space to write the direntry/direntries to disk, or there is an error writing to storage.

func Free

func Free(n DirectoryNode, index int) (*direntry.Dirent, error)

Free frees the direntry at a provided index inside a directory node.

func IsEmpty

func IsEmpty(n DirectoryNode) (bool, error)

IsEmpty returns true if "n" represents an empty directory.

func Lookup

func Lookup(n DirectoryNode, name string) (*direntry.Dirent, int, error)

Lookup finds a dirent with a given name inside a directory node

Returns the direntry and the index at which the node was found.

func MakeEmpty

func MakeEmpty(n DirectoryNode) error

MakeEmpty writes the "last free" direntry to the node in a location indicating it is empty. It also updates the node's size to reflect that it is empty.

func Read

func Read(n DirectoryNode, index int) (entry *direntry.Dirent, numSlots int, err error)

Read reads the direntry at an index. Returns the number of direntry slots used by the direntry. This is meaningful for indexing purposes.

func Update

func Update(parent DirectoryNode, cluster uint32, mTime time.Time, size uint32, direntryIndex int) (uint32, error)

Update updates the direntry for the child node by updating its parent direntry. Cannot be used to alter a direntry name. Returns the old cluster which was replaced

func WriteDotAndDotDot

func WriteDotAndDotDot(n DirectoryNode, cluster, parentCluster uint32) error

WriteDotAndDotDot updates the "." and ".." entries for a directory. Does not alter node size and does not write any free entries.

Types

type Dcache

type Dcache struct {
	sync.Mutex
	// contains filtered or unexported fields
}

Dcache destribes a cache of directories

func (*Dcache) Acquire

func (d *Dcache) Acquire(id uint32)

Acquire increments the number of references to a node in the dcache Precondition: Key exists in dcache

Thread-safe

func (*Dcache) AllEntries

func (d *Dcache) AllEntries() []DirectoryNode

AllEntries returns all nodes in the dcache

NOT thread-safe

func (*Dcache) CreateOrAcquire

func (d *Dcache) CreateOrAcquire(m *Metadata, id uint32, mtime time.Time) (DirectoryNode, error)

CreateOrAcquire either (1) Creates a new node and places it in the dcache (ref = 1), or (2) Acquires a node which is already in the dcache (ref++) Use this function when access is needed to a Directory which may or may not be open.

Thread-safe

func (*Dcache) Init

func (d *Dcache) Init()

Init initializes dcache structure

func (*Dcache) Insert

func (d *Dcache) Insert(id uint32, n DirectoryNode)

Insert adds a node to the dcache Precondition: Key does NOT exist in dcache

Thread-safe

func (*Dcache) Lookup

func (d *Dcache) Lookup(id uint32) (DirectoryNode, error)

Lookup (and acquire) the directory node, if it exists

Thread-safe

func (*Dcache) Release

func (d *Dcache) Release(id uint32)

Release decreases a reference to a directory in the dcache Precondition: Key exists in dcache

Thread-safe

func (*Dcache) Transfer

func (d *Dcache) Transfer(src, dst uint32, count int)

Transfer moves count references from one ID to another.

type DirectoryNode

type DirectoryNode interface {
	Node

	RemoveFile(direntIndex int)                 // Remove a child file open in this directory
	ChildFiles() []FileNode                     // Return the child files open in this directory
	ChildFile(direntIndex int) (FileNode, bool) // Return a child file open at a particular direntIndex

	// Methods which do not require lock
	IsRoot() bool // True iff the node corresponds to the root of a filesystem
	ID() uint32   // Unique ID which identifies directory. Guaranteed to be 0 for root nodes
	// contains filtered or unexported methods
}

DirectoryNode implements the interface of a directory in the FAT filesystem

func NewDirectory

func NewDirectory(m *Metadata, startCluster uint32, mtime time.Time) (DirectoryNode, error)

NewDirectory makes a new node representing a directory.

func NewRoot

func NewRoot(m *Metadata, offsetStart, maxSize int64) DirectoryNode

NewRoot makes a new root, specific for FAT-12 / FAT-16

type FileNode

type FileNode interface {
	Node
	WriteAt(p []byte, off int64) (int, error) // Implements io.WriterAt
	ReadAt(p []byte, off int64) (int, error)  // Implements io.ReaderAt

	MoveFile(newParent DirectoryNode, newDirentIndex int) // Relocate a file node to a new directory
	LockParent() (parent DirectoryNode, direntIndex int)  // Return the parent directory (locked, if it exists) for this file
	Parent() (parent DirectoryNode, direntIndex int)      // Return the parent directory for this file (NOT thread-safe)
}

FileNode implements the interface of a file (leaf node) in the FAT filesystem

func NewFile

func NewFile(m *Metadata, parent DirectoryNode, direntIndex int, startCluster uint32, mtime time.Time) (FileNode, error)

NewFile creates a new node representing a file.

type Metadata

type Metadata struct {
	Dev        *thinio.Conductor      // Access to device (with cache).
	Br         *bootrecord.Bootrecord // Superblock of filesystem
	ClusterMgr *cluster.Manager
	Readonly   bool

	Dcache
}

Metadata describes the important, shared metadata of the filesystem.

func (*Metadata) Init

func (m *Metadata) Init()

Init initializes metadata structure

type Node

type Node interface {
	sync.Locker // Writer-lock access
	RLock()     // Reader-lock access
	RUnlock()   // Unlock reader lock

	// Write-access methods, which may modify the contents of the Node
	SetSize(size int64)        // Change node size. Shrinking can remove clusters
	SetMTime(mtime time.Time)  // Updates the last modified time
	RefUp()                    // Increment refs
	RefDown(numRefs int) error // Decrement refs, possibly delete clusters if they're unused
	MarkDeleted()              // Mark that the node's clusters should be deleted when refs is zero

	// Read-access methods, which do not modify the contents of the Node
	Size() int64          // Return the number of bytes accessible within the node
	StartCluster() uint32 // Returns the first cluster of the node (or EOF)
	NumClusters() int     // Returns the number of clusters used by the node (internally)
	RefCount() int        // Number of external references ('refs') to the node
	MTime() time.Time     // Get last modified time of node, if known
	IsDeleted() bool      // Return if the entry has been deleted

	// Accessible without a lock
	IsDirectory() bool   // True iff the node corresponds to a directory
	Metadata() *Metadata // Return info about the node's filesystem
	// contains filtered or unexported methods
}

Node implements the interface of a single node (file, directory, or root) in the FAT filesystem.

Jump to

Keyboard shortcuts

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