diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-16 08:29:36 -0600 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-03-16 08:29:36 -0600 |
commit | c0f33186aa7a8903c5e7406024f13fad48cd14e3 (patch) | |
tree | c8361c8278b07839be9af2ccee3507d324a7a216 /lib/btrfs/btrfsprim | |
parent | c2925f0f8a5d69369b43de0d2d201291fe5ed9d1 (diff) | |
parent | 17833fa13d5a7dcd79ad507fe4abf96b4a4a898b (diff) |
Merge branch 'lukeshu/errs'
Diffstat (limited to 'lib/btrfs/btrfsprim')
-rw-r--r-- | lib/btrfs/btrfsprim/itemtype.go | 7 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/key.go | 101 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/key_test.go | 59 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/misc.go | 71 | ||||
-rw-r--r-- | lib/btrfs/btrfsprim/objid.go | 3 |
5 files changed, 169 insertions, 72 deletions
diff --git a/lib/btrfs/btrfsprim/itemtype.go b/lib/btrfs/btrfsprim/itemtype.go index f33179a..682fecd 100644 --- a/lib/btrfs/btrfsprim/itemtype.go +++ b/lib/btrfs/btrfsprim/itemtype.go @@ -2,7 +2,10 @@ package btrfsprim -import "fmt" +import ( + "fmt" + "math" +) type ItemType uint8 @@ -39,6 +42,8 @@ const ( UUID_RECEIVED_SUBVOL_KEY ItemType = 252 UUID_SUBVOL_KEY ItemType = 251 XATTR_ITEM_KEY ItemType = 24 + + MAX_KEY ItemType = math.MaxUint8 ) func (t ItemType) String() string { diff --git a/lib/btrfs/btrfsprim/key.go b/lib/btrfs/btrfsprim/key.go new file mode 100644 index 0000000..b07cc8c --- /dev/null +++ b/lib/btrfs/btrfsprim/key.go @@ -0,0 +1,101 @@ +// Copyright (C) 2022-2023 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package btrfsprim + +import ( + "fmt" + "math" + + "git.lukeshu.com/btrfs-progs-ng/lib/binstruct" + "git.lukeshu.com/btrfs-progs-ng/lib/containers" +) + +type Key struct { + ObjectID ObjID `bin:"off=0x0, siz=0x8"` // Each tree has its own set of Object IDs. + ItemType ItemType `bin:"off=0x8, siz=0x1"` + Offset uint64 `bin:"off=0x9, siz=0x8"` // The meaning depends on the item type. + binstruct.End `bin:"off=0x11"` +} + +const MaxOffset uint64 = math.MaxUint64 + +// mimics print-tree.c:btrfs_print_key() +func (key Key) Format(tree ObjID) string { + switch tree { + case UUID_TREE_OBJECTID: + return fmt.Sprintf("(%v %v %#08x)", + key.ObjectID.Format(tree), + key.ItemType, + key.Offset) + case ROOT_TREE_OBJECTID, QUOTA_TREE_OBJECTID: + return fmt.Sprintf("(%v %v %v)", + key.ObjectID.Format(tree), + key.ItemType, + ObjID(key.Offset).Format(tree)) + default: + if key.Offset == math.MaxUint64 { + return fmt.Sprintf("(%v %v -1)", + key.ObjectID.Format(tree), + key.ItemType) + } else { + return fmt.Sprintf("(%v %v %v)", + key.ObjectID.Format(tree), + key.ItemType, + key.Offset) + } + } +} + +func (key Key) String() string { + return key.Format(0) +} + +var MaxKey = Key{ + ObjectID: math.MaxUint64, + ItemType: math.MaxUint8, + Offset: math.MaxUint64, +} + +func (key Key) Mm() Key { + switch { + case key.Offset > 0: + key.Offset-- + case key.ItemType > 0: + key.ItemType-- + key.Offset = MaxOffset + case key.ObjectID > 0: + key.ObjectID-- + key.ItemType = MAX_KEY + key.Offset = MaxOffset + } + return key +} + +func (key Key) Pp() Key { + switch { + case key.Offset < MaxOffset: + key.Offset++ + case key.ItemType < MAX_KEY: + key.ItemType++ + key.Offset = 0 + case key.ObjectID < MAX_OBJECTID: + key.ObjectID++ + key.ItemType = 0 + key.Offset = 0 + } + return key +} + +func (a Key) Compare(b Key) int { + if d := containers.NativeCompare(a.ObjectID, b.ObjectID); d != 0 { + return d + } + if d := containers.NativeCompare(a.ItemType, b.ItemType); d != 0 { + return d + } + return containers.NativeCompare(a.Offset, b.Offset) +} + +var _ containers.Ordered[Key] = Key{} diff --git a/lib/btrfs/btrfsprim/key_test.go b/lib/btrfs/btrfsprim/key_test.go new file mode 100644 index 0000000..6274b43 --- /dev/null +++ b/lib/btrfs/btrfsprim/key_test.go @@ -0,0 +1,59 @@ +// Copyright (C) 2023 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package btrfsprim + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func k(objID ObjID, typ ItemType, offset uint64) Key { + return Key{ + ObjectID: objID, + ItemType: typ, + Offset: offset, + } +} + +func eq(t *testing.T, act, exp Key) { + t.Helper() + assert.Equal(t, exp, act) +} + +func ppEq(t *testing.T, in, exp Key) { + t.Helper() + eq(t, in.Pp(), exp) + if in != MaxKey { + eq(t, exp.Mm(), in) + } +} + +func mmEq(t *testing.T, in, exp Key) { + t.Helper() + eq(t, in.Mm(), exp) + if in != (Key{}) { + eq(t, exp.Pp(), in) + } +} + +func TestKey(t *testing.T) { + t.Parallel() + + eq(t, MaxKey, k(18446744073709551615, 255, 18446744073709551615)) + + // pp + ppEq(t, k(0, 0, 0), k(0, 0, 1)) + ppEq(t, k(0, 0, 18446744073709551615), k(0, 1, 0)) + ppEq(t, k(0, 255, 0), k(0, 255, 1)) + ppEq(t, k(0, 255, 18446744073709551615), k(1, 0, 0)) + ppEq(t, MaxKey, k(18446744073709551615, 255, 18446744073709551615)) + + // mm + mmEq(t, MaxKey, k(18446744073709551615, 255, 18446744073709551614)) + mmEq(t, k(18446744073709551615, 255, 0), k(18446744073709551615, 254, 18446744073709551615)) + mmEq(t, k(18446744073709551615, 0, 0), k(18446744073709551614, 255, 18446744073709551615)) + mmEq(t, k(0, 0, 0), k(0, 0, 0)) +} diff --git a/lib/btrfs/btrfsprim/misc.go b/lib/btrfs/btrfsprim/misc.go index ca2e313..38290d6 100644 --- a/lib/btrfs/btrfsprim/misc.go +++ b/lib/btrfs/btrfsprim/misc.go @@ -5,84 +5,13 @@ package btrfsprim import ( - "fmt" - "math" "time" "git.lukeshu.com/btrfs-progs-ng/lib/binstruct" - "git.lukeshu.com/btrfs-progs-ng/lib/containers" ) type Generation uint64 -type Key struct { - ObjectID ObjID `bin:"off=0x0, siz=0x8"` // Each tree has its own set of Object IDs. - ItemType ItemType `bin:"off=0x8, siz=0x1"` - Offset uint64 `bin:"off=0x9, siz=0x8"` // The meaning depends on the item type. - binstruct.End `bin:"off=0x11"` -} - -// mimics print-tree.c:btrfs_print_key() -func (key Key) Format(tree ObjID) string { - switch tree { - case UUID_TREE_OBJECTID: - return fmt.Sprintf("(%v %v %#08x)", - key.ObjectID.Format(tree), - key.ItemType, - key.Offset) - case ROOT_TREE_OBJECTID, QUOTA_TREE_OBJECTID: - return fmt.Sprintf("(%v %v %v)", - key.ObjectID.Format(tree), - key.ItemType, - ObjID(key.Offset).Format(tree)) - default: - if key.Offset == math.MaxUint64 { - return fmt.Sprintf("(%v %v -1)", - key.ObjectID.Format(tree), - key.ItemType) - } else { - return fmt.Sprintf("(%v %v %v)", - key.ObjectID.Format(tree), - key.ItemType, - key.Offset) - } - } -} - -func (key Key) String() string { - return key.Format(0) -} - -var MaxKey = Key{ - ObjectID: math.MaxUint64, - ItemType: math.MaxUint8, - Offset: math.MaxUint64, -} - -func (key Key) Mm() Key { - switch { - case key.Offset > 0: - key.Offset-- - case key.ItemType > 0: - key.ItemType-- - case key.ObjectID > 0: - key.ObjectID-- - } - return key -} - -func (a Key) Compare(b Key) int { - if d := containers.NativeCompare(a.ObjectID, b.ObjectID); d != 0 { - return d - } - if d := containers.NativeCompare(a.ItemType, b.ItemType); d != 0 { - return d - } - return containers.NativeCompare(a.Offset, b.Offset) -} - -var _ containers.Ordered[Key] = Key{} - type Time struct { Sec int64 `bin:"off=0x0, siz=0x8"` // Number of seconds since 1970-01-01T00:00:00Z. NSec uint32 `bin:"off=0x8, siz=0x4"` // Number of nanoseconds since the beginning of the second. diff --git a/lib/btrfs/btrfsprim/objid.go b/lib/btrfs/btrfsprim/objid.go index 1aea030..f364957 100644 --- a/lib/btrfs/btrfsprim/objid.go +++ b/lib/btrfs/btrfsprim/objid.go @@ -6,6 +6,7 @@ package btrfsprim import ( "fmt" + "math" ) type ObjID uint64 @@ -52,6 +53,8 @@ const ( // ??? EMPTY_SUBVOL_DIR_OBJECTID ObjID = 2 + + MAX_OBJECTID ObjID = math.MaxUint64 ) var ( |