diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2013-07-03 21:25:17 +0800 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-07-03 14:06:55 -0400 |
commit | 30d5c8a49f088d76fb2806240393fc035ed75290 (patch) | |
tree | f5a1652ad936c259f1cbc653a61384b3b2a31c2a /volumes.c | |
parent | 65534643f6e919c39f58bef31ebcffd48d8b1895 (diff) |
Btrfs-progs: Add chunk recover function - using old chunk items
Add chunk-recover program to check or rebuild chunk tree when the system
chunk array or chunk tree is broken.
Due to the importance of the system chunk array and chunk tree, if one of
them is broken, the whole btrfs will be broken even other data are OK.
But we have some hint(fsid, checksum...) to salvage the old metadata.
So this function will first scan the whole file system and collect the
needed data(chunk/block group/dev extent), and check for the references
between them. If the references are OK, the chunk tree can be rebuilt and
luckily the file system will be mountable.
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'volumes.c')
-rw-r--r-- | volumes.c | 11 |
1 files changed, 4 insertions, 7 deletions
@@ -52,9 +52,6 @@ static inline int nr_data_stripes(struct map_lookup *map) #define is_parity_stripe(x) ( ((x) == BTRFS_RAID5_P_STRIPE) || ((x) == BTRFS_RAID6_Q_STRIPE) ) -#define map_lookup_size(n) (sizeof(struct map_lookup) + \ - (sizeof(struct btrfs_bio_stripe) * (n))) - static LIST_HEAD(fs_uuids); static struct btrfs_device *__find_device(struct list_head *head, u64 devid, @@ -823,7 +820,7 @@ again: if (!chunk) return -ENOMEM; - map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); + map = kmalloc(btrfs_map_lookup_size(num_stripes), GFP_NOFS); if (!map) { kfree(chunk); return -ENOMEM; @@ -935,7 +932,7 @@ int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans, if (!chunk) return -ENOMEM; - map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); + map = kmalloc(btrfs_map_lookup_size(num_stripes), GFP_NOFS); if (!map) { kfree(chunk); return -ENOMEM; @@ -1420,7 +1417,7 @@ int btrfs_bootstrap_super_map(struct btrfs_mapping_tree *map_tree, list_for_each(cur, &fs_devices->devices) { num_stripes++; } - map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); + map = kmalloc(btrfs_map_lookup_size(num_stripes), GFP_NOFS); if (!map) return -ENOMEM; @@ -1517,7 +1514,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, } num_stripes = btrfs_chunk_num_stripes(leaf, chunk); - map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS); + map = kmalloc(btrfs_map_lookup_size(num_stripes), GFP_NOFS); if (!map) return -ENOMEM; |