btrfs-progs: convert: Fix a bug that makes convert asserts at scan time
[platform/upstream/btrfs-progs.git] / btrfsck.h
1 /*
2  * Copyright (C) 2013 FUJITSU LIMITED.  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 __BTRFS_CHECK_H__
21 #define __BTRFS_CHECK_H__
22
23 #if BTRFS_FLAT_INCLUDES
24 #include "kerncompat.h"
25 #include "ctree.h"
26 #include "extent-cache.h"
27 #include "list.h"
28 #else
29 #include <btrfs/kerncompat.h>
30 #include <btrfs/ctree.h>
31 #include <btrfs/extent-cache.h>
32 #include <btrfs/list.h>
33 #endif /* BTRFS_FLAT_INCLUDES */
34
35 struct block_group_record {
36         struct cache_extent cache;
37         /* Used to identify the orphan block groups */
38         struct list_head list;
39
40         u64 generation;
41
42         u64 objectid;
43         u8  type;
44         u64 offset;
45
46         u64 flags;
47 };
48
49 struct block_group_tree {
50         struct cache_tree tree;
51         struct list_head block_groups;
52 };
53
54 struct device_record {
55         struct rb_node node;
56         u64 devid;
57
58         u64 generation;
59
60         u64 objectid;
61         u8  type;
62         u64 offset;
63
64         u64 total_byte;
65         u64 byte_used;
66
67         u64 real_used;
68 };
69
70 struct stripe {
71         u64 devid;
72         u64 offset;
73         u8 dev_uuid[BTRFS_UUID_SIZE];
74 };
75
76 struct chunk_record {
77         struct cache_extent cache;
78
79         struct list_head list;
80         struct list_head dextents;
81         struct block_group_record *bg_rec;
82
83         u64 generation;
84
85         u64 objectid;
86         u8  type;
87         u64 offset;
88
89         u64 owner;
90         u64 length;
91         u64 type_flags;
92         u64 stripe_len;
93         u16 num_stripes;
94         u16 sub_stripes;
95         u32 io_align;
96         u32 io_width;
97         u32 sector_size;
98         struct stripe stripes[0];
99 };
100
101 struct device_extent_record {
102         struct cache_extent cache;
103         /*
104          * Used to identify the orphan device extents (the device extents
105          * don't belong to a chunk or a device)
106          */
107         struct list_head chunk_list;
108         struct list_head device_list;
109
110         u64 generation;
111
112         u64 objectid;
113         u8  type;
114         u64 offset;
115
116         u64 chunk_objecteid;
117         u64 chunk_offset;
118         u64 length;
119 };
120
121 struct device_extent_tree {
122         struct cache_tree tree;
123         /*
124          * The idea is:
125          * When checking the chunk information, we move the device extents
126          * that has its chunk to the chunk's device extents list. After the
127          * check, if there are still some device extents in no_chunk_orphans,
128          * it means there are some device extents which don't belong to any
129          * chunk.
130          *
131          * The usage of no_device_orphans is the same as the first one, but it
132          * is for the device information check.
133          */
134         struct list_head no_chunk_orphans;
135         struct list_head no_device_orphans;
136 };
137
138 static inline unsigned long btrfs_chunk_record_size(int num_stripes)
139 {
140         return sizeof(struct chunk_record) +
141                sizeof(struct stripe) * num_stripes;
142 }
143 void free_chunk_cache_tree(struct cache_tree *chunk_cache);
144
145 /*
146  * Function to check validation for num_stripes, or it can call
147  * float point error for 0 division
148  * return < 0 for invalid combination
149  * return 0 for valid combination
150  */
151 static inline int check_num_stripes(u64 type, int num_stripes)
152 {
153         if (num_stripes == 0)
154                 return -1;
155         if (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes <= 1)
156                 return -1;
157         if (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes <= 2)
158                 return -1;
159         return 0;
160 }
161
162 u64 calc_stripe_length(u64 type, u64 length, int num_stripes);
163 /* For block group tree */
164 static inline void block_group_tree_init(struct block_group_tree *tree)
165 {
166         cache_tree_init(&tree->tree);
167         INIT_LIST_HEAD(&tree->block_groups);
168 }
169
170 int insert_block_group_record(struct block_group_tree *tree,
171                               struct block_group_record *bg_rec);
172 void free_block_group_tree(struct block_group_tree *tree);
173
174 /* For device extent tree */
175 static inline void device_extent_tree_init(struct device_extent_tree *tree)
176 {
177         cache_tree_init(&tree->tree);
178         INIT_LIST_HEAD(&tree->no_chunk_orphans);
179         INIT_LIST_HEAD(&tree->no_device_orphans);
180 }
181
182 int insert_device_extent_record(struct device_extent_tree *tree,
183                                 struct device_extent_record *de_rec);
184 void free_device_extent_tree(struct device_extent_tree *tree);
185
186
187 /* Create various in-memory record by on-disk data */
188 struct chunk_record *btrfs_new_chunk_record(struct extent_buffer *leaf,
189                                             struct btrfs_key *key,
190                                             int slot);
191 struct block_group_record *
192 btrfs_new_block_group_record(struct extent_buffer *leaf, struct btrfs_key *key,
193                              int slot);
194 struct device_extent_record *
195 btrfs_new_device_extent_record(struct extent_buffer *leaf,
196                                struct btrfs_key *key, int slot);
197
198 int check_chunks(struct cache_tree *chunk_cache,
199                  struct block_group_tree *block_group_cache,
200                  struct device_extent_tree *dev_extent_cache,
201                  struct list_head *good, struct list_head *bad,
202                  struct list_head *rebuild, int silent);
203 #endif