aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-11-26 04:24:43 -0500
committerChris Mason <chris.mason@fusionio.com>2012-12-16 20:46:11 -0500
commit9247f3170b2c3d648707c93bbebcd763fac17c06 (patch)
tree6e521e62171197502743b712271438be607ad293
parent905b0dda06a064db08b8a814e968786ff3c4cc19 (diff)
Btrfs: use slabs for auto defrag allocation
The auto defrag 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> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/file.c28
-rw-r--r--fs/btrfs/super.c9
3 files changed, 34 insertions, 5 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 91ff078e85d..389c05715ea 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3505,6 +3505,8 @@ void btrfs_get_block_group_info(struct list_head *groups_list,
3505 struct btrfs_ioctl_space_info *space); 3505 struct btrfs_ioctl_space_info *space);
3506 3506
3507/* file.c */ 3507/* file.c */
3508int btrfs_auto_defrag_init(void);
3509void btrfs_auto_defrag_exit(void);
3508int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, 3510int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
3509 struct inode *inode); 3511 struct inode *inode);
3510int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info); 3512int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index bd7f1b01e05..15117eae85c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -41,6 +41,7 @@
41#include "compat.h" 41#include "compat.h"
42#include "volumes.h" 42#include "volumes.h"
43 43
44static struct kmem_cache *btrfs_inode_defrag_cachep;
44/* 45/*
45 * when auto defrag is enabled we 46 * when auto defrag is enabled we
46 * queue up these defrag structs to remember which 47 * queue up these defrag structs to remember which
@@ -127,7 +128,7 @@ static void __btrfs_add_inode_defrag(struct inode *inode,
127 return; 128 return;
128 129
129exists: 130exists:
130 kfree(defrag); 131 kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
131 return; 132 return;
132 133
133} 134}
@@ -157,7 +158,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
157 else 158 else
158 transid = BTRFS_I(inode)->root->last_trans; 159 transid = BTRFS_I(inode)->root->last_trans;
159 160
160 defrag = kzalloc(sizeof(*defrag), GFP_NOFS); 161 defrag = kmem_cache_zalloc(btrfs_inode_defrag_cachep, GFP_NOFS);
161 if (!defrag) 162 if (!defrag)
162 return -ENOMEM; 163 return -ENOMEM;
163 164
@@ -169,7 +170,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
169 if (!test_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags)) 170 if (!test_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags))
170 __btrfs_add_inode_defrag(inode, defrag); 171 __btrfs_add_inode_defrag(inode, defrag);
171 else 172 else
172 kfree(defrag); 173 kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
173 spin_unlock(&root->fs_info->defrag_inodes_lock); 174 spin_unlock(&root->fs_info->defrag_inodes_lock);
174 return 0; 175 return 0;
175} 176}
@@ -315,7 +316,8 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info)
315next: 316next:
316 spin_lock(&fs_info->defrag_inodes_lock); 317 spin_lock(&fs_info->defrag_inodes_lock);
317next_free: 318next_free:
318 kfree(defrag); 319 if (defrag)
320 kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
319 } 321 }
320 spin_unlock(&fs_info->defrag_inodes_lock); 322 spin_unlock(&fs_info->defrag_inodes_lock);
321 323
@@ -2293,3 +2295,21 @@ const struct file_operations btrfs_file_operations = {
2293 .compat_ioctl = btrfs_ioctl, 2295 .compat_ioctl = btrfs_ioctl,
2294#endif 2296#endif
2295}; 2297};
2298
2299void btrfs_auto_defrag_exit(void)
2300{
2301 if (btrfs_inode_defrag_cachep)
2302 kmem_cache_destroy(btrfs_inode_defrag_cachep);
2303}
2304
2305int btrfs_auto_defrag_init(void)
2306{
2307 btrfs_inode_defrag_cachep = kmem_cache_create("btrfs_inode_defrag",
2308 sizeof(struct inode_defrag), 0,
2309 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
2310 NULL);
2311 if (!btrfs_inode_defrag_cachep)
2312 return -ENOMEM;
2313
2314 return 0;
2315}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index def4f24b58d..99545df1b86 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1680,10 +1680,14 @@ static int __init init_btrfs_fs(void)
1680 if (err) 1680 if (err)
1681 goto free_ordered_data; 1681 goto free_ordered_data;
1682 1682
1683 err = btrfs_interface_init(); 1683 err = btrfs_auto_defrag_init();
1684 if (err) 1684 if (err)
1685 goto free_delayed_inode; 1685 goto free_delayed_inode;
1686 1686
1687 err = btrfs_interface_init();
1688 if (err)
1689 goto free_auto_defrag;
1690
1687 err = register_filesystem(&btrfs_fs_type); 1691 err = register_filesystem(&btrfs_fs_type);
1688 if (err) 1692 if (err)
1689 goto unregister_ioctl; 1693 goto unregister_ioctl;
@@ -1695,6 +1699,8 @@ static int __init init_btrfs_fs(void)
1695 1699
1696unregister_ioctl: 1700unregister_ioctl:
1697 btrfs_interface_exit(); 1701 btrfs_interface_exit();
1702free_auto_defrag:
1703 btrfs_auto_defrag_exit();
1698free_delayed_inode: 1704free_delayed_inode:
1699 btrfs_delayed_inode_exit(); 1705 btrfs_delayed_inode_exit();
1700free_ordered_data: 1706free_ordered_data:
@@ -1714,6 +1720,7 @@ free_compress:
1714static void __exit exit_btrfs_fs(void) 1720static void __exit exit_btrfs_fs(void)
1715{ 1721{
1716 btrfs_destroy_cachep(); 1722 btrfs_destroy_cachep();
1723 btrfs_auto_defrag_exit();
1717 btrfs_delayed_inode_exit(); 1724 btrfs_delayed_inode_exit();
1718 ordered_data_exit(); 1725 ordered_data_exit();
1719 extent_map_exit(); 1726 extent_map_exit();