Documentation
¶
Overview ¶
Package ext4 provides read/write access to ext4 filesystem images without requiring root privileges. It supports raw disk images (MBR/GPT) as well as bare filesystem images and handles modern ext4 features: extents, 64-bit block numbers, flex_bg, dir_htree and metadata_csum (CRC32c checksums).
Package ext4 provides read/write access to ext4 filesystem images. See ext4.go for exported types and constants.
tryMutex implements a mutex with TryLock semantics using a buffered channel of size 1. It provides Lock/Unlock (blocking) and TryLock
Index ¶
- Constants
- Variables
- func AddDirEntry(f ReaderWriterAt, fsOffset int64, sb *Superblock, dir *Inode, child uint32, ...) error
- func AddFastSymlink(t *testing.T, fs *Ext4FS, parentPath, name, target string)
- func AddRangeToTx(tx *Transaction, f ReaderWriterAt, fsOffset int64, sb *Superblock, ...) error
- func AllocBlocks(f ReaderWriterAt, fsOffset int64, sb *Superblock, n uint32) ([]uint64, error)
- func AllocInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, isDir bool) (uint32, error)
- func BgdOffset(sb *Superblock, g uint32) int64
- func BgdRaw(d *Bgd) []byte
- func BgdTableBlock(sb *Superblock) uint64
- func CRC32c(crc uint32, data []byte) uint32
- func ClearBit(b []byte, i int)
- func CloneFSImageFromPath(path string) ([]byte, error)
- func ComputeInodeCsum(sb *Superblock, in *Inode)
- func CreateFullWorker(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32, capacity int) error
- func CsumSeed(sb *Superblock) uint32
- func DecrementAndFreeInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) error
- func DirBlockForPath(t *testing.T, rw ReaderWriterAt, sb *Superblock, path string) uint64
- func DumpBlockingFallbacks()
- func DumpCommitTrace()
- func DumpDebugLog(w io.Writer)
- func EncodeBGD(d *Bgd, sb *Superblock) []byte
- func EnqueueRawCommitOps(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32, starts []int64, ...) (chan error, uint64, error)
- func FindFreeBit(b []byte, maxBits int) (int, bool)
- func FindFreeRun(b []byte, maxBits, n int) ([]int, bool)
- func Format(path string, sizeBytes int64, cfg FormatConfig) (filesystem.Filesystem, error)
- func FreeBlock(f ReaderWriterAt, fsOffset int64, sb *Superblock, block uint64) error
- func FreeInodeBlocks(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) error
- func FreeInodeSlot(f ReaderWriterAt, fsOffset int64, sb *Superblock, inodeNum uint32) error
- func GetCommitWorkerIdleSecs() int
- func GetSeqForAck(ack chan error) (uint64, bool)
- func HookMemFileBuf(h *HookMemFile) []byte
- func InodeNum(in *Inode) uint32
- func InodeOffsetFor(r ReaderWriterAt, sb *Superblock, inodeNum uint32) int64
- func InodeRaw(in *Inode) []byte
- func InodeSizeVal(in *Inode) uint64
- func IsDir(in *Inode) bool
- func IsRegular(in *Inode) bool
- func IsSeqAcked(seq uint64) bool
- func IsSymlink(in *Inode) bool
- func MakeDir(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string, ...) error
- func MarkSeqAcked(seq uint64)
- func MinDirentSize(nameLen int) int
- func NewOwner() uint64
- func NumBlockGroups(sb *Superblock) uint32
- func Open(imagePath string, partIndex int) (filesystem.Filesystem, error)
- func OpenFromDevice(dev blockDevice, partIndex int) (filesystem.Filesystem, error)
- func OwnerFrom(ctx context.Context) (uint64, bool)
- func PartitionOffset(r io.ReaderAt, partIndex int) (int64, error)
- func ReadBitmap(f ReaderWriterAt, fsOffset int64, sb *Superblock, bitmapBlock uint64) ([]byte, error)
- func ReadFileData(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) ([]byte, error)
- func ReadRawBlock(f ReaderWriterAt, fsOffset int64, sb *Superblock, blockNum uint64) ([]byte, error)
- func ReadSymlink(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) (string, error)
- func RemoveDir(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) error
- func RemoveFile(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) error
- func RemoveWorkerFor(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32)
- func Rename(f ReaderWriterAt, fsOffset int64, sb *Superblock, oldPath, newPath string) error
- func RootDirBlockFor(t *testing.T, rw ReaderWriterAt, sb *Superblock) uint64
- func SetAckToSeqDeleteGraceMS(ms int)
- func SetAddDirEntryAllocBlocks(fn func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)) func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)
- func SetAddDirEntrySetInlineExtents(fn func(*Inode, []extentLeaf) error) func(*Inode, []extentLeaf) error
- func SetAddDirEntryWriteBlock(fn func(ReaderWriterAt, int64, *Superblock, uint64, []byte) error) func(ReaderWriterAt, int64, *Superblock, uint64, []byte) error
- func SetBit(b []byte, i int)
- func SetCommitWorkerIdleSecs(s int)
- func SetFormatOpenFS(fn func(string, int) (filesystem.Filesystem, error)) func(string, int) (filesystem.Filesystem, error)
- func SetFormatOpenFile(fn func(string) (FormatFile, error)) func(string) (FormatFile, error)
- func SetFormatRandRead(fn func([]byte) (int, error)) func([]byte) (int, error)
- func SetInlineExtents(in *Inode, exts []ExtentLeaf) error
- func SetMakeDirAllocBlocks(fn func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)) func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)
- func SetMakeDirAllocInode(fn func(ReaderWriterAt, int64, *Superblock, bool) (uint32, error)) func(ReaderWriterAt, int64, *Superblock, bool) (uint32, error)
- func SetMode(in *Inode, mode uint16, links uint16)
- func SetReadLinkReadInode(fn func(ReaderWriterAt, int64, *Superblock, uint32) (*Inode, error)) func(ReaderWriterAt, int64, *Superblock, uint32) (*Inode, error)
- func SetRemoveDirChildDir(fn func(ReaderWriterAt, int64, *Superblock, string) error) func(ReaderWriterAt, int64, *Superblock, string) error
- func SetRemoveDirChildFile(fn func(ReaderWriterAt, int64, *Superblock, string) error) func(ReaderWriterAt, int64, *Superblock, string) error
- func SetRemoveDirFreeBlocks(fn func(ReaderWriterAt, int64, *Superblock, *Inode) error) func(ReaderWriterAt, int64, *Superblock, *Inode) error
- func SetRemoveDirFreeSlot(fn func(ReaderWriterAt, int64, *Superblock, uint32) error) func(ReaderWriterAt, int64, *Superblock, uint32) error
- func SetSize(in *Inode, size uint64)
- func SetWriteFileSetInlineExtents(fn func(*Inode, []extentLeaf) error) func(*Inode, []extentLeaf) error
- func TryInsertDirEntry(buf []byte, childIno uint32, name string, fileType uint8, needed int) bool
- func UpdateDirBlockCsum(buf []byte, sb *Superblock, dir *Inode)
- func UpdateDotDot(f ReaderWriterAt, fsOffset int64, sb *Superblock, dirIno *Inode, ...) error
- func WithOwner(ctx context.Context) (context.Context, uint64)
- func WorkerExistsFor(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32) bool
- func WriteBGD(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32, d *Bgd) error
- func WriteBitmapBuf(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32, d *Bgd, ...) error
- func WriteBitmapWithCsum(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32, d *Bgd, ...) error
- func WriteDirEntry(buf []byte, off int, ino uint32, recLen uint16, name string, fileType uint8)
- func WriteFileRaw(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string, data []byte, ...) error
- func WriteInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) error
- func WriteRawBlock(f ReaderWriterAt, fsOffset int64, sb *Superblock, blockNum uint64, data []byte) error
- func WriteSuperblock(f ReaderWriterAt, fsOffset int64, sb *Superblock) error
- func ZeroDirEntry(f ReaderWriterAt, fsOffset int64, sb *Superblock, dirIno *Inode, name string) error
- func ZeroEntryInBlock(buf []byte, name string, le binary.ByteOrder) bool
- type Bgd
- type BlockDevice
- type DirEntry
- type Ext4FS
- type ExtentLeaf
- type FS
- type FormatConfig
- type FormatFile
- type HookMemFile
- type Inode
- func LookupParent(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) (*Inode, string, error)
- func LookupPath(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) (*Inode, error)
- func NewTestInode(num uint32, inodeSize uint16) *Inode
- func ReadInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, inodeNum uint32) (*Inode, error)
- type Journal
- type ReaderWriterAt
- type Stat
- type Superblock
- type Transaction
Constants ¶
const ( FeatIncompatFiletype = 0x0002 FeatIncompatExtents = 0x0040 FeatIncompat64bit = 0x0080 FeatIncompatFlexBg = 0x0200 FeatIncompatCsumSeed = 0x2000 FeatIncompatInlineData = 0x8000 )
Incompatible feature flags (must understand to read/write).
const ( FeatROCompatSparseSuper = 0x0001 FeatROCompatLargeFile = 0x0002 FeatROCompatGdtCsum = 0x0010 FeatROCompatMetadataCsum = 0x0400 )
Read-only compatible feature flags.
const ( InodeFlagHashIndex = 0x00001000 // directory uses htree index InodeFlagExtents = 0x00080000 // inode uses extent tree InodeFlagInlineData = 0x10000000 // data stored inline in inode )
Inode flags.
const ( FtUnknown = 0 FtRegFile = 1 FtDir = 2 FtSymlink = 7 FtDirTail = 0xDE // fake tail entry carrying checksum )
Directory entry file types.
const ExtentMagic uint16 = 0xF30A
Extent tree magic number.
const MaxLabelLen = 16
MaxLabelLen is the on-disk size of the ext4 volume label (s_volume_name, at superblock offset 0x78).
const RootIno uint32 = 2
Well-known inode numbers.
Variables ¶
var ( InodeOffMode = inodeOffMode InodeOffSizeLo = inodeOffSizeLo InodeOffLinksCount = inodeOffLinksCount InodeOffFlags = inodeOffFlags InodeOffBlock = inodeOffBlock InodeOffGeneration = inodeOffGeneration InodeOffFilACLLo = inodeOffFilACLLo InodeOffSizeHi = inodeOffSizeHi InodeOffBlocksHi = inodeOffBlocksHi InodeOffCsumLo = inodeOffCsumLo InodeOffExtraIsize = inodeOffExtraIsize InodeOffCsumHi = inodeOffCsumHi )
Export inode offset constants used by tests.
var CommitHook func(seq uint64, entries int)
CommitHook, when set (tests only), is invoked with the transaction sequence number each time a transaction is committed. This allows tests to observe/measure commit behavior without parsing debug logs. CommitHook, when set (tests only), is invoked with the transaction sequence number and the number of entries each time a transaction is committed. This allows tests to observe/measure commit behavior without parsing debug logs.
var LinuxPartTypeGPT = linuxPartTypeGPT
Expose partition constants for tests.
var SectorSize = sectorSize
Functions ¶
func AddDirEntry ¶
func AddDirEntry(f ReaderWriterAt, fsOffset int64, sb *Superblock, dir *Inode, child uint32, name string, fileType uint8) error
AddDirEntry exposes addDirEntry.
func AddFastSymlink ¶
AddFastSymlink creates a symlink inode and dir entry in the live filesystem (used by tests that need a quick symlink creation helper).
func AddRangeToTx ¶
func AddRangeToTx(tx *Transaction, f ReaderWriterAt, fsOffset int64, sb *Superblock, startAbs int64, data []byte) error
AddRangeToTx exposes addRangeToTx so external tests can prepare transaction entries using the same locking semantics as production callers. This prevents test-only preparations from bypassing per-block locking and triggering lost-update races.
func AllocBlocks ¶
func AllocBlocks(f ReaderWriterAt, fsOffset int64, sb *Superblock, n uint32) ([]uint64, error)
AllocBlocks exposes allocBlocks.
func AllocInode ¶
func AllocInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, isDir bool) (uint32, error)
AllocInode exposes allocInode.
func BgdTableBlock ¶
func BgdTableBlock(sb *Superblock) uint64
func CloneFSImageFromPath ¶
CloneFSImageFromPath reads the image file into a buffer copy for in-memory tests.
func CreateFullWorker ¶
func CreateFullWorker(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32, capacity int) error
CreateFullWorker inserts a commitWorker for the provided file/group with a tasks channel of the given capacity and pre-fills it so enqueue attempts will hit the queue-full fallback path. Returns an error if a worker already exists for the computed key.
func CsumSeed ¶
func CsumSeed(sb *Superblock) uint32
func DecrementAndFreeInode ¶
func DecrementAndFreeInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) error
DecrementAndFreeInode exposes decrementAndFreeInode.
func DirBlockForPath ¶
func DirBlockForPath(t *testing.T, rw ReaderWriterAt, sb *Superblock, path string) uint64
DirBlockForPath returns the first data block for the given path.
func DumpBlockingFallbacks ¶
func DumpBlockingFallbacks()
func DumpCommitTrace ¶
func DumpCommitTrace()
func DumpDebugLog ¶
DumpDebugLog writes the accumulated debug buffer to the provided writer.
func EncodeBGD ¶
func EncodeBGD(d *Bgd, sb *Superblock) []byte
EncodeBGD encodes a decoded BGD into its raw descriptor bytes and returns the raw byte slice for inspection by external tests.
func EnqueueRawCommitOps ¶
func EnqueueRawCommitOps(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32, starts []int64, datas [][]byte) (chan error, uint64, error)
EnqueueRawCommitOps exposes a thin wrapper allowing tests to enqueue a multi-op commit where each op is specified by a start offset (relative to fsOffset) and a data slice. This is useful for constructing a single commit that contains both a bitmap write and a BGD write so the worker's `lastBitmap` optimization can be exercised in tests.
func Format ¶
func Format(path string, sizeBytes int64, cfg FormatConfig) (filesystem.Filesystem, error)
Format creates a new ext4 filesystem in the file at path. The file is created (or truncated) and formatted. sizeBytes must be a multiple of 4096 and large enough to hold filesystem metadata plus at least one data block.
On success the newly formatted filesystem is opened and returned; the caller must Close it when done.
func FreeBlock ¶
func FreeBlock(f ReaderWriterAt, fsOffset int64, sb *Superblock, block uint64) error
FreeBlock exposes freeBlock.
func FreeInodeBlocks ¶
func FreeInodeBlocks(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) error
FreeInodeBlocks exposes freeInodeBlocks.
func FreeInodeSlot ¶
func FreeInodeSlot(f ReaderWriterAt, fsOffset int64, sb *Superblock, inodeNum uint32) error
FreeInodeSlot exposes freeInodeSlot.
func GetCommitWorkerIdleSecs ¶
func GetCommitWorkerIdleSecs() int
Get/Set commit worker idle duration (seconds) for tests.
func GetSeqForAck ¶
Test-only helpers to observe and control ack->seq mapping behavior. GetSeqForAck returns the registered seq for the provided ack channel and a boolean indicating whether the mapping exists.
func HookMemFileBuf ¶
func HookMemFileBuf(h *HookMemFile) []byte
HookMemFileBuf returns the underlying buffer for tests that need to mutate or inspect the raw bytes inside a HookMemFile.
func InodeOffsetFor ¶
func InodeOffsetFor(r ReaderWriterAt, sb *Superblock, inodeNum uint32) int64
InodeOffsetFor computes inode byte offset (helper for tests).
func InodeSizeVal ¶
func IsSeqAcked ¶
func MakeDir ¶
func MakeDir(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string, perm os.FileMode) error
MakeDir exposes the internal makeDir helper for external tests.
func NewOwner ¶
func NewOwner() uint64
NewOwner returns a new unique owner token for locking purposes.
func NumBlockGroups ¶
func NumBlockGroups(sb *Superblock) uint32
Exported superblock convenience accessors for external tests.
func Open ¶
func Open(imagePath string, partIndex int) (filesystem.Filesystem, error)
Open opens an ext4 filesystem image at imagePath, automatically detecting the partition table (MBR / GPT) and using the first Linux partition. Pass partIndex = -1 for auto-detection (first Linux partition).
func OpenFromDevice ¶
func OpenFromDevice(dev blockDevice, partIndex int) (filesystem.Filesystem, error)
OpenFromDevice opens an ext4 filesystem backed by an arbitrary block device. dev must remain valid until the returned Filesystem is closed.
func ReadBitmap ¶
func ReadBitmap(f ReaderWriterAt, fsOffset int64, sb *Superblock, bitmapBlock uint64) ([]byte, error)
ReadBitmap exposes readBitmap.
func ReadFileData ¶
func ReadFileData(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) ([]byte, error)
ReadFileData exposes readFileData.
func ReadRawBlock ¶
func ReadRawBlock(f ReaderWriterAt, fsOffset int64, sb *Superblock, blockNum uint64) ([]byte, error)
ReadRawBlock exposes readRawBlock.
func ReadSymlink ¶
func ReadSymlink(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) (string, error)
ReadSymlink exposes readSymlink.
func RemoveDir ¶
func RemoveDir(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) error
RemoveDir exposes removeDir for tests that operate on low-level images.
func RemoveFile ¶
func RemoveFile(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) error
RemoveFile exposes removeFile for tests that operate on low-level images.
func RemoveWorkerFor ¶
func RemoveWorkerFor(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32)
RemoveWorkerFor removes any injected worker for the given file/group.
func Rename ¶
func Rename(f ReaderWriterAt, fsOffset int64, sb *Superblock, oldPath, newPath string) error
Rename exposes the internal rename helper for external tests.
func RootDirBlockFor ¶
func RootDirBlockFor(t *testing.T, rw ReaderWriterAt, sb *Superblock) uint64
RootDirBlockFor returns the first data block for the root directory.
func SetAckToSeqDeleteGraceMS ¶
func SetAckToSeqDeleteGraceMS(ms int)
SetAckToSeqDeleteGraceMS sets the test-only ack->seq deletion grace duration in milliseconds. Useful for exercising TTL behavior in tests.
func SetAddDirEntryAllocBlocks ¶
func SetAddDirEntryAllocBlocks(fn func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)) func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)
Setters for addDirEntry package-level hooks so external tests can inject failures or behavior.
func SetAddDirEntryWriteBlock ¶
func SetAddDirEntryWriteBlock(fn func(ReaderWriterAt, int64, *Superblock, uint64, []byte) error) func(ReaderWriterAt, int64, *Superblock, uint64, []byte) error
func SetCommitWorkerIdleSecs ¶
func SetCommitWorkerIdleSecs(s int)
func SetFormatOpenFS ¶
func SetFormatOpenFS(fn func(string, int) (filesystem.Filesystem, error)) func(string, int) (filesystem.Filesystem, error)
func SetFormatOpenFile ¶
func SetFormatOpenFile(fn func(string) (FormatFile, error)) func(string) (FormatFile, error)
Format hook setters - allow external tests to inject file/open/rand behavior.
func SetFormatRandRead ¶
func SetInlineExtents ¶
func SetInlineExtents(in *Inode, exts []ExtentLeaf) error
SetInlineExtents sets inline extents on an inode (wrapped method).
func SetMakeDirAllocBlocks ¶
func SetMakeDirAllocBlocks(fn func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)) func(ReaderWriterAt, int64, *Superblock, uint32) ([]uint64, error)
func SetMakeDirAllocInode ¶
func SetMakeDirAllocInode(fn func(ReaderWriterAt, int64, *Superblock, bool) (uint32, error)) func(ReaderWriterAt, int64, *Superblock, bool) (uint32, error)
func SetReadLinkReadInode ¶
func SetReadLinkReadInode(fn func(ReaderWriterAt, int64, *Superblock, uint32) (*Inode, error)) func(ReaderWriterAt, int64, *Superblock, uint32) (*Inode, error)
func SetRemoveDirChildDir ¶
func SetRemoveDirChildDir(fn func(ReaderWriterAt, int64, *Superblock, string) error) func(ReaderWriterAt, int64, *Superblock, string) error
Setter helpers for package-level hooks used by tests.
func SetRemoveDirChildFile ¶
func SetRemoveDirChildFile(fn func(ReaderWriterAt, int64, *Superblock, string) error) func(ReaderWriterAt, int64, *Superblock, string) error
func SetRemoveDirFreeBlocks ¶
func SetRemoveDirFreeBlocks(fn func(ReaderWriterAt, int64, *Superblock, *Inode) error) func(ReaderWriterAt, int64, *Superblock, *Inode) error
func SetRemoveDirFreeSlot ¶
func SetRemoveDirFreeSlot(fn func(ReaderWriterAt, int64, *Superblock, uint32) error) func(ReaderWriterAt, int64, *Superblock, uint32) error
func TryInsertDirEntry ¶
func UpdateDirBlockCsum ¶
func UpdateDirBlockCsum(buf []byte, sb *Superblock, dir *Inode)
UpdateDirBlockCsum exposes updateDirBlockCsum for tests.
func UpdateDotDot ¶
func UpdateDotDot(f ReaderWriterAt, fsOffset int64, sb *Superblock, dirIno *Inode, newParentIno uint32) error
UpdateDotDot exposes the internal updateDotDot helper for tests that need to exercise updating '..' directory entries.
func WithOwner ¶
WithOwner returns a new context that carries a unique owner token and the token itself. Useful for propagating an ownership token through call chains.
func WorkerExistsFor ¶
func WorkerExistsFor(f ReaderWriterAt, fsOffset int64, sb *Superblock, group uint32) bool
WorkerExistsFor returns true if a worker is registered for the file/group.
func WriteBGD ¶
func WriteBGD(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32, d *Bgd) error
WriteBGD exposes writeBGD.
func WriteBitmapBuf ¶
func WriteBitmapBuf(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32, d *Bgd, isBlock bool, bitmapBlock uint64, bmap []byte) error
WriteBitmapBuf exposes writeBitmapBuf for low-level bitmap testing.
func WriteBitmapWithCsum ¶
func WriteBitmapWithCsum(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32, d *Bgd, isBlockBitmap bool) error
WriteBitmapWithCsum exposes writeBitmapWithCsum.
func WriteDirEntry ¶
func WriteFileRaw ¶
func WriteFileRaw(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string, data []byte, perm os.FileMode) error
WriteFileRaw exposes the internal writeFile helper used by package tests.
func WriteInode ¶
func WriteInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, in *Inode) error
WriteInode exposes writeInode.
func WriteRawBlock ¶
func WriteRawBlock(f ReaderWriterAt, fsOffset int64, sb *Superblock, blockNum uint64, data []byte) error
WriteRawBlock exposes writeRawBlock.
func WriteSuperblock ¶
func WriteSuperblock(f ReaderWriterAt, fsOffset int64, sb *Superblock) error
func ZeroDirEntry ¶
func ZeroDirEntry(f ReaderWriterAt, fsOffset int64, sb *Superblock, dirIno *Inode, name string) error
ZeroDirEntry exposes zeroDirEntry.
Types ¶
type Bgd ¶
type Bgd = bgd
func ReadBGD ¶
func ReadBGD(f ReaderWriterAt, fsOffset int64, sb *Superblock, g uint32) (*Bgd, error)
ReadBGD exposes readBGD.
type BlockDevice ¶
type BlockDevice = blockDevice
BlockDevice is the exported alias of blockDevice, lets external packages satisfy the interface and pass instances to OpenFromDevice. Without it, OpenFromDevice's signature `(dev blockDevice, …)` references an unexported type — only code inside this package could call it. Use cases for implementing BlockDevice externally:
- LUKS / dm-crypt: wrap a github.com/go-fde/luks.Device so ext4.OpenFromDevice reads the plaintext payload.
- In-memory testing: feed a *bytes.Reader-backed fixture into the FS without writing a tempfile.
- qcow2 / DMG / other image formats from the go-diskimages family: surface the unpacked block view as a BlockDevice.
type DirEntry ¶
DirEntry is a parsed directory entry.
func ParseDirBlock ¶
func ReadDir ¶
func ReadDir(f ReaderWriterAt, fsOffset int64, sb *Superblock, dirIno *Inode) ([]DirEntry, error)
ReadDir exposes readDir for tests that need to enumerate directory entries from a single inode.
type Ext4FS ¶
type Ext4FS = ext4FS
Expose the concrete FS type as an exported alias for tests.
type ExtentLeaf ¶
type ExtentLeaf = extentLeaf
func BuildExtents ¶
func BuildExtents(phys []uint64) []ExtentLeaf
BuildExtents converts phys block list into exported ExtentLeaf slice.
func ParseExtentNode ¶
func ParseExtentNode(f ReaderWriterAt, fsOffset int64, sb *Superblock, buf []byte, inodeNum uint32, inodeRaw []byte) ([]ExtentLeaf, error)
ParseExtentNode exposes parseExtentNode.
type FS ¶
type FS = ext4FS
FS is a public alias for the concrete ext4 filesystem type. Used by downstream packages (apple-vz/grub) that need to refer to the concrete type for method receivers. The Ext4FS alias (same target) is gated behind `//go:build test` for test-only helpers; FS is always available so production code can hold a typed pointer.
type FormatConfig ¶
type FormatConfig struct {
// UUID is the filesystem UUID. A random v4 UUID is generated when all bytes are zero.
UUID [16]byte
// Label is the volume label stored in the superblock (trimmed to 16 bytes).
Label string
}
FormatConfig holds optional parameters for Format. All fields are optional; sensible defaults are used when left at their zero value.
type FormatFile ¶
type FormatFile = formatFile
FormatFile is an alias to the internal formatFile interface used by Format.
type HookMemFile ¶
type HookMemFile struct {
// Exported hook fields are convenient for external tests.
ReadHook func(off int64, p []byte) error
WriteHook func(off int64, p []byte) error
// contains filtered or unexported fields
}
HookMemFile is a small in-memory reader/writer used by tests.
func CloneFSImage ¶
func CloneFSImage(t *testing.T, fs *Ext4FS) *HookMemFile
CloneFSImage reads the backing file for an open FS into a HookMemFile copy.
func NewHookMemFile ¶
func NewHookMemFile(buf []byte) *HookMemFile
NewHookMemFile returns a HookMemFile backed by the provided buffer. This is a convenience for external tests that need a HookMemFile with an initial backing store.
type Inode ¶
type Inode = inode
func LookupParent ¶
func LookupParent(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) (*Inode, string, error)
LookupParent exposes lookupParent for tests validating parent resolution.
func LookupPath ¶
func LookupPath(f ReaderWriterAt, fsOffset int64, sb *Superblock, path string) (*Inode, error)
LookupPath exposes lookupPath.
func NewTestInode ¶
Inode helpers and accessors for tests.
func ReadInode ¶
func ReadInode(f ReaderWriterAt, fsOffset int64, sb *Superblock, inodeNum uint32) (*Inode, error)
ReadInode exposes readInode.
type Journal ¶
type Journal struct {
// contains filtered or unexported fields
}
Journal represents an on-disk sidecar journal attached to a filesystem image. When enabled it persists transactions to the sidecar and can replay committed transactions at Open time.
func OpenJournal ¶
OpenJournal opens/creates a sidecar journal for the provided backing reader/writer. It returns a Journal that is enabled when a sidecar file can be created; otherwise it returns a disabled journal (no-op).
func (*Journal) Close ¶
Close cleanly shuts down the journal including sync workers and closes the underlying journal file. It also unregisters the journal.
Each Transaction.Commit applies its entries to the backing image synchronously before returning, so at Close all committed entries are already persisted on disk. Truncate the journal file so the next Open does not replay a growing log of already-applied transactions (which would otherwise turn ReplayOnOpen into an O(N) tax on every reopen).
func (*Journal) ReplayOnOpen ¶
ReplayOnOpen scans the sidecar journal for committed transactions and applies them to the backing image. Partial or uncommitted transactions are ignored.
func (*Journal) StartTx ¶
func (j *Journal) StartTx() (*Transaction, error)
StartTx creates a new transaction associated with the journal.
type ReaderWriterAt ¶
type ReaderWriterAt = readerWriterAt
Exported aliases to internal types so test packages can refer to them
type Superblock ¶
type Superblock = superblock
func CloneSuperblock ¶
func CloneSuperblock(sb *Superblock) *Superblock
CloneSuperblock returns a deep copy of a superblock.
func CloneSuperblockFromFS ¶
func CloneSuperblockFromFS(fs *Ext4FS) *Superblock
CloneSuperblockFromFS returns a copy of the open filesystem's superblock.
func NewTestSuperblock ¶
func NewTestSuperblock(inodesPerGroup, blocksPerGroup, numGroups uint32, blockSize uint32) *Superblock
NewTestSuperblock builds an in-memory superblock for tests.
func ReadSuperblock ¶
func ReadSuperblock(f ReaderWriterAt, fsOffset int64) (*Superblock, error)
Superblock helpers.
type Transaction ¶
type Transaction struct {
// contains filtered or unexported fields
}
Transaction collects metadata blocks to be journaled and committed.
func (*Transaction) Abort ¶
func (tx *Transaction) Abort() error
Abort cancels the transaction. For this implementation this is a no-op unless the transaction has been committed.
func (*Transaction) AddBlock ¶
func (tx *Transaction) AddBlock(blockNum uint64, data []byte) error
AddBlock appends a metadata block to the transaction. The data is copied. AddBlock adds or updates the entry for blockNum in the transaction. If an entry for blockNum already exists it is replaced so each block appears at most once in the journal record. Callers that want to build on a previous in-tx modification of the same block must first call GetBlock to retrieve the current in-tx state before overlaying their changes and calling AddBlock.
func (*Transaction) AddCommitCallback ¶
func (tx *Transaction) AddCommitCallback(cb func(uint64)) error
AddCommitCallback registers a callback to be invoked when this transaction is applied. The callback receives the transaction sequence number. It is an error to register callbacks after the transaction has been committed.
func (*Transaction) Commit ¶
func (tx *Transaction) Commit() error
Commit writes the transaction to the sidecar journal and then applies the blocks to the backing filesystem image (write-through). This provides a straightforward durability model and simplifies replay semantics.
func (*Transaction) GetBlock ¶
func (tx *Transaction) GetBlock(blockNum uint64) []byte
GetBlock returns the current in-transaction data for blockNum, or nil if the block has not been prepared into this transaction yet. The returned slice is a copy and safe to modify.
Source Files
¶
- alloc.go
- bgd.go
- blockdevice.go
- blockmap.go
- checksum.go
- commit_dispatch.go
- debug_log.go
- debug_seq_map.go
- delete.go
- dir.go
- exports.go
- ext4.go
- format.go
- fs.go
- fsck.go
- inline.go
- inode.go
- inode_table_locks.go
- ioctl.go
- journal.go
- label.go
- lock_flags.go
- locks.go
- metadata_locks.go
- mkdir.go
- owner.go
- partition.go
- rename.go
- resize.go
- rw_wrapper_noop.go
- superblock.go
- test_helpers.go
- test_wrappers.go
- trace_nontest.go
- trace_noop.go
- write.go