summaryrefslogtreecommitdiff
path: root/lib/btrfs/btrfsprim/objid.go
blob: 5896030ad876a7b249bd98a8abd6c81e6b7025a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (C) 2022-2023  Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later

package btrfsprim

import (
	"fmt"
)

type ObjID uint64

const maxUint64pp = 0x1_00000000_00000000

const (
	// The IDs of the various trees
	ROOT_TREE_OBJECTID        ObjID = 1 // holds pointers to all of the tree roots
	EXTENT_TREE_OBJECTID      ObjID = 2 // stores information about which extents are in use, and reference counts
	CHUNK_TREE_OBJECTID       ObjID = 3 // chunk tree stores translations from logical -> physical block numbering
	DEV_TREE_OBJECTID         ObjID = 4 // stores info about which areas of a given device are in use; one per device
	FS_TREE_OBJECTID          ObjID = 5 // one per subvolume, storing files and directories
	ROOT_TREE_DIR_OBJECTID    ObjID = 6 // directory objectid inside the root tree
	CSUM_TREE_OBJECTID        ObjID = 7 // holds checksums of all the data extents
	QUOTA_TREE_OBJECTID       ObjID = 8
	UUID_TREE_OBJECTID        ObjID = 9  // for storing items that use the UUID_*_KEY
	FREE_SPACE_TREE_OBJECTID  ObjID = 10 // tracks free space in block groups.
	BLOCK_GROUP_TREE_OBJECTID ObjID = 11 // hold the block group items.

	// Objects in the DEV_TREE
	DEV_STATS_OBJECTID ObjID = 0 // device stats in the device tree

	// ???
	BALANCE_OBJECTID         ObjID = maxUint64pp - 4 // for storing balance parameters in the root tree
	ORPHAN_OBJECTID          ObjID = maxUint64pp - 5 // orphan objectid for tracking unlinked/truncated files
	TREE_LOG_OBJECTID        ObjID = maxUint64pp - 6 // does write ahead logging to speed up fsyncs
	TREE_LOG_FIXUP_OBJECTID  ObjID = maxUint64pp - 7
	TREE_RELOC_OBJECTID      ObjID = maxUint64pp - 8 // space balancing
	DATA_RELOC_TREE_OBJECTID ObjID = maxUint64pp - 9
	EXTENT_CSUM_OBJECTID     ObjID = maxUint64pp - 10 // extent checksums all have this objectid
	FREE_SPACE_OBJECTID      ObjID = maxUint64pp - 11 // For storing free space cache
	FREE_INO_OBJECTID        ObjID = maxUint64pp - 12 // stores the inode number for the free-ino cache

	MULTIPLE_OBJECTIDS ObjID = maxUint64pp - 255 // dummy objectid represents multiple objectids

	// All files have objectids in this range.
	FIRST_FREE_OBJECTID ObjID = 256
	LAST_FREE_OBJECTID  ObjID = maxUint64pp - 256

	FIRST_CHUNK_TREE_OBJECTID ObjID = 256

	// Objects in the CHUNK_TREE
	DEV_ITEMS_OBJECTID ObjID = 1

	// ???
	EMPTY_SUBVOL_DIR_OBJECTID ObjID = 2
)

func (id ObjID) Format(typ ItemType) string {
	switch typ {
	case PERSISTENT_ITEM_KEY:
		names := map[ObjID]string{
			DEV_STATS_OBJECTID: "DEV_STATS",
		}
		if name, ok := names[id]; ok {
			return name
		}
		return fmt.Sprintf("%d", int64(id))
	case DEV_EXTENT_KEY:
		return fmt.Sprintf("%d", int64(id))
	case QGROUP_RELATION_KEY:
		//nolint:gomnd // The left 48 bits are the "qgroup level", and the right 16 bits are the subvolume ID.
		return fmt.Sprintf("%d/%d",
			uint64(id)>>48,
			uint64(id)&((1<<48)-1))
	case UUID_SUBVOL_KEY, UUID_RECEIVED_SUBVOL_KEY:
		return fmt.Sprintf("%#016x", uint64(id))
	case DEV_ITEM_KEY:
		names := map[ObjID]string{
			BALANCE_OBJECTID:         "BALANCE",
			ORPHAN_OBJECTID:          "ORPHAN",
			TREE_LOG_OBJECTID:        "TREE_LOG",
			TREE_LOG_FIXUP_OBJECTID:  "TREE_LOG_FIXUP",
			TREE_RELOC_OBJECTID:      "TREE_RELOC",
			DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE",
			EXTENT_CSUM_OBJECTID:     "EXTENT_CSUM",
			FREE_SPACE_OBJECTID:      "FREE_SPACE",
			FREE_INO_OBJECTID:        "FREE_INO",
			MULTIPLE_OBJECTIDS:       "MULTIPLE",

			DEV_ITEMS_OBJECTID: "DEV_ITEMS",
		}
		if name, ok := names[id]; ok {
			return name
		}
		return fmt.Sprintf("%d", int64(id))
	case CHUNK_ITEM_KEY:
		names := map[ObjID]string{
			BALANCE_OBJECTID:         "BALANCE",
			ORPHAN_OBJECTID:          "ORPHAN",
			TREE_LOG_OBJECTID:        "TREE_LOG",
			TREE_LOG_FIXUP_OBJECTID:  "TREE_LOG_FIXUP",
			TREE_RELOC_OBJECTID:      "TREE_RELOC",
			DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE",
			EXTENT_CSUM_OBJECTID:     "EXTENT_CSUM",
			FREE_SPACE_OBJECTID:      "FREE_SPACE",
			FREE_INO_OBJECTID:        "FREE_INO",
			MULTIPLE_OBJECTIDS:       "MULTIPLE",

			FIRST_CHUNK_TREE_OBJECTID: "FIRST_CHUNK_TREE",
		}
		if name, ok := names[id]; ok {
			return name
		}
		return fmt.Sprintf("%d", int64(id))
	default:
		names := map[ObjID]string{
			BALANCE_OBJECTID:         "BALANCE",
			ORPHAN_OBJECTID:          "ORPHAN",
			TREE_LOG_OBJECTID:        "TREE_LOG",
			TREE_LOG_FIXUP_OBJECTID:  "TREE_LOG_FIXUP",
			TREE_RELOC_OBJECTID:      "TREE_RELOC",
			DATA_RELOC_TREE_OBJECTID: "DATA_RELOC_TREE",
			EXTENT_CSUM_OBJECTID:     "EXTENT_CSUM",
			FREE_SPACE_OBJECTID:      "FREE_SPACE",
			FREE_INO_OBJECTID:        "FREE_INO",
			MULTIPLE_OBJECTIDS:       "MULTIPLE",

			ROOT_TREE_OBJECTID:        "ROOT_TREE",
			EXTENT_TREE_OBJECTID:      "EXTENT_TREE",
			CHUNK_TREE_OBJECTID:       "CHUNK_TREE",
			DEV_TREE_OBJECTID:         "DEV_TREE",
			FS_TREE_OBJECTID:          "FS_TREE",
			ROOT_TREE_DIR_OBJECTID:    "ROOT_TREE_DIR",
			CSUM_TREE_OBJECTID:        "CSUM_TREE",
			QUOTA_TREE_OBJECTID:       "QUOTA_TREE",
			UUID_TREE_OBJECTID:        "UUID_TREE",
			FREE_SPACE_TREE_OBJECTID:  "FREE_SPACE_TREE",
			BLOCK_GROUP_TREE_OBJECTID: "BLOCK_GROUP_TREE",
		}
		if name, ok := names[id]; ok {
			return name
		}
		return fmt.Sprintf("%d", int64(id))
	}
}

func (id ObjID) String() string {
	return id.Format(UNTYPED_KEY)
}