aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-03-25 16:50:33 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:01 -0400
commit593060d756e0c2382d59cf00d5f3b9e3a336c408 (patch)
treec102f8abd9210eeba8ae4e7f6626b80cfed1b8d8 /fs/btrfs
parent8a4b83cc8bd75fca29ac68615896d9e92820e7c2 (diff)
Btrfs: Implement raid0 when multiple devices are present
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent-tree.c102
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/volumes.c130
5 files changed, 173 insertions, 66 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 7556f8319c60..f43dfe7ffe6d 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -413,6 +413,7 @@ struct btrfs_csum_item {
413#define BTRFS_BLOCK_GROUP_DATA (1 << 0) 413#define BTRFS_BLOCK_GROUP_DATA (1 << 0)
414#define BTRFS_BLOCK_GROUP_SYSTEM (1 << 1) 414#define BTRFS_BLOCK_GROUP_SYSTEM (1 << 1)
415#define BTRFS_BLOCK_GROUP_METADATA (1 << 2) 415#define BTRFS_BLOCK_GROUP_METADATA (1 << 2)
416#define BTRFS_BLOCK_GROUP_RAID0 (1 << 3)
416 417
417 418
418struct btrfs_block_group_item { 419struct btrfs_block_group_item {
@@ -498,6 +499,8 @@ struct btrfs_fs_info {
498 u64 delalloc_bytes; 499 u64 delalloc_bytes;
499 u64 last_alloc; 500 u64 last_alloc;
500 u64 last_data_alloc; 501 u64 last_data_alloc;
502 int extra_data_alloc_bits;
503 int extra_alloc_bits;
501}; 504};
502 505
503/* 506/*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index f971a29e4f20..d8474796dea2 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -736,6 +736,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
736 fs_info->total_pinned = 0; 736 fs_info->total_pinned = 0;
737 fs_info->last_alloc = 0; 737 fs_info->last_alloc = 0;
738 fs_info->last_data_alloc = 0; 738 fs_info->last_data_alloc = 0;
739 fs_info->extra_alloc_bits = 0;
740 fs_info->extra_data_alloc_bits = 0;
739 741
740#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) 742#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
741 INIT_WORK(&fs_info->trans_work, btrfs_transaction_cleaner, fs_info); 743 INIT_WORK(&fs_info->trans_work, btrfs_transaction_cleaner, fs_info);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e9ef644ff56f..c226656f29b7 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -172,7 +172,7 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
172 172
173static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) 173static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits)
174{ 174{
175 return (cache->flags & bits); 175 return (cache->flags & bits) == bits;
176} 176}
177 177
178static int noinline find_search_start(struct btrfs_root *root, 178static int noinline find_search_start(struct btrfs_root *root,
@@ -1010,6 +1010,35 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
1010 1010
1011} 1011}
1012 1012
1013static int update_space_info(struct btrfs_fs_info *info, u64 flags,
1014 u64 total_bytes, u64 bytes_used,
1015 struct btrfs_space_info **space_info)
1016{
1017 struct btrfs_space_info *found;
1018
1019 found = __find_space_info(info, flags);
1020 if (found) {
1021 found->total_bytes += total_bytes;
1022 found->bytes_used += bytes_used;
1023 WARN_ON(found->total_bytes < found->bytes_used);
1024 *space_info = found;
1025 return 0;
1026 }
1027 found = kmalloc(sizeof(*found), GFP_NOFS);
1028 if (!found)
1029 return -ENOMEM;
1030
1031 list_add(&found->list, &info->space_info);
1032 found->flags = flags;
1033 found->total_bytes = total_bytes;
1034 found->bytes_used = bytes_used;
1035 found->bytes_pinned = 0;
1036 found->full = 0;
1037 *space_info = found;
1038 return 0;
1039}
1040
1041
1013static int do_chunk_alloc(struct btrfs_trans_handle *trans, 1042static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1014 struct btrfs_root *extent_root, u64 alloc_bytes, 1043 struct btrfs_root *extent_root, u64 alloc_bytes,
1015 u64 flags) 1044 u64 flags)
@@ -1021,6 +1050,11 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1021 int ret; 1050 int ret;
1022 1051
1023 space_info = __find_space_info(extent_root->fs_info, flags); 1052 space_info = __find_space_info(extent_root->fs_info, flags);
1053 if (!space_info) {
1054 ret = update_space_info(extent_root->fs_info, flags,
1055 0, 0, &space_info);
1056 BUG_ON(ret);
1057 }
1024 BUG_ON(!space_info); 1058 BUG_ON(!space_info);
1025 1059
1026 if (space_info->full) 1060 if (space_info->full)
@@ -1044,6 +1078,17 @@ printk("space info full %Lu\n", flags);
1044 extent_root->fs_info->chunk_root->root_key.objectid, 1078 extent_root->fs_info->chunk_root->root_key.objectid,
1045 start, num_bytes); 1079 start, num_bytes);
1046 BUG_ON(ret); 1080 BUG_ON(ret);
1081
1082 if (flags & BTRFS_BLOCK_GROUP_RAID0) {
1083 if (flags & BTRFS_BLOCK_GROUP_DATA) {
1084 extent_root->fs_info->extra_data_alloc_bits =
1085 BTRFS_BLOCK_GROUP_RAID0;
1086 }
1087 if (flags & BTRFS_BLOCK_GROUP_METADATA) {
1088 extent_root->fs_info->extra_alloc_bits =
1089 BTRFS_BLOCK_GROUP_RAID0;
1090 }
1091 }
1047 return 0; 1092 return 0;
1048} 1093}
1049 1094
@@ -1655,24 +1700,31 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1655 struct btrfs_extent_ref *ref; 1700 struct btrfs_extent_ref *ref;
1656 struct btrfs_path *path; 1701 struct btrfs_path *path;
1657 struct btrfs_key keys[2]; 1702 struct btrfs_key keys[2];
1703 int extra_chunk_alloc_bits = 0;
1658 1704
1659 if (data) { 1705 if (data) {
1660 data = BTRFS_BLOCK_GROUP_DATA; 1706 data = BTRFS_BLOCK_GROUP_DATA | info->extra_data_alloc_bits;
1661 } else if (root == root->fs_info->chunk_root) { 1707 } else if (root == root->fs_info->chunk_root) {
1662 data = BTRFS_BLOCK_GROUP_SYSTEM; 1708 data = BTRFS_BLOCK_GROUP_SYSTEM;
1663 } else { 1709 } else {
1664 data = BTRFS_BLOCK_GROUP_METADATA; 1710 data = BTRFS_BLOCK_GROUP_METADATA | info->extra_alloc_bits;
1665 } 1711 }
1712 if (btrfs_super_num_devices(&info->super_copy) > 1 &&
1713 !(data & BTRFS_BLOCK_GROUP_SYSTEM))
1714 extra_chunk_alloc_bits = BTRFS_BLOCK_GROUP_RAID0;
1666 1715
1667 if (root->ref_cows) { 1716 if (root->ref_cows) {
1668 if (data != BTRFS_BLOCK_GROUP_METADATA) { 1717 if (!(data & BTRFS_BLOCK_GROUP_METADATA)) {
1669 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 1718 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
1670 2 * 1024 * 1024, 1719 2 * 1024 * 1024,
1671 BTRFS_BLOCK_GROUP_METADATA); 1720 BTRFS_BLOCK_GROUP_METADATA |
1721 info->extra_alloc_bits |
1722 extra_chunk_alloc_bits);
1672 BUG_ON(ret); 1723 BUG_ON(ret);
1673 } 1724 }
1674 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 1725 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
1675 num_bytes + 2 * 1024 * 1024, data); 1726 num_bytes + 2 * 1024 * 1024, data |
1727 extra_chunk_alloc_bits);
1676 BUG_ON(ret); 1728 BUG_ON(ret);
1677 } 1729 }
1678 1730
@@ -2627,34 +2679,6 @@ error:
2627 return ret; 2679 return ret;
2628} 2680}
2629 2681
2630static int update_space_info(struct btrfs_fs_info *info, u64 flags,
2631 u64 total_bytes, u64 bytes_used,
2632 struct btrfs_space_info **space_info)
2633{
2634 struct btrfs_space_info *found;
2635
2636 found = __find_space_info(info, flags);
2637 if (found) {
2638 found->total_bytes += total_bytes;
2639 found->bytes_used += bytes_used;
2640 WARN_ON(found->total_bytes < found->bytes_used);
2641 *space_info = found;
2642 return 0;
2643 }
2644 found = kmalloc(sizeof(*found), GFP_NOFS);
2645 if (!found)
2646 return -ENOMEM;
2647
2648 list_add(&found->list, &info->space_info);
2649 found->flags = flags;
2650 found->total_bytes = total_bytes;
2651 found->bytes_used = bytes_used;
2652 found->bytes_pinned = 0;
2653 found->full = 0;
2654 *space_info = found;
2655 return 0;
2656}
2657
2658int btrfs_read_block_groups(struct btrfs_root *root) 2682int btrfs_read_block_groups(struct btrfs_root *root)
2659{ 2683{
2660 struct btrfs_path *path; 2684 struct btrfs_path *path;
@@ -2712,6 +2736,16 @@ int btrfs_read_block_groups(struct btrfs_root *root)
2712 } else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) { 2736 } else if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
2713 bit = BLOCK_GROUP_METADATA; 2737 bit = BLOCK_GROUP_METADATA;
2714 } 2738 }
2739 if (cache->flags & BTRFS_BLOCK_GROUP_RAID0) {
2740 if (cache->flags & BTRFS_BLOCK_GROUP_DATA) {
2741 info->extra_data_alloc_bits =
2742 BTRFS_BLOCK_GROUP_RAID0;
2743 }
2744 if (cache->flags & BTRFS_BLOCK_GROUP_METADATA) {
2745 info->extra_alloc_bits =
2746 BTRFS_BLOCK_GROUP_RAID0;
2747 }
2748 }
2715 2749
2716 ret = update_space_info(info, cache->flags, found_key.offset, 2750 ret = update_space_info(info, cache->flags, found_key.offset,
2717 btrfs_block_group_used(&cache->item), 2751 btrfs_block_group_used(&cache->item),
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5140d6801846..db60d85598ce 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -317,8 +317,6 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
317 map_length = length; 317 map_length = length;
318 ret = btrfs_map_block(map_tree, logical, &physical, &map_length, &dev); 318 ret = btrfs_map_block(map_tree, logical, &physical, &map_length, &dev);
319 if (map_length < length + size) { 319 if (map_length < length + size) {
320 printk("merge bio hook logical %Lu bio len %Lu physical %Lu "
321 "len %Lu\n", logical, length, physical, map_length);
322 return 1; 320 return 1;
323 } 321 }
324 return 0; 322 return 0;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 263f01cc3db4..d8fce32a3bbc 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -18,6 +18,7 @@
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/bio.h> 19#include <linux/bio.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <asm/div64.h>
21#include "ctree.h" 22#include "ctree.h"
22#include "extent_map.h" 23#include "extent_map.h"
23#include "disk-io.h" 24#include "disk-io.h"
@@ -25,10 +26,24 @@
25#include "print-tree.h" 26#include "print-tree.h"
26#include "volumes.h" 27#include "volumes.h"
27 28
28struct map_lookup { 29struct stripe {
29 struct btrfs_device *dev; 30 struct btrfs_device *dev;
30 u64 physical; 31 u64 physical;
31}; 32};
33
34struct map_lookup {
35 u64 type;
36 int io_align;
37 int io_width;
38 int stripe_len;
39 int sector_size;
40 int num_stripes;
41 struct stripe stripes[];
42};
43
44#define map_lookup_size(n) (sizeof(struct map_lookup) + \
45 (sizeof(struct stripe) * (n)))
46
32static DEFINE_MUTEX(uuid_mutex); 47static DEFINE_MUTEX(uuid_mutex);
33static LIST_HEAD(fs_uuids); 48static LIST_HEAD(fs_uuids);
34 49
@@ -592,6 +607,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
592 u64 *num_bytes, u64 type) 607 u64 *num_bytes, u64 type)
593{ 608{
594 u64 dev_offset; 609 u64 dev_offset;
610 struct btrfs_fs_info *info = extent_root->fs_info;
595 struct btrfs_root *chunk_root = extent_root->fs_info->chunk_root; 611 struct btrfs_root *chunk_root = extent_root->fs_info->chunk_root;
596 struct btrfs_stripe *stripes; 612 struct btrfs_stripe *stripes;
597 struct btrfs_device *device = NULL; 613 struct btrfs_device *device = NULL;
@@ -610,10 +626,18 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
610 int looped = 0; 626 int looped = 0;
611 int ret; 627 int ret;
612 int index; 628 int index;
629 int stripe_len = 64 * 1024;
613 struct btrfs_key key; 630 struct btrfs_key key;
614 631
615 if (list_empty(dev_list)) 632 if (list_empty(dev_list))
616 return -ENOSPC; 633 return -ENOSPC;
634
635 if (type & BTRFS_BLOCK_GROUP_RAID0)
636 num_stripes = btrfs_super_num_devices(&info->super_copy);
637 if (type & BTRFS_BLOCK_GROUP_DATA)
638 stripe_len = 64 * 1024;
639 if (type & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM))
640 stripe_len = 32 * 1024;
617again: 641again:
618 INIT_LIST_HEAD(&private_devs); 642 INIT_LIST_HEAD(&private_devs);
619 cur = dev_list->next; 643 cur = dev_list->next;
@@ -650,9 +674,15 @@ again:
650 if (!chunk) 674 if (!chunk)
651 return -ENOMEM; 675 return -ENOMEM;
652 676
677 map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS);
678 if (!map) {
679 kfree(chunk);
680 return -ENOMEM;
681 }
682
653 stripes = &chunk->stripe; 683 stripes = &chunk->stripe;
654 684
655 *num_bytes = calc_size; 685 *num_bytes = calc_size * num_stripes;
656 index = 0; 686 index = 0;
657 while(index < num_stripes) { 687 while(index < num_stripes) {
658 BUG_ON(list_empty(&private_devs)); 688 BUG_ON(list_empty(&private_devs));
@@ -669,6 +699,8 @@ printk("alloc chunk size %Lu from dev %Lu\n", calc_size, device->devid);
669 ret = btrfs_update_device(trans, device); 699 ret = btrfs_update_device(trans, device);
670 BUG_ON(ret); 700 BUG_ON(ret);
671 701
702 map->stripes[index].dev = device;
703 map->stripes[index].physical = dev_offset;
672 btrfs_set_stack_stripe_devid(stripes + index, device->devid); 704 btrfs_set_stack_stripe_devid(stripes + index, device->devid);
673 btrfs_set_stack_stripe_offset(stripes + index, dev_offset); 705 btrfs_set_stack_stripe_offset(stripes + index, dev_offset);
674 physical = dev_offset; 706 physical = dev_offset;
@@ -680,12 +712,18 @@ printk("alloc chunk size %Lu from dev %Lu\n", calc_size, device->devid);
680 key.offset = *num_bytes; 712 key.offset = *num_bytes;
681 key.type = BTRFS_CHUNK_ITEM_KEY; 713 key.type = BTRFS_CHUNK_ITEM_KEY;
682 btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid); 714 btrfs_set_stack_chunk_owner(chunk, extent_root->root_key.objectid);
683 btrfs_set_stack_chunk_stripe_len(chunk, 64 * 1024); 715 btrfs_set_stack_chunk_stripe_len(chunk, stripe_len);
684 btrfs_set_stack_chunk_type(chunk, type); 716 btrfs_set_stack_chunk_type(chunk, type);
685 btrfs_set_stack_chunk_num_stripes(chunk, num_stripes); 717 btrfs_set_stack_chunk_num_stripes(chunk, num_stripes);
686 btrfs_set_stack_chunk_io_align(chunk, extent_root->sectorsize); 718 btrfs_set_stack_chunk_io_align(chunk, stripe_len);
687 btrfs_set_stack_chunk_io_width(chunk, extent_root->sectorsize); 719 btrfs_set_stack_chunk_io_width(chunk, stripe_len);
688 btrfs_set_stack_chunk_sector_size(chunk, extent_root->sectorsize); 720 btrfs_set_stack_chunk_sector_size(chunk, extent_root->sectorsize);
721 map->sector_size = extent_root->sectorsize;
722 map->stripe_len = stripe_len;
723 map->io_align = stripe_len;
724 map->io_width = stripe_len;
725 map->type = type;
726 map->num_stripes = num_stripes;
689 727
690 ret = btrfs_insert_item(trans, chunk_root, &key, chunk, 728 ret = btrfs_insert_item(trans, chunk_root, &key, chunk,
691 btrfs_chunk_item_size(num_stripes)); 729 btrfs_chunk_item_size(num_stripes));
@@ -695,25 +733,11 @@ printk("alloc chunk size %Lu from dev %Lu\n", calc_size, device->devid);
695 em = alloc_extent_map(GFP_NOFS); 733 em = alloc_extent_map(GFP_NOFS);
696 if (!em) 734 if (!em)
697 return -ENOMEM; 735 return -ENOMEM;
698 map = kmalloc(sizeof(*map), GFP_NOFS);
699 if (!map) {
700 free_extent_map(em);
701 return -ENOMEM;
702 }
703
704 em->bdev = (struct block_device *)map; 736 em->bdev = (struct block_device *)map;
705 em->start = key.objectid; 737 em->start = key.objectid;
706 em->len = key.offset; 738 em->len = key.offset;
707 em->block_start = 0; 739 em->block_start = 0;
708 740
709 map->physical = physical;
710 map->dev = device;
711
712 if (!map->dev) {
713 kfree(map);
714 free_extent_map(em);
715 return -EIO;
716 }
717 kfree(chunk); 741 kfree(chunk);
718 742
719 em_tree = &extent_root->fs_info->mapping_tree.map_tree; 743 em_tree = &extent_root->fs_info->mapping_tree.map_tree;
@@ -758,6 +782,9 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
758 struct map_lookup *map; 782 struct map_lookup *map;
759 struct extent_map_tree *em_tree = &map_tree->map_tree; 783 struct extent_map_tree *em_tree = &map_tree->map_tree;
760 u64 offset; 784 u64 offset;
785 u64 stripe_offset;
786 u64 stripe_nr;
787 int stripe_index;
761 788
762 789
763 spin_lock(&em_tree->lock); 790 spin_lock(&em_tree->lock);
@@ -767,9 +794,40 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree,
767 BUG_ON(em->start > logical || em->start + em->len < logical); 794 BUG_ON(em->start > logical || em->start + em->len < logical);
768 map = (struct map_lookup *)em->bdev; 795 map = (struct map_lookup *)em->bdev;
769 offset = logical - em->start; 796 offset = logical - em->start;
770 *phys = map->physical + offset; 797
771 *length = em->len - offset; 798 stripe_nr = offset;
772 *dev = map->dev; 799 /*
800 * stripe_nr counts the total number of stripes we have to stride
801 * to get to this block
802 */
803 do_div(stripe_nr, map->stripe_len);
804
805 stripe_offset = stripe_nr * map->stripe_len;
806 BUG_ON(offset < stripe_offset);
807
808 /* stripe_offset is the offset of this block in its stripe*/
809 stripe_offset = offset - stripe_offset;
810
811 /*
812 * after this do_div call, stripe_nr is the number of stripes
813 * on this device we have to walk to find the data, and
814 * stripe_index is the number of our device in the stripe array
815 */
816 stripe_index = do_div(stripe_nr, map->num_stripes);
817
818 BUG_ON(stripe_index >= map->num_stripes);
819
820 *phys = map->stripes[stripe_index].physical + stripe_offset +
821 stripe_nr * map->stripe_len;
822
823 if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
824 /* we limit the length of each bio to what fits in a stripe */
825 *length = min_t(u64, em->len - offset,
826 map->stripe_len - stripe_offset);
827 } else {
828 *length = em->len - offset;
829 }
830 *dev = map->stripes[stripe_index].dev;
773 free_extent_map(em); 831 free_extent_map(em);
774 spin_unlock(&em_tree->lock); 832 spin_unlock(&em_tree->lock);
775 return 0; 833 return 0;
@@ -822,7 +880,9 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
822 u64 logical; 880 u64 logical;
823 u64 length; 881 u64 length;
824 u64 devid; 882 u64 devid;
883 int num_stripes;
825 int ret; 884 int ret;
885 int i;
826 886
827 logical = key->objectid; 887 logical = key->objectid;
828 length = key->offset; 888 length = key->offset;
@@ -846,7 +906,8 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
846 em = alloc_extent_map(GFP_NOFS); 906 em = alloc_extent_map(GFP_NOFS);
847 if (!em) 907 if (!em)
848 return -ENOMEM; 908 return -ENOMEM;
849 map = kmalloc(sizeof(*map), GFP_NOFS); 909 num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
910 map = kmalloc(map_lookup_size(num_stripes), GFP_NOFS);
850 if (!map) { 911 if (!map) {
851 free_extent_map(em); 912 free_extent_map(em);
852 return -ENOMEM; 913 return -ENOMEM;
@@ -857,13 +918,22 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key,
857 em->len = length; 918 em->len = length;
858 em->block_start = 0; 919 em->block_start = 0;
859 920
860 map->physical = btrfs_stripe_offset_nr(leaf, chunk, 0); 921 map->num_stripes = num_stripes;
861 devid = btrfs_stripe_devid_nr(leaf, chunk, 0); 922 map->io_width = btrfs_chunk_io_width(leaf, chunk);
862 map->dev = btrfs_find_device(root, devid); 923 map->io_align = btrfs_chunk_io_align(leaf, chunk);
863 if (!map->dev) { 924 map->sector_size = btrfs_chunk_sector_size(leaf, chunk);
864 kfree(map); 925 map->stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
865 free_extent_map(em); 926 map->type = btrfs_chunk_type(leaf, chunk);
866 return -EIO; 927 for (i = 0; i < num_stripes; i++) {
928 map->stripes[i].physical =
929 btrfs_stripe_offset_nr(leaf, chunk, i);
930 devid = btrfs_stripe_devid_nr(leaf, chunk, i);
931 map->stripes[i].dev = btrfs_find_device(root, devid);
932 if (!map->stripes[i].dev) {
933 kfree(map);
934 free_extent_map(em);
935 return -EIO;
936 }
867 } 937 }
868 938
869 spin_lock(&map_tree->map_tree.lock); 939 spin_lock(&map_tree->map_tree.lock);