Btrfs: split btrfs_map_block into two parts for direct I/O.
RFC PATCH 7/12 Btrfs: split btrfs_map_block into two parts for direct I/O.
The part of btrfs_map_block() that decodes the extent map and rw/logical/length/mirror parameters is split into a routine btrfs_map_to_stripe() so direct I/O can build multiple bios with one lookup_extent_mapping().
The part of btrfs_map_block() that does lookup_extent_mapping() and optional creation of the btrfs_multi_bio struct now calls btrfs_map_to_stripe().
Signed-off-by jim owens <[email protected]>
--- fs/btrfs/volumes.c | 84 +++++++++++++++++++++++++++++++-------------------- fs/btrfs/volumes.h | 10 ++++++ 2 files changed, 61 insertions(+), 33 deletions(-)
fs/btrfs/volumes.c +51 -33
@@ -2614,33 +2614,16 @@ static int find_live_mirror(struct map_lookup *map, int first, int num,return optimal; } -int btrfs_map_block (struct btrfs_mapping_tree *map_tree,int rw, -u64 logical,u64 *length, -struct btrfs_multi_bio **multi_ret, -int mirror_num) +void btrfs_map_to_stripe (struct extent_map *em,int rw,int mirror_num, +u64 logical,u64 *length, +struct btrfs_stripe_info *stripe_info) { -struct extent_map *em;struct map_lookup *map; -struct extent_map_tree *em_tree = &map_tree->map_tree;u64 offset;u64 stripe_offset;u64 stripe_nr;int stripe_index; -int i;int num_stripes; -int max_errors; -struct btrfs_multi_bio *multi; - -read_lock (&em_tree->lock); - em =lookup_extent_mapping (em_tree, logical, *length); -read_unlock (&em_tree->lock); - -if (!em) { -printk (KERN_CRIT "unable to find logical %llu len %llu\n" , - (unsigned long long )logical, - (unsigned long long )*length); -BUG (); - }BUG_ON (em->start > logical || em->start + em->len < logical); map = (struct map_lookup *)em->bdev;
@@ -2670,19 +2653,19 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, *length =min (*length, em->len - offset); } -if (!multi_ret) - goto out; +if (!stripe_info) +return ;if (mirror_num > map->num_stripes) mirror_num =0 ; - max_errors =0 ; + stripe_info->max_errors =0 ;if (rw & (1 <<BIO_RW )) {if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |BTRFS_BLOCK_GROUP_DUP )) - max_errors =1 ; + stripe_info->max_errors =1 ;else if (map->type &BTRFS_BLOCK_GROUP_RAID10 ) - max_errors =1 ; + stripe_info->max_errors =1 ; } num_stripes =1 ;
@@ -2729,22 +2712,57 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, }BUG_ON (stripe_index >= map->num_stripes); - multi =kzalloc (btrfs_multi_bio_size (num_stripes),GFP_NOFS ); + stripe_info->num_stripes = num_stripes; + stripe_info->stripe_index = stripe_index; + stripe_info->phys_offset = stripe_offset + stripe_nr * map->stripe_len; +} + +int btrfs_map_block (struct btrfs_mapping_tree *map_tree,int rw, +u64 logical,u64 *length, +struct btrfs_multi_bio **multi_ret,int mirror_num) +{ +struct extent_map *em; +struct map_lookup *map; +struct extent_map_tree *em_tree = &map_tree->map_tree; +struct btrfs_multi_bio *multi; +struct btrfs_stripe_info stripe_info; +int i; + +read_lock (&em_tree->lock); + em =lookup_extent_mapping (em_tree, logical, *length); +read_unlock (&em_tree->lock); + +if (!em) { +printk (KERN_CRIT "unable to find logical %llu len %llu\n" , + (unsigned long long )logical, + (unsigned long long )*length); +BUG (); + } + +btrfs_map_to_stripe (em, rw, mirror_num, logical, length, + multi_ret ? &stripe_info :NULL ); +if (!multi_ret) + goto out; + + multi =kzalloc (btrfs_multi_bio_size (stripe_info.num_stripes),GFP_NOFS );if (!multi)return -ENOMEM ; *multi_ret = multi;atomic_set (&multi->error,0 ); - multi->num_stripes = num_stripes; - multi->max_errors = max_errors; + multi->num_stripes = stripe_info.num_stripes; + multi->max_errors = stripe_info.max_errors; -for (i =0 ; i < num_stripes; i++) { + map = (struct map_lookup *)em->bdev; +for (i =0 ; i < stripe_info.num_stripes; i++) { multi->stripes[i].physical = - map->stripes[stripe_index].physical + - stripe_offset + stripe_nr * map->stripe_len; - multi->stripes[i].dev = map->stripes[stripe_index].dev; - stripe_index++; + map->stripes[stripe_info.stripe_index].physical + + stripe_info.phys_offset; + multi->stripes[i].dev = + map->stripes[stripe_info.stripe_index].dev; + stripe_info.stripe_index++; } + out:free_extent_map (em);return 0 ;
fs/btrfs/volumes.h +10 -0
@@ -135,6 +135,13 @@ struct btrfs_multi_bio {struct btrfs_bio_stripe stripes[]; }; +struct btrfs_stripe_info { +int num_stripes; +int max_errors; +int stripe_index; +u64 phys_offset; +}; +#define btrfs_multi_bio_size (n) (sizeof(struct btrfs_multi_bio) + \ (sizeof(struct btrfs_bio_stripe) * (n)))
@@ -142,6 +149,9 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,struct btrfs_device *device, u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 start, u64 num_bytes); +void btrfs_map_to_stripe (struct extent_map *em,int rw,int mirror_num, +u64 logical,u64 *length, +struct btrfs_stripe_info *stripe_info);int btrfs_map_block (struct btrfs_mapping_tree *map_tree,int rw,u64 logical,u64 *length,struct btrfs_multi_bio **multi_ret,int mirror_num);
Signature · 1 line
1.5.6.3