summaryrefslogtreecommitdiff
path: root/lib/btrfs/btrfsitem/item_root.go
blob: 8bdc3dff5bb439019c4230fb303df712d8e0526a (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
// Copyright (C) 2022-2023  Luke Shumaker <lukeshu@lukeshu.com>
//
// SPDX-License-Identifier: GPL-2.0-or-later

package btrfsitem

import (
	"git.lukeshu.com/btrfs-progs-ng/lib/binstruct"
	"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsprim"
	"git.lukeshu.com/btrfs-progs-ng/lib/btrfs/btrfsvol"
	"git.lukeshu.com/btrfs-progs-ng/lib/fmtutil"
)

// A Root goes in the ROOT_TREE and defines one of the other trees in
// the filesystem.  All trees have a Root item describing them, except
// for the ROOT_TREE, CHUNK_TREE, TREE_LOG, and BLOCK_GROUP_TREE,
// which are defined directly in the superblock.
//
// Key:
//
//	key.objectid = tree ID
//	key.offset   = one of:
//	   - 0 if objectid is one of the BTRFS_*_TREE_OBJECTID defines or a non-snapshot volume; or
//	   - transaction_id of when this snapshot was created
//
// This tree might contain nodes with node.Head.Owner set to the
// root.ParentUUID tree, *if* the node.Head.Generation is
// less-than-or-equal-to the root's key.offset.  The "or-equal-to"
// part of that might be surprising, which is why I called it out.
type Root struct { // trivial ROOT_ITEM=132
	Inode         Inode                `bin:"off=0x000, siz=0xa0"` // ???
	Generation    btrfsprim.Generation `bin:"off=0x0a0, siz=0x08"`
	RootDirID     btrfsprim.ObjID      `bin:"off=0x0a8, siz=0x08"` // inode number of the root inode
	ByteNr        btrfsvol.LogicalAddr `bin:"off=0x0b0, siz=0x08"` // root node
	ByteLimit     int64                `bin:"off=0x0b8, siz=0x08"` // always 0 (unused)
	BytesUsed     int64                `bin:"off=0x0c0, siz=0x08"`
	LastSnapshot  int64                `bin:"off=0x0c8, siz=0x08"`
	Flags         RootFlags            `bin:"off=0x0d0, siz=0x08"`
	Refs          int32                `bin:"off=0x0d8, siz=0x04"`
	DropProgress  btrfsprim.Key        `bin:"off=0x0dc, siz=0x11"`
	DropLevel     uint8                `bin:"off=0x0ed, siz=0x01"`
	Level         uint8                `bin:"off=0x0ee, siz=0x01"`
	GenerationV2  btrfsprim.Generation `bin:"off=0x0ef, siz=0x08"`
	UUID          btrfsprim.UUID       `bin:"off=0x0f7, siz=0x10"`
	ParentUUID    btrfsprim.UUID       `bin:"off=0x107, siz=0x10"`
	ReceivedUUID  btrfsprim.UUID       `bin:"off=0x117, siz=0x10"`
	CTransID      int64                `bin:"off=0x127, siz=0x08"`
	OTransID      int64                `bin:"off=0x12f, siz=0x08"`
	STransID      int64                `bin:"off=0x137, siz=0x08"`
	RTransID      int64                `bin:"off=0x13f, siz=0x08"`
	CTime         btrfsprim.Time       `bin:"off=0x147, siz=0x0c"`
	OTime         btrfsprim.Time       `bin:"off=0x153, siz=0x0c"`
	STime         btrfsprim.Time       `bin:"off=0x15f, siz=0x0c"`
	RTime         btrfsprim.Time       `bin:"off=0x16b, siz=0x0c"`
	GlobalTreeID  btrfsprim.ObjID      `bin:"off=0x177, siz=0x08"` // ???
	Reserved      [7]int64             `bin:"off=0x17f, siz=0x38"`
	binstruct.End `bin:"off=0x1b7"`
}

type RootFlags uint64

const (
	ROOT_SUBVOL_RDONLY RootFlags = 1 << iota
)

var rootFlagNames = []string{
	"SUBVOL_RDONLY",
}

func (f RootFlags) Has(req RootFlags) bool { return f&req == req }
func (f RootFlags) String() string         { return fmtutil.BitfieldString(f, rootFlagNames, fmtutil.HexLower) }