btrfs-progs: convert: Fix a bug leads to discontinuous extents
[btrfs-progs-unstable/devel.git] / btrfsck.h
blobe16f52f59b018f9da2e24a1892e3fdd7ccab172d
1 /*
2 * Copyright (C) 2013 FUJITSU LIMITED. All rights reserved.
3 * Written by Miao Xie <miaox@cn.fujitsu.com>
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.
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.
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.
20 #ifndef __BTRFS_CHECK_H__
21 #define __BTRFS_CHECK_H__
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 */
35 struct block_group_record {
36 struct cache_extent cache;
37 /* Used to identify the orphan block groups */
38 struct list_head list;
40 u64 generation;
42 u64 objectid;
43 u8 type;
44 u64 offset;
46 u64 flags;
49 struct block_group_tree {
50 struct cache_tree tree;
51 struct list_head block_groups;
54 struct device_record {
55 struct rb_node node;
56 u64 devid;
58 u64 generation;
60 u64 objectid;
61 u8 type;
62 u64 offset;
64 u64 total_byte;
65 u64 byte_used;
67 u64 real_used;
70 struct stripe {
71 u64 devid;
72 u64 offset;
73 u8 dev_uuid[BTRFS_UUID_SIZE];
76 struct chunk_record {
77 struct cache_extent cache;
79 struct list_head list;
80 struct list_head dextents;
81 struct block_group_record *bg_rec;
83 u64 generation;
85 u64 objectid;
86 u8 type;
87 u64 offset;
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];
101 struct device_extent_record {
102 struct cache_extent cache;
104 * Used to identify the orphan device extents (the device extents
105 * don't belong to a chunk or a device)
107 struct list_head chunk_list;
108 struct list_head device_list;
110 u64 generation;
112 u64 objectid;
113 u8 type;
114 u64 offset;
116 u64 chunk_objecteid;
117 u64 chunk_offset;
118 u64 length;
121 struct device_extent_tree {
122 struct cache_tree tree;
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.
131 * The usage of no_device_orphans is the same as the first one, but it
132 * is for the device information check.
134 struct list_head no_chunk_orphans;
135 struct list_head no_device_orphans;
138 static inline unsigned long btrfs_chunk_record_size(int num_stripes)
140 return sizeof(struct chunk_record) +
141 sizeof(struct stripe) * num_stripes;
143 void free_chunk_cache_tree(struct cache_tree *chunk_cache);
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
151 static inline int check_num_stripes(u64 type, int num_stripes)
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;
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)
166 cache_tree_init(&tree->tree);
167 INIT_LIST_HEAD(&tree->block_groups);
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);
174 /* For device extent tree */
175 static inline void device_extent_tree_init(struct device_extent_tree *tree)
177 cache_tree_init(&tree->tree);
178 INIT_LIST_HEAD(&tree->no_chunk_orphans);
179 INIT_LIST_HEAD(&tree->no_device_orphans);
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);
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);
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