go-ext4: github.com/dsoprea/go-ext4 Index | Examples | Files | Directories

package ext4

import "github.com/dsoprea/go-ext4"

Index

Examples

Package Files

block_group_descriptor.go block_group_descriptor_list.go directory.go directory_browser.go directory_walk.go extent.go inode.go inode_reader.go superblock.go testing_common.go

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,
    }
)

type BlockGroupDescriptor Uses

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

func NewBlockGroupDescriptorWithReader Uses

func NewBlockGroupDescriptorWithReader(r io.Reader, sb *Superblock) (bgd *BlockGroupDescriptor, err error)

func (*BlockGroupDescriptor) Data Uses

func (bgd *BlockGroupDescriptor) Data() *BlockGroupDescriptorData

func (*BlockGroupDescriptor) Dump Uses

func (bgd *BlockGroupDescriptor) Dump()

func (*BlockGroupDescriptor) InodeBitmapBlock Uses

func (bgd *BlockGroupDescriptor) InodeBitmapBlock() uint64

func (*BlockGroupDescriptor) InodeTableBlock Uses

func (bgd *BlockGroupDescriptor) InodeTableBlock() uint64

InodeTableBlock returns the absolute block number of the inode-table.

func (*BlockGroupDescriptor) IsBitmapNotInitialized Uses

func (bgd *BlockGroupDescriptor) IsBitmapNotInitialized() bool

func (*BlockGroupDescriptor) IsInodeTableAndBitmapNotInitialized Uses

func (bgd *BlockGroupDescriptor) IsInodeTableAndBitmapNotInitialized() bool

func (*BlockGroupDescriptor) IsInodeTableZeroed Uses

func (bgd *BlockGroupDescriptor) IsInodeTableZeroed() bool

func (*BlockGroupDescriptor) Superblock Uses

func (bgd *BlockGroupDescriptor) Superblock() *Superblock

type BlockGroupDescriptorData Uses

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 Uses

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

func NewBlockGroupDescriptorListWithReadSeeker Uses

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 Uses

func (bgdl *BlockGroupDescriptorList) GetWithAbsoluteInode(n int) (bgd *BlockGroupDescriptor, err error)

type DirectoryBrowser Uses

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

DirectoryBrowser provides high-level directory navigation.

func NewDirectoryBrowser Uses

func NewDirectoryBrowser(rs io.ReadSeeker, inode *Inode) *DirectoryBrowser

func (*DirectoryBrowser) Next Uses

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 Uses

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

DirectoryEntry wraps the raw directory entry and provides higher-level functionality.

func (*DirectoryEntry) Data Uses

func (de *DirectoryEntry) Data() *Ext4DirEntry2

func (*DirectoryEntry) IsBlockDevice Uses

func (de *DirectoryEntry) IsBlockDevice() bool

func (*DirectoryEntry) IsCharacterDevice Uses

func (de *DirectoryEntry) IsCharacterDevice() bool

func (*DirectoryEntry) IsDirectory Uses

func (de *DirectoryEntry) IsDirectory() bool

func (*DirectoryEntry) IsFifo Uses

func (de *DirectoryEntry) IsFifo() bool

func (*DirectoryEntry) IsRegular Uses

func (de *DirectoryEntry) IsRegular() bool

func (*DirectoryEntry) IsSocket Uses

func (de *DirectoryEntry) IsSocket() bool
func (de *DirectoryEntry) IsSymbolicLink() bool

func (*DirectoryEntry) IsUnknownType Uses

func (de *DirectoryEntry) IsUnknownType() bool

func (*DirectoryEntry) Name Uses

func (de *DirectoryEntry) Name() string

func (*DirectoryEntry) String Uses

func (de *DirectoryEntry) String() string

func (*DirectoryEntry) TypeName Uses

func (de *DirectoryEntry) TypeName() string

type DirectoryWalk Uses

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

DirectoryWalk provides full directory-structure recursion.

func NewDirectoryWalk Uses

func NewDirectoryWalk(rs io.ReadSeeker, bgd *BlockGroupDescriptor, rootInodeNumber int) (dw *DirectoryWalk, err error)

func (*DirectoryWalk) Next Uses

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.

Code:

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 Uses

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 Uses

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 Uses

func (eh *ExtentHeaderNode) String() string

type ExtentIndexNode Uses

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 Uses

func (ein *ExtentIndexNode) LeafPhysicalBlock() uint64

func (*ExtentIndexNode) String Uses

func (ein *ExtentIndexNode) String() string

type ExtentLeafNode Uses

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 Uses

func (eln *ExtentLeafNode) StartPhysicalBlock() uint64

func (*ExtentLeafNode) String Uses

func (eln *ExtentLeafNode) String() string

type ExtentNavigator Uses

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

func NewExtentNavigatorWithReadSeeker Uses

func NewExtentNavigatorWithReadSeeker(rs io.ReadSeeker, inode *Inode) *ExtentNavigator

func (*ExtentNavigator) Read Uses

func (en *ExtentNavigator) Read(offset uint64) (data []byte, err error)

Read returns the inode data from the given offset to the end of the logical block that it's found in.

"logical", meaning that (0) refers to the first block of this inode's data.

Code:

f, inode, err := GetTestInode(TestFileInodeNumber)
log.PanicIf(err)

defer f.Close()

en := NewExtentNavigatorWithReadSeeker(f, inode)

inodeSize := inode.Size()
actualBytes := make([]byte, inodeSize)

for offset := uint64(0); offset < inodeSize; {
    data, err := en.Read(offset)
    log.PanicIf(err)

    copy(actualBytes[offset:], data)
    offset += uint64(len(data))
}

// Take the first part, strip some nonprintable characters from the front,
// and normalize the newlines so that this example tests properly.
firstPart := string(actualBytes[3:100])
firstPart = strings.Replace(firstPart, "\r\n", "\n", -1)

fmt.Println(firstPart)

Output:

The Project Gutenberg EBook of The Jungle, by Upton Sinclair

This eBook is for the use of anyo

type ExtentTail Uses

type ExtentTail struct {
    EbChecksum uint32
}

type Inode Uses

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

func GetInode Uses

func GetInode(filesystemPath string, inodeNumber int) (f *os.File, inode *Inode, err error)

func GetTestInode Uses

func GetTestInode(inodeNumber int) (f *os.File, inode *Inode, err error)

GetTestInode returns a test inode struct and `os.File` for the file. It's the responsibility of the caller to close it.

func NewInodeWithReadSeeker Uses

func NewInodeWithReadSeeker(bgd *BlockGroupDescriptor, rs io.ReadSeeker, absoluteInodeNumber int) (inode *Inode, err error)

func (*Inode) AccessTime Uses

func (inode *Inode) AccessTime() time.Time

func (*Inode) BlockGroupDescriptor Uses

func (inode *Inode) BlockGroupDescriptor() (bgd *BlockGroupDescriptor)

func (*Inode) Data Uses

func (inode *Inode) Data() *InodeData

func (*Inode) DeletionTime Uses

func (inode *Inode) DeletionTime() time.Time

func (*Inode) Dump Uses

func (inode *Inode) Dump()

func (*Inode) DumpFlags Uses

func (inode *Inode) DumpFlags(includeFalses bool)

func (*Inode) FileCreationTime Uses

func (inode *Inode) FileCreationTime() time.Time

func (*Inode) Flag Uses

func (inode *Inode) Flag(flag int) bool

func (*Inode) InodeChangeTime Uses

func (inode *Inode) InodeChangeTime() time.Time

func (*Inode) ModificationTime Uses

func (inode *Inode) ModificationTime() time.Time

func (*Inode) Size Uses

func (inode *Inode) Size() uint64

func (*Inode) String Uses

func (inode *Inode) String() string

type InodeData Uses

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 Uses

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

InodeReader fulfills the `io.Reader` interface to read arbitrary amounts of data.

func NewInodeReader Uses

func NewInodeReader(en *ExtentNavigator) *InodeReader

func (*InodeReader) Offset Uses

func (ir *InodeReader) Offset() uint64

func (*InodeReader) Read Uses

func (ir *InodeReader) Read(p []byte) (n int, err error)

Read fills the given slice with data and returns an `io.EOF` error with (0) bytes when done. (`n`) may be less then `len(p)`.

func (*InodeReader) Skip Uses

func (ir *InodeReader) Skip(n uint64) (skipped uint64, err error)

Skip simulates a read but just discards the data.

type Superblock Uses

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

func NewSuperblockWithReader Uses

func NewSuperblockWithReader(rs io.ReadSeeker) (sb *Superblock, err error)

Code:

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 Uses

func (sb *Superblock) BlockCount() uint64

func (*Superblock) BlockGroupCount Uses

func (sb *Superblock) BlockGroupCount() (blockGroups uint64)

func (*Superblock) BlockGroupInodeNumberWithAbsoluteInodeNumber Uses

func (sb *Superblock) BlockGroupInodeNumberWithAbsoluteInodeNumber(absoluteInodeNumber int) int

func (*Superblock) BlockGroupNumberWithAbsoluteInodeNumber Uses

func (sb *Superblock) BlockGroupNumberWithAbsoluteInodeNumber(absoluteInodeNumber int) int

func (*Superblock) BlockSize Uses

func (sb *Superblock) BlockSize() uint32

func (*Superblock) Data Uses

func (sb *Superblock) Data() *SuperblockData

func (*Superblock) Dump Uses

func (sb *Superblock) Dump()

func (*Superblock) DumpFeatures Uses

func (sb *Superblock) DumpFeatures(includeFalses bool)

func (*Superblock) HasCompatibleFeature Uses

func (sb *Superblock) HasCompatibleFeature(mask uint32) bool

func (*Superblock) HasExtended Uses

func (sb *Superblock) HasExtended() bool

func (*Superblock) HasIncompatibleFeature Uses

func (sb *Superblock) HasIncompatibleFeature(mask uint32) bool

func (*Superblock) HasReadonlyCompatibleFeature Uses

func (sb *Superblock) HasReadonlyCompatibleFeature(mask uint32) bool

func (*Superblock) Is64Bit Uses

func (sb *Superblock) Is64Bit() bool

func (*Superblock) LastCheckTime Uses

func (sb *Superblock) LastCheckTime() time.Time

func (*Superblock) MountTime Uses

func (sb *Superblock) MountTime() time.Time

func (*Superblock) ReadPhysicalBlock Uses

func (sb *Superblock) ReadPhysicalBlock(absoluteBlockNumber uint64, length uint64) (data []byte, err error)

Code:

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 Uses

func (sb *Superblock) VolumeName() string

func (*Superblock) WriteTime Uses

func (sb *Superblock) WriteTime() time.Time

type SuperblockData Uses

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

Directories

PathSynopsis
jbd2

Package ext4 imports 13 packages (graph) and is imported by 1 packages. Updated 2018-10-02. Refresh now. Tools for package owners.