From patchwork Tue May 11 08:24:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yan, Zheng" X-Patchwork-Id: 98636 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4B8Q44x022016 for ; Tue, 11 May 2010 08:26:04 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757164Ab0EKIZw (ORCPT ); Tue, 11 May 2010 04:25:52 -0400 Received: from rcsinet10.oracle.com ([148.87.113.121]:28715 "EHLO rcsinet10.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757107Ab0EKIZu (ORCPT ); Tue, 11 May 2010 04:25:50 -0400 Received: from rcsinet15.oracle.com (rcsinet15.oracle.com [148.87.113.117]) by rcsinet10.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o4B8Pjka011147 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 11 May 2010 08:25:47 GMT Received: from acsmt354.oracle.com (acsmt354.oracle.com [141.146.40.154]) by rcsinet15.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o4B8Pfae024400 for ; Tue, 11 May 2010 08:25:42 GMT Received: from abhmt020.oracle.com by acsmt355.oracle.com with ESMTP id 254021681273566302; Tue, 11 May 2010 01:25:02 -0700 Received: from [192.168.0.100] (/118.112.27.58) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 11 May 2010 01:25:01 -0700 Message-ID: <4BE91454.6030203@oracle.com> Date: Tue, 11 May 2010 16:24:52 +0800 From: "Yan, Zheng" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100330 Fedora/3.0.4-1.fc12 Thunderbird/3.0.4 MIME-Version: 1.0 To: linux-btrfs@vger.kernel.org CC: Chris Mason Subject: [PATCH 3/5] btrfs: split btrfs_alloc_free_block() X-Auth-Type: Internal IP X-Source-IP: rcsinet15.oracle.com [148.87.113.117] X-CT-RefId: str=0001.0A090207.4BE9148C.006B:SCFMA4539811,ss=1,fgs=0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 11 May 2010 08:26:04 +0000 (UTC) diff -urp 3/fs/btrfs/ctree.h 4/fs/btrfs/ctree.h --- 3/fs/btrfs/ctree.h 2010-05-11 14:09:45.052107958 +0800 +++ 4/fs/btrfs/ctree.h 2010-05-11 13:15:47.060357000 +0800 @@ -1978,6 +1978,15 @@ struct btrfs_block_group_cache *btrfs_lo void btrfs_put_block_group(struct btrfs_block_group_cache *cache); u64 btrfs_find_block_group(struct btrfs_root *root, u64 search_start, u64 search_hint, int owner); +struct extent_buffer *btrfs_reserve_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u32 blocksize, int level, + u64 hint, u64 empty_size); +int btrfs_alloc_reserved_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, + u64 parent, u64 root_objectid, + struct btrfs_disk_key *key, int level); struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, u32 blocksize, u64 parent, u64 root_objectid, diff -urp 3/fs/btrfs/extent-tree.c 4/fs/btrfs/extent-tree.c --- 3/fs/btrfs/extent-tree.c 2010-05-11 14:12:00.044357180 +0800 +++ 4/fs/btrfs/extent-tree.c 2010-05-11 13:26:38.036107000 +0800 @@ -4956,64 +4998,6 @@ int btrfs_alloc_logged_file_extent(struc return ret; } -/* - * finds a free extent and does all the dirty work required for allocation - * returns the key for the extent through ins, and a tree buffer for - * the first block of the extent through buf. - * - * returns 0 if everything worked, non-zero otherwise. - */ -static int alloc_tree_block(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - u64 num_bytes, u64 parent, u64 root_objectid, - struct btrfs_disk_key *key, int level, - u64 empty_size, u64 hint_byte, u64 search_end, - struct btrfs_key *ins) -{ - int ret; - u64 flags = 0; - - ret = btrfs_reserve_extent(trans, root, num_bytes, num_bytes, - empty_size, hint_byte, search_end, - ins, 0); - if (ret) - return ret; - - if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) { - if (parent == 0) - parent = ins->objectid; - flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; - } else - BUG_ON(parent > 0); - - if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { - struct btrfs_delayed_extent_op *extent_op; - extent_op = kzalloc(sizeof(*extent_op), GFP_NOFS); - BUG_ON(!extent_op); - if (key) - memcpy(&extent_op->key, key, sizeof(extent_op->key)); - extent_op->flags_to_set = flags; - extent_op->update_key = 1; - extent_op->update_gen = 1; - extent_op->update_flags = 1; - - ret = btrfs_add_delayed_tree_ref(trans, ins->objectid, - ins->offset, parent, root_objectid, - level, BTRFS_ADD_DELAYED_EXTENT, - extent_op); - BUG_ON(ret); - } - - if (root_objectid == root->root_key.objectid) { - u64 used; - spin_lock(&root->node_lock); - used = btrfs_root_used(&root->root_item) + num_bytes; - btrfs_set_root_used(&root->root_item, used); - spin_unlock(&root->node_lock); - } - return ret; -} - struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytenr, u32 blocksize, @@ -5052,8 +5036,68 @@ struct extent_buffer *btrfs_init_new_buf return buf; } +struct extent_buffer *btrfs_reserve_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u32 blocksize, int level, + u64 hint, u64 empty_size) +{ + + struct btrfs_key ins; + struct extent_buffer *buf; + int ret; + + ret = btrfs_reserve_extent(trans, root, blocksize, blocksize, + empty_size, hint, (u64)-1, &ins, 0); + if (ret) + return ERR_PTR(ret); + + buf = btrfs_init_new_buffer(trans, root, ins.objectid, + blocksize, level); + BUG_ON(IS_ERR(buf)); + + return buf; +} + +int btrfs_alloc_reserved_tree_block(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct extent_buffer *buf, + u64 parent, u64 root_objectid, + struct btrfs_disk_key *key, int level) +{ + struct btrfs_delayed_extent_op *extent_op; + int ret; + + if (root_objectid == BTRFS_TREE_LOG_OBJECTID) + return 0; + + if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) { + if (parent == 0) + parent = buf->start; + } else + BUG_ON(parent > 0); + + extent_op = kzalloc(sizeof(*extent_op), GFP_NOFS); + BUG_ON(!extent_op); + if (key) + memcpy(&extent_op->key, key, sizeof(extent_op->key)); + + if (parent > 0) + extent_op->flags_to_set = BTRFS_BLOCK_FLAG_FULL_BACKREF; + extent_op->update_key = 1; + extent_op->update_gen = 1; + extent_op->update_flags = 1; + + ret = btrfs_add_delayed_tree_ref(trans, buf->start, buf->len, + parent, root_objectid, level, + BTRFS_ADD_DELAYED_EXTENT, extent_op); + return ret; +} + /* - * helper function to allocate a block for a given tree + * finds a free extent and does all the dirty work required for allocation + * returns the key for the extent through ins, and a tree buffer for + * the first block of the extent through buf. + * * returns the tree buffer or NULL. */ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, @@ -5062,19 +5106,17 @@ struct extent_buffer *btrfs_alloc_free_b struct btrfs_disk_key *key, int level, u64 hint, u64 empty_size) { - struct btrfs_key ins; - int ret; struct extent_buffer *buf; + int ret; - ret = alloc_tree_block(trans, root, blocksize, parent, root_objectid, - key, level, empty_size, hint, (u64)-1, &ins); - if (ret) { - BUG_ON(ret > 0); - return ERR_PTR(ret); - } + buf = btrfs_reserve_tree_block(trans, root, blocksize, level, + hint, empty_size); + if (IS_ERR(buf)) + return ERR_CAST(buf); - buf = btrfs_init_new_buffer(trans, root, ins.objectid, - blocksize, level); + ret = btrfs_alloc_reserved_tree_block(trans, root, buf, parent, + root_objectid, key, level); + BUG_ON(ret); return buf; }