diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 2b76c794..c2a25699 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -484,6 +484,93 @@ out:
 	return NULL;
 }
 
+struct ext4_reada_bitmap {
+	struct super_block *sb;
+	ext4_group_t bg_start;
+	struct work_struct wq;
+};
+
+static void ext4_read_block_bitmaps(struct super_block *sb,
+				    ext4_group_t block_group, unsigned long nr)
+{
+	ext4_group_t bg;
+	int i = 0;
+	struct buffer_head **bh = NULL;
+	ext4_group_t ngroups = ext4_get_groups_count(sb);
+	ext4_group_t end_group;
+	int read_count = 0;
+
+	atomic_inc(&EXT4_SB(sb)->s_bbitmap_reada_flighting);
+	if (nr > 1048576)
+		nr = 1048576;
+
+	end_group = block_group + nr - 1;
+	if (end_group >= ngroups) {
+		end_group = ngroups - 1;
+		nr = end_group - block_group + 1;
+	}
+
+	bh = kzalloc(sizeof(struct buffer_head *) * nr, GFP_NOFS);
+	if (!bh) {
+		ext4_warning(sb, "Failed to allocate memory for bitmaps readahead");
+		atomic_dec(&EXT4_SB(sb)->s_bbitmap_reada_flighting);
+		return;
+	}
+
+	for (bg = block_group; bg <= end_group; bg++)
+		if (!(bh[i++] = ext4_read_block_bitmap_nowait(sb, bg)))
+			ext4_warning(sb, "failed to reada group's bbitmap %llu\n",
+					(unsigned long long)bg);
+	i = 0;
+	for (bg = block_group; bg <= end_group; bg++) {
+		if (bh[i]) {
+			if (buffer_new(bh[i]))
+				read_count++;
+			ext4_wait_block_bitmap(sb, bg, bh[i]);
+		}
+		i++;
+	}
+
+	printk(KERN_ERR "async thread read bbitmaps: %d, flighting IO: %d\n",
+			read_count, atomic_read(&EXT4_SB(sb)->s_bbitmap_reada_flighting));
+	for (i = 0; i < nr; i++)
+		brelse(bh[i]);
+	kfree(bh);
+	atomic_dec(&EXT4_SB(sb)->s_bbitmap_reada_flighting);
+}
+
+static void ext4_reada_bbitmap_work(struct work_struct *work)
+{
+	unsigned reada_blks;
+	struct ext4_reada_bitmap *erb = container_of(work,
+						struct ext4_reada_bitmap, wq);
+
+	reada_blks = EXT4_SB(erb->sb)->s_bbitmap_readahead_blks;
+	if (reada_blks)
+		ext4_read_block_bitmaps(erb->sb, erb->bg_start, reada_blks);
+	kfree(erb);
+}
+
+void ext4_read_block_bitmaps_async(struct super_block *sb,
+				   ext4_group_t block_group)
+{
+	ext4_group_t ngroups = ext4_get_groups_count(sb);
+
+	/* sumit readahead bitmaps request if possible */
+	if (EXT4_SB(sb)->s_bbitmap_readahead_blks &&
+	    block_group < ngroups &&
+	    atomic_read(&EXT4_SB(sb)->s_bbitmap_reada_flighting) <
+	    EXT4_SB(sb)->s_bbitmap_reada_req_limit) {
+		struct ext4_reada_bitmap *erb = kzalloc(sizeof(*erb), GFP_NOFS);
+
+		erb->sb = sb;
+		erb->bg_start = block_group;
+		INIT_WORK(&erb->wq, ext4_reada_bbitmap_work);
+		queue_work(EXT4_SB(sb)->bbitmap_reada_wq, &erb->wq);
+	}
+}
+
+
 /* Returns 0 on success, 1 on error */
 int ext4_wait_block_bitmap(struct super_block *sb, ext4_group_t block_group,
 			   struct buffer_head *bh)
@@ -517,6 +604,11 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
 	bh = ext4_read_block_bitmap_nowait(sb, block_group);
 	if (!bh)
 		return NULL;
+
+	/* race doesn't matter */
+	if (buffer_new(bh))
+		ext4_read_block_bitmaps_async(sb, block_group + 1);
+
 	if (ext4_wait_block_bitmap(sb, block_group, bh)) {
 		put_bh(bh);
 		return NULL;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index d4761dfa..e0e077fe 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1412,6 +1412,9 @@ struct ext4_sb_info {
 	unsigned int s_mb_group_prealloc;
 	unsigned int s_max_dir_size_kb;
 	unsigned long s_warning_dir_size;
+	unsigned int s_bbitmap_readahead_blks;
+	unsigned int s_bbitmap_reada_req_limit;
+	atomic_t s_bbitmap_reada_flighting;
 	/* where last allocation was done - for stream allocation */
 	unsigned long s_mb_last_group;
 	unsigned long s_mb_last_start;
@@ -1449,6 +1452,9 @@ struct ext4_sb_info {
 	/* workqueue for reserved extent conversions (buffered io) */
 	struct workqueue_struct *rsv_conversion_wq;
 
+	/* workqueue for bbitmap readahead*/
+	struct workqueue_struct *bbitmap_reada_wq;
+
 	/* timer for periodic error stats printing */
 	struct timer_list s_err_report;
 
@@ -2236,6 +2242,8 @@ extern int ext4_wait_block_bitmap(struct super_block *sb,
 				  struct buffer_head *bh);
 extern struct buffer_head *ext4_read_block_bitmap(struct super_block *sb,
 						  ext4_group_t block_group);
+void ext4_read_block_bitmaps_async(struct super_block *sb,
+				   ext4_group_t block_group);
 extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
 					      ext4_group_t block_group,
 					      struct ext4_group_desc *gdp);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index d9b00e42..7db58912 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -883,6 +883,10 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 		mb_debug(1, "read bitmap for group %u\n", group);
 	}
 
+	/* race dosen't matter */
+	if (buffer_new(bh[i - 1]))
+		ext4_read_block_bitmaps_async(sb, group + 1);
+
 	/* wait for I/O completion */
 	for (i = 0, group = first_group; i < groups_per_page; i++, group++) {
 		if (bh[i] && ext4_wait_block_bitmap(sb, group, bh[i])) {
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index fb05762e..b235c165 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -823,6 +823,9 @@ static void ext4_put_super(struct super_block *sb)
 	flush_workqueue(sbi->rsv_conversion_wq);
 	destroy_workqueue(sbi->rsv_conversion_wq);
 
+	flush_workqueue(sbi->bbitmap_reada_wq);
+	destroy_workqueue(sbi->bbitmap_reada_wq);
+
 	if (sbi->s_journal) {
 		aborted = is_journal_aborted(sbi->s_journal);
 		err = jbd2_journal_destroy(sbi->s_journal);
@@ -2802,6 +2805,8 @@ EXT4_RW_ATTR_SBI_UI(warning_ratelimit_interval_ms, s_warning_ratelimit_state.int
 EXT4_RW_ATTR_SBI_UI(warning_ratelimit_burst, s_warning_ratelimit_state.burst);
 EXT4_RW_ATTR_SBI_UI(msg_ratelimit_interval_ms, s_msg_ratelimit_state.interval);
 EXT4_RW_ATTR_SBI_UI(msg_ratelimit_burst, s_msg_ratelimit_state.burst);
+EXT4_RW_ATTR_SBI_UI(bbitmap_readahead_blks, s_bbitmap_readahead_blks);
+EXT4_RW_ATTR_SBI_UI(bbitmap_reada_req_limit, s_bbitmap_reada_req_limit);
 EXT4_RO_ATTR_ES_UI(errors_count, s_error_count);
 EXT4_RO_ATTR_ES_UI(first_error_time, s_first_error_time);
 EXT4_RO_ATTR_ES_UI(last_error_time, s_last_error_time);
@@ -2832,6 +2837,8 @@ static struct attribute *ext4_attrs[] = {
 	ATTR_LIST(warning_ratelimit_burst),
 	ATTR_LIST(msg_ratelimit_interval_ms),
 	ATTR_LIST(msg_ratelimit_burst),
+	ATTR_LIST(bbitmap_readahead_blks),
+	ATTR_LIST(bbitmap_reada_req_limit),
 	ATTR_LIST(errors_count),
 	ATTR_LIST(first_error_time),
 	ATTR_LIST(last_error_time),
@@ -4305,6 +4312,14 @@ no_journal:
 		goto failed_mount4;
 	}
 
+	sbi->s_bbitmap_reada_req_limit = 1; /* default is 1 */
+	sbi->bbitmap_reada_wq = alloc_workqueue("ext4-bbitmap-reada", WQ_UNBOUND, 0);
+	if (!sbi->rsv_conversion_wq) {
+		printk(KERN_ERR "EXT4-fs: failed to create bbitmap reada workqueue\n");
+		ret = -ENOMEM;
+		goto failed_mount4;
+	}
+
 	/*
 	 * The jbd2_journal_load will have done any necessary log recovery,
 	 * so we can safely mount the rest of the filesystem now.
@@ -4500,6 +4515,8 @@ failed_mount4:
 	ext4_msg(sb, KERN_ERR, "mount failed");
 	if (EXT4_SB(sb)->rsv_conversion_wq)
 		destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq);
+	if (EXT4_SB(sb)->bbitmap_reada_wq)
+		destroy_workqueue(EXT4_SB(sb)->bbitmap_reada_wq);
 failed_mount_wq:
 	if (sbi->s_journal) {
 		jbd2_journal_destroy(sbi->s_journal);