summaryrefslogtreecommitdiff
path: root/pkg/btrfs/types_item.go
blob: 828ba020a788e6bf622d9d644d7c96108a8d85ca (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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
package btrfs

import (
	"fmt"

	"lukeshu.com/btrfs-tools/pkg/binstruct"
)

type ItemType uint8

const (
	BTRFS_UNTYPED_KEY = ItemType(0)

	// inode items have the data typically returned from stat and store other
	// info about object characteristics.  There is one for every file and dir in
	// the FS
	BTRFS_INODE_ITEM_KEY   = ItemType(1)
	BTRFS_INODE_REF_KEY    = ItemType(12)
	BTRFS_INODE_EXTREF_KEY = ItemType(13)
	BTRFS_XATTR_ITEM_KEY   = ItemType(24)

	BTRFS_VERITY_DESC_ITEM_KEY   = ItemType(36) // new
	BTRFS_VERITY_MERKLE_ITEM_KEY = ItemType(37) // new

	BTRFS_ORPHAN_ITEM_KEY = ItemType(48)

	BTRFS_DIR_LOG_ITEM_KEY  = ItemType(60)
	BTRFS_DIR_LOG_INDEX_KEY = ItemType(72)
	// dir items are the name -> inode pointers in a directory.  There is one
	// for every name in a directory.
	BTRFS_DIR_ITEM_KEY  = ItemType(84)
	BTRFS_DIR_INDEX_KEY = ItemType(96)

	// extent data is for file data
	BTRFS_EXTENT_DATA_KEY = ItemType(108)

	// csum items have the checksums for data in the extents
	BTRFS_CSUM_ITEM_KEY = ItemType(120) // new
	// extent csums are stored in a separate tree and hold csums for
	// an entire extent on disk.
	BTRFS_EXTENT_CSUM_KEY = ItemType(128)

	// root items point to tree roots.  There are typically in the root
	// tree used by the super block to find all the other trees
	BTRFS_ROOT_ITEM_KEY = ItemType(132)

	// root backrefs tie subvols and snapshots to the directory entries that
	// reference them
	BTRFS_ROOT_BACKREF_KEY = ItemType(144)

	// root refs make a fast index for listing all of the snapshots and
	// subvolumes referenced by a given root.  They point directly to the
	// directory item in the root that references the subvol
	BTRFS_ROOT_REF_KEY = ItemType(156)

	// extent items are in the extent map tree.  These record which blocks
	// are used, and how many references there are to each block
	BTRFS_EXTENT_ITEM_KEY = ItemType(168)

	// The same as the BTRFS_EXTENT_ITEM_KEY, except it's metadata we already know
	// the length, so we save the level in key->offset instead of the length.
	BTRFS_METADATA_ITEM_KEY = ItemType(169) // new

	BTRFS_TREE_BLOCK_REF_KEY = ItemType(176)

	BTRFS_EXTENT_DATA_REF_KEY = ItemType(178)

	// old style extent backrefs
	BTRFS_EXTENT_REF_V0_KEY = ItemType(180)

	BTRFS_SHARED_BLOCK_REF_KEY = ItemType(182)

	BTRFS_SHARED_DATA_REF_KEY = ItemType(184)

	// block groups give us hints into the extent allocation trees.  Which
	// blocks are free etc etc
	BTRFS_BLOCK_GROUP_ITEM_KEY = ItemType(192)

	// Every block group is represented in the free space tree by a free space info
	// item, which stores some accounting information. It is keyed on
	// (block_group_start, FREE_SPACE_INFO, block_group_length).
	BTRFS_FREE_SPACE_INFO_KEY = ItemType(198) // new

	// A free space extent tracks an extent of space that is free in a block group.
	// It is keyed on (start, FREE_SPACE_EXTENT, length).
	BTRFS_FREE_SPACE_EXTENT_KEY = ItemType(199) // new

	// When a block group becomes very fragmented, we convert it to use bitmaps
	// instead of extents. A free space bitmap is keyed on
	// (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with
	// (length / sectorsize) bits.
	BTRFS_FREE_SPACE_BITMAP_KEY = ItemType(200) // new

	BTRFS_DEV_EXTENT_KEY = ItemType(204)
	BTRFS_DEV_ITEM_KEY   = ItemType(216)
	BTRFS_CHUNK_ITEM_KEY = ItemType(228)

	// quota groups
	BTRFS_QGROUP_STATUS_KEY   = ItemType(240) // new
	BTRFS_QGROUP_INFO_KEY     = ItemType(242) // new
	BTRFS_QGROUP_LIMIT_KEY    = ItemType(244) // new
	BTRFS_QGROUP_RELATION_KEY = ItemType(246) // new

	// The key type for tree items that are stored persistently, but do not need to
	// exist for extended period of time. The items can exist in any tree.
	//
	// [subtype, BTRFS_TEMPORARY_ITEM_KEY, data]
	//
	// Existing items:
	//
	// - balance status item
	//   (BTRFS_BALANCE_OBJECTID, BTRFS_TEMPORARY_ITEM_KEY, 0)
	BTRFS_TEMPORARY_ITEM_KEY = ItemType(248) // new

	// The key type for tree items that are stored persistently and usually exist
	// for a long period, eg. filesystem lifetime. The item kinds can be status
	// information, stats or preference values. The item can exist in any tree.
	//
	// [subtype, BTRFS_PERSISTENT_ITEM_KEY, data]
	//
	// Existing items:
	//
	// - device statistics, store IO stats in the device tree, one key for all
	//   stats
	//   (BTRFS_DEV_STATS_OBJECTID, BTRFS_DEV_STATS_KEY, 0)
	BTRFS_PERSISTENT_ITEM_KEY = ItemType(249) // new

	// Persistently stores the device replace state in the device tree.
	// The key is built like this: (0, BTRFS_DEV_REPLACE_KEY, 0).
	BTRFS_DEV_REPLACE_KEY = ItemType(250)

	// Stores items that allow to quickly map UUIDs to something else.
	// These items are part of the filesystem UUID tree.
	// The key is built like this:
	// (UUID_upper_64_bits, BTRFS_UUID_KEY*, UUID_lower_64_bits).
	BTRFS_UUID_KEY_SUBVOL          = ItemType(251) // for UUIDs assigned to subvols // new
	BTRFS_UUID_KEY_RECEIVED_SUBVOL = ItemType(252) // for UUIDs assigned to received subvols // new

	// string items are for debugging.  They just store a short string of
	// data in the FS
	BTRFS_STRING_ITEM_KEY = ItemType(253)
)

func (t ItemType) String() string {
	names := map[ItemType]string{
		BTRFS_UNTYPED_KEY:              "UNTYPED",
		BTRFS_INODE_ITEM_KEY:           "INODE_ITEM",
		BTRFS_INODE_REF_KEY:            "INODE_REF",
		BTRFS_INODE_EXTREF_KEY:         "INODE_EXTREF",
		BTRFS_XATTR_ITEM_KEY:           "XATTR_ITEM",
		BTRFS_VERITY_DESC_ITEM_KEY:     "VERITY_DESC_ITEM",
		BTRFS_VERITY_MERKLE_ITEM_KEY:   "VERITY_MERKLE_ITEM",
		BTRFS_ORPHAN_ITEM_KEY:          "ORPHAN_ITEM",
		BTRFS_DIR_LOG_ITEM_KEY:         "DIR_LOG_ITEM",
		BTRFS_DIR_LOG_INDEX_KEY:        "DIR_LOG_INDEX",
		BTRFS_DIR_ITEM_KEY:             "DIR_ITEM",
		BTRFS_DIR_INDEX_KEY:            "DIR_INDEX",
		BTRFS_EXTENT_DATA_KEY:          "EXTENT_DATA",
		BTRFS_CSUM_ITEM_KEY:            "CSUM_ITEM",
		BTRFS_EXTENT_CSUM_KEY:          "EXTENT_CSUM",
		BTRFS_ROOT_ITEM_KEY:            "ROOT_ITEM",
		BTRFS_ROOT_BACKREF_KEY:         "ROOT_BACKREF",
		BTRFS_ROOT_REF_KEY:             "ROOT_REF",
		BTRFS_EXTENT_ITEM_KEY:          "EXTENT_ITEM",
		BTRFS_METADATA_ITEM_KEY:        "METADATA_ITEM",
		BTRFS_TREE_BLOCK_REF_KEY:       "TREE_BLOCK_REF",
		BTRFS_EXTENT_DATA_REF_KEY:      "EXTENT_DATA_REF",
		BTRFS_EXTENT_REF_V0_KEY:        "EXTENT_REF_V0",
		BTRFS_SHARED_BLOCK_REF_KEY:     "SHARED_BLOCK_REF",
		BTRFS_SHARED_DATA_REF_KEY:      "SHARED_DATA_REF",
		BTRFS_BLOCK_GROUP_ITEM_KEY:     "BLOCK_GROUP_ITEM",
		BTRFS_FREE_SPACE_INFO_KEY:      "FREE_SPACE_INFO",
		BTRFS_FREE_SPACE_EXTENT_KEY:    "FREE_SPACE_EXTENT",
		BTRFS_FREE_SPACE_BITMAP_KEY:    "FREE_SPACE_BITMAP",
		BTRFS_DEV_EXTENT_KEY:           "DEV_EXTENT",
		BTRFS_DEV_ITEM_KEY:             "DEV_ITEM",
		BTRFS_CHUNK_ITEM_KEY:           "CHUNK_ITEM",
		BTRFS_QGROUP_STATUS_KEY:        "QGROUP_STATUS",
		BTRFS_QGROUP_INFO_KEY:          "QGROUP_INFO",
		BTRFS_QGROUP_LIMIT_KEY:         "QGROUP_LIMIT",
		BTRFS_QGROUP_RELATION_KEY:      "QGROUP_RELATION",
		BTRFS_TEMPORARY_ITEM_KEY:       "TEMPORARY_ITEM",
		BTRFS_PERSISTENT_ITEM_KEY:      "PERSISTENT_ITEM",
		BTRFS_DEV_REPLACE_KEY:          "DEV_REPLACE",
		BTRFS_UUID_KEY_SUBVOL:          "UUID_KEY_SUBVOL",
		BTRFS_UUID_KEY_RECEIVED_SUBVOL: "UUID_KEY_RECEIVED_SUBVOL",
		BTRFS_STRING_ITEM_KEY:          "STRING_ITEM",
	}
	if name, ok := names[t]; ok {
		return name
	}
	return fmt.Sprintf("%d", t)
}

type DevItem struct {
	DeviceID ObjID `bin:"off=0,    siz=8"` // device ID

	NumBytes     uint64 `bin:"off=8,    siz=8"` // number of bytes
	NumBytesUsed uint64 `bin:"off=10,   siz=8"` // number of bytes used

	IOOptimalAlign uint32 `bin:"off=18,   siz=4"` // optimal I/O align
	IOOptimalWidth uint32 `bin:"off=1c,   siz=4"` // optimal I/O width
	IOMinSize      uint32 `bin:"off=20,   siz=4"` // minimal I/O size (sector size)

	Type        uint64     `bin:"off=24,   siz=8"` // type
	Generation  Generation `bin:"off=2c,   siz=8"` // generation
	StartOffset uint64     `bin:"off=34,   siz=8"` // start offset
	DevGroup    uint32     `bin:"off=3c,   siz=4"` // dev group
	SeekSpeed   uint8      `bin:"off=40,   siz=1"` // seek speed
	Bandwidth   uint8      `bin:"off=41,   siz=1"` // bandwidth

	DevUUID UUID `bin:"off=42,   siz=10"` // device UUID
	FSUUID  UUID `bin:"off=52,   siz=10"` // FS UUID

	binstruct.End `bin:"off=62"`
}

type InodeRefItem struct {
	Index         int64 `bin:"off=0, siz=8"`
	NameLen       int16 `bin:"off=8, siz=2"`
	binstruct.End `bin:"off=a"`
	Name          []byte `bin:"-"`
}

type InodeItem struct {
	Generation    int64    `bin:"off=0, siz=8"`
	TransID       int64    `bin:"off=8, siz=8"`
	Size          int64    `bin:"off=10, siz=8"`
	NumBytes      int64    `bin:"off=18, siz=8"`
	BlockGroup    int64    `bin:"off=20, siz=8"`
	NLink         int32    `bin:"off=28, siz=4"`
	UID           int32    `bin:"off=2C, siz=4"`
	GID           int32    `bin:"off=30, siz=4"`
	Mode          int32    `bin:"off=34, siz=4"`
	RDev          int64    `bin:"off=38, siz=8"`
	Flags         uint64   `bin:"off=40, siz=8"`
	Sequence      int64    `bin:"off=48, siz=8"`
	Reserved      [4]int64 `bin:"off=50, siz=20"`
	ATime         Time     `bin:"off=70, siz=c"`
	CTime         Time     `bin:"off=7c, siz=c"`
	MTime         Time     `bin:"off=88, siz=c"`
	OTime         Time     `bin:"off=94, siz=c"`
	binstruct.End `bin:"off=a0"`
}

type RootItem struct {
	Inode         InodeItem     `bin:"off=0, siz=a0"`
	Generation    int64         `bin:"off=a0, siz=8"`
	RootDirID     int64         `bin:"off=a8, siz=8"`
	ByteNr        LogicalAddr   `bin:"off=b0, siz=8"`
	ByteLimit     int64         `bin:"off=b8, siz=8"`
	BytesUsed     int64         `bin:"off=c0, siz=8"`
	LastSnapshot  int64         `bin:"off=c8, siz=8"`
	Flags         RootItemFlags `bin:"off=d0, siz=8"`
	Refs          int32         `bin:"off=d8, siz=4"`
	DropProgress  Key           `bin:"off=dc, siz=11"`
	DropLevel     uint8         `bin:"off=ed, siz=1"`
	Level         uint8         `bin:"off=ee, siz=1"`
	GenerationV2  int64         `bin:"off=ef, siz=8"`
	UUID          UUID          `bin:"off=F7, siz=10"`
	ParentUUID    UUID          `bin:"off=107, siz=10"`
	ReceivedUUID  UUID          `bin:"off=117, siz=10"`
	CTransID      int64         `bin:"off=127, siz=8"`
	OTransID      int64         `bin:"off=12f, siz=8"`
	STransID      int64         `bin:"off=137, siz=8"`
	RTransID      int64         `bin:"off=13f, siz=8"`
	CTime         Time          `bin:"off=147, siz=c"`
	OTime         Time          `bin:"off=153, siz=c"`
	STime         Time          `bin:"off=15F, siz=c"`
	RTime         Time          `bin:"off=16b, siz=c"`
	GlobalTreeID  ObjID         `bin:"off=177, siz=8"`
	Reserved      [7]int64      `bin:"off=17f, siz=38"`
	binstruct.End `bin:"off=1b7"`
}