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 (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 )
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 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
Output:
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) */ }