aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-11-20 21:21:28 -0500
committerJosef Bacik <jbacik@fusionio.com>2013-02-20 09:36:34 -0500
commit78a6184a3ff9041280ee56273c01e5679a831b39 (patch)
tree0310eb020cf6ed7a8ff71feb8c468bb6e42488fa /fs
parent6f60cbd3ae442cb35861bb522f388db123d42ec1 (diff)
Btrfs: use slabs for delayed reference allocation
The delayed reference allocation is in the fast path of the IO, so use slabs to improve the speed of the allocation. And besides that, it can do check for leaked objects when the module is removed. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/delayed-ref.c74
-rw-r--r--fs/btrfs/delayed-ref.h37
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/extent-tree.c14
-rw-r--r--fs/btrfs/super.c9
5 files changed, 115 insertions, 21 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index ae9411773397..455894f1ca3b 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -23,6 +23,10 @@
23#include "delayed-ref.h" 23#include "delayed-ref.h"
24#include "transaction.h" 24#include "transaction.h"
25 25
26struct kmem_cache *btrfs_delayed_ref_head_cachep;
27struct kmem_cache *btrfs_delayed_tree_ref_cachep;
28struct kmem_cache *btrfs_delayed_data_ref_cachep;
29struct kmem_cache *btrfs_delayed_extent_op_cachep;
26/* 30/*
27 * delayed back reference update tracking. For subvolume trees 31 * delayed back reference update tracking. For subvolume trees
28 * we queue up extent allocations and backref maintenance for 32 * we queue up extent allocations and backref maintenance for
@@ -511,7 +515,7 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing,
511 ref->extent_op->flags_to_set; 515 ref->extent_op->flags_to_set;
512 existing_ref->extent_op->update_flags = 1; 516 existing_ref->extent_op->update_flags = 1;
513 } 517 }
514 kfree(ref->extent_op); 518 btrfs_free_delayed_extent_op(ref->extent_op);
515 } 519 }
516 } 520 }
517 /* 521 /*
@@ -592,7 +596,7 @@ static noinline void add_delayed_ref_head(struct btrfs_fs_info *fs_info,
592 * we've updated the existing ref, free the newly 596 * we've updated the existing ref, free the newly
593 * allocated ref 597 * allocated ref
594 */ 598 */
595 kfree(head_ref); 599 kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref);
596 } else { 600 } else {
597 delayed_refs->num_heads++; 601 delayed_refs->num_heads++;
598 delayed_refs->num_heads_ready++; 602 delayed_refs->num_heads_ready++;
@@ -653,7 +657,7 @@ static noinline void add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
653 * we've updated the existing ref, free the newly 657 * we've updated the existing ref, free the newly
654 * allocated ref 658 * allocated ref
655 */ 659 */
656 kfree(full_ref); 660 kmem_cache_free(btrfs_delayed_tree_ref_cachep, full_ref);
657 } else { 661 } else {
658 delayed_refs->num_entries++; 662 delayed_refs->num_entries++;
659 trans->delayed_ref_updates++; 663 trans->delayed_ref_updates++;
@@ -714,7 +718,7 @@ static noinline void add_delayed_data_ref(struct btrfs_fs_info *fs_info,
714 * we've updated the existing ref, free the newly 718 * we've updated the existing ref, free the newly
715 * allocated ref 719 * allocated ref
716 */ 720 */
717 kfree(full_ref); 721 kmem_cache_free(btrfs_delayed_data_ref_cachep, full_ref);
718 } else { 722 } else {
719 delayed_refs->num_entries++; 723 delayed_refs->num_entries++;
720 trans->delayed_ref_updates++; 724 trans->delayed_ref_updates++;
@@ -738,13 +742,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
738 struct btrfs_delayed_ref_root *delayed_refs; 742 struct btrfs_delayed_ref_root *delayed_refs;
739 743
740 BUG_ON(extent_op && extent_op->is_data); 744 BUG_ON(extent_op && extent_op->is_data);
741 ref = kmalloc(sizeof(*ref), GFP_NOFS); 745 ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
742 if (!ref) 746 if (!ref)
743 return -ENOMEM; 747 return -ENOMEM;
744 748
745 head_ref = kmalloc(sizeof(*head_ref), GFP_NOFS); 749 head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
746 if (!head_ref) { 750 if (!head_ref) {
747 kfree(ref); 751 kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
748 return -ENOMEM; 752 return -ENOMEM;
749 } 753 }
750 754
@@ -786,13 +790,13 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
786 struct btrfs_delayed_ref_root *delayed_refs; 790 struct btrfs_delayed_ref_root *delayed_refs;
787 791
788 BUG_ON(extent_op && !extent_op->is_data); 792 BUG_ON(extent_op && !extent_op->is_data);
789 ref = kmalloc(sizeof(*ref), GFP_NOFS); 793 ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
790 if (!ref) 794 if (!ref)
791 return -ENOMEM; 795 return -ENOMEM;
792 796
793 head_ref = kmalloc(sizeof(*head_ref), GFP_NOFS); 797 head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
794 if (!head_ref) { 798 if (!head_ref) {
795 kfree(ref); 799 kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
796 return -ENOMEM; 800 return -ENOMEM;
797 } 801 }
798 802
@@ -826,7 +830,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
826 struct btrfs_delayed_ref_head *head_ref; 830 struct btrfs_delayed_ref_head *head_ref;
827 struct btrfs_delayed_ref_root *delayed_refs; 831 struct btrfs_delayed_ref_root *delayed_refs;
828 832
829 head_ref = kmalloc(sizeof(*head_ref), GFP_NOFS); 833 head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
830 if (!head_ref) 834 if (!head_ref)
831 return -ENOMEM; 835 return -ENOMEM;
832 836
@@ -860,3 +864,51 @@ btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr)
860 return btrfs_delayed_node_to_head(ref); 864 return btrfs_delayed_node_to_head(ref);
861 return NULL; 865 return NULL;
862} 866}
867
868void btrfs_delayed_ref_exit(void)
869{
870 if (btrfs_delayed_ref_head_cachep)
871 kmem_cache_destroy(btrfs_delayed_ref_head_cachep);
872 if (btrfs_delayed_tree_ref_cachep)
873 kmem_cache_destroy(btrfs_delayed_tree_ref_cachep);
874 if (btrfs_delayed_data_ref_cachep)
875 kmem_cache_destroy(btrfs_delayed_data_ref_cachep);
876 if (btrfs_delayed_extent_op_cachep)
877 kmem_cache_destroy(btrfs_delayed_extent_op_cachep);
878}
879
880int btrfs_delayed_ref_init(void)
881{
882 btrfs_delayed_ref_head_cachep = kmem_cache_create(
883 "btrfs_delayed_ref_head",
884 sizeof(struct btrfs_delayed_ref_head), 0,
885 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
886 if (!btrfs_delayed_ref_head_cachep)
887 goto fail;
888
889 btrfs_delayed_tree_ref_cachep = kmem_cache_create(
890 "btrfs_delayed_tree_ref",
891 sizeof(struct btrfs_delayed_tree_ref), 0,
892 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
893 if (!btrfs_delayed_tree_ref_cachep)
894 goto fail;
895
896 btrfs_delayed_data_ref_cachep = kmem_cache_create(
897 "btrfs_delayed_data_ref",
898 sizeof(struct btrfs_delayed_data_ref), 0,
899 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
900 if (!btrfs_delayed_data_ref_cachep)
901 goto fail;
902
903 btrfs_delayed_extent_op_cachep = kmem_cache_create(
904 "btrfs_delayed_extent_op",
905 sizeof(struct btrfs_delayed_extent_op), 0,
906 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
907 if (!btrfs_delayed_extent_op_cachep)
908 goto fail;
909
910 return 0;
911fail:
912 btrfs_delayed_ref_exit();
913 return -ENOMEM;
914}
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index c9d703693df0..fe50392cdf76 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -141,12 +141,47 @@ struct btrfs_delayed_ref_root {
141 u64 run_delayed_start; 141 u64 run_delayed_start;
142}; 142};
143 143
144extern struct kmem_cache *btrfs_delayed_ref_head_cachep;
145extern struct kmem_cache *btrfs_delayed_tree_ref_cachep;
146extern struct kmem_cache *btrfs_delayed_data_ref_cachep;
147extern struct kmem_cache *btrfs_delayed_extent_op_cachep;
148
149int btrfs_delayed_ref_init(void);
150void btrfs_delayed_ref_exit(void);
151
152static inline struct btrfs_delayed_extent_op *
153btrfs_alloc_delayed_extent_op(void)
154{
155 return kmem_cache_alloc(btrfs_delayed_extent_op_cachep, GFP_NOFS);
156}
157
158static inline void
159btrfs_free_delayed_extent_op(struct btrfs_delayed_extent_op *op)
160{
161 if (op)
162 kmem_cache_free(btrfs_delayed_extent_op_cachep, op);
163}
164
144static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref) 165static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref)
145{ 166{
146 WARN_ON(atomic_read(&ref->refs) == 0); 167 WARN_ON(atomic_read(&ref->refs) == 0);
147 if (atomic_dec_and_test(&ref->refs)) { 168 if (atomic_dec_and_test(&ref->refs)) {
148 WARN_ON(ref->in_tree); 169 WARN_ON(ref->in_tree);
149 kfree(ref); 170 switch (ref->type) {
171 case BTRFS_TREE_BLOCK_REF_KEY:
172 case BTRFS_SHARED_BLOCK_REF_KEY:
173 kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
174 break;
175 case BTRFS_EXTENT_DATA_REF_KEY:
176 case BTRFS_SHARED_DATA_REF_KEY:
177 kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
178 break;
179 case 0:
180 kmem_cache_free(btrfs_delayed_ref_head_cachep, ref);
181 break;
182 default:
183 BUG();
184 }
150 } 185 }
151} 186}
152 187
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 65f03670a952..4438aac4947f 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3614,7 +3614,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
3614 continue; 3614 continue;
3615 } 3615 }
3616 3616
3617 kfree(head->extent_op); 3617 btrfs_free_delayed_extent_op(head->extent_op);
3618 delayed_refs->num_heads--; 3618 delayed_refs->num_heads--;
3619 if (list_empty(&head->cluster)) 3619 if (list_empty(&head->cluster))
3620 delayed_refs->num_heads_ready--; 3620 delayed_refs->num_heads_ready--;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 61da9d0bb805..9bd87f0d73d0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2285,7 +2285,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
2285 ref = &locked_ref->node; 2285 ref = &locked_ref->node;
2286 2286
2287 if (extent_op && must_insert_reserved) { 2287 if (extent_op && must_insert_reserved) {
2288 kfree(extent_op); 2288 btrfs_free_delayed_extent_op(extent_op);
2289 extent_op = NULL; 2289 extent_op = NULL;
2290 } 2290 }
2291 2291
@@ -2294,7 +2294,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
2294 2294
2295 ret = run_delayed_extent_op(trans, root, 2295 ret = run_delayed_extent_op(trans, root,
2296 ref, extent_op); 2296 ref, extent_op);
2297 kfree(extent_op); 2297 btrfs_free_delayed_extent_op(extent_op);
2298 2298
2299 if (ret) { 2299 if (ret) {
2300 list_del_init(&locked_ref->cluster); 2300 list_del_init(&locked_ref->cluster);
@@ -2338,7 +2338,7 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
2338 must_insert_reserved); 2338 must_insert_reserved);
2339 2339
2340 btrfs_put_delayed_ref(ref); 2340 btrfs_put_delayed_ref(ref);
2341 kfree(extent_op); 2341 btrfs_free_delayed_extent_op(extent_op);
2342 count++; 2342 count++;
2343 2343
2344 if (ret) { 2344 if (ret) {
@@ -2586,7 +2586,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
2586 struct btrfs_delayed_extent_op *extent_op; 2586 struct btrfs_delayed_extent_op *extent_op;
2587 int ret; 2587 int ret;
2588 2588
2589 extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); 2589 extent_op = btrfs_alloc_delayed_extent_op();
2590 if (!extent_op) 2590 if (!extent_op)
2591 return -ENOMEM; 2591 return -ENOMEM;
2592 2592
@@ -2598,7 +2598,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
2598 ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr, 2598 ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr,
2599 num_bytes, extent_op); 2599 num_bytes, extent_op);
2600 if (ret) 2600 if (ret)
2601 kfree(extent_op); 2601 btrfs_free_delayed_extent_op(extent_op);
2602 return ret; 2602 return ret;
2603} 2603}
2604 2604
@@ -5330,7 +5330,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
5330 if (head->extent_op) { 5330 if (head->extent_op) {
5331 if (!head->must_insert_reserved) 5331 if (!head->must_insert_reserved)
5332 goto out; 5332 goto out;
5333 kfree(head->extent_op); 5333 btrfs_free_delayed_extent_op(head->extent_op);
5334 head->extent_op = NULL; 5334 head->extent_op = NULL;
5335 } 5335 }
5336 5336
@@ -6400,7 +6400,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
6400 6400
6401 if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { 6401 if (root_objectid != BTRFS_TREE_LOG_OBJECTID) {
6402 struct btrfs_delayed_extent_op *extent_op; 6402 struct btrfs_delayed_extent_op *extent_op;
6403 extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); 6403 extent_op = btrfs_alloc_delayed_extent_op();
6404 BUG_ON(!extent_op); /* -ENOMEM */ 6404 BUG_ON(!extent_op); /* -ENOMEM */
6405 if (key) 6405 if (key)
6406 memcpy(&extent_op->key, key, sizeof(extent_op->key)); 6406 memcpy(&extent_op->key, key, sizeof(extent_op->key));
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index d8982e9601d3..67b373bf3ff9 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1684,10 +1684,14 @@ static int __init init_btrfs_fs(void)
1684 if (err) 1684 if (err)
1685 goto free_delayed_inode; 1685 goto free_delayed_inode;
1686 1686
1687 err = btrfs_interface_init(); 1687 err = btrfs_delayed_ref_init();
1688 if (err) 1688 if (err)
1689 goto free_auto_defrag; 1689 goto free_auto_defrag;
1690 1690
1691 err = btrfs_interface_init();
1692 if (err)
1693 goto free_delayed_ref;
1694
1691 err = register_filesystem(&btrfs_fs_type); 1695 err = register_filesystem(&btrfs_fs_type);
1692 if (err) 1696 if (err)
1693 goto unregister_ioctl; 1697 goto unregister_ioctl;
@@ -1699,6 +1703,8 @@ static int __init init_btrfs_fs(void)
1699 1703
1700unregister_ioctl: 1704unregister_ioctl:
1701 btrfs_interface_exit(); 1705 btrfs_interface_exit();
1706free_delayed_ref:
1707 btrfs_delayed_ref_exit();
1702free_auto_defrag: 1708free_auto_defrag:
1703 btrfs_auto_defrag_exit(); 1709 btrfs_auto_defrag_exit();
1704free_delayed_inode: 1710free_delayed_inode:
@@ -1720,6 +1726,7 @@ free_compress:
1720static void __exit exit_btrfs_fs(void) 1726static void __exit exit_btrfs_fs(void)
1721{ 1727{
1722 btrfs_destroy_cachep(); 1728 btrfs_destroy_cachep();
1729 btrfs_delayed_ref_exit();
1723 btrfs_auto_defrag_exit(); 1730 btrfs_auto_defrag_exit();
1724 btrfs_delayed_inode_exit(); 1731 btrfs_delayed_inode_exit();
1725 ordered_data_exit(); 1732 ordered_data_exit();