Documentation
¶
Index ¶
- Constants
- Variables
- type BlockGroupDescriptor
- func (bgd *BlockGroupDescriptor) Data() *BlockGroupDescriptorData
- func (bgd *BlockGroupDescriptor) Dump()
- func (bgd *BlockGroupDescriptor) InodeBitmapBlock() uint64
- func (bgd *BlockGroupDescriptor) InodeTableBlock() uint64
- func (bgd *BlockGroupDescriptor) IsBitmapNotInitialized() bool
- func (bgd *BlockGroupDescriptor) IsInodeTableAndBitmapNotInitialized() bool
- func (bgd *BlockGroupDescriptor) IsInodeTableZeroed() bool
- func (bgd *BlockGroupDescriptor) Superblock() *Superblock
- type BlockGroupDescriptorData
- type BlockGroupDescriptorList
- type DirectoryBrowser
- type DirectoryEntry
- func (de *DirectoryEntry) Data() *Ext4DirEntry2
- func (de *DirectoryEntry) IsBlockDevice() bool
- func (de *DirectoryEntry) IsCharacterDevice() bool
- func (de *DirectoryEntry) IsDirectory() bool
- func (de *DirectoryEntry) IsFifo() bool
- func (de *DirectoryEntry) IsRegular() bool
- func (de *DirectoryEntry) IsSocket() bool
- func (de *DirectoryEntry) IsSymbolicLink() bool
- func (de *DirectoryEntry) IsUnknownType() bool
- func (de *DirectoryEntry) Name() string
- func (de *DirectoryEntry) String() string
- func (de *DirectoryEntry) TypeName() string
- type DirectoryWalk
- type Ext4DirEntry2
- type ExtentHeaderNode
- type ExtentIndexNode
- type ExtentLeafNode
- type ExtentNavigator
- type ExtentTail
- type Inode
- func GetInode(filesystemPath string, inodeNumber int) (f *os.File, inode *Inode, err error)
- func GetTestInode(inodeNumber int) (f *os.File, inode *Inode, err error)
- func GetTestInodeWithSym(inodeNumber int) (f *os.File, inode *Inode, err error)
- func NewInodeWithReadSeeker(bgd *BlockGroupDescriptor, rs io.ReadSeeker, absoluteInodeNumber int) (inode *Inode, err error)
- func (inode *Inode) AccessTime() time.Time
- func (inode *Inode) BlockGroupDescriptor() (bgd *BlockGroupDescriptor)
- func (inode *Inode) Data() *InodeData
- func (inode *Inode) DeletionTime() time.Time
- func (inode *Inode) Dump()
- func (inode *Inode) DumpFlags(includeFalses bool)
- func (inode *Inode) FileCreationTime() time.Time
- func (inode *Inode) Flag(flag int) bool
- func (inode *Inode) InodeChangeTime() time.Time
- func (inode *Inode) ModificationTime() time.Time
- func (inode *Inode) Size() uint64
- func (inode *Inode) String() string
- type InodeData
- type InodeReader
- type Superblock
- func (sb *Superblock) BlockCount() uint64
- func (sb *Superblock) BlockGroupCount() (blockGroups uint64)
- func (sb *Superblock) BlockGroupInodeNumberWithAbsoluteInodeNumber(absoluteInodeNumber int) int
- func (sb *Superblock) BlockGroupNumberWithAbsoluteInodeNumber(absoluteInodeNumber int) int
- func (sb *Superblock) BlockSize() uint32
- func (sb *Superblock) Data() *SuperblockData
- func (sb *Superblock) Dump()
- func (sb *Superblock) DumpFeatures(includeFalses bool)
- func (sb *Superblock) HasCompatibleFeature(mask uint32) bool
- func (sb *Superblock) HasExtended() bool
- func (sb *Superblock) HasIncompatibleFeature(mask uint32) bool
- func (sb *Superblock) HasReadonlyCompatibleFeature(mask uint32) bool
- func (sb *Superblock) Is64Bit() bool
- func (sb *Superblock) LastCheckTime() time.Time
- func (sb *Superblock) MountTime() time.Time
- func (sb *Superblock) ReadPhysicalBlock(absoluteBlockNumber uint64, length uint64) (data []byte, err error)
- func (sb *Superblock) VolumeName() string
- func (sb *Superblock) WriteTime() time.Time
- type SuperblockData
Examples ¶
Constants ¶
const ( BgdFlagInodeTableAndBitmapNotInitialized = uint16(0x1) BgdFlagBitmapNotInitialized = uint16(0x2) BgdFlagInodeTableZeroed = uint16(0x4) )
const ( Ext4FilenameMaxLen = 255 Ext4DirectoryEntrySize = Ext4FilenameMaxLen + 8 )
const ( FileTypeUnknown = uint8(0x0) FileTypeRegular = uint8(0x1) FileTypeDirectory = uint8(0x2) FileTypeCharacterDevice = uint8(0x3) FileTypeBlockDevice = uint8(0x4) FileTypeFifo = uint8(0x5) FileTypeSocket = uint8(0x6) FileTypeSymbolicLink = uint8(0x7) )
File types.
const ( ExtentMagic = uint16(0xf30A) ExtentHeaderSize = 12 ExtentIndexAndLeafSize = 12 )
const ( InodeDefectiveBlocks = 1 InodeRootDirectory = 2 InodeUserQuota = 3 InodeGroupQuota = 4 InodeBootLoader = 5 InodeUndeleteDirectory = 6 InodeReservedGroupDescriptors = 7 InodeJournal = 8 InodeExclude = 9 InodeReplica = 10 )
Reserved inodes.
const ( Ext4NdirBlocks = 12 Ext4IndBlock = Ext4NdirBlocks Ext4DindBlock = (Ext4IndBlock + 1) Ext4TindBlock = (Ext4DindBlock + 1) Ext4NBlocks = (Ext4TindBlock + 1) )
const ( InodeFlagSecrm = 0x1 InodeFlagUnrm = 0x2 InodeFlagCompr = 0x4 InodeFlagSync = 0x8 InodeFlagImmutable = 0x10 InodeFlagAppend = 0x20 InodeFlagNodump = 0x40 InodeFlagNoatime = 0x80 InodeFlagDirty = 0x100 InodeFlagComprblk = 0x200 InodeFlagNocompr = 0x400 InodeFlagEncrypt = 0x800 InodeFlagIndex = 0x1000 InodeFlagImagic = 0x2000 InodeFlagJournalData = 0x4000 InodeFlagNotail = 0x8000 InodeFlagDirsync = 0x10000 InodeFlagTopdir = 0x20000 InodeFlagHugeFile = 0x40000 InodeFlagExtents = 0x80000 InodeFlagEaInode = 0x200000 InodeFlagEofblocks = 0x400000 InodeFlagSnapfile = 0x01000000 InodeFlagSnapfileDeleted = 0x04000000 InodeFlagSnapfileShrunk = 0x08000000 InodeFlagInlineData = 0x10000000 InodeFlagProjinherit = 0x20000000 )
const ( Ext4Magic = 0xef53 SuperblockSize = 1024 // The first superblock is after the bootloader code. Superblock0Offset = int64(1024) )
const ( SbStateCleanlyUnmounted = 0x0001 SbStateErrorsDetected = 0x0002 SbStateOrphansBeingRecovered = 0x0004 )
const ( SbErrorsContinue = 1 SbErrorsRemountReadonly = 2 SbErrorsPanic = 3 )
const ( SbOsLinux = 0 SbOsHurd = 1 SbOsMasix = 2 SbOsFreebsd = 3 SbOsLites = 4 )
const ( SbRevlevelGoodOldRev = 0 SbRevlevelDynamicRev = 1 )
const ( SbDefHashVersionLegacy = 0x0 SbDefHashVersionHalfMd4 = 0x1 SbDefHashVersionTea = 0x2 SbDefHashVersionLegacyUnsigned = 0x3 SbDefHashVersionHalfMd4Unsigned = 0x4 SbDefHashVersionTeaUnsigned = 0x5 )
const ( SbMountOptionDebug = uint32(0x001) SbMountOptionBsdGroups = uint32(0x002) SbMountOptionXattrUser = uint32(0x004) SbMountOptionAcl = uint32(0x008) SbMountOptionUid16 = uint32(0x010) SbMountOptionJmodeData = uint32(0x020) SbMountOptionJmodeOrdered = uint32(0x040) SbMountOptionJmodeWback = uint32(0x060) SbMountOptionNoBarrier = uint32(0x100) SbMountOptionBlockValidity = uint32(0x200) SbMountOptionDiscard = uint32(0x400) SbMountOptionNoDelAlloc = uint32(0x800) )
const ( SbFlagSignedDirectoryHash = uint32(0x1) SbFlagUnsignedDirectoryHash = uint32(0x2) SbFlagTestDevelopmentCode = uint32(0x4) )
const ( SbEncryptAlgoInvalid = uint8(0) SbEncryptAlgoAes256Xt = uint8(1) SbEncryptAlgoAes256Gcm = uint8(2) SbEncryptAlgoAes256Cbc = uint8(3) )
const ( // COMPAT_DIR_PREALLOC SbFeatureCompatDirPrealloc = uint32(0x0001) // COMPAT_IMAGIC_INODES SbFeatureCompatImagicInodes = uint32(0x0002) // COMPAT_HAS_JOURNAL SbFeatureCompatHasJournal = uint32(0x0004) // COMPAT_EXT_ATTR SbFeatureCompatExtAttr = uint32(0x0008) // COMPAT_RESIZE_INODE SbFeatureCompatResizeInode = uint32(0x0010) // COMPAT_DIR_INDEX SbFeatureCompatDirIndex = uint32(0x0020) // COMPAT_LAZY_BG SbFeatureCompatLazyBg = uint32(0x40) // COMPAT_EXCLUDE_INODE SbFeatureCompatExcludeInode = uint32(0x80) // COMPAT_EXCLUDE_BITMAP SbFeatureCompatExcludeBitmap = uint32(0x100) // COMPAT_SPARSE_SUPER2 SbFeatureCompatSparseSuperblockV2 = uint32(0x200) )
const ( // RO_COMPAT_SPARSE_SUPER SbFeatureRoCompatSparseSuper = uint32(0x1) // RO_COMPAT_LARGE_FILE SbFeatureRoCompatLargeFile = uint32(0x2) // RO_COMPAT_BTREE_DIR SbFeatureRoCompatBtreeDir = uint32(0x4) // RO_COMPAT_HUGE_FILE SbFeatureRoCompatHugeFile = uint32(0x8) // RO_COMPAT_GDT_CSUM SbFeatureRoCompatGdtCsum = uint32(0x10) // RO_COMPAT_DIR_NLINK SbFeatureRoCompatDirNlink = uint32(0x20) // RO_COMPAT_EXTRA_ISIZE SbFeatureRoCompatExtraIsize = uint32(0x40) // RO_COMPAT_HAS_SNAPSHOT SbFeatureRoCompatHasSnapshot = uint32(0x80) // RO_COMPAT_QUOTA SbFeatureRoCompatQuota = uint32(0x100) // RO_COMPAT_BIGALLOC SbFeatureRoCompatBigAlloc = uint32(0x200) // RO_COMPAT_METADATA_CSUM SbFeatureRoCompatMetadataCsum = uint32(0x400) // RO_COMPAT_REPLICA SbFeatureRoCompatReplica = uint32(0x800) // RO_COMPAT_READONLY SbFeatureRoCompatReadonly = uint32(0x1000) // RO_COMPAT_PROJECT SbFeatureRoCompatProject = uint32(0x2000) )
const ( // INCOMPAT_COMPRESSION SbFeatureIncompatCompression = uint32(0x0001) // INCOMPAT_FILETYPE SbFeatureIncompatFiletype = uint32(0x0002) // INCOMPAT_RECOVER SbFeatureIncompatRecover = uint32(0x0004) /* Needs recovery */ // INCOMPAT_JOURNAL_DEV SbFeatureIncompatJournalDev = uint32(0x0008) /* Journal device */ // INCOMPAT_META_BG SbFeatureIncompatMetaBg = uint32(0x0010) // INCOMPAT_EXTENTS SbFeatureIncompatExtents = uint32(0x0040) /* extents support */ // INCOMPAT_64BIT SbFeatureIncompat64bit = uint32(0x0080) // INCOMPAT_MMP SbFeatureIncompatMmp = uint32(0x0100) // INCOMPAT_FLEX_BG SbFeatureIncompatFlexBg = uint32(0x0200) // INCOMPAT_EA_INODE SbFeatureIncompatLargeExtendedAttributeValues = uint32(0x400) // INCOMPAT_DIRDATA SbFeatureIncompatDirData = uint32(0x1000) // INCOMPAT_CSUM_SEED SbFeatureIncompatCsumSeed = uint32(0x2000) // INCOMPAT_LARGEDIR SbFeatureIncompatLargeDir = uint32(0x4000) // INCOMPAT_INLINE_DATA SbFeatureIncompatInlineData = uint32(0x8000) // INCOMPAT_ENCRYPT SbFeatureIncompatEncrypt = uint32(0x10000) )
const ( TestDirectoryInodeNumber = 2 TestFileInodeNumber = 12 TestSymlinkInodeNumber = 13 )
const (
BlockGroupDescriptorSize = 64
)
const (
Ext4ExtentChecksumTailSize = 4
)
Variables ¶
var ( // SbFeatureCompatNames is an ordered list of names. SbFeatureCompatNames = []string{ "DirIndex", "DirPrealloc", "ExcludeBitmap", "ExcludeInode", "ExtAttr", "HasJournal", "ImagicInodes", "LazyBg", "ResizeInode", "SparseSuper2", } SbFeatureCompatLookup = map[string]uint32{ "DirPrealloc": SbFeatureCompatDirPrealloc, "ImagicInodes": SbFeatureCompatImagicInodes, "HasJournal": SbFeatureCompatHasJournal, "ExtAttr": SbFeatureCompatExtAttr, "ResizeInode": SbFeatureCompatResizeInode, "DirIndex": SbFeatureCompatDirIndex, "LazyBg": SbFeatureCompatLazyBg, "ExcludeInode": SbFeatureCompatExcludeInode, "ExcludeBitmap": SbFeatureCompatExcludeBitmap, "SparseSuper2": SbFeatureCompatSparseSuperblockV2, } )
var ( // SbFeatureRoCompatNames is an ordered list of names. SbFeatureRoCompatNames = []string{ "BigAlloc", "BtreeDir", "DirNlink", "ExtraIsize", "GdtCsum", "HasSnapshot", "HugeFile", "LargeFile", "MetadataCsum", "Project", "Quota", "Readonly", "Replica", "SparseSuper", } SbFeatureRoCompatLookup = map[string]uint32{ "SparseSuper": SbFeatureRoCompatSparseSuper, "LargeFile": SbFeatureRoCompatLargeFile, "BtreeDir": SbFeatureRoCompatBtreeDir, "HugeFile": SbFeatureRoCompatHugeFile, "GdtCsum": SbFeatureRoCompatGdtCsum, "DirNlink": SbFeatureRoCompatDirNlink, "ExtraIsize": SbFeatureRoCompatExtraIsize, "HasSnapshot": SbFeatureRoCompatHasSnapshot, "Quota": SbFeatureRoCompatQuota, "BigAlloc": SbFeatureRoCompatBigAlloc, "MetadataCsum": SbFeatureRoCompatMetadataCsum, "Replica": SbFeatureRoCompatReplica, "Readonly": SbFeatureRoCompatReadonly, "Project": SbFeatureRoCompatProject, } )
var ( // SbFeatureIncompatNames is an ordered list of names. SbFeatureIncompatNames = []string{ "64bit", "Compression", "CsumSeed", "DirData", "Encrypt", "Extents", "Filetype", "FlexBg", "InlineData", "JournalDev", "LargeDir", "LargeExtendedAttributeValues", "MetaBg", "Mmp", "Recover", } SbFeatureIncompatLookup = map[string]uint32{ "Compression": SbFeatureIncompatCompression, "Filetype": SbFeatureIncompatFiletype, "Recover": SbFeatureIncompatRecover, "JournalDev": SbFeatureIncompatJournalDev, "MetaBg": SbFeatureIncompatMetaBg, "Extents": SbFeatureIncompatExtents, "64bit": SbFeatureIncompat64bit, "Mmp": SbFeatureIncompatMmp, "FlexBg": SbFeatureIncompatFlexBg, "LargeExtendedAttributeValues": SbFeatureIncompatLargeExtendedAttributeValues, "DirData": SbFeatureIncompatDirData, "CsumSeed": SbFeatureIncompatCsumSeed, "LargeDir": SbFeatureIncompatLargeDir, "InlineData": SbFeatureIncompatInlineData, "Encrypt": SbFeatureIncompatEncrypt, } )
var (
ErrNotExt4 = errors.New("not ext4")
)
var ( FileTypeLookup = map[uint8]string{ FileTypeUnknown: "unknown", FileTypeRegular: "regular", FileTypeDirectory: "directory", FileTypeCharacterDevice: "character device", FileTypeBlockDevice: "block device", FileTypeFifo: "fifo", FileTypeSocket: "socket", FileTypeSymbolicLink: "symbolic link", } )
var ( InodeFlagLookup = map[string]int{ "Secrm": InodeFlagSecrm, "Unrm": InodeFlagUnrm, "Compr": InodeFlagCompr, "Sync": InodeFlagSync, "Immutable": InodeFlagImmutable, "Append": InodeFlagAppend, "Nodump": InodeFlagNodump, "Noatime": InodeFlagNoatime, "Dirty": InodeFlagDirty, "Comprblk": InodeFlagComprblk, "Nocompr": InodeFlagNocompr, "Encrypt": InodeFlagEncrypt, "Index": InodeFlagIndex, "Imagic": InodeFlagImagic, "JournalData": InodeFlagJournalData, "Notail": InodeFlagNotail, "Dirsync": InodeFlagDirsync, "Topdir": InodeFlagTopdir, "HugeFile": InodeFlagHugeFile, "Extents": InodeFlagExtents, "EaInode": InodeFlagEaInode, "Eofblocks": InodeFlagEofblocks, "Snapfile": InodeFlagSnapfile, "SnapfileDeleted": InodeFlagSnapfileDeleted, "SnapfileShrunk": InodeFlagSnapfileShrunk, "InlineData": InodeFlagInlineData, "Projinherit": InodeFlagProjinherit, } )
Functions ¶
This section is empty.
Types ¶
type BlockGroupDescriptor ¶
type BlockGroupDescriptor struct {
// contains filtered or unexported fields
}
func NewBlockGroupDescriptorWithReader ¶
func NewBlockGroupDescriptorWithReader(r io.Reader, sb *Superblock) (bgd *BlockGroupDescriptor, err error)
func (*BlockGroupDescriptor) Data ¶
func (bgd *BlockGroupDescriptor) Data() *BlockGroupDescriptorData
func (*BlockGroupDescriptor) Dump ¶
func (bgd *BlockGroupDescriptor) Dump()
func (*BlockGroupDescriptor) InodeBitmapBlock ¶
func (bgd *BlockGroupDescriptor) InodeBitmapBlock() uint64
func (*BlockGroupDescriptor) InodeTableBlock ¶
func (bgd *BlockGroupDescriptor) InodeTableBlock() uint64
InodeTableBlock returns the absolute block number of the inode-table.
func (*BlockGroupDescriptor) IsBitmapNotInitialized ¶
func (bgd *BlockGroupDescriptor) IsBitmapNotInitialized() bool
func (*BlockGroupDescriptor) IsInodeTableAndBitmapNotInitialized ¶
func (bgd *BlockGroupDescriptor) IsInodeTableAndBitmapNotInitialized() bool
func (*BlockGroupDescriptor) IsInodeTableZeroed ¶
func (bgd *BlockGroupDescriptor) IsInodeTableZeroed() bool
func (*BlockGroupDescriptor) Superblock ¶
func (bgd *BlockGroupDescriptor) Superblock() *Superblock
type BlockGroupDescriptorData ¶
type BlockGroupDescriptorData struct {
BgBlockBitmapLo uint32 /* Blocks bitmap block */
BgInodeBitmapLo uint32 /* Inodes bitmap block */
BgInodeTableLo uint32 /* Inodes table block */
BgFreeBlocksCountLo uint16 /* Free blocks count */
BgFreeInodesCountLo uint16 /* Free inodes count */
BgUsedDirsCountLo uint16 /* Directories count */
BgFlags uint16 /* EXT4_BG_flags (INODE_UNINIT, etc) */
BgExcludeBitmapLo uint32 /* Lower 32-bits of location of snapshot exclusion bitmap. */
BgBlockBitmapCsumLo uint16 /* Lower 16-bits of the block bitmap checksum. */
BgInodeBitmapCsumLo uint16 /* Lower 16-bits of the inode bitmap checksum. */
BgItableUnusedLo uint16 /* Unused inodes count */
BgChecksum uint16 /* crc16(sb_uuid+group+desc) */
BgBlockBitmapHi uint32 /* Blocks bitmap block MSB */
BgInodeBitmapHi uint32 /* Inodes bitmap block MSB */
BgInodeTableHi uint32 /* Inodes table block MSB */
BgFreeBlocksCountHi uint16 /* Free blocks count MSB */
BgFreeInodesCountHi uint16 /* Free inodes count MSB */
BgUsedDirsCountHi uint16 /* Directories count MSB */
BgItableUnusedHi uint16 /* Unused inodes count MSB */
BgExcludeBitmapHi uint32 /* Upper 32-bits of location of snapshot exclusion bitmap. */
BgBlockBitmapCsumHi uint16 /* Upper 16-bits of the block bitmap checksum. */
BgInodeBitmapCsumHi uint16 /* Upper 16-bits of the inode bitmap checksum. */
BgReserved2 uint32 /* Padding to 64 bytes. */
}
type BlockGroupDescriptorList ¶
type BlockGroupDescriptorList struct {
// contains filtered or unexported fields
}
func NewBlockGroupDescriptorListWithReadSeeker ¶
func NewBlockGroupDescriptorListWithReadSeeker(rs io.ReadSeeker, sb *Superblock) (bgdl *BlockGroupDescriptorList, err error)
NewBlockGroupDescriptorListWithReadSeeker returns a `BlockGroupDescriptorsList`, which has all block-group-descriptors in a big slice. Filesystems with the flex_bg capability flag (most) will group all of the BGD data together right at the top.
func (*BlockGroupDescriptorList) GetWithAbsoluteInode ¶
func (bgdl *BlockGroupDescriptorList) GetWithAbsoluteInode(n int) (bgd *BlockGroupDescriptor, err error)
type DirectoryBrowser ¶
type DirectoryBrowser struct {
// contains filtered or unexported fields
}
DirectoryBrowser provides high-level directory navigation.
func NewDirectoryBrowser ¶
func NewDirectoryBrowser(rs io.ReadSeeker, inode *Inode) *DirectoryBrowser
func (*DirectoryBrowser) Next ¶
func (db *DirectoryBrowser) Next() (de *DirectoryEntry, err error)
Next parses the next directory entry from the underlying inode data reader. Returns `io.EOF` when done. This will also return the "." and ".." entries.
type DirectoryEntry ¶
type DirectoryEntry struct {
// contains filtered or unexported fields
}
DirectoryEntry wraps the raw directory entry and provides higher-level functionality.
func (*DirectoryEntry) Data ¶
func (de *DirectoryEntry) Data() *Ext4DirEntry2
func (*DirectoryEntry) IsBlockDevice ¶
func (de *DirectoryEntry) IsBlockDevice() bool
func (*DirectoryEntry) IsCharacterDevice ¶
func (de *DirectoryEntry) IsCharacterDevice() bool
func (*DirectoryEntry) IsDirectory ¶
func (de *DirectoryEntry) IsDirectory() bool
func (*DirectoryEntry) IsFifo ¶
func (de *DirectoryEntry) IsFifo() bool
func (*DirectoryEntry) IsRegular ¶
func (de *DirectoryEntry) IsRegular() bool
func (*DirectoryEntry) IsSocket ¶
func (de *DirectoryEntry) IsSocket() bool
func (*DirectoryEntry) IsSymbolicLink ¶
func (de *DirectoryEntry) IsSymbolicLink() bool
func (*DirectoryEntry) IsUnknownType ¶
func (de *DirectoryEntry) IsUnknownType() bool
func (*DirectoryEntry) Name ¶
func (de *DirectoryEntry) Name() string
func (*DirectoryEntry) String ¶
func (de *DirectoryEntry) String() string
func (*DirectoryEntry) TypeName ¶
func (de *DirectoryEntry) TypeName() string
type DirectoryWalk ¶
type DirectoryWalk struct {
// contains filtered or unexported fields
}
DirectoryWalk provides full directory-structure recursion.
func NewDirectoryWalk ¶
func NewDirectoryWalk(rs io.ReadSeeker, bgd *BlockGroupDescriptor, rootInodeNumber int) (dw *DirectoryWalk, err error)
func (*DirectoryWalk) Next ¶
func (dw *DirectoryWalk) Next() (fullPath string, de *DirectoryEntry, err error)
Next steps through the entire tree starting at the given root inode, one entry at a time. We guarantee that all adjacent entries will be processed adjacently. This will not return the "." and ".." entries.
Example ¶
inodeNumber := InodeRootDirectory
filepath := path.Join(assetsPath, "hierarchy_32.ext4")
f, err := os.Open(filepath)
log.PanicIf(err)
defer f.Close()
_, err = f.Seek(Superblock0Offset, io.SeekStart)
log.PanicIf(err)
sb, err := NewSuperblockWithReader(f)
log.PanicIf(err)
bgdl, err := NewBlockGroupDescriptorListWithReadSeeker(f, sb)
log.PanicIf(err)
bgd, err := bgdl.GetWithAbsoluteInode(inodeNumber)
log.PanicIf(err)
dw, err := NewDirectoryWalk(f, bgd, inodeNumber)
log.PanicIf(err)
allEntries := make([]string, 0)
for {
fullPath, de, err := dw.Next()
if err == io.EOF {
break
} else if err != nil {
log.Panic(err)
}
description := fmt.Sprintf("%s: %s", fullPath, de.String())
allEntries = append(allEntries, description)
}
sort.Strings(allEntries)
for _, entryDescription := range allEntries {
fmt.Println(entryDescription)
}
Output: directory1/fortune1: DirectoryEntry<NAME=[fortune1] INODE=(15) TYPE=[regular]-(1)> directory1/fortune2: DirectoryEntry<NAME=[fortune2] INODE=(14) TYPE=[regular]-(1)> directory1/fortune5: DirectoryEntry<NAME=[fortune5] INODE=(20) TYPE=[regular]-(1)> directory1/fortune6: DirectoryEntry<NAME=[fortune6] INODE=(21) TYPE=[regular]-(1)> directory1/subdirectory1/fortune3: DirectoryEntry<NAME=[fortune3] INODE=(17) TYPE=[regular]-(1)> directory1/subdirectory1/fortune4: DirectoryEntry<NAME=[fortune4] INODE=(18) TYPE=[regular]-(1)> directory1/subdirectory1: DirectoryEntry<NAME=[subdirectory1] INODE=(16) TYPE=[directory]-(2)> directory1/subdirectory2/fortune7: DirectoryEntry<NAME=[fortune7] INODE=(22) TYPE=[regular]-(1)> directory1/subdirectory2/fortune8: DirectoryEntry<NAME=[fortune8] INODE=(23) TYPE=[regular]-(1)> directory1/subdirectory2: DirectoryEntry<NAME=[subdirectory2] INODE=(19) TYPE=[directory]-(2)> directory1: DirectoryEntry<NAME=[directory1] INODE=(13) TYPE=[directory]-(2)> directory2/fortune10: DirectoryEntry<NAME=[fortune10] INODE=(26) TYPE=[regular]-(1)> directory2/fortune9: DirectoryEntry<NAME=[fortune9] INODE=(25) TYPE=[regular]-(1)> directory2: DirectoryEntry<NAME=[directory2] INODE=(24) TYPE=[directory]-(2)> lost+found: DirectoryEntry<NAME=[lost+found] INODE=(11) TYPE=[directory]-(2)> thejungle.txt: DirectoryEntry<NAME=[thejungle.txt] INODE=(12) TYPE=[regular]-(1)>
type Ext4DirEntry2 ¶
type Ext4DirEntry2 struct {
Inode uint32 // Number of the inode that this directory entry points to.
RecLen uint16 // Length of this directory entry.
NameLen uint8 // Length of the file name.
FileType uint8 // File type code, see ftype table below.
Name []byte // File name. Has a maximum size of Ext4FilenameMaxLen but actual length derived from `RecLen`.
}
Ext4DirEntry2 is one of potentially many sequential entries stored in a directory inode.
type ExtentHeaderNode ¶
type ExtentHeaderNode struct {
EhMagic uint16 /* probably will support different formats */
EhEntryCount uint16 /* number of valid entries */
EhMax uint16 /* capacity of store in entries */
EhDepth uint16 /* has tree real underlying blocks? */
EhGeneration uint32 /* generation of the tree */
}
func (*ExtentHeaderNode) String ¶
func (eh *ExtentHeaderNode) String() string
type ExtentIndexNode ¶
type ExtentIndexNode struct {
EiLogicalBlock uint32 /* index covers logical blocks from 'block' */
EiLeafPhysicalBlockLo uint32 /* pointer to the physical block of the next level. leaf or next index could be there */
EiLeafPhysicalBlockHi uint16 /* high 16 bits of physical block */
EiUnused uint16
}
func (*ExtentIndexNode) LeafPhysicalBlock ¶
func (ein *ExtentIndexNode) LeafPhysicalBlock() uint64
func (*ExtentIndexNode) String ¶
func (ein *ExtentIndexNode) String() string
type ExtentLeafNode ¶
type ExtentLeafNode struct {
EeFirstLogicalBlock uint32 /* first logical block extent covers */
EeLogicalBlockCount uint16 /* number of blocks covered by extent */
EeStartPhysicalBlockHi uint16 /* high 16 bits of physical block */
EeStartPhysicalBlockLo uint32 /* low 32 bits of physical block */
}
func (*ExtentLeafNode) StartPhysicalBlock ¶
func (eln *ExtentLeafNode) StartPhysicalBlock() uint64
func (*ExtentLeafNode) String ¶
func (eln *ExtentLeafNode) String() string
type ExtentNavigator ¶
type ExtentNavigator struct {
// contains filtered or unexported fields
}
func NewExtentNavigatorWithReadSeeker ¶
func NewExtentNavigatorWithReadSeeker(rs io.ReadSeeker, inode *Inode) *ExtentNavigator
type ExtentTail ¶
type ExtentTail struct {
EbChecksum uint32
}
type Inode ¶
type Inode struct {
// contains filtered or unexported fields
}
func GetTestInode ¶
GetTestInode returns a test inode struct and `os.File` for the file. It's the responsibility of the caller to close it.
func GetTestInodeWithSym ¶
func NewInodeWithReadSeeker ¶
func NewInodeWithReadSeeker(bgd *BlockGroupDescriptor, rs io.ReadSeeker, absoluteInodeNumber int) (inode *Inode, err error)
func (*Inode) AccessTime ¶
func (*Inode) BlockGroupDescriptor ¶
func (inode *Inode) BlockGroupDescriptor() (bgd *BlockGroupDescriptor)
func (*Inode) DeletionTime ¶
func (*Inode) FileCreationTime ¶
func (*Inode) InodeChangeTime ¶
func (*Inode) ModificationTime ¶
type InodeData ¶
type InodeData struct {
IMode uint16 /* File mode */
IUid uint16 /* Low 16 bits of Owner Uid */
ISizeLo uint32 /* Size in bytes */
IAtime uint32 /* Access time */
ICtime uint32 /* Inode Change time */
IMtime uint32 /* Modification time */
IDtime uint32 /* Deletion Time */
IGid uint16 /* Low 16 bits of Group Id */
ILinksCount uint16 /* Links count */
IBlocksLo uint32 /* Blocks count */
IFlags uint32 /* File flags */
// union {
// struct {
// __le32 l_i_version;
// } linux1;
// struct {
// __u32 h_i_translator;
// } hurd1;
// struct {
// __u32 m_i_reserved1;
// } masix1;
// } osd1; /* OS dependent 1 */
Osd1 [4]byte
/*
IBlock is a general buffer for our data, which can have various
interpretations. `Ext4NBlocks` comes from the kernel where it is a count in
terms of uint32's, which is then cast as a struct. However, it works better
for us as an array of bytes.
*/
IBlock [Ext4NBlocks * 4]byte
IGeneration uint32 /* File version (for NFS) */
IFileAclLo uint32 /* File ACL */
ISizeHigh uint32
IObsoFaddr uint32 /* Obsoleted fragment address */
// union {
// struct {
// __le16 l_i_blocks_high; /* were l_i_reserved1 */
// __le16 l_i_file_acl_high;
// __le16 l_i_uid_high; /* these 2 fields */
// __le16 l_i_gid_high; /* were reserved2[0] */
// __le16 l_i_checksum_lo;/* crc32c(uuid+inum+inode) LE */
// __le16 l_i_reserved;
// } linux2;
// struct {
// __le16 h_i_reserved1; Obsoleted fragment number/size which are removed in ext4
// __u16 h_i_mode_high;
// __u16 h_i_uid_high;
// __u16 h_i_gid_high;
// __u32 h_i_author;
// } hurd2;
// struct {
// __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
// __le16 m_i_file_acl_high;
// __u32 m_i_reserved2[2];
// } masix2;
// } osd2; /* OS dependent 2 */
Osd2 [12]byte
IExtraIsize uint16
IChecksumHi uint16 /* crc32c(uuid+inum+inode) BE */
ICtimeExtra uint32 /* extra Change time (nsec << 2 | epoch) */
IMtimeExtra uint32 /* extra Modification time(nsec << 2 | epoch) */
IAtimeExtra uint32 /* extra Access time (nsec << 2 | epoch) */
ICrtime uint32 /* File Creation time */
ICrtimeExtra uint32 /* extra FileCreationtime (nsec << 2 | epoch) */
IVersionHi uint32 /* high 32 bits for 64-bit version */
IProjid uint32 /* Project ID */
}
type InodeReader ¶
type InodeReader struct {
// contains filtered or unexported fields
}
InodeReader fulfills the `io.Reader` interface to read arbitrary amounts of data.
func NewInodeReader ¶
func NewInodeReader(en *ExtentNavigator) *InodeReader
func (*InodeReader) Offset ¶
func (ir *InodeReader) Offset() uint64
type Superblock ¶
type Superblock struct {
// contains filtered or unexported fields
}
func NewSuperblockWithReader ¶
func NewSuperblockWithReader(rs io.ReadSeeker) (sb *Superblock, err error)
Example ¶
filepath := path.Join(assetsPath, "tiny.ext4") f, err := os.Open(filepath) log.PanicIf(err) defer f.Close() // Skip over the boot-code at the front of the filesystem. _, err = f.Seek(Superblock0Offset, io.SeekStart) log.PanicIf(err) sb, err := NewSuperblockWithReader(f) log.PanicIf(err) fmt.Println(sb.VolumeName())
Output: tinyimage
func (*Superblock) BlockCount ¶
func (sb *Superblock) BlockCount() uint64
func (*Superblock) BlockGroupCount ¶
func (sb *Superblock) BlockGroupCount() (blockGroups uint64)
func (*Superblock) BlockGroupInodeNumberWithAbsoluteInodeNumber ¶
func (sb *Superblock) BlockGroupInodeNumberWithAbsoluteInodeNumber(absoluteInodeNumber int) int
func (*Superblock) BlockGroupNumberWithAbsoluteInodeNumber ¶
func (sb *Superblock) BlockGroupNumberWithAbsoluteInodeNumber(absoluteInodeNumber int) int
func (*Superblock) BlockSize ¶
func (sb *Superblock) BlockSize() uint32
func (*Superblock) Data ¶
func (sb *Superblock) Data() *SuperblockData
func (*Superblock) Dump ¶
func (sb *Superblock) Dump()
func (*Superblock) DumpFeatures ¶
func (sb *Superblock) DumpFeatures(includeFalses bool)
func (*Superblock) HasCompatibleFeature ¶
func (sb *Superblock) HasCompatibleFeature(mask uint32) bool
func (*Superblock) HasExtended ¶
func (sb *Superblock) HasExtended() bool
func (*Superblock) HasIncompatibleFeature ¶
func (sb *Superblock) HasIncompatibleFeature(mask uint32) bool
func (*Superblock) HasReadonlyCompatibleFeature ¶
func (sb *Superblock) HasReadonlyCompatibleFeature(mask uint32) bool
func (*Superblock) Is64Bit ¶
func (sb *Superblock) Is64Bit() bool
func (*Superblock) LastCheckTime ¶
func (sb *Superblock) LastCheckTime() time.Time
func (*Superblock) MountTime ¶
func (sb *Superblock) MountTime() time.Time
func (*Superblock) ReadPhysicalBlock ¶
func (sb *Superblock) ReadPhysicalBlock(absoluteBlockNumber uint64, length uint64) (data []byte, err error)
Example ¶
filepath := path.Join(assetsPath, "tiny.ext4") f, err := os.Open(filepath) log.PanicIf(err) defer f.Close() _, err = f.Seek(Superblock0Offset, io.SeekStart) log.PanicIf(err) sb, err := NewSuperblockWithReader(f) log.PanicIf(err) pBlock := uint64(sb.Data().SFirstDataBlock) data, err := sb.ReadPhysicalBlock(pBlock, uint64(SuperblockSize)) log.PanicIf(err) data = data
func (*Superblock) VolumeName ¶
func (sb *Superblock) VolumeName() string
func (*Superblock) WriteTime ¶
func (sb *Superblock) WriteTime() time.Time
type SuperblockData ¶
type SuperblockData struct {
// 0x00
SInodesCount uint32
SBlocksCountLo uint32
SRBlocksCountLo uint32
SFreeBlocksCountLo uint32
// 0x10
SFreeInodesCount uint32
SFirstDataBlock uint32
SLogBlockSize uint32
SLogClusterSize uint32
// 0x20
SBlocksPerGroup uint32
SClustersPerGroup uint32
SInodesPerGroup uint32
SMtime uint32
// 0x30
SWtime uint32
SMntCount uint16
SMaxMntCount uint16
SMagic uint16
SState uint16
SErrors uint16
SMinorRevLevel uint16
// 0x40
SLastcheck uint32
SCheckinterval uint32
SCreatorOs uint32
SRevLevel uint32
// 0x50
SDefResuid uint16
SDefResgid uint16
/*
* These fields are for EXT4_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/
SFirstIno uint32 /* First non-reserved inode */
SInodeSize uint16 /* size of inode structure */
SBlockGroupNr uint16 /* block group # of this superblock */
SFeatureCompat uint32 /* compatible feature set */
// 0x60
SFeatureIncompat uint32 /* incompatible feature set */
SFeatureRoCompat uint32 /* readonly-compatible feature set */
// 0x68
SUuid [16]uint8 /* 128-bit uuid for volume */
// 0x78
SVolumeName [16]byte /* volume name */
// 0x88
SLastMounted [64]byte /* directory where last mounted */
// 0xC8
SAlgorithmUsageBitmap uint32 /* For compression */
/*
* Performance hints. Directory preallocation should only
* happen if the EXT4_FEATURE_COMPAT_DIR_PREALLOC flag is on.
*/
SPreallocBlocks uint8 /* Nr of blocks to try to preallocate*/
SPreallocDirBlocks uint8 /* Nr to preallocate for dirs */
SReservedGdtBlocks uint16 /* Per group desc for online growth */
// 0xD0
/*
* Journaling support valid if EXT4_FEATURE_COMPAT_HAS_JOURNAL set.
*/
SJournalUuid [16]uint8 /* uuid of journal superblock */
// 0xE0
SJournalInum uint32 /* inode number of journal file */
SJournalDev uint32 /* device number of journal file */
SLastOrphan uint32 /* start of list of inodes to delete */
SHashSeed [4]uint32 /* HTREE hash seed */
SDefHashVersion uint8 /* Default hash version to use */
SJnlBackupType uint8
SDescSize uint16 /* Size of group descriptors, in bytes, if the 64bit incompat feature flag is set. */
// 0x100
SDefaultMountOpts uint32
SFirstMetaBg uint32 /* First metablock block group */
SMkfsTime uint32 /* When the filesystem was created */
SJnlBlocks [17]uint32 /* Backup of the journal inode */
// 0x150
SBlocksCountHi uint32 /* Blocks count */
SRBlocksCountHi uint32 /* Reserved blocks count */
SFreeBlocksCountHi uint32 /* Free blocks count */
SMinExtraIsize uint16 /* All inodes have at least # bytes */
SWantExtraIsize uint16 /* New inodes should reserve # bytes */
SFlags uint32 /* Miscellaneous flags */
SRaidStride uint16 /* RAID stride */
SMmpInterval uint16 /* # seconds to wait in MMP checking */
SMmpBlock uint64 /* Block for multi-mount protection */
SRaidStripeWidth uint32 /* blocks on all data disks (N*stride)*/
SLogGroupsPerFlex uint8 /* FLEX_BG group size */
SChecksumType uint8 /* metadata checksum algorithm used */
SEncryptionLevel uint8 /* versioning level for encryption */
SReservedPad uint8 /* Padding to next 32bits */
SKbytesWritten uint64 /* nr of lifetime kilobytes written */
SSnapshotInum uint32 /* Inode number of active snapshot */
SSnapshotId uint32 /* sequential ID of active snapshot */
SSnapshotRBlocksCount uint64 /* reserved blocks for active snapshot's future use */
SSnapshotList uint32 /* inode number of the head of the on-disk snapshot list */
SErrorCount uint32 /* number of fs errors */
SFirstErrorTime uint32 /* first time an error happened */
SFirstErrorIno uint32 /* inode involved in first error */
SFirstErrorBlock uint64 /* block involved of first error */
SFirstErrorFunc [32]uint8 /* function where the error happened */
SFirstErrorLine uint32 /* line number where error happened */
SLastErrorTime uint32 /* most recent time of an error */
SLastErrorIno uint32 /* inode involved in last error */
SLastErrorLine uint32 /* line number where error happened */
SLastErrorBlock uint64 /* block involved of last error */
SLastErrorFunc [32]uint8 /* function where the error happened */
SMountOpts [64]uint8
SUsrQuotaInum uint32 /* inode for tracking user quota */
SGrpQuotaInum uint32 /* inode for tracking group quota */
SOverheadClusters uint32 /* overhead blocks/clusters in fs */
SBackupBgs [2]uint32 /* groups with sparse_super2 SBs */
SEncryptAlgos [4]uint8 /* Encryption algorithms in use */
SEncryptPwSalt [16]uint8 /* Salt used for string2key algorithm */
SLpfIno uint32 /* Location of the lost+found inode */
SPrjQuotaInum uint32 /* inode for tracking project quota */
SChecksumSeed uint32 /* crc32c(uuid) if csum_seed set */
SWtimeHi uint8
SMtimeHi uint8
SMkfsTimeHi uint8
SLastcheckHi uint8
SFirstErrorTimeHi uint8
SLastErrorTimeHi uint8
SPad [2]uint8
SReserved [96]uint32 /* Padding to the end of the block */
SChecksum int32 /* crc32c(superblock) */
}