Skip to content

Commit

Permalink
fix(xfs): support directory btree extents
Browse files Browse the repository at this point in the history
  • Loading branch information
masahiro331 committed Jun 7, 2023
1 parent 679b545 commit db911cc
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 31 deletions.
30 changes: 15 additions & 15 deletions xfs/inode.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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
}

Expand Down
43 changes: 27 additions & 16 deletions xfs/xfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

"golang.org/x/xerrors"

"github.com/masahiro331/go-xfs-filesystem/log"
"github.com/masahiro331/go-xfs-filesystem/xfs/utils"
)

Expand Down Expand Up @@ -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 {
Expand All @@ -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")
}
Expand Down

0 comments on commit db911cc

Please sign in to comment.