summaryrefslogtreecommitdiff
path: root/cmds-check.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-07-03 21:25:19 +0800
committerChris Mason <chris.mason@fusionio.com>2013-07-03 14:06:55 -0400
commit3b9e6dd4379ed8f2fb50bee8dce4245038498211 (patch)
tree62d67b301d3e8981a74703f4c0fd7591b179aaf4 /cmds-check.c
parent68acb1075e0da2d9f170cb52f561c5225787dbdf (diff)
Btrfs-progs: Add chunk rebuild function for RAID1/SINGLE/DUP
Add chunk rebuild for RAID1/SINGLE/DUP to chunk-recover command. Before this patch chunk-recover can only scan and reuse the old chunk data to recover. With this patch, chunk-recover can use the reference between chunk/block group/dev extent to rebuild the whole chunk tree even when old chunks are not available. 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 'cmds-check.c')
-rw-r--r--cmds-check.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/cmds-check.c b/cmds-check.c
index c3c7575e..185d91fc 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -4926,24 +4926,24 @@ repair_abort:
return err;
}
-static u64 calc_stripe_length(struct chunk_record *chunk_rec)
+u64 calc_stripe_length(u64 type, u64 length, int num_stripes)
{
u64 stripe_size;
- if (chunk_rec->type_flags & BTRFS_BLOCK_GROUP_RAID0) {
- stripe_size = chunk_rec->length;
- stripe_size /= chunk_rec->num_stripes;
- } else if (chunk_rec->type_flags & BTRFS_BLOCK_GROUP_RAID10) {
- stripe_size = chunk_rec->length * 2;
- stripe_size /= chunk_rec->num_stripes;
- } else if (chunk_rec->type_flags & BTRFS_BLOCK_GROUP_RAID5) {
- stripe_size = chunk_rec->length;
- stripe_size /= (chunk_rec->num_stripes - 1);
- } else if (chunk_rec->type_flags & BTRFS_BLOCK_GROUP_RAID6) {
- stripe_size = chunk_rec->length;
- stripe_size /= (chunk_rec->num_stripes - 2);
+ if (type & BTRFS_BLOCK_GROUP_RAID0) {
+ stripe_size = length;
+ stripe_size /= num_stripes;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID10) {
+ stripe_size = length * 2;
+ stripe_size /= num_stripes;
+ } else if (type & BTRFS_BLOCK_GROUP_RAID5) {
+ stripe_size = length;
+ stripe_size /= (num_stripes - 1);
+ } else if (type & BTRFS_BLOCK_GROUP_RAID6) {
+ stripe_size = length;
+ stripe_size /= (num_stripes - 2);
} else {
- stripe_size = chunk_rec->length;
+ stripe_size = length;
}
return stripe_size;
}
@@ -5006,7 +5006,8 @@ static int check_chunk_refs(struct chunk_record *chunk_rec,
ret = -1;
}
- length = calc_stripe_length(chunk_rec);
+ length = calc_stripe_length(chunk_rec->type_flags, chunk_rec->length,
+ chunk_rec->num_stripes);
for (i = 0; i < chunk_rec->num_stripes; ++i) {
devid = chunk_rec->stripes[i].devid;
offset = chunk_rec->stripes[i].offset;