aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/backref.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r--fs/btrfs/backref.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index f3cb19114c95..0552a599b28f 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -119,6 +119,26 @@ struct __prelim_ref {
119 u64 wanted_disk_byte; 119 u64 wanted_disk_byte;
120}; 120};
121 121
122static struct kmem_cache *btrfs_prelim_ref_cache;
123
124int __init btrfs_prelim_ref_init(void)
125{
126 btrfs_prelim_ref_cache = kmem_cache_create("btrfs_prelim_ref",
127 sizeof(struct __prelim_ref),
128 0,
129 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
130 NULL);
131 if (!btrfs_prelim_ref_cache)
132 return -ENOMEM;
133 return 0;
134}
135
136void btrfs_prelim_ref_exit(void)
137{
138 if (btrfs_prelim_ref_cache)
139 kmem_cache_destroy(btrfs_prelim_ref_cache);
140}
141
122/* 142/*
123 * the rules for all callers of this function are: 143 * the rules for all callers of this function are:
124 * - obtaining the parent is the goal 144 * - obtaining the parent is the goal
@@ -165,7 +185,7 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
165{ 185{
166 struct __prelim_ref *ref; 186 struct __prelim_ref *ref;
167 187
168 ref = kmalloc(sizeof(*ref), gfp_mask); 188 ref = kmem_cache_alloc(btrfs_prelim_ref_cache, gfp_mask);
169 if (!ref) 189 if (!ref)
170 return -ENOMEM; 190 return -ENOMEM;
171 191
@@ -368,7 +388,8 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
368 388
369 /* additional parents require new refs being added here */ 389 /* additional parents require new refs being added here */
370 while ((node = ulist_next(parents, &uiter))) { 390 while ((node = ulist_next(parents, &uiter))) {
371 new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS); 391 new_ref = kmem_cache_alloc(btrfs_prelim_ref_cache,
392 GFP_NOFS);
372 if (!new_ref) { 393 if (!new_ref) {
373 ret = -ENOMEM; 394 ret = -ENOMEM;
374 goto out; 395 goto out;
@@ -492,7 +513,7 @@ static void __merge_refs(struct list_head *head, int mode)
492 ref1->count += ref2->count; 513 ref1->count += ref2->count;
493 514
494 list_del(&ref2->list); 515 list_del(&ref2->list);
495 kfree(ref2); 516 kmem_cache_free(btrfs_prelim_ref_cache, ref2);
496 } 517 }
497 518
498 } 519 }
@@ -955,7 +976,7 @@ again:
955 } 976 }
956 } 977 }
957 list_del(&ref->list); 978 list_del(&ref->list);
958 kfree(ref); 979 kmem_cache_free(btrfs_prelim_ref_cache, ref);
959 } 980 }
960 981
961out: 982out:
@@ -963,13 +984,13 @@ out:
963 while (!list_empty(&prefs)) { 984 while (!list_empty(&prefs)) {
964 ref = list_first_entry(&prefs, struct __prelim_ref, list); 985 ref = list_first_entry(&prefs, struct __prelim_ref, list);
965 list_del(&ref->list); 986 list_del(&ref->list);
966 kfree(ref); 987 kmem_cache_free(btrfs_prelim_ref_cache, ref);
967 } 988 }
968 while (!list_empty(&prefs_delayed)) { 989 while (!list_empty(&prefs_delayed)) {
969 ref = list_first_entry(&prefs_delayed, struct __prelim_ref, 990 ref = list_first_entry(&prefs_delayed, struct __prelim_ref,
970 list); 991 list);
971 list_del(&ref->list); 992 list_del(&ref->list);
972 kfree(ref); 993 kmem_cache_free(btrfs_prelim_ref_cache, ref);
973 } 994 }
974 995
975 return ret; 996 return ret;