diff options
Diffstat (limited to 'lib/btrfs')
-rw-r--r-- | lib/btrfs/Makefile | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_extent.go | 10 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_freespacebitmap.go | 10 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/item_inoderef.go | 12 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/items.go | 18 | ||||
-rw-r--r-- | lib/btrfs/btrfsitem/items_gen.go | 48 | ||||
-rw-r--r-- | lib/btrfs/btrfstree/ops.go | 2 | ||||
-rw-r--r-- | lib/btrfs/btrfstree/root.go | 4 | ||||
-rw-r--r-- | lib/btrfs/csums.go | 4 | ||||
-rw-r--r-- | lib/btrfs/io2_lv.go | 4 | ||||
-rw-r--r-- | lib/btrfs/io3_btree.go | 4 | ||||
-rw-r--r-- | lib/btrfs/io4_fs.go | 52 |
12 files changed, 88 insertions, 82 deletions
diff --git a/lib/btrfs/Makefile b/lib/btrfs/Makefile index cbcaf9e..00c22e7 100644 --- a/lib/btrfs/Makefile +++ b/lib/btrfs/Makefile @@ -35,7 +35,7 @@ btrfsitem/items_gen.go: btrfsitem/items.txt $(MAKEFILE_LIST) echo 'var untypedObjID2gotype = map[btrfsprim.ObjID]reflect.Type{'; \ sed -En 's|UNTYPED=0:(.*) (.*)|btrfsprim.\1: reflect.TypeOf(\2{}),|p' $<; \ echo '}'; \ - sed -En 's,(.*)=(.*) (.+),\3,p' $< | LC_COLLATE=C sort -u | sed 's,.*,func (&) isItem() {},'; \ + sed -En 's,(.*)=(.*) (.+),\3,p' $< | LC_COLLATE=C sort -u | sed 's,.*,func (*&) isItem() {},'; \ } | gofmt >$@ files += btrfsitem/items_gen.go diff --git a/lib/btrfs/btrfsitem/item_extent.go b/lib/btrfs/btrfsitem/item_extent.go index 66aae1d..72371a9 100644 --- a/lib/btrfs/btrfsitem/item_extent.go +++ b/lib/btrfs/btrfsitem/item_extent.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> // // SPDX-License-Identifier: GPL-2.0-or-later @@ -114,8 +114,8 @@ func (o *ExtentInlineRef) UnmarshalBinary(dat []byte) (int, error) { return n, err } case EXTENT_DATA_REF_KEY: - var dref ExtentDataRef - _n, err := binstruct.Unmarshal(dat[n:], &dref) + dref := new(ExtentDataRef) + _n, err := binstruct.Unmarshal(dat[n:], dref) n += _n o.Body = dref if err != nil { @@ -127,8 +127,8 @@ func (o *ExtentInlineRef) UnmarshalBinary(dat []byte) (int, error) { if err != nil { return n, err } - var sref SharedDataRef - _n, err = binstruct.Unmarshal(dat[n:], &sref) + sref := new(SharedDataRef) + _n, err = binstruct.Unmarshal(dat[n:], sref) n += _n o.Body = sref if err != nil { diff --git a/lib/btrfs/btrfsitem/item_freespacebitmap.go b/lib/btrfs/btrfsitem/item_freespacebitmap.go index ad46204..742d126 100644 --- a/lib/btrfs/btrfsitem/item_freespacebitmap.go +++ b/lib/btrfs/btrfsitem/item_freespacebitmap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> // // SPDX-License-Identifier: GPL-2.0-or-later @@ -6,13 +6,15 @@ package btrfsitem // key.objectid = object ID of the FreeSpaceInfo (logical_addr) // key.offset = offset of the FreeSpaceInfo (size) -type FreeSpaceBitmap []byte // FREE_SPACE_BITMAP=200 +type FreeSpaceBitmap struct { // FREE_SPACE_BITMAP=200 + Bitmap []byte +} func (o *FreeSpaceBitmap) UnmarshalBinary(dat []byte) (int, error) { - *o = dat + o.Bitmap = dat return len(dat), nil } func (o FreeSpaceBitmap) MarshalBinary() ([]byte, error) { - return []byte(o), nil + return o.Bitmap, nil } diff --git a/lib/btrfs/btrfsitem/item_inoderef.go b/lib/btrfs/btrfsitem/item_inoderef.go index 083f19e..c90fe44 100644 --- a/lib/btrfs/btrfsitem/item_inoderef.go +++ b/lib/btrfs/btrfsitem/item_inoderef.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> // // SPDX-License-Identifier: GPL-2.0-or-later @@ -16,10 +16,12 @@ import ( // // Might have multiple entries if the same file has multiple hardlinks // in the same directory. -type InodeRefs []InodeRef // INODE_REF=12 +type InodeRefs struct { // INODE_REF=12 + Refs []InodeRef +} func (o *InodeRefs) UnmarshalBinary(dat []byte) (int, error) { - *o = nil + o.Refs = nil n := 0 for n < len(dat) { var ref InodeRef @@ -28,14 +30,14 @@ func (o *InodeRefs) UnmarshalBinary(dat []byte) (int, error) { if err != nil { return n, err } - *o = append(*o, ref) + o.Refs = append(o.Refs, ref) } return n, nil } func (o InodeRefs) MarshalBinary() ([]byte, error) { var dat []byte - for _, ref := range o { + for _, ref := range o.Refs { _dat, err := binstruct.Marshal(ref) dat = append(dat, _dat...) if err != nil { diff --git a/lib/btrfs/btrfsitem/items.go b/lib/btrfs/btrfsitem/items.go index 67f96fa..9964e2d 100644 --- a/lib/btrfs/btrfsitem/items.go +++ b/lib/btrfs/btrfsitem/items.go @@ -25,7 +25,7 @@ type Error struct { Err error } -func (Error) isItem() {} +func (*Error) isItem() {} func (o Error) MarshalBinary() ([]byte, error) { return o.Dat, nil @@ -43,7 +43,7 @@ func UnmarshalItem(key btrfsprim.Key, csumType btrfssum.CSumType, dat []byte) It var ok bool gotyp, ok = untypedObjID2gotype[key.ObjectID] if !ok { - return Error{ + return &Error{ Dat: dat, Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v, ObjectID:%v}, dat): unknown object ID for untyped item", key.ItemType, key.ObjectID), @@ -53,31 +53,31 @@ func UnmarshalItem(key btrfsprim.Key, csumType btrfssum.CSumType, dat []byte) It var ok bool gotyp, ok = keytype2gotype[key.ItemType] if !ok { - return Error{ + return &Error{ Dat: dat, Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): unknown item type", key.ItemType), } } } - retPtr := reflect.New(gotyp) - if csums, ok := retPtr.Interface().(*ExtentCSum); ok { + ptr := reflect.New(gotyp) + if csums, ok := ptr.Interface().(*ExtentCSum); ok { csums.ChecksumSize = csumType.Size() csums.Addr = btrfsvol.LogicalAddr(key.Offset) } - n, err := binstruct.Unmarshal(dat, retPtr.Interface()) + n, err := binstruct.Unmarshal(dat, ptr.Interface()) if err != nil { - return Error{ + return &Error{ Dat: dat, Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): %w", key.ItemType, err), } } if n < len(dat) { - return Error{ + return &Error{ Dat: dat, Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): left over data: got %v bytes but only consumed %v", key.ItemType, len(dat), n), } } //nolint:forcetypeassert // items_gen.go has all types in keytype2gotype implement the Item interface. - return retPtr.Elem().Interface().(Item) + return ptr.Interface().(Item) } diff --git a/lib/btrfs/btrfsitem/items_gen.go b/lib/btrfs/btrfsitem/items_gen.go index 9daef81..21c6795 100644 --- a/lib/btrfs/btrfsitem/items_gen.go +++ b/lib/btrfs/btrfsitem/items_gen.go @@ -80,27 +80,27 @@ var untypedObjID2gotype = map[btrfsprim.ObjID]reflect.Type{ btrfsprim.FREE_SPACE_OBJECTID: reflect.TypeOf(FreeSpaceHeader{}), } -func (BlockGroup) isItem() {} -func (Chunk) isItem() {} -func (Dev) isItem() {} -func (DevExtent) isItem() {} -func (DevStats) isItem() {} -func (DirEntry) isItem() {} -func (Empty) isItem() {} -func (Extent) isItem() {} -func (ExtentCSum) isItem() {} -func (ExtentDataRef) isItem() {} -func (FileExtent) isItem() {} -func (FreeSpaceBitmap) isItem() {} -func (FreeSpaceHeader) isItem() {} -func (FreeSpaceInfo) isItem() {} -func (Inode) isItem() {} -func (InodeRefs) isItem() {} -func (Metadata) isItem() {} -func (QGroupInfo) isItem() {} -func (QGroupLimit) isItem() {} -func (QGroupStatus) isItem() {} -func (Root) isItem() {} -func (RootRef) isItem() {} -func (SharedDataRef) isItem() {} -func (UUIDMap) isItem() {} +func (*BlockGroup) isItem() {} +func (*Chunk) isItem() {} +func (*Dev) isItem() {} +func (*DevExtent) isItem() {} +func (*DevStats) isItem() {} +func (*DirEntry) isItem() {} +func (*Empty) isItem() {} +func (*Extent) isItem() {} +func (*ExtentCSum) isItem() {} +func (*ExtentDataRef) isItem() {} +func (*FileExtent) isItem() {} +func (*FreeSpaceBitmap) isItem() {} +func (*FreeSpaceHeader) isItem() {} +func (*FreeSpaceInfo) isItem() {} +func (*Inode) isItem() {} +func (*InodeRefs) isItem() {} +func (*Metadata) isItem() {} +func (*QGroupInfo) isItem() {} +func (*QGroupLimit) isItem() {} +func (*QGroupStatus) isItem() {} +func (*Root) isItem() {} +func (*RootRef) isItem() {} +func (*SharedDataRef) isItem() {} +func (*UUIDMap) isItem() {} diff --git a/lib/btrfs/btrfstree/ops.go b/lib/btrfs/btrfstree/ops.go index cdacef9..bda4ac8 100644 --- a/lib/btrfs/btrfstree/ops.go +++ b/lib/btrfs/btrfstree/ops.go @@ -207,7 +207,7 @@ func (fs TreeOperatorImpl) treeWalk(ctx context.Context, path TreePath, errHandl ToKey: item.Key, ToMaxKey: item.Key, }) - if errBody, isErr := item.Body.(btrfsitem.Error); isErr { + if errBody, isErr := item.Body.(*btrfsitem.Error); isErr { if cbs.BadItem == nil { errHandle(&TreeError{Path: itemPath, Err: errBody.Err}) } else { diff --git a/lib/btrfs/btrfstree/root.go b/lib/btrfs/btrfstree/root.go index 319904b..ace2b49 100644 --- a/lib/btrfs/btrfstree/root.go +++ b/lib/btrfs/btrfstree/root.go @@ -72,14 +72,14 @@ func LookupTreeRoot(fs TreeOperator, sb Superblock, treeID btrfsprim.ObjID) (*Tr return nil, err } switch rootItemBody := rootItem.Body.(type) { - case btrfsitem.Root: + case *btrfsitem.Root: return &TreeRoot{ TreeID: treeID, RootNode: rootItemBody.ByteNr, Level: rootItemBody.Level, Generation: rootItemBody.Generation, }, nil - case btrfsitem.Error: + case *btrfsitem.Error: return nil, fmt.Errorf("malformed ROOT_ITEM for tree %v: %w", treeID, rootItemBody.Err) default: panic(fmt.Errorf("should not happen: ROOT_ITEM has unexpected item type: %T", rootItemBody)) diff --git a/lib/btrfs/csums.go b/lib/btrfs/csums.go index a32f090..2bfa588 100644 --- a/lib/btrfs/csums.go +++ b/lib/btrfs/csums.go @@ -60,9 +60,9 @@ func LookupCSum(fs btrfstree.TreeOperator, alg btrfssum.CSumType, laddr btrfsvol return btrfssum.SumRun[btrfsvol.LogicalAddr]{}, fmt.Errorf("item type is %v, not EXTENT_CSUM", item.Key.ItemType) } switch body := item.Body.(type) { - case btrfsitem.ExtentCSum: + case *btrfsitem.ExtentCSum: return body.SumRun, nil - case btrfsitem.Error: + case *btrfsitem.Error: return btrfssum.SumRun[btrfsvol.LogicalAddr]{}, body.Err default: panic(fmt.Errorf("should not happen: EXTENT_CSUM has unexpected item type: %T", body)) diff --git a/lib/btrfs/io2_lv.go b/lib/btrfs/io2_lv.go index ac7ea70..856ac20 100644 --- a/lib/btrfs/io2_lv.go +++ b/lib/btrfs/io2_lv.go @@ -173,13 +173,13 @@ func (fs *FS) initDev(ctx context.Context, sb btrfstree.Superblock) error { return nil } switch itemBody := item.Body.(type) { - case btrfsitem.Chunk: + case *btrfsitem.Chunk: for _, mapping := range itemBody.Mappings(item.Key) { if err := fs.LV.AddMapping(mapping); err != nil { return err } } - case btrfsitem.Error: + case *btrfsitem.Error: // do nothing default: // This is a panic because the item decoder should not emit CHUNK_ITEM items as diff --git a/lib/btrfs/io3_btree.go b/lib/btrfs/io3_btree.go index 8ec4b41..18df98e 100644 --- a/lib/btrfs/io3_btree.go +++ b/lib/btrfs/io3_btree.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com> +// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> // // SPDX-License-Identifier: GPL-2.0-or-later @@ -43,7 +43,7 @@ func (fs *FS) populateTreeUUIDs(ctx context.Context) { }, btrfstree.TreeWalkHandler{ Item: func(_ btrfstree.TreePath, item btrfstree.Item) error { - itemBody, ok := item.Body.(btrfsitem.Root) + itemBody, ok := item.Body.(*btrfsitem.Root) if !ok { return nil } diff --git a/lib/btrfs/io4_fs.go b/lib/btrfs/io4_fs.go index adc0928..c21cafc 100644 --- a/lib/btrfs/io4_fs.go +++ b/lib/btrfs/io4_fs.go @@ -88,9 +88,9 @@ func (sv *Subvolume) init() { sv.rootErr = err } else { switch rootBody := root.Body.(type) { - case btrfsitem.Root: - sv.rootVal = rootBody - case btrfsitem.Error: + case *btrfsitem.Root: + sv.rootVal = *rootBody + case *btrfsitem.Error: sv.rootErr = fmt.Errorf("FS_TREE ROOT_ITEM has malformed body: %w", rootBody.Err) default: panic(fmt.Errorf("should not happen: ROOT_ITEM has unexpected item type: %T", rootBody)) @@ -126,9 +126,10 @@ func (sv *Subvolume) LoadBareInode(inode btrfsprim.ObjID) (*BareInode, error) { } switch itemBody := item.Body.(type) { - case btrfsitem.Inode: - val.InodeItem = &itemBody - case btrfsitem.Error: + case *btrfsitem.Inode: + bodyCopy := *itemBody + val.InodeItem = &bodyCopy + case *btrfsitem.Error: val.Errs = append(val.Errs, fmt.Errorf("malformed inode: %w", itemBody.Err)) default: panic(fmt.Errorf("should not happen: INODE_ITEM has unexpected item type: %T", itemBody)) @@ -164,24 +165,25 @@ func (sv *Subvolume) LoadFullInode(inode btrfsprim.ObjID) (*FullInode, error) { switch item.Key.ItemType { case btrfsitem.INODE_ITEM_KEY: switch itemBody := item.Body.(type) { - case btrfsitem.Inode: + case *btrfsitem.Inode: if val.InodeItem != nil { if !reflect.DeepEqual(itemBody, *val.InodeItem) { val.Errs = append(val.Errs, fmt.Errorf("multiple inodes")) } continue } - val.InodeItem = &itemBody - case btrfsitem.Error: + bodyCopy := *itemBody + val.InodeItem = &bodyCopy + case *btrfsitem.Error: val.Errs = append(val.Errs, fmt.Errorf("malformed INODE_ITEM: %w", itemBody.Err)) default: panic(fmt.Errorf("should not happen: INODE_ITEM has unexpected item type: %T", itemBody)) } case btrfsitem.XATTR_ITEM_KEY: switch itemBody := item.Body.(type) { - case btrfsitem.DirEntry: + case *btrfsitem.DirEntry: val.XAttrs[string(itemBody.Name)] = string(itemBody.Data) - case btrfsitem.Error: + case *btrfsitem.Error: val.Errs = append(val.Errs, fmt.Errorf("malformed XATTR_ITEM: %w", itemBody.Err)) default: panic(fmt.Errorf("should not happen: XATTR_ITEM has unexpected item type: %T", itemBody)) @@ -225,15 +227,15 @@ func (dir *Dir) populate() { switch item.Key.ItemType { case btrfsitem.INODE_REF_KEY: switch body := item.Body.(type) { - case btrfsitem.InodeRefs: - if len(body) != 1 { + case *btrfsitem.InodeRefs: + if len(body.Refs) != 1 { dir.Errs = append(dir.Errs, fmt.Errorf("INODE_REF item with %d entries on a directory", - len(body))) + len(body.Refs))) continue } ref := InodeRef{ Inode: btrfsprim.ObjID(item.Key.Offset), - InodeRef: body[0], + InodeRef: body.Refs[0], } if dir.DotDot != nil { if !reflect.DeepEqual(ref, *dir.DotDot) { @@ -242,14 +244,14 @@ func (dir *Dir) populate() { continue } dir.DotDot = &ref - case btrfsitem.Error: + case *btrfsitem.Error: dir.Errs = append(dir.Errs, fmt.Errorf("malformed INODE_REF: %w", body.Err)) default: panic(fmt.Errorf("should not happen: INODE_REF has unexpected item type: %T", body)) } case btrfsitem.DIR_ITEM_KEY: switch entry := item.Body.(type) { - case btrfsitem.DirEntry: + case *btrfsitem.DirEntry: namehash := btrfsitem.NameHash(entry.Name) if namehash != item.Key.Offset { dir.Errs = append(dir.Errs, fmt.Errorf("direntry crc32c mismatch: key=%#x crc32c(%q)=%#x", @@ -262,8 +264,8 @@ func (dir *Dir) populate() { } continue } - dir.ChildrenByName[string(entry.Name)] = entry - case btrfsitem.Error: + dir.ChildrenByName[string(entry.Name)] = *entry + case *btrfsitem.Error: dir.Errs = append(dir.Errs, fmt.Errorf("malformed DIR_ITEM: %w", entry.Err)) default: panic(fmt.Errorf("should not happen: DIR_ITEM has unexpected item type: %T", entry)) @@ -271,15 +273,15 @@ func (dir *Dir) populate() { case btrfsitem.DIR_INDEX_KEY: index := item.Key.Offset switch entry := item.Body.(type) { - case btrfsitem.DirEntry: + case *btrfsitem.DirEntry: if other, exists := dir.ChildrenByIndex[index]; exists { if !reflect.DeepEqual(entry, other) { dir.Errs = append(dir.Errs, fmt.Errorf("multiple instances of direntry index %v", index)) } continue } - dir.ChildrenByIndex[index] = entry - case btrfsitem.Error: + dir.ChildrenByIndex[index] = *entry + case *btrfsitem.Error: dir.Errs = append(dir.Errs, fmt.Errorf("malformed DIR_INDEX: %w", entry.Err)) default: panic(fmt.Errorf("should not happen: DIR_INDEX has unexpected item type: %T", entry)) @@ -361,12 +363,12 @@ func (file *File) populate() { // TODO case btrfsitem.EXTENT_DATA_KEY: switch itemBody := item.Body.(type) { - case btrfsitem.FileExtent: + case *btrfsitem.FileExtent: file.Extents = append(file.Extents, FileExtent{ OffsetWithinFile: int64(item.Key.Offset), - FileExtent: itemBody, + FileExtent: *itemBody, }) - case btrfsitem.Error: + case *btrfsitem.Error: file.Errs = append(file.Errs, fmt.Errorf("malformed EXTENT_DATA: %w", itemBody.Err)) default: panic(fmt.Errorf("should not happen: EXTENT_DATA has unexpected item type: %T", itemBody)) |