btrfs-progs: Remove superfluous BUG_ON check.
[platform/upstream/btrfs-progs.git] / btrfsck.h
1 /*
2  * Copyright (C) 2013 Fujitsu.  All rights reserved.
3  * Written by Miao Xie <miaox@cn.fujitsu.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public
7  * License v2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 021110-1307, USA.
18  */
19
20 #ifndef __CHUNK_CHECK_H__
21 #define __CHUNK_CHECK_H__
22
23 #if BTRFS_FLAT_INCLUDES
24 #include "kerncompat.h"
25 #include "extent-cache.h"
26 #include "list.h"
27 #else
28 #include <btrfs/kerncompat.h>
29 #include <btrfs/extent-cache.h>
30 #include <btrfs/list.h>
31 #endif /* BTRFS_FLAT_INCLUDES */
32
33 struct block_group_record {
34         struct cache_extent cache;
35         /* Used to identify the orphan block groups */
36         struct list_head list;
37
38         u64 generation;
39
40         u64 objectid;
41         u8  type;
42         u64 offset;
43
44         u64 flags;
45 };
46
47 struct block_group_tree {
48         struct cache_tree tree;
49         struct list_head block_groups;
50 };
51
52 struct device_record {
53         struct rb_node node;
54         u64 devid;
55
56         u64 generation;
57
58         u64 objectid;
59         u8  type;
60         u64 offset;
61
62         u64 total_byte;
63         u64 byte_used;
64
65         u64 real_used;
66 };
67
68 struct stripe {
69         u64 devid;
70         u64 offset;
71         u8 dev_uuid[BTRFS_UUID_SIZE];
72 };
73
74 struct chunk_record {
75         struct cache_extent cache;
76
77         struct list_head list;
78         struct list_head dextents;
79         struct block_group_record *bg_rec;
80
81         u64 generation;
82
83         u64 objectid;
84         u8  type;
85         u64 offset;
86
87         u64 owner;
88         u64 length;
89         u64 type_flags;
90         u64 stripe_len;
91         u16 num_stripes;
92         u16 sub_stripes;
93         u32 io_align;
94         u32 io_width;
95         u32 sector_size;
96         struct stripe stripes[0];
97 };
98
99 struct device_extent_record {
100         struct cache_extent cache;
101         /*
102          * Used to identify the orphan device extents (the device extents
103          * don't belong to a chunk or a device)
104          */
105         struct list_head chunk_list;
106         struct list_head device_list;
107
108         u64 generation;
109
110         u64 objectid;
111         u8  type;
112         u64 offset;
113
114         u64 chunk_objecteid;
115         u64 chunk_offset;
116         u64 length;
117 };
118
119 struct device_extent_tree {
120         struct cache_tree tree;
121         /*
122          * The idea is:
123          * When checking the chunk information, we move the device extents
124          * that has its chunk to the chunk's device extents list. After the
125          * check, if there are still some device extents in no_chunk_orphans,
126          * it means there are some device extents which don't belong to any
127          * chunk.
128          *
129          * The usage of no_device_orphans is the same as the first one, but it
130          * is for the device information check.
131          */
132         struct list_head no_chunk_orphans;
133         struct list_head no_device_orphans;
134 };
135
136 static inline unsigned long btrfs_chunk_record_size(int num_stripes)
137 {
138         return sizeof(struct chunk_record) +
139                sizeof(struct stripe) * num_stripes;
140 }
141 void free_chunk_cache_tree(struct cache_tree *chunk_cache);
142
143 u64 calc_stripe_length(u64 type, u64 length, int num_stripes);
144 /* For block group tree */
145 static inline void block_group_tree_init(struct block_group_tree *tree)
146 {
147         cache_tree_init(&tree->tree);
148         INIT_LIST_HEAD(&tree->block_groups);
149 }
150
151 int insert_block_group_record(struct block_group_tree *tree,
152                               struct block_group_record *bg_rec);
153 void free_block_group_tree(struct block_group_tree *tree);
154
155 /* For device extent tree */
156 static inline void device_extent_tree_init(struct device_extent_tree *tree)
157 {
158         cache_tree_init(&tree->tree);
159         INIT_LIST_HEAD(&tree->no_chunk_orphans);
160         INIT_LIST_HEAD(&tree->no_device_orphans);
161 }
162
163 int insert_device_extent_record(struct device_extent_tree *tree,
164                                 struct device_extent_record *de_rec);
165 void free_device_extent_tree(struct device_extent_tree *tree);
166
167
168 /* Create various in-memory record by on-disk data */
169 struct chunk_record *btrfs_new_chunk_record(struct extent_buffer *leaf,
170                                             struct btrfs_key *key,
171                                             int slot);
172 struct block_group_record *
173 btrfs_new_block_group_record(struct extent_buffer *leaf, struct btrfs_key *key,
174                              int slot);
175 struct device_extent_record *
176 btrfs_new_device_extent_record(struct extent_buffer *leaf,
177                                struct btrfs_key *key, int slot);
178
179 int check_chunks(struct cache_tree *chunk_cache,
180                  struct block_group_tree *block_group_cache,
181                  struct device_extent_tree *dev_extent_cache,
182                  struct list_head *good, struct list_head *bad, int silent);
183 #endif