}
        return 0;
 }
+
+void nilfs_palloc_setup_cache(struct inode *inode,
+                             struct nilfs_palloc_cache *cache)
+{
+       NILFS_MDT(inode)->mi_palloc_cache = cache;
+       spin_lock_init(&cache->lock);
+}
+
+void nilfs_palloc_clear_cache(struct inode *inode)
+{
+       struct nilfs_palloc_cache *cache = NILFS_MDT(inode)->mi_palloc_cache;
+
+       spin_lock(&cache->lock);
+       brelse(cache->prev_desc.bh);
+       brelse(cache->prev_bitmap.bh);
+       brelse(cache->prev_entry.bh);
+       cache->prev_desc.bh = NULL;
+       cache->prev_bitmap.bh = NULL;
+       cache->prev_entry.bh = NULL;
+       spin_unlock(&cache->lock);
+}
+
+void nilfs_palloc_destroy_cache(struct inode *inode)
+{
+       nilfs_palloc_clear_cache(inode);
+       NILFS_MDT(inode)->mi_palloc_cache = NULL;
+}
 
 #define nilfs_clear_bit_atomic         ext2_clear_bit_atomic
 #define nilfs_find_next_zero_bit       ext2_find_next_zero_bit
 
+/*
+ * persistent object allocator cache
+ */
+
+struct nilfs_bh_assoc {
+       unsigned long blkoff;
+       struct buffer_head *bh;
+};
+
+struct nilfs_palloc_cache {
+       spinlock_t lock;
+       struct nilfs_bh_assoc prev_desc;
+       struct nilfs_bh_assoc prev_bitmap;
+       struct nilfs_bh_assoc prev_entry;
+};
+
+void nilfs_palloc_setup_cache(struct inode *inode,
+                             struct nilfs_palloc_cache *cache);
+void nilfs_palloc_clear_cache(struct inode *inode);
+void nilfs_palloc_destroy_cache(struct inode *inode);
+
 #endif /* _NILFS_ALLOC_H */
 
 {
        struct nilfs_mdt_info *mdi = NILFS_MDT(inode);
 
+       if (mdi->mi_palloc_cache)
+               nilfs_palloc_destroy_cache(inode);
        nilfs_mdt_clear(inode);
 
        kfree(mdi->mi_bgl); /* kfree(NULL) is safe */
 
  * @mi_entry_size: size of an entry
  * @mi_first_entry_offset: offset to the first entry
  * @mi_entries_per_block: number of entries in a block
+ * @mi_palloc_cache: persistent object allocator cache
  * @mi_blocks_per_group: number of blocks in a group
  * @mi_blocks_per_desc_block: number of blocks per descriptor block
  */
        unsigned                mi_entry_size;
        unsigned                mi_first_entry_offset;
        unsigned long           mi_entries_per_block;
+       struct nilfs_palloc_cache *mi_palloc_cache;
        unsigned long           mi_blocks_per_group;
        unsigned long           mi_blocks_per_desc_block;
 };