From patchwork Mon Jan 4 21:13:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: jim owens X-Patchwork-Id: 70743 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o04LDroH024995 for ; Mon, 4 Jan 2010 21:13:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752919Ab0ADVNv (ORCPT ); Mon, 4 Jan 2010 16:13:51 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752842Ab0ADVNv (ORCPT ); Mon, 4 Jan 2010 16:13:51 -0500 Received: from g6t0184.atlanta.hp.com ([15.193.32.61]:21280 "EHLO g6t0184.atlanta.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752215Ab0ADVNu (ORCPT ); Mon, 4 Jan 2010 16:13:50 -0500 Received: from g5t0029.atlanta.hp.com (g5t0029.atlanta.hp.com [16.228.8.141]) by g6t0184.atlanta.hp.com (Postfix) with ESMTP id E9939C078 for ; Mon, 4 Jan 2010 21:13:49 +0000 (UTC) Received: from ldl (ldl.fc.hp.com [15.11.146.30]) by g5t0029.atlanta.hp.com (Postfix) with ESMTP id B023520024 for ; Mon, 4 Jan 2010 21:13:49 +0000 (UTC) Received: from localhost (ldl.fc.hp.com [127.0.0.1]) by ldl (Postfix) with ESMTP id 684C9CF0011; Mon, 4 Jan 2010 14:13:49 -0700 (MST) Received: from ldl ([127.0.0.1]) by localhost (ldl.fc.hp.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id WDOzh0mN8QBB; Mon, 4 Jan 2010 14:13:49 -0700 (MST) Received: from [192.168.0.99] (squirrel.fc.hp.com [15.11.146.57]) (Authenticated sender: owens@fc.hp.com) by ldl (Postfix) with ESMTPA id CD14DCF000E; Mon, 4 Jan 2010 14:13:48 -0700 (MST) Message-ID: <4B425A0B.4050602@hp.com> Date: Mon, 04 Jan 2010 16:13:47 -0500 From: jim owens User-Agent: Thunderbird 2.0.0.23 (X11/20090817) MIME-Version: 1.0 To: linux-btrfs Subject: [RFC 07/12 PATCH] Btrfs: split btrfs_map_block into two parts for direct I/O. Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 0e3146a..48727ee 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -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; diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index d5aab74..76c4394 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -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);