From 1faafcd3809fe5b452a1a742137ca2cb7336aad6 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 1 Jan 2023 17:39:11 -0700 Subject: lint: Turn on dupword --- lib/btrfs/btrfsitem/item_uuid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/btrfs/btrfsitem') diff --git a/lib/btrfs/btrfsitem/item_uuid.go b/lib/btrfs/btrfsitem/item_uuid.go index e1a6cf9..5f5f357 100644 --- a/lib/btrfs/btrfsitem/item_uuid.go +++ b/lib/btrfs/btrfsitem/item_uuid.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -12,7 +12,7 @@ import ( ) // The Key for this item is a UUID, and the item is a subvolume IDs -// that that UUID maps to. +// that UUID maps to. // // key.objectid = first half of UUID // key.offset = second half of UUID -- cgit v1.2.3-54-g00ecf From 493ec396fab32d9e8859e34ad497fdb0a910a33c Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 1 Jan 2023 17:49:11 -0700 Subject: lint: Turn on forcetypeassert --- .golangci.yml | 1 - lib/binstruct/size.go | 3 +- lib/btrfs/btrfsitem/items.go | 3 +- lib/btrfs/io2_lv.go | 18 ++++-- lib/btrfs/io4_fs.go | 129 ++++++++++++++++++++++++++++--------------- lib/containers/lru.go | 5 +- lib/containers/set.go | 7 ++- lib/containers/syncmap.go | 6 +- lib/textui/progress.go | 1 + 9 files changed, 116 insertions(+), 57 deletions(-) (limited to 'lib/btrfs/btrfsitem') diff --git a/.golangci.yml b/.golangci.yml index 7dd7f00..d5c6e53 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -27,7 +27,6 @@ linters: - cyclop - exhaustive - exhaustruct - - forcetypeassert - funlen - gci - gochecknoglobals diff --git a/lib/binstruct/size.go b/lib/binstruct/size.go index 365da85..52fa380 100644 --- a/lib/binstruct/size.go +++ b/lib/binstruct/size.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -30,6 +30,7 @@ var ( func staticSize(typ reflect.Type) (int, error) { if typ.Implements(staticSizerType) { + //nolint:forcetypeassert // Already did a type check via reflection. return reflect.New(typ).Elem().Interface().(StaticSizer).BinaryStaticSize(), nil } if typ.Implements(marshalerType) || typ.Implements(unmarshalerType) { diff --git a/lib/btrfs/btrfsitem/items.go b/lib/btrfs/btrfsitem/items.go index 29b3cb0..d300179 100644 --- a/lib/btrfs/btrfsitem/items.go +++ b/lib/btrfs/btrfsitem/items.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -79,5 +79,6 @@ func UnmarshalItem(key btrfsprim.Key, csumType btrfssum.CSumType, dat []byte) It key.ItemType, len(dat), n), } } + //nolint:forcetypeassert // items_gen.go has all types in keytype2gotype implement the Item interface. return retPtr.Elem().Interface().(Item) } diff --git a/lib/btrfs/io2_lv.go b/lib/btrfs/io2_lv.go index 5580285..3f82cd0 100644 --- a/lib/btrfs/io2_lv.go +++ b/lib/btrfs/io2_lv.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -171,10 +171,20 @@ func (fs *FS) initDev(ctx context.Context, sb btrfstree.Superblock) error { if item.Key.ItemType != btrfsitem.CHUNK_ITEM_KEY { return nil } - for _, mapping := range item.Body.(btrfsitem.Chunk).Mappings(item.Key) { - if err := fs.LV.AddMapping(mapping); err != nil { - return err + switch itemBody := item.Body.(type) { + case btrfsitem.Chunk: + for _, mapping := range itemBody.Mappings(item.Key) { + if err := fs.LV.AddMapping(mapping); err != nil { + return err + } } + case btrfsitem.Error: + // do nothing + default: + // This is a panic because the item decoder should not emit CHUNK_ITEM items as + // anything but btrfsitem.Chunk or btrfsitem.Error without this code also being + // updated. + panic(fmt.Errorf("should not happen: CHUNK_ITEM has unexpected item type: %T", itemBody)) } return nil }, diff --git a/lib/btrfs/io4_fs.go b/lib/btrfs/io4_fs.go index ea81bc2..d7c2770 100644 --- a/lib/btrfs/io4_fs.go +++ b/lib/btrfs/io4_fs.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -152,17 +152,29 @@ func (sv *Subvolume) LoadFullInode(inode btrfsprim.ObjID) (*FullInode, error) { for _, item := range items { switch item.Key.ItemType { case btrfsitem.INODE_ITEM_KEY: - itemBody := item.Body.(btrfsitem.Inode) - if val.InodeItem != nil { - if !reflect.DeepEqual(itemBody, *val.InodeItem) { - val.Errs = append(val.Errs, fmt.Errorf("multiple inodes")) + switch itemBody := item.Body.(type) { + case btrfsitem.Inode: + if val.InodeItem != nil { + if !reflect.DeepEqual(itemBody, *val.InodeItem) { + val.Errs = append(val.Errs, fmt.Errorf("multiple inodes")) + } + continue } - continue + val.InodeItem = &itemBody + 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)) } - val.InodeItem = &itemBody case btrfsitem.XATTR_ITEM_KEY: - itemBody := item.Body.(btrfsitem.DirEntry) - val.XAttrs[string(itemBody.Name)] = string(itemBody.Data) + switch itemBody := item.Body.(type) { + case btrfsitem.DirEntry: + val.XAttrs[string(itemBody.Name)] = string(itemBody.Data) + 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)) + } default: val.OtherItems = append(val.OtherItems, item) } @@ -200,48 +212,66 @@ func (ret *Dir) populate() { for _, item := range ret.OtherItems { switch item.Key.ItemType { case btrfsitem.INODE_REF_KEY: - body := item.Body.(btrfsitem.InodeRefs) - if len(body) != 1 { - ret.Errs = append(ret.Errs, fmt.Errorf("INODE_REF item with %d entries on a directory", - len(body))) - continue - } - ref := InodeRef{ - Inode: btrfsprim.ObjID(item.Key.Offset), - InodeRef: body[0], - } - if ret.DotDot != nil { - if !reflect.DeepEqual(ref, *ret.DotDot) { - ret.Errs = append(ret.Errs, fmt.Errorf("multiple INODE_REF items on a directory")) + switch body := item.Body.(type) { + case btrfsitem.InodeRefs: + if len(body) != 1 { + ret.Errs = append(ret.Errs, fmt.Errorf("INODE_REF item with %d entries on a directory", + len(body))) + continue + } + ref := InodeRef{ + Inode: btrfsprim.ObjID(item.Key.Offset), + InodeRef: body[0], } - continue + if ret.DotDot != nil { + if !reflect.DeepEqual(ref, *ret.DotDot) { + ret.Errs = append(ret.Errs, fmt.Errorf("multiple INODE_REF items on a directory")) + } + continue + } + ret.DotDot = &ref + case btrfsitem.Error: + ret.Errs = append(ret.Errs, fmt.Errorf("malformed INODE_REF: %w", body.Err)) + default: + panic(fmt.Errorf("should not happen: INODE_REF has unexpected item type: %T", body)) } - ret.DotDot = &ref case btrfsitem.DIR_ITEM_KEY: - entry := item.Body.(btrfsitem.DirEntry) - namehash := btrfsitem.NameHash(entry.Name) - if namehash != item.Key.Offset { - ret.Errs = append(ret.Errs, fmt.Errorf("direntry crc32c mismatch: key=%#x crc32c(%q)=%#x", - item.Key.Offset, entry.Name, namehash)) - continue - } - if other, exists := ret.ChildrenByName[string(entry.Name)]; exists { - if !reflect.DeepEqual(entry, other) { - ret.Errs = append(ret.Errs, fmt.Errorf("multiple instances of direntry name %q", entry.Name)) + switch entry := item.Body.(type) { + case btrfsitem.DirEntry: + namehash := btrfsitem.NameHash(entry.Name) + if namehash != item.Key.Offset { + ret.Errs = append(ret.Errs, fmt.Errorf("direntry crc32c mismatch: key=%#x crc32c(%q)=%#x", + item.Key.Offset, entry.Name, namehash)) + continue + } + if other, exists := ret.ChildrenByName[string(entry.Name)]; exists { + if !reflect.DeepEqual(entry, other) { + ret.Errs = append(ret.Errs, fmt.Errorf("multiple instances of direntry name %q", entry.Name)) + } + continue } - continue + ret.ChildrenByName[string(entry.Name)] = entry + case btrfsitem.Error: + ret.Errs = append(ret.Errs, fmt.Errorf("malformed DIR_ITEM: %w", entry.Err)) + default: + panic(fmt.Errorf("should not happen: DIR_ITEM has unexpected item type: %T", entry)) } - ret.ChildrenByName[string(entry.Name)] = entry case btrfsitem.DIR_INDEX_KEY: index := item.Key.Offset - entry := item.Body.(btrfsitem.DirEntry) - if other, exists := ret.ChildrenByIndex[index]; exists { - if !reflect.DeepEqual(entry, other) { - ret.Errs = append(ret.Errs, fmt.Errorf("multiple instances of direntry index %v", index)) + switch entry := item.Body.(type) { + case btrfsitem.DirEntry: + if other, exists := ret.ChildrenByIndex[index]; exists { + if !reflect.DeepEqual(entry, other) { + ret.Errs = append(ret.Errs, fmt.Errorf("multiple instances of direntry index %v", index)) + } + continue } - continue + ret.ChildrenByIndex[index] = entry + case btrfsitem.Error: + ret.Errs = append(ret.Errs, fmt.Errorf("malformed DIR_INDEX: %w", entry.Err)) + default: + panic(fmt.Errorf("should not happen: DIR_INDEX has unexpected item type: %T", entry)) } - ret.ChildrenByIndex[index] = entry default: panic(fmt.Errorf("TODO: handle item type %v", item.Key.ItemType)) } @@ -317,10 +347,17 @@ func (ret *File) populate() { case btrfsitem.INODE_REF_KEY: // TODO case btrfsitem.EXTENT_DATA_KEY: - ret.Extents = append(ret.Extents, FileExtent{ - OffsetWithinFile: int64(item.Key.Offset), - FileExtent: item.Body.(btrfsitem.FileExtent), - }) + switch itemBody := item.Body.(type) { + case btrfsitem.FileExtent: + ret.Extents = append(ret.Extents, FileExtent{ + OffsetWithinFile: int64(item.Key.Offset), + FileExtent: itemBody, + }) + case btrfsitem.Error: + ret.Errs = append(ret.Errs, fmt.Errorf("malformed EXTENT_DATA: %w", itemBody.Err)) + default: + panic(fmt.Errorf("should not happen: EXTENT_DATA has unexpected item type: %T", itemBody)) + } default: panic(fmt.Errorf("TODO: handle item type %v", item.Key.ItemType)) } diff --git a/lib/containers/lru.go b/lib/containers/lru.go index a235a12..12446b0 100644 --- a/lib/containers/lru.go +++ b/lib/containers/lru.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -44,6 +44,7 @@ func (c *LRUCache[K, V]) Get(key K) (value V, ok bool) { c.init() _value, ok := c.inner.Get(key) if ok { + //nolint:forcetypeassert // Typed wrapper around untyped lib. value = _value.(V) } return value, ok @@ -53,6 +54,7 @@ func (c *LRUCache[K, V]) Keys() []K { untyped := c.inner.Keys() typed := make([]K, len(untyped)) for i := range untyped { + //nolint:forcetypeassert // Typed wrapper around untyped lib. typed[i] = untyped[i].(K) } return typed @@ -65,6 +67,7 @@ func (c *LRUCache[K, V]) Peek(key K) (value V, ok bool) { c.init() _value, ok := c.inner.Peek(key) if ok { + //nolint:forcetypeassert // Typed wrapper around untyped lib. value = _value.(V) } return value, ok diff --git a/lib/containers/set.go b/lib/containers/set.go index 67ba7ac..4fc8aad 100644 --- a/lib/containers/set.go +++ b/lib/containers/set.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -22,7 +22,10 @@ var ( _ lowmemjson.Decodable = (*Set[int])(nil) ) -func cast[T any](x any) T { return x.(T) } +func cast[T any](x any) T { + //nolint:forcetypeassert // Only called within a type switch. + return x.(T) +} func (o Set[T]) EncodeJSON(w io.Writer) error { var less func(a, b T) bool diff --git a/lib/containers/syncmap.go b/lib/containers/syncmap.go index fb7f59b..4af678f 100644 --- a/lib/containers/syncmap.go +++ b/lib/containers/syncmap.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,6 +18,7 @@ func (m *SyncMap[K, V]) Delete(key K) { func (m *SyncMap[K, V]) Load(key K) (value V, ok bool) { _value, ok := m.inner.Load(key) if ok { + //nolint:forcetypeassert // Typed wrapper around untyped lib. value = _value.(V) } return value, ok @@ -25,17 +26,20 @@ func (m *SyncMap[K, V]) Load(key K) (value V, ok bool) { func (m *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { _value, ok := m.inner.LoadAndDelete(key) if ok { + //nolint:forcetypeassert // Typed wrapper around untyped lib. value = _value.(V) } return value, ok } func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { _actual, loaded := m.inner.LoadOrStore(key, value) + //nolint:forcetypeassert // Typed wrapper around untyped lib. actual = _actual.(V) return actual, loaded } func (m *SyncMap[K, V]) Range(f func(key K, value V) bool) { m.inner.Range(func(key, value any) bool { + //nolint:forcetypeassert // Typed wrapper around untyped lib. return f(key.(K), value.(V)) }) } diff --git a/lib/textui/progress.go b/lib/textui/progress.go index 56fda96..68d986f 100644 --- a/lib/textui/progress.go +++ b/lib/textui/progress.go @@ -56,6 +56,7 @@ func (p *Progress[T]) Done() { } func (p *Progress[T]) flush(force bool) { + //nolint:forcetypeassert // It wasn't worth it to me (yet?) to make a typed wrapper around atomic.Value. cur := p.cur.Load().(T) if !force && cur == p.oldStat { return -- cgit v1.2.3-54-g00ecf From a06a7fb2d5bbf1ca5659de06fc9e975666bdcf9f Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 1 Jan 2023 19:33:03 -0700 Subject: lint: Turn on gofumpt All edits to .go files are made by `tools/bin/golangci-lint run --fix ./...`, not by me as a human. --- .golangci.yml | 1 - lib/binstruct/binint/builtins.go | 12 ++++++++++++ lib/btrfs/btrfsitem/items.go | 1 - lib/btrfs/btrfssum/csum_test.go | 1 - lib/btrfs/btrfstree/ops.go | 2 +- lib/btrfs/btrfstree/types_node.go | 14 ++++++++++---- lib/btrfs/btrfsvol/lvm.go | 3 +++ lib/btrfs/io2_lv.go | 1 + lib/btrfs/io3_btree.go | 3 +++ lib/btrfs/io4_fs.go | 1 - lib/btrfsprogs/btrfsinspect/mount.go | 10 +++++++--- lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go | 2 ++ lib/containers/lru.go | 7 +++++++ lib/containers/syncmap.go | 5 +++++ lib/fmtutil/fmt.go | 3 ++- lib/textui/text.go | 4 +--- 16 files changed, 54 insertions(+), 16 deletions(-) (limited to 'lib/btrfs/btrfsitem') diff --git a/.golangci.yml b/.golangci.yml index 953b512..edb8499 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -35,7 +35,6 @@ linters: - godot - godox - goerr113 - - gofumpt - gomnd - gomoddirectives - ireturn diff --git a/lib/binstruct/binint/builtins.go b/lib/binstruct/binint/builtins.go index 01186bc..e4be2a6 100644 --- a/lib/binstruct/binint/builtins.go +++ b/lib/binstruct/binint/builtins.go @@ -34,6 +34,7 @@ func (x U16le) MarshalBinary() ([]byte, error) { binary.LittleEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } + func (x *U16le) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 2); err != nil { return 0, err @@ -50,6 +51,7 @@ func (x U32le) MarshalBinary() ([]byte, error) { binary.LittleEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } + func (x *U32le) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 4); err != nil { return 0, err @@ -66,6 +68,7 @@ func (x U64le) MarshalBinary() ([]byte, error) { binary.LittleEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } + func (x *U64le) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 8); err != nil { return 0, err @@ -84,6 +87,7 @@ func (x U16be) MarshalBinary() ([]byte, error) { binary.BigEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } + func (x *U16be) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 2); err != nil { return 0, err @@ -100,6 +104,7 @@ func (x U32be) MarshalBinary() ([]byte, error) { binary.BigEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } + func (x *U32be) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 4); err != nil { return 0, err @@ -116,6 +121,7 @@ func (x U64be) MarshalBinary() ([]byte, error) { binary.BigEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } + func (x *U64be) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 8); err != nil { return 0, err @@ -148,6 +154,7 @@ func (x I16le) MarshalBinary() ([]byte, error) { binary.LittleEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } + func (x *I16le) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 2); err != nil { return 0, err @@ -164,6 +171,7 @@ func (x I32le) MarshalBinary() ([]byte, error) { binary.LittleEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } + func (x *I32le) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 4); err != nil { return 0, err @@ -180,6 +188,7 @@ func (x I64le) MarshalBinary() ([]byte, error) { binary.LittleEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } + func (x *I64le) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 8); err != nil { return 0, err @@ -198,6 +207,7 @@ func (x I16be) MarshalBinary() ([]byte, error) { binary.BigEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } + func (x *I16be) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 2); err != nil { return 0, err @@ -214,6 +224,7 @@ func (x I32be) MarshalBinary() ([]byte, error) { binary.BigEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } + func (x *I32be) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 4); err != nil { return 0, err @@ -230,6 +241,7 @@ func (x I64be) MarshalBinary() ([]byte, error) { binary.BigEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } + func (x *I64be) UnmarshalBinary(dat []byte) (int, error) { if err := binutil.NeedNBytes(dat, 8); err != nil { return 0, err diff --git a/lib/btrfs/btrfsitem/items.go b/lib/btrfs/btrfsitem/items.go index d300179..67f96fa 100644 --- a/lib/btrfs/btrfsitem/items.go +++ b/lib/btrfs/btrfsitem/items.go @@ -70,7 +70,6 @@ func UnmarshalItem(key btrfsprim.Key, csumType btrfssum.CSumType, dat []byte) It Dat: dat, Err: fmt.Errorf("btrfsitem.UnmarshalItem({ItemType:%v}, dat): %w", key.ItemType, err), } - } if n < len(dat) { return Error{ diff --git a/lib/btrfs/btrfssum/csum_test.go b/lib/btrfs/btrfssum/csum_test.go index 5c17779..0a4aef6 100644 --- a/lib/btrfs/btrfssum/csum_test.go +++ b/lib/btrfs/btrfssum/csum_test.go @@ -22,7 +22,6 @@ func TestCSumFormat(t *testing.T) { } csum := btrfssum.CSum{0xbd, 0x7b, 0x41, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0} testcases := map[string]TestCase{ - "s": {InputSum: csum, InputFmt: "%s", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"}, "x": {InputSum: csum, InputFmt: "%x", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"}, "v": {InputSum: csum, InputFmt: "%v", Output: "bd7b41f400000000000000000000000000000000000000000000000000000000"}, diff --git a/lib/btrfs/btrfstree/ops.go b/lib/btrfs/btrfstree/ops.go index ddab630..537773a 100644 --- a/lib/btrfs/btrfstree/ops.go +++ b/lib/btrfs/btrfstree/ops.go @@ -504,7 +504,7 @@ func (fs TreeOperatorImpl) TreeSearchAll(treeID btrfsprim.ObjID, fn func(btrfspr } middleItem := middleNode.Data.BodyLeaf[middlePath.Node(-1).FromItemIdx] - var ret = []Item{middleItem} + ret := []Item{middleItem} var errs derror.MultiError for prevPath, prevNode := middlePath, middleNode; true; { prevPath, prevNode, err = fs.prev(prevPath, prevNode) diff --git a/lib/btrfs/btrfstree/types_node.go b/lib/btrfs/btrfstree/types_node.go index d2e91de..b709d34 100644 --- a/lib/btrfs/btrfstree/types_node.go +++ b/lib/btrfs/btrfstree/types_node.go @@ -26,11 +26,13 @@ type NodeFlags uint64 func (NodeFlags) BinaryStaticSize() int { return 7 } + func (f NodeFlags) MarshalBinary() ([]byte, error) { var bs [8]byte binary.LittleEndian.PutUint64(bs[:], uint64(f)) return bs[:7], nil } + func (f *NodeFlags) UnmarshalBinary(dat []byte) (int, error) { var bs [8]byte copy(bs[:7], dat[:7]) @@ -418,9 +420,11 @@ func (e *IOError) Unwrap() error { return e.Err } // NodeError are ErrNotANode and *IOError. func ReadNode[Addr ~int64](fs diskio.File[Addr], sb Superblock, addr Addr, exp NodeExpectations) (*diskio.Ref[Addr, Node], error) { if int(sb.NodeSize) < binstruct.StaticSize(NodeHeader{}) { - return nil, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, + return nil, &NodeError[Addr]{ + Op: "btrfstree.ReadNode", NodeAddr: addr, Err: fmt.Errorf("superblock.NodeSize=%v is too small to contain even a node header (%v bytes)", - sb.NodeSize, binstruct.StaticSize(NodeHeader{}))} + sb.NodeSize, binstruct.StaticSize(NodeHeader{})), + } } nodeBuf := make([]byte, sb.NodeSize) if _, err := fs.ReadAt(nodeBuf, addr); err != nil { @@ -456,9 +460,11 @@ func ReadNode[Addr ~int64](fs diskio.File[Addr], sb Superblock, addr Addr, exp N return nodeRef, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, Err: err} } if stored != calced { - return nodeRef, &NodeError[Addr]{Op: "btrfstree.ReadNode", NodeAddr: addr, + return nodeRef, &NodeError[Addr]{ + Op: "btrfstree.ReadNode", NodeAddr: addr, Err: fmt.Errorf("looks like a node but is corrupt: checksum mismatch: stored=%v calculated=%v", - stored, calced)} + stored, calced), + } } // parse (main) diff --git a/lib/btrfs/btrfsvol/lvm.go b/lib/btrfs/btrfsvol/lvm.go index 605524b..1cb1ded 100644 --- a/lib/btrfs/btrfsvol/lvm.go +++ b/lib/btrfs/btrfsvol/lvm.go @@ -82,6 +82,7 @@ func (lv *LogicalVolume[PhysicalVolume]) Close() error { } return nil } + func (lv *LogicalVolume[PhysicalVolume]) AddPhysicalVolume(id DeviceID, dev PhysicalVolume) error { lv.init() if other, exists := lv.id2pv[id]; exists { @@ -121,9 +122,11 @@ type Mapping struct { func (lv *LogicalVolume[PhysicalVolume]) CouldAddMapping(m Mapping) bool { return lv.addMapping(m, true) == nil } + func (lv *LogicalVolume[PhysicalVolume]) AddMapping(m Mapping) error { return lv.addMapping(m, false) } + func (lv *LogicalVolume[PhysicalVolume]) addMapping(m Mapping, dryRun bool) error { lv.init() // sanity check diff --git a/lib/btrfs/io2_lv.go b/lib/btrfs/io2_lv.go index 3f82cd0..ac7ea70 100644 --- a/lib/btrfs/io2_lv.go +++ b/lib/btrfs/io2_lv.go @@ -70,6 +70,7 @@ func (fs *FS) Size() btrfsvol.LogicalAddr { func (fs *FS) ReadAt(p []byte, off btrfsvol.LogicalAddr) (int, error) { return fs.LV.ReadAt(p, off) } + func (fs *FS) WriteAt(p []byte, off btrfsvol.LogicalAddr) (int, error) { return fs.LV.WriteAt(p, off) } diff --git a/lib/btrfs/io3_btree.go b/lib/btrfs/io3_btree.go index b8c1a6d..8ec4b41 100644 --- a/lib/btrfs/io3_btree.go +++ b/lib/btrfs/io3_btree.go @@ -17,12 +17,15 @@ import ( func (fs *FS) TreeWalk(ctx context.Context, treeID btrfsprim.ObjID, errHandle func(*btrfstree.TreeError), cbs btrfstree.TreeWalkHandler) { btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeWalk(ctx, treeID, errHandle, cbs) } + func (fs *FS) TreeLookup(treeID btrfsprim.ObjID, key btrfsprim.Key) (btrfstree.Item, error) { return btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeLookup(treeID, key) } + func (fs *FS) TreeSearch(treeID btrfsprim.ObjID, fn func(key btrfsprim.Key, size uint32) int) (btrfstree.Item, error) { return btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeSearch(treeID, fn) } + func (fs *FS) TreeSearchAll(treeID btrfsprim.ObjID, fn func(key btrfsprim.Key, size uint32) int) ([]btrfstree.Item, error) { return btrfstree.TreeOperatorImpl{NodeSource: fs}.TreeSearchAll(treeID, fn) } diff --git a/lib/btrfs/io4_fs.go b/lib/btrfs/io4_fs.go index d9c7cdb..3848ef1 100644 --- a/lib/btrfs/io4_fs.go +++ b/lib/btrfs/io4_fs.go @@ -95,7 +95,6 @@ func (sv *Subvolume) init() { default: panic(fmt.Errorf("should not happen: ROOT_ITEM has unexpected item type: %T", rootBody)) } - }) } diff --git a/lib/btrfsprogs/btrfsinspect/mount.go b/lib/btrfsprogs/btrfsinspect/mount.go index 29193cb..f061526 100644 --- a/lib/btrfsprogs/btrfsinspect/mount.go +++ b/lib/btrfsprogs/btrfsinspect/mount.go @@ -144,11 +144,11 @@ func inodeItemToFUSE(itemBody btrfsitem.Inode) fuseops.InodeAttributes { Size: uint64(itemBody.Size), Nlink: uint32(itemBody.NLink), Mode: uint32(itemBody.Mode), - //RDev: itemBody.Rdev, // jacobsa/fuse doesn't expose rdev + // RDev: itemBody.Rdev, // jacobsa/fuse doesn't expose rdev Atime: itemBody.ATime.ToStd(), Mtime: itemBody.MTime.ToStd(), Ctime: itemBody.CTime.ToStd(), - //Crtime: itemBody.OTime, + // Crtime: itemBody.OTime, Uid: uint32(itemBody.UID), Gid: uint32(itemBody.GID), } @@ -260,7 +260,7 @@ func (sv *subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) e Child: 2, // an inode number that a real file will never have Attributes: fuseops.InodeAttributes{ Nlink: 1, - Mode: uint32(btrfsitem.ModeFmtDir | 0700), + Mode: uint32(btrfsitem.ModeFmtDir | 0o700), }, } return nil @@ -315,6 +315,7 @@ func (sv *subvolume) OpenDir(_ context.Context, op *fuseops.OpenDirOp) error { op.Handle = handle return nil } + func (sv *subvolume) ReadDir(_ context.Context, op *fuseops.ReadDirOp) error { state, ok := sv.dirHandles.Load(op.Handle) if !ok { @@ -348,6 +349,7 @@ func (sv *subvolume) ReadDir(_ context.Context, op *fuseops.ReadDirOp) error { } return nil } + func (sv *subvolume) ReleaseDirHandle(_ context.Context, op *fuseops.ReleaseDirHandleOp) error { _, ok := sv.dirHandles.LoadAndDelete(op.Handle) if !ok { @@ -369,6 +371,7 @@ func (sv *subvolume) OpenFile(_ context.Context, op *fuseops.OpenFileOp) error { op.KeepPageCache = true return nil } + func (sv *subvolume) ReadFile(_ context.Context, op *fuseops.ReadFileOp) error { state, ok := sv.fileHandles.Load(op.Handle) if !ok { @@ -392,6 +395,7 @@ func (sv *subvolume) ReadFile(_ context.Context, op *fuseops.ReadFileOp) error { return err } + func (sv *subvolume) ReleaseFileHandle(_ context.Context, op *fuseops.ReleaseFileHandleOp) error { _, ok := sv.fileHandles.LoadAndDelete(op.Handle) if !ok { diff --git a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go index 3057e75..5d0804c 100644 --- a/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildnodes/rebuild.go @@ -386,6 +386,7 @@ func (o *rebuilder) want(ctx context.Context, reason string, treeID btrfsprim.Ob fmt.Sprintf("tree=%v key={%v %v ?}", treeID, objID, typ)) o._want(ctx, treeID, objID, typ) } + func (o *rebuilder) _want(ctx context.Context, treeID btrfsprim.ObjID, objID btrfsprim.ObjID, typ btrfsprim.ItemType) (key btrfsprim.Key, ok bool) { if !o.rebuilt.AddTree(ctx, treeID) { o.itemQueue = append(o.itemQueue, o.curKey) @@ -429,6 +430,7 @@ func (o *rebuilder) wantOff(ctx context.Context, reason string, treeID btrfsprim ctx = dlog.WithField(ctx, "btrfsinspect.rebuild-nodes.rebuild.want.key", keyAndTree{TreeID: treeID, Key: key}) o._wantOff(ctx, treeID, key) } + func (o *rebuilder) _wantOff(ctx context.Context, treeID btrfsprim.ObjID, tgt btrfsprim.Key) (ok bool) { if !o.rebuilt.AddTree(ctx, treeID) { o.itemQueue = append(o.itemQueue, o.curKey) diff --git a/lib/containers/lru.go b/lib/containers/lru.go index 12446b0..bfda361 100644 --- a/lib/containers/lru.go +++ b/lib/containers/lru.go @@ -36,10 +36,12 @@ func (c *LRUCache[K, V]) Add(key K, value V) { c.init() c.inner.Add(key, value) } + func (c *LRUCache[K, V]) Contains(key K) bool { c.init() return c.inner.Contains(key) } + func (c *LRUCache[K, V]) Get(key K) (value V, ok bool) { c.init() _value, ok := c.inner.Get(key) @@ -49,6 +51,7 @@ func (c *LRUCache[K, V]) Get(key K) (value V, ok bool) { } return value, ok } + func (c *LRUCache[K, V]) Keys() []K { c.init() untyped := c.inner.Keys() @@ -59,10 +62,12 @@ func (c *LRUCache[K, V]) Keys() []K { } return typed } + func (c *LRUCache[K, V]) Len() int { c.init() return c.inner.Len() } + func (c *LRUCache[K, V]) Peek(key K) (value V, ok bool) { c.init() _value, ok := c.inner.Peek(key) @@ -72,10 +77,12 @@ func (c *LRUCache[K, V]) Peek(key K) (value V, ok bool) { } return value, ok } + func (c *LRUCache[K, V]) Purge() { c.init() c.inner.Purge() } + func (c *LRUCache[K, V]) Remove(key K) { c.init() c.inner.Remove(key) diff --git a/lib/containers/syncmap.go b/lib/containers/syncmap.go index 4af678f..74da4b3 100644 --- a/lib/containers/syncmap.go +++ b/lib/containers/syncmap.go @@ -15,6 +15,7 @@ type SyncMap[K comparable, V any] struct { func (m *SyncMap[K, V]) Delete(key K) { m.inner.Delete(key) } + func (m *SyncMap[K, V]) Load(key K) (value V, ok bool) { _value, ok := m.inner.Load(key) if ok { @@ -23,6 +24,7 @@ func (m *SyncMap[K, V]) Load(key K) (value V, ok bool) { } return value, ok } + func (m *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { _value, ok := m.inner.LoadAndDelete(key) if ok { @@ -31,18 +33,21 @@ func (m *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { } return value, ok } + func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) { _actual, loaded := m.inner.LoadOrStore(key, value) //nolint:forcetypeassert // Typed wrapper around untyped lib. actual = _actual.(V) return actual, loaded } + func (m *SyncMap[K, V]) Range(f func(key K, value V) bool) { m.inner.Range(func(key, value any) bool { //nolint:forcetypeassert // Typed wrapper around untyped lib. return f(key.(K), value.(V)) }) } + func (m *SyncMap[K, V]) Store(key K, value V) { m.inner.Store(key, value) } diff --git a/lib/fmtutil/fmt.go b/lib/fmtutil/fmt.go index 3898046..b310eb6 100644 --- a/lib/fmtutil/fmt.go +++ b/lib/fmtutil/fmt.go @@ -52,7 +52,8 @@ func FormatByteArrayStringer( fmt.Formatter }, objBytes []byte, - f fmt.State, verb rune) { + f fmt.State, verb rune, +) { switch verb { case 'v': if !f.Flag('#') { diff --git a/lib/textui/text.go b/lib/textui/text.go index d6a80b3..615516d 100644 --- a/lib/textui/text.go +++ b/lib/textui/text.go @@ -72,9 +72,7 @@ type Portion[T constraints.Integer] struct { N, D T } -var ( - _ fmt.Stringer = Portion[int]{} -) +var _ fmt.Stringer = Portion[int]{} // String implements fmt.Stringer. func (p Portion[T]) String() string { -- cgit v1.2.3-54-g00ecf From 97fa22c161056c289a9978f20e3fb6b05d779a23 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 1 Jan 2023 20:48:22 -0700 Subject: lint: Turn on gomnd --- .golangci.yml | 7 +- cmd/btrfs-rec/inspect_lstrees.go | 2 +- cmd/btrfs-rec/inspect_rebuildmappings.go | 2 +- cmd/btrfs-rec/inspect_scandevices.go | 2 +- lib/binstruct/binint/builtins.go | 117 +++++++++++---------- lib/binstruct/size.go | 15 ++- lib/btrfs/btrfsitem/statmode.go | 4 +- lib/btrfs/btrfsprim/objid.go | 3 +- lib/btrfs/btrfsprim/uuid.go | 3 +- lib/btrfs/btrfssum/csum.go | 3 +- lib/btrfs/btrfssum/shortsum.go | 5 +- lib/btrfs/btrfstree/types_node.go | 10 +- lib/btrfsprogs/btrfsinspect/mount.go | 2 +- .../btrfsinspect/rebuildmappings/fuzzymatchsums.go | 4 +- .../btrfsinspect/rebuildmappings/matchsums.go | 7 +- .../rebuildmappings/rebuildmappings.go | 9 +- lib/btrfsprogs/btrfsutil/open.go | 7 +- 17 files changed, 115 insertions(+), 87 deletions(-) (limited to 'lib/btrfs/btrfsitem') diff --git a/.golangci.yml b/.golangci.yml index edb8499..f412141 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -35,7 +35,6 @@ linters: - godot - godox - goerr113 - - gomnd - gomoddirectives - ireturn - lll @@ -70,6 +69,12 @@ linters-settings: - appendAssign gofmt: simplify: true + gomnd: + ignored-numbers: + - '2' + ignored-functions: + - 'binutil.NeedNBytes' + - 'textui.Tunable' nolintlint: require-explanation: true require-specific: true diff --git a/cmd/btrfs-rec/inspect_lstrees.go b/cmd/btrfs-rec/inspect_lstrees.go index a6d86eb..0f70cd1 100644 --- a/cmd/btrfs-rec/inspect_lstrees.go +++ b/cmd/btrfs-rec/inspect_lstrees.go @@ -54,7 +54,7 @@ func init() { } numWidth := len(strconv.Itoa(slices.Max(treeErrCnt, totalItems))) - table := tabwriter.NewWriter(os.Stdout, 0, 8, 2, ' ', 0) + table := tabwriter.NewWriter(os.Stdout, 0, 8, 2, ' ', 0) //nolint:gomnd // This is what looks Nice. textui.Fprintf(table, " errors\t% *s\n", numWidth, strconv.Itoa(treeErrCnt)) for _, typ := range maps.SortedKeys(treeItemCnt) { textui.Fprintf(table, " %v items\t% *s\n", typ, numWidth, strconv.Itoa(treeItemCnt[typ])) diff --git a/cmd/btrfs-rec/inspect_rebuildmappings.go b/cmd/btrfs-rec/inspect_rebuildmappings.go index b805fc3..4555e58 100644 --- a/cmd/btrfs-rec/inspect_rebuildmappings.go +++ b/cmd/btrfs-rec/inspect_rebuildmappings.go @@ -50,7 +50,7 @@ func init() { if err := writeJSONFile(os.Stdout, fs, lowmemjson.ReEncoder{ Indent: "\t", ForceTrailingNewlines: true, - CompactIfUnder: 120, + CompactIfUnder: 120, //nolint:gomnd // This is what looks Nice. }); err != nil { return err } diff --git a/cmd/btrfs-rec/inspect_scandevices.go b/cmd/btrfs-rec/inspect_scandevices.go index bca1b13..410fa4f 100644 --- a/cmd/btrfs-rec/inspect_scandevices.go +++ b/cmd/btrfs-rec/inspect_scandevices.go @@ -34,7 +34,7 @@ func init() { if err := writeJSONFile(os.Stdout, results, lowmemjson.ReEncoder{ Indent: "\t", ForceTrailingNewlines: true, - CompactIfUnder: 16, + CompactIfUnder: 16, //nolint:gomnd // This is what looks Nice. }); err != nil { return err } diff --git a/lib/binstruct/binint/builtins.go b/lib/binstruct/binint/builtins.go index e4be2a6..cfd0fc2 100644 --- a/lib/binstruct/binint/builtins.go +++ b/lib/binstruct/binint/builtins.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,242 +10,249 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/binstruct/binutil" ) +const ( + sizeof8 = 1 + sizeof16 = 2 + sizeof32 = 4 + sizeof64 = 8 +) + // unsigned type U8 uint8 -func (U8) BinaryStaticSize() int { return 1 } +func (U8) BinaryStaticSize() int { return sizeof8 } func (x U8) MarshalBinary() ([]byte, error) { return []byte{byte(x)}, nil } func (x *U8) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 1); err != nil { + if err := binutil.NeedNBytes(dat, sizeof8); err != nil { return 0, err } *x = U8(dat[0]) - return 1, nil + return sizeof8, nil } // unsigned little endian type U16le uint16 -func (U16le) BinaryStaticSize() int { return 2 } +func (U16le) BinaryStaticSize() int { return sizeof16 } func (x U16le) MarshalBinary() ([]byte, error) { - var buf [2]byte + var buf [sizeof16]byte binary.LittleEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } func (x *U16le) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 2); err != nil { + if err := binutil.NeedNBytes(dat, sizeof16); err != nil { return 0, err } *x = U16le(binary.LittleEndian.Uint16(dat)) - return 2, nil + return sizeof16, nil } type U32le uint32 -func (U32le) BinaryStaticSize() int { return 4 } +func (U32le) BinaryStaticSize() int { return sizeof32 } func (x U32le) MarshalBinary() ([]byte, error) { - var buf [4]byte + var buf [sizeof32]byte binary.LittleEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } func (x *U32le) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 4); err != nil { + if err := binutil.NeedNBytes(dat, sizeof32); err != nil { return 0, err } *x = U32le(binary.LittleEndian.Uint32(dat)) - return 4, nil + return sizeof32, nil } type U64le uint64 -func (U64le) BinaryStaticSize() int { return 8 } +func (U64le) BinaryStaticSize() int { return sizeof64 } func (x U64le) MarshalBinary() ([]byte, error) { - var buf [8]byte + var buf [sizeof64]byte binary.LittleEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } func (x *U64le) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 8); err != nil { + if err := binutil.NeedNBytes(dat, sizeof64); err != nil { return 0, err } *x = U64le(binary.LittleEndian.Uint64(dat)) - return 8, nil + return sizeof64, nil } // unsigned big endian type U16be uint16 -func (U16be) BinaryStaticSize() int { return 2 } +func (U16be) BinaryStaticSize() int { return sizeof16 } func (x U16be) MarshalBinary() ([]byte, error) { - var buf [2]byte + var buf [sizeof16]byte binary.BigEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } func (x *U16be) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 2); err != nil { + if err := binutil.NeedNBytes(dat, sizeof16); err != nil { return 0, err } *x = U16be(binary.BigEndian.Uint16(dat)) - return 2, nil + return sizeof16, nil } type U32be uint32 -func (U32be) BinaryStaticSize() int { return 4 } +func (U32be) BinaryStaticSize() int { return sizeof32 } func (x U32be) MarshalBinary() ([]byte, error) { - var buf [4]byte + var buf [sizeof32]byte binary.BigEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } func (x *U32be) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 4); err != nil { + if err := binutil.NeedNBytes(dat, sizeof32); err != nil { return 0, err } *x = U32be(binary.BigEndian.Uint32(dat)) - return 4, nil + return sizeof32, nil } type U64be uint64 -func (U64be) BinaryStaticSize() int { return 8 } +func (U64be) BinaryStaticSize() int { return sizeof64 } func (x U64be) MarshalBinary() ([]byte, error) { - var buf [8]byte + var buf [sizeof64]byte binary.BigEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } func (x *U64be) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 8); err != nil { + if err := binutil.NeedNBytes(dat, sizeof64); err != nil { return 0, err } *x = U64be(binary.BigEndian.Uint64(dat)) - return 8, nil + return sizeof64, nil } // signed type I8 int8 -func (I8) BinaryStaticSize() int { return 1 } +func (I8) BinaryStaticSize() int { return sizeof8 } func (x I8) MarshalBinary() ([]byte, error) { return []byte{byte(x)}, nil } func (x *I8) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 1); err != nil { + if err := binutil.NeedNBytes(dat, sizeof8); err != nil { return 0, err } *x = I8(dat[0]) - return 1, nil + return sizeof8, nil } // signed little endian type I16le int16 -func (I16le) BinaryStaticSize() int { return 2 } +func (I16le) BinaryStaticSize() int { return sizeof16 } func (x I16le) MarshalBinary() ([]byte, error) { - var buf [2]byte + var buf [sizeof16]byte binary.LittleEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } func (x *I16le) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 2); err != nil { + if err := binutil.NeedNBytes(dat, sizeof16); err != nil { return 0, err } *x = I16le(binary.LittleEndian.Uint16(dat)) - return 2, nil + return sizeof16, nil } type I32le int32 -func (I32le) BinaryStaticSize() int { return 4 } +func (I32le) BinaryStaticSize() int { return sizeof32 } func (x I32le) MarshalBinary() ([]byte, error) { - var buf [4]byte + var buf [sizeof32]byte binary.LittleEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } func (x *I32le) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 4); err != nil { + if err := binutil.NeedNBytes(dat, sizeof32); err != nil { return 0, err } *x = I32le(binary.LittleEndian.Uint32(dat)) - return 4, nil + return sizeof32, nil } type I64le int64 -func (I64le) BinaryStaticSize() int { return 8 } +func (I64le) BinaryStaticSize() int { return sizeof64 } func (x I64le) MarshalBinary() ([]byte, error) { - var buf [8]byte + var buf [sizeof64]byte binary.LittleEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } func (x *I64le) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 8); err != nil { + if err := binutil.NeedNBytes(dat, sizeof64); err != nil { return 0, err } *x = I64le(binary.LittleEndian.Uint64(dat)) - return 8, nil + return sizeof64, nil } // signed big endian type I16be int16 -func (I16be) BinaryStaticSize() int { return 2 } +func (I16be) BinaryStaticSize() int { return sizeof16 } func (x I16be) MarshalBinary() ([]byte, error) { - var buf [2]byte + var buf [sizeof16]byte binary.BigEndian.PutUint16(buf[:], uint16(x)) return buf[:], nil } func (x *I16be) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 2); err != nil { + if err := binutil.NeedNBytes(dat, sizeof16); err != nil { return 0, err } *x = I16be(binary.BigEndian.Uint16(dat)) - return 2, nil + return sizeof16, nil } type I32be int32 -func (I32be) BinaryStaticSize() int { return 4 } +func (I32be) BinaryStaticSize() int { return sizeof32 } func (x I32be) MarshalBinary() ([]byte, error) { - var buf [4]byte + var buf [sizeof32]byte binary.BigEndian.PutUint32(buf[:], uint32(x)) return buf[:], nil } func (x *I32be) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 4); err != nil { + if err := binutil.NeedNBytes(dat, sizeof32); err != nil { return 0, err } *x = I32be(binary.BigEndian.Uint32(dat)) - return 4, nil + return sizeof32, nil } type I64be int64 -func (I64be) BinaryStaticSize() int { return 8 } +func (I64be) BinaryStaticSize() int { return sizeof64 } func (x I64be) MarshalBinary() ([]byte, error) { - var buf [8]byte + var buf [sizeof64]byte binary.BigEndian.PutUint64(buf[:], uint64(x)) return buf[:], nil } func (x *I64be) UnmarshalBinary(dat []byte) (int, error) { - if err := binutil.NeedNBytes(dat, 8); err != nil { + if err := binutil.NeedNBytes(dat, sizeof64); err != nil { return 0, err } *x = I64be(binary.BigEndian.Uint64(dat)) - return 8, nil + return sizeof64, nil } diff --git a/lib/binstruct/size.go b/lib/binstruct/size.go index 52fa380..d6d70c6 100644 --- a/lib/binstruct/size.go +++ b/lib/binstruct/size.go @@ -28,6 +28,13 @@ var ( unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() ) +const ( + sizeof8 = 1 + sizeof16 = 2 + sizeof32 = 4 + sizeof64 = 8 +) + func staticSize(typ reflect.Type) (int, error) { if typ.Implements(staticSizerType) { //nolint:forcetypeassert // Already did a type check via reflection. @@ -43,13 +50,13 @@ func staticSize(typ reflect.Type) (int, error) { } switch typ.Kind() { case reflect.Uint8, reflect.Int8: - return 1, nil + return sizeof8, nil case reflect.Uint16, reflect.Int16: - return 2, nil + return sizeof16, nil case reflect.Uint32, reflect.Int32: - return 4, nil + return sizeof32, nil case reflect.Uint64, reflect.Int64: - return 8, nil + return sizeof64, nil case reflect.Ptr: return staticSize(typ.Elem()) case reflect.Array: diff --git a/lib/btrfs/btrfsitem/statmode.go b/lib/btrfs/btrfsitem/statmode.go index a1302ee..557b688 100644 --- a/lib/btrfs/btrfsitem/statmode.go +++ b/lib/btrfs/btrfsitem/statmode.go @@ -1,5 +1,5 @@ // Copyright (C) 2020-2021 Ambassador Labs -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: Apache-2.0 // @@ -9,7 +9,6 @@ package btrfsitem type StatMode uint32 -//nolint:deadcode,varcheck // not all of these modes will be used const ( // 16 bits = 5⅓ octal characters @@ -73,6 +72,7 @@ func (mode StatMode) IsRegular() bool { // 's' (GNU `ls` behavior; though POSIX notes that many // implementations use '=' for sockets). func (mode StatMode) String() string { + //nolint:gomnd // Magic numbers is all this is. buf := [10]byte{ // type: This string is easy; it directly pairs with // the above ModeFmtXXX list above; the character in diff --git a/lib/btrfs/btrfsprim/objid.go b/lib/btrfs/btrfsprim/objid.go index 17a0eeb..5ba213d 100644 --- a/lib/btrfs/btrfsprim/objid.go +++ b/lib/btrfs/btrfsprim/objid.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -68,6 +68,7 @@ func (id ObjID) Format(typ ItemType) string { case DEV_EXTENT_KEY: return fmt.Sprintf("%d", int64(id)) case QGROUP_RELATION_KEY: + //nolint:gomnd // TODO: I'm not sure what the 48/16 bit split means. return fmt.Sprintf("%d/%d", uint64(id)>>48, uint64(id)&((1<<48)-1)) diff --git a/lib/btrfs/btrfsprim/uuid.go b/lib/btrfs/btrfsprim/uuid.go index 4e3fd6b..0103ee4 100644 --- a/lib/btrfs/btrfsprim/uuid.go +++ b/lib/btrfs/btrfsprim/uuid.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -56,6 +56,7 @@ func (a UUID) Cmp(b UUID) int { return 0 } +//nolint:gomnd // This is all magic numbers. func ParseUUID(str string) (UUID, error) { var ret UUID j := 0 diff --git a/lib/btrfs/btrfssum/csum.go b/lib/btrfs/btrfssum/csum.go index 770f6ea..6df9efd 100644 --- a/lib/btrfs/btrfssum/csum.go +++ b/lib/btrfs/btrfssum/csum.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -70,6 +70,7 @@ func (typ CSumType) String() string { } func (typ CSumType) Size() int { + //nolint:gomnd // This is where we define the magic numbers. sizes := map[CSumType]int{ TYPE_CRC32: 4, TYPE_XXHASH: 8, diff --git a/lib/btrfs/btrfssum/shortsum.go b/lib/btrfs/btrfssum/shortsum.go index 6fd0c68..aaf7a89 100644 --- a/lib/btrfs/btrfssum/shortsum.go +++ b/lib/btrfs/btrfssum/shortsum.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -56,10 +56,11 @@ func (sum ShortSum) EncodeJSON(w io.Writer) error { } func deHex(r rune) (byte, bool) { - if r > 0xff { + if r > math.MaxUint8 { return 0, false } c := byte(r) + //nolint:gomnd // Hex conversion. switch { case '0' <= c && c <= '9': return c - '0', true diff --git a/lib/btrfs/btrfstree/types_node.go b/lib/btrfs/btrfstree/types_node.go index b709d34..a26215b 100644 --- a/lib/btrfs/btrfstree/types_node.go +++ b/lib/btrfs/btrfstree/types_node.go @@ -23,21 +23,23 @@ import ( type NodeFlags uint64 +const sizeofNodeFlags = 7 + func (NodeFlags) BinaryStaticSize() int { - return 7 + return sizeofNodeFlags } func (f NodeFlags) MarshalBinary() ([]byte, error) { var bs [8]byte binary.LittleEndian.PutUint64(bs[:], uint64(f)) - return bs[:7], nil + return bs[:sizeofNodeFlags], nil } func (f *NodeFlags) UnmarshalBinary(dat []byte) (int, error) { var bs [8]byte - copy(bs[:7], dat[:7]) + copy(bs[:sizeofNodeFlags], dat[:sizeofNodeFlags]) *f = NodeFlags(binary.LittleEndian.Uint64(bs[:])) - return 7, nil + return sizeofNodeFlags, nil } var ( diff --git a/lib/btrfsprogs/btrfsinspect/mount.go b/lib/btrfsprogs/btrfsinspect/mount.go index f061526..d10037d 100644 --- a/lib/btrfsprogs/btrfsinspect/mount.go +++ b/lib/btrfsprogs/btrfsinspect/mount.go @@ -260,7 +260,7 @@ func (sv *subvolume) LookUpInode(_ context.Context, op *fuseops.LookUpInodeOp) e Child: 2, // an inode number that a real file will never have Attributes: fuseops.InodeAttributes{ Nlink: 1, - Mode: uint32(btrfsitem.ModeFmtDir | 0o700), + Mode: uint32(btrfsitem.ModeFmtDir | 0o700), //nolint:gomnd // TODO }, } return nil diff --git a/lib/btrfsprogs/btrfsinspect/rebuildmappings/fuzzymatchsums.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/fuzzymatchsums.go index a8d05eb..9e6b864 100644 --- a/lib/btrfsprogs/btrfsinspect/rebuildmappings/fuzzymatchsums.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/fuzzymatchsums.go @@ -112,8 +112,8 @@ func fuzzyMatchBlockGroupSums(ctx context.Context, if apply { lvl = dlog.LogLevelInfo } - dlog.Logf(ctx, lvl, "(%v/%v) blockgroup[laddr=%v] matches=[%s]; bestpossible=%v%% (based on %v runs)", - i+1, numBlockgroups, bgLAddr, matchesStr, int(100*bgRun.PctFull()), len(bgRun.Runs)) + dlog.Logf(ctx, lvl, "(%v/%v) blockgroup[laddr=%v] matches=[%s]; bestpossible=%v (based on %v runs)", + i+1, numBlockgroups, bgLAddr, matchesStr, number.Percent(bgRun.PctFull()), len(bgRun.Runs)) if !apply { continue } diff --git a/lib/btrfsprogs/btrfsinspect/rebuildmappings/matchsums.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/matchsums.go index be82f87..02c657f 100644 --- a/lib/btrfsprogs/btrfsinspect/rebuildmappings/matchsums.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/matchsums.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -8,6 +8,7 @@ import ( "context" "github.com/datawire/dlib/dlog" + "golang.org/x/text/number" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfssum" @@ -55,8 +56,8 @@ func matchBlockGroupSums(ctx context.Context, if len(matches) == 1 { lvl = dlog.LogLevelInfo } - dlog.Logf(ctx, lvl, "(%v/%v) blockgroup[laddr=%v] has %v matches based on %v%% coverage from %v runs", - i+1, numBlockgroups, bgLAddr, len(matches), int(100*bgRun.PctFull()), len(bgRun.Runs)) + dlog.Logf(ctx, lvl, "(%v/%v) blockgroup[laddr=%v] has %v matches based on %v coverage from %v runs", + i+1, numBlockgroups, bgLAddr, len(matches), number.Percent(bgRun.PctFull()), len(bgRun.Runs)) if len(matches) != 1 { continue } diff --git a/lib/btrfsprogs/btrfsinspect/rebuildmappings/rebuildmappings.go b/lib/btrfsprogs/btrfsinspect/rebuildmappings/rebuildmappings.go index 7311aca..665bc96 100644 --- a/lib/btrfsprogs/btrfsinspect/rebuildmappings/rebuildmappings.go +++ b/lib/btrfsprogs/btrfsinspect/rebuildmappings/rebuildmappings.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,6 +15,7 @@ import ( "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect" "git.lukeshu.com/btrfs-progs-ng/lib/containers" "git.lukeshu.com/btrfs-progs-ng/lib/maps" + "git.lukeshu.com/btrfs-progs-ng/lib/textui" ) func getNodeSize(fs *btrfs.FS) (btrfsvol.AddrDelta, error) { @@ -189,20 +190,20 @@ func RebuildMappings(ctx context.Context, fs *btrfs.FS, scanResults btrfsinspect unmappedPhysical += region.End.Sub(region.Beg) } } - dlog.Infof(ctx, "... %d KiB of unmapped physical space (across %d regions)", int(unmappedPhysical/1024), numUnmappedPhysical) + dlog.Infof(ctx, "... %d of unmapped physical space (across %d regions)", textui.IEC(unmappedPhysical, "B"), numUnmappedPhysical) unmappedLogicalRegions := ListUnmappedLogicalRegions(fs, logicalSums) var unmappedLogical btrfsvol.AddrDelta for _, region := range unmappedLogicalRegions { unmappedLogical += region.Size() } - dlog.Infof(ctx, "... %d KiB of unmapped summed logical space (across %d regions)", int(unmappedLogical/1024), len(unmappedLogicalRegions)) + dlog.Infof(ctx, "... %d of unmapped summed logical space (across %d regions)", textui.IEC(unmappedLogical, "B"), len(unmappedLogicalRegions)) var unmappedBlockGroups btrfsvol.AddrDelta for _, bg := range bgs { unmappedBlockGroups += bg.Size } - dlog.Infof(ctx, "... %d KiB of unmapped block groups (across %d groups)", int(unmappedBlockGroups/1024), len(bgs)) + dlog.Infof(ctx, "... %d of unmapped block groups (across %d groups)", textui.IEC(unmappedBlockGroups, "B"), len(bgs)) dlog.Info(_ctx, "detailed report:") for _, devID := range maps.SortedKeys(unmappedPhysicalRegions) { diff --git a/lib/btrfsprogs/btrfsutil/open.go b/lib/btrfsprogs/btrfsutil/open.go index 441d4e2..c5ee314 100644 --- a/lib/btrfsprogs/btrfsutil/open.go +++ b/lib/btrfsprogs/btrfsutil/open.go @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Luke Shumaker +// Copyright (C) 2022-2023 Luke Shumaker // // SPDX-License-Identifier: GPL-2.0-or-later @@ -31,8 +31,9 @@ func Open(ctx context.Context, flag int, filenames ...string) (*btrfs.FS, error) } bufFile := diskio.NewBufferedFile[btrfsvol.PhysicalAddr]( typedFile, - textui.Tunable[btrfsvol.PhysicalAddr](16384), // block size: 16KiB - textui.Tunable(1024), // number of blocks to buffer; total of 16MiB + //nolint:gomnd // False positive: gomnd.ignored-functions=[textui.Tunable] doesn't support type params. + textui.Tunable[btrfsvol.PhysicalAddr](16*1024), // block size: 16KiB + textui.Tunable(1024), // number of blocks to buffer; total of 16MiB ) devFile := &btrfs.Device{ File: bufFile, -- cgit v1.2.3-54-g00ecf