summaryrefslogtreecommitdiff
path: root/cmd/btrfs-fsck/pass1.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/btrfs-fsck/pass1.go')
-rw-r--r--cmd/btrfs-fsck/pass1.go163
1 files changed, 0 insertions, 163 deletions
diff --git a/cmd/btrfs-fsck/pass1.go b/cmd/btrfs-fsck/pass1.go
deleted file mode 100644
index e22cebd..0000000
--- a/cmd/btrfs-fsck/pass1.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (C) 2022 Luke Shumaker <lukeshu@lukeshu.com>
-//
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package main
-
-import (
- "context"
- "fmt"
- "os"
-
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfs"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsitem"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsinspect"
- "git.lukeshu.com/btrfs-progs-ng/lib/btrfsprogs/btrfsutil"
- "git.lukeshu.com/btrfs-progs-ng/lib/diskio"
-)
-
-func pass1(ctx context.Context, fs *btrfs.FS, superblock *btrfs.Superblock) (map[btrfsvol.LogicalAddr]struct{}, error) {
- fmt.Printf("\nPass 1: chunk mappings...\n")
-
- fmt.Printf("Pass 1: ... walking fs\n")
- visitedNodes := make(map[btrfsvol.LogicalAddr]struct{})
- btrfsutil.WalkAllTrees(ctx, fs, btrfsutil.WalkAllTreesHandler{
- TreeWalkHandler: btrfs.TreeWalkHandler{
- Node: func(path btrfs.TreePath, node *diskio.Ref[btrfsvol.LogicalAddr, btrfs.Node]) error {
- visitedNodes[node.Addr] = struct{}{}
- return nil
- },
- },
- Err: func(err *btrfsutil.WalkError) {
- fmt.Printf("Pass 1: ... walk fs: error: %v\n", err)
- },
- })
-
- fsFoundNodes := make(map[btrfsvol.LogicalAddr]struct{})
- for _, dev := range fs.LV.PhysicalVolumes() {
- fmt.Printf("Pass 1: ... dev[%q] scanning for nodes...\n", dev.Name())
- devResult, err := btrfsinspect.ScanOneDevice(ctx, dev, *superblock)
- if err != nil {
- return nil, err
- }
-
- fmt.Printf("Pass 1: ... dev[%q] re-inserting lost+found mappings\n", dev.Name())
- devResult.AddToLV(ctx, fs, dev)
-
- // merge those results in to the total-fs results
- for laddr := range devResult.FoundNodes {
- fsFoundNodes[laddr] = struct{}{}
- }
- }
-
- fmt.Printf("Pass 1: ... logical address space:\n")
- btrfsinspect.PrintLogicalSpace(os.Stdout, fs)
- fmt.Printf("Pass 1: ... physical address space:\n")
- btrfsinspect.PrintPhysicalSpace(os.Stdout, fs)
-
- fmt.Printf("Pass 1: ... writing re-constructed chunks\n")
- pass1WriteReconstructedChunks(ctx, fs)
-
- return fsFoundNodes, nil
-}
-
-func pass1WriteReconstructedChunks(ctx context.Context, fs *btrfs.FS) {
- superblock, _ := fs.Superblock()
-
- // FIXME(lukeshu): OK, so this just assumes that all the
- // reconstructed stripes fit in one node, and that we can just
- // store that node at the root node of the chunk tree. This
- // isn't true in general, but it's true of my particular
- // filesystem.
- reconstructedNode := &diskio.Ref[btrfsvol.LogicalAddr, btrfs.Node]{
- File: fs,
- Addr: superblock.ChunkTree,
- Data: btrfs.Node{
- Size: superblock.NodeSize,
- Head: btrfs.NodeHeader{
- MetadataUUID: superblock.EffectiveMetadataUUID(),
- Addr: superblock.ChunkTree,
- Flags: btrfs.NodeWritten,
- //BackrefRef: ???,
- //ChunkTreeUUID: ???,
- Generation: superblock.ChunkRootGeneration,
- Owner: btrfs.CHUNK_TREE_OBJECTID,
- Level: 0,
- },
- },
- }
-
- for _, dev := range fs.LV.PhysicalVolumes() {
- superblock, _ := dev.Superblock()
- reconstructedNode.Data.BodyLeaf = append(reconstructedNode.Data.BodyLeaf, btrfs.Item{
- Key: btrfs.Key{
- ObjectID: btrfs.DEV_ITEMS_OBJECTID,
- ItemType: btrfsitem.DEV_ITEM_KEY,
- Offset: uint64(superblock.DevItem.DevID),
- },
- Body: superblock.DevItem,
- })
- }
-
- for _, mapping := range fs.LV.Mappings() {
- chunkIdx := len(reconstructedNode.Data.BodyLeaf) - 1
- if len(reconstructedNode.Data.BodyLeaf) == 0 || reconstructedNode.Data.BodyLeaf[chunkIdx].Key.Offset != uint64(mapping.LAddr) {
- reconstructedNode.Data.BodyLeaf = append(reconstructedNode.Data.BodyLeaf, btrfs.Item{
- Key: btrfs.Key{
- ObjectID: btrfs.FIRST_CHUNK_TREE_OBJECTID,
- ItemType: btrfsitem.CHUNK_ITEM_KEY,
- Offset: uint64(mapping.LAddr),
- },
- Body: btrfsitem.Chunk{
- Head: btrfsitem.ChunkHeader{
- Size: mapping.Size,
- Owner: btrfs.EXTENT_TREE_OBJECTID,
- StripeLen: 65536, // ???
- Type: mapping.Flags.Val,
- IOOptimalAlign: superblock.DevItem.IOOptimalAlign,
- IOOptimalWidth: superblock.DevItem.IOOptimalWidth,
- IOMinSize: superblock.DevItem.IOMinSize,
- SubStripes: 1,
- },
- },
- })
- chunkIdx++
- }
- dev := fs.LV.PhysicalVolumes()[mapping.PAddr.Dev]
- devSB, _ := dev.Superblock()
- chunkBody := reconstructedNode.Data.BodyLeaf[chunkIdx].Body.(btrfsitem.Chunk)
- chunkBody.Stripes = append(chunkBody.Stripes, btrfsitem.ChunkStripe{
- DeviceID: mapping.PAddr.Dev,
- Offset: mapping.PAddr.Addr,
- DeviceUUID: devSB.DevItem.DevUUID,
- })
- reconstructedNode.Data.BodyLeaf[chunkIdx].Body = chunkBody
- }
-
- var err error
- reconstructedNode.Data.Head.Checksum, err = reconstructedNode.Data.CalculateChecksum()
- if err != nil {
- fmt.Printf("Pass 1: ... new node checksum: error: %v\n", err)
- }
-
- if err := reconstructedNode.Write(); err != nil {
- fmt.Printf("Pass 1: ... write new node: error: %v\n", err)
- }
-
- if err := fs.ReInit(ctx); err != nil {
- fmt.Printf("Pass 1: ... re-init mappings: %v\n", err)
- }
-
- sbs, _ := fs.Superblocks()
- for i, sb := range sbs {
- sb.Data.ChunkLevel = reconstructedNode.Data.Head.Level
- sb.Data.Checksum, err = sb.Data.CalculateChecksum()
- if err != nil {
- fmt.Printf("Pass 1: ... calculate superblock %d checksum: %v\n", i, err)
- }
- if err := sb.Write(); err != nil {
- fmt.Printf("Pass 1: ... write superblock %d: %v\n", i, err)
- }
- }
-}