diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2013-07-03 21:25:19 +0800 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-07-03 14:06:55 -0400 |
commit | 3b9e6dd4379ed8f2fb50bee8dce4245038498211 (patch) | |
tree | 62d67b301d3e8981a74703f4c0fd7591b179aaf4 /cmds-check.c | |
parent | 68acb1075e0da2d9f170cb52f561c5225787dbdf (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.c | 31 |
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; |