diff options
Diffstat (limited to 'lib/btrfsutil/listnodes.go')
-rw-r--r-- | lib/btrfsutil/listnodes.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/btrfsutil/listnodes.go b/lib/btrfsutil/listnodes.go new file mode 100644 index 0000000..16300da --- /dev/null +++ b/lib/btrfsutil/listnodes.go @@ -0,0 +1,66 @@ +// Copyright (C) 2023 Luke Shumaker <lukeshu@lukeshu.com> +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package btrfsutil + +import ( + "context" + + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfstree" + "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol" + "git.lukeshu.com/btrfs-progs-ng/lib/containers" + "git.lukeshu.com/btrfs-progs-ng/lib/diskio" + "git.lukeshu.com/btrfs-progs-ng/lib/maps" + "git.lukeshu.com/btrfs-progs-ng/lib/textui" +) + +type nodeScanner struct { + nodes containers.Set[btrfsvol.LogicalAddr] +} + +type nodeStats struct { + numNodes int +} + +func (s nodeStats) String() string { + return textui.Sprintf("found: %d nodes", s.numNodes) +} + +var _ DeviceScanner[nodeStats, containers.Set[btrfsvol.LogicalAddr]] = (*nodeScanner)(nil) + +func newNodeScanner(ctx context.Context, sb btrfstree.Superblock, numBytes btrfsvol.PhysicalAddr, numSectors int) DeviceScanner[nodeStats, containers.Set[btrfsvol.LogicalAddr]] { + s := new(nodeScanner) + s.nodes = make(containers.Set[btrfsvol.LogicalAddr]) + return s +} + +func (s *nodeScanner) ScanStats() nodeStats { + return nodeStats{numNodes: len(s.nodes)} +} + +func (*nodeScanner) ScanSector(ctx context.Context, dev *btrfs.Device, paddr btrfsvol.PhysicalAddr) error { + return nil +} + +func (s *nodeScanner) ScanNode(ctx context.Context, nodeRef *diskio.Ref[btrfsvol.PhysicalAddr, btrfstree.Node]) error { + s.nodes.Insert(nodeRef.Data.Head.Addr) + return nil +} + +func (s *nodeScanner) ScanDone(ctx context.Context) (containers.Set[btrfsvol.LogicalAddr], error) { + return s.nodes, nil +} + +func ListNodes(ctx context.Context, fs *btrfs.FS) ([]btrfsvol.LogicalAddr, error) { + perDev, err := ScanDevices[nodeStats, containers.Set[btrfsvol.LogicalAddr]](ctx, fs, newNodeScanner) + if err != nil { + return nil, err + } + set := make(containers.Set[btrfsvol.LogicalAddr]) + for _, devSet := range perDev { + set.InsertFrom(devSet) + } + return maps.SortedKeys(set), nil +} |