diff --git a/xfs/inode.go b/xfs/inode.go index 926d95b..af4da86 100644 --- a/xfs/inode.go +++ b/xfs/inode.go @@ -16,8 +16,6 @@ import ( var ( InodeSupportVersion = 3 - UnsupportedDir2BlockHeaderErr = xerrors.New("unsupported block") - XFS_DIR2_SPACE_SIZE = int64(1) << (32 + XFS_DIR2_DATA_ALIGN_LOG) XFS_DIR2_DATA_OFFSET = XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE XFS_DIR2_LEAF_OFFSET = XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE @@ -35,10 +33,11 @@ type Inode struct { // S_IFDIR directoryLocal *DirectoryLocal directoryExtents *DirectoryExtents + directoryBtree *Btree // S_IFREG regularExtent *RegularExtent - regularBtree *RegularBtree + regularBtree *Btree // S_IFLNK symlinkString *SymlinkString @@ -48,15 +47,15 @@ type RegularExtent struct { bmbtRecs []BmbtRec } -type RegularBtree struct { - bmbrBlock BmbrBlock - bmbtRecs []BmbtRec -} - type DirectoryExtents struct { bmbtRecs []BmbtRec } +type Btree struct { + bmbrBlock BmbrBlock + bmbtRecs []BmbtRec +} + type DirectoryLocal struct { dir2SfHdr Dir2SfHdr entries []Dir2SfEntry @@ -424,16 +423,11 @@ func (xfs *FileSystem) parseBmbrBlock(r io.Reader, inode Inode) (*BmbrBlock, err } func (xfs *FileSystem) inodeFormatBtree(r io.Reader, inode Inode) (Inode, error) { - if !inode.inodeCore.IsRegular() { - log.Logger.Warnf("not support XFS_DINODE_FMT_BTREE type: %+v", inode) - return Inode{}, xerrors.Errorf("invalid inode") - } - bmbrBlock, err := xfs.parseBmbrBlock(r, inode) if err != nil { return Inode{}, xerrors.Errorf("parse bmbr block error: %w", err) } - btree := &RegularBtree{ + btree := &Btree{ bmbrBlock: *bmbrBlock, } if bmbrBlock.Level == 1 { @@ -455,7 +449,13 @@ func (xfs *FileSystem) inodeFormatBtree(r io.Reader, inode Inode) (Inode, error) return Inode{}, xerrors.Errorf("parse multi level btree error: %w", err) } } - inode.regularBtree = btree + if inode.inodeCore.IsRegular() { + inode.regularBtree = btree + } + if inode.inodeCore.IsDir() { + inode.directoryBtree = btree + } + return inode, nil } diff --git a/xfs/xfs.go b/xfs/xfs.go index a1ac9c9..f2ecde0 100644 --- a/xfs/xfs.go +++ b/xfs/xfs.go @@ -11,7 +11,6 @@ import ( "golang.org/x/xerrors" - "github.com/masahiro331/go-xfs-filesystem/log" "github.com/masahiro331/go-xfs-filesystem/xfs/utils" ) @@ -342,6 +341,21 @@ func (xfs *FileSystem) listFileInfo(ino uint64) ([]FileInfo, error) { return fileInfos, nil } +func (xfs *FileSystem) parseTree(bmbtRecs []BmbtRec) ([]Entry, error) { + var entries []Entry + for _, b := range bmbtRecs { + p := b.Unpack() + blockEntries, err := xfs.parseDir2Block(p) + if err != nil { + return nil, xerrors.Errorf("failed to parse dir2 block: %w", err) + } + for _, entry := range blockEntries { + entries = append(entries, entry) + } + } + return entries, nil +} + func (xfs *FileSystem) listEntries(ino uint64) ([]Entry, error) { inode, err := xfs.ParseInode(ino) if err != nil { @@ -361,22 +375,19 @@ func (xfs *FileSystem) listEntries(ino uint64) ([]Entry, error) { if len(inode.directoryExtents.bmbtRecs) == 0 { return nil, xerrors.New("directory extents tree bmbtRecs is empty error") } - - for _, b := range inode.directoryExtents.bmbtRecs { - p := b.Unpack() - blockEntries, err := xfs.parseDir2Block(p) - if err != nil { - log.Logger.Warn(err) - } - - if len(blockEntries) == 0 { - continue - } - - for _, entry := range blockEntries { - entries = append(entries, entry) - } + entries, err = xfs.parseTree(inode.directoryExtents.bmbtRecs) + if err != nil { + return nil, xerrors.Errorf("failed to parse extents tree: %w", err) + } + } else if inode.directoryBtree != nil { + if len(inode.directoryBtree.bmbtRecs) == 0 { + return nil, xerrors.New("directory extents btree bmbtRecs is empty error") } + entries, err = xfs.parseTree(inode.directoryBtree.bmbtRecs) + if err != nil { + return nil, xerrors.Errorf("failed to parse btree: %w", err) + } + } else { return nil, xerrors.New("not found entries") }