#include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
+#include <linux/mempool.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/bio.h>
 #include <linux/fs.h>
        struct gfs2_sbd *sdp = bd->bd_gl->gl_sbd;
 
        end_buffer_write_sync(bh, uptodate);
-       free_buffer_head(bh);
+       mempool_free(bh, gfs2_bh_pool);
        unlock_buffer(real_bh);
        brelse(real_bh);
        if (atomic_dec_and_test(&sdp->sd_log_in_flight))
        u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head);
        struct buffer_head *bh;
 
-       bh = alloc_buffer_head(GFP_NOFS | __GFP_NOFAIL);
+       bh = mempool_alloc(gfs2_bh_pool, GFP_NOFS);
        atomic_set(&bh->b_count, 1);
        bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock);
        set_bh_page(bh, real->b_page, bh_offset(real));
 
 #include <linux/rcupdate.h>
 #include <linux/rculist_bl.h>
 #include <linux/atomic.h>
+#include <linux/mempool.h>
 
 #include "gfs2.h"
 #include "incore.h"
        address_space_init_once(mapping);
 }
 
+static void *gfs2_bh_alloc(gfp_t mask, void *data)
+{
+       return alloc_buffer_head(mask);
+}
+
+static void gfs2_bh_free(void *ptr, void *data)
+{
+       return free_buffer_head(ptr);
+}
+
 /**
  * init_gfs2_fs - Register GFS2 as a filesystem
  *
        gfs2_control_wq = alloc_workqueue("gfs2_control",
                               WQ_NON_REENTRANT | WQ_UNBOUND | WQ_FREEZABLE, 0);
        if (!gfs2_control_wq)
+               goto fail_recovery;
+
+       gfs2_bh_pool = mempool_create(1024, gfs2_bh_alloc, gfs2_bh_free, NULL);
+       if (!gfs2_bh_pool)
                goto fail_control;
 
        gfs2_register_debugfs();
        return 0;
 
 fail_control:
+       destroy_workqueue(gfs2_control_wq);
+fail_recovery:
        destroy_workqueue(gfs_recovery_wq);
 fail_wq:
        unregister_filesystem(&gfs2meta_fs_type);
 
        rcu_barrier();
 
+       mempool_destroy(gfs2_bh_pool);
        kmem_cache_destroy(gfs2_quotad_cachep);
        kmem_cache_destroy(gfs2_rgrpd_cachep);
        kmem_cache_destroy(gfs2_bufdata_cachep);
 
 struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
 struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
 struct kmem_cache *gfs2_quotad_cachep __read_mostly;
+mempool_t *gfs2_bh_pool __read_mostly;
 
 void gfs2_assert_i(struct gfs2_sbd *sdp)
 {
 
 #ifndef __UTIL_DOT_H__
 #define __UTIL_DOT_H__
 
+#include <linux/mempool.h>
+
 #include "incore.h"
 
 #define fs_printk(level, fs, fmt, arg...) \
 extern struct kmem_cache *gfs2_bufdata_cachep;
 extern struct kmem_cache *gfs2_rgrpd_cachep;
 extern struct kmem_cache *gfs2_quotad_cachep;
+extern mempool_t *gfs2_bh_pool;
 
 static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
                                           unsigned int *p)