---
 drivers/md/dm-thin.c |   40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

Index: linux-3.1-rc9/drivers/md/dm-thin.c
===================================================================
--- linux-3.1-rc9.orig/drivers/md/dm-thin.c
+++ linux-3.1-rc9/drivers/md/dm-thin.c
@@ -490,7 +490,7 @@ struct pool {
 
 	spinlock_t lock;
 	struct bio_list deferred_bios;
-	struct bio_list awaiting_commit;
+	struct bio_list deferred_flush_bios;
 	struct list_head prepared_mappings;
 
 	struct bio_list retry_on_resume_list;
@@ -618,9 +618,13 @@ static void remap_and_issue(struct thin_
 
 	remap(tc, bio, block);
 
+	/*
+	 * Batch together any FUA/FLUSH bios we find and then issue
+	 * a single commit for them in process_deferred_bios().
+	 */
 	if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
 		spin_lock_irqsave(&pool->lock, flags);
-		bio_list_add(&pool->awaiting_commit, bio);
+		bio_list_add(&pool->deferred_flush_bios, bio);
 		spin_unlock_irqrestore(&pool->lock, flags);
 	} else
 		generic_make_request(bio);
@@ -1215,6 +1219,7 @@ static void process_deferred_bios(struct
 	unsigned long flags;
 	struct bio *bio;
 	struct bio_list bios;
+	int r;
 
 	bio_list_init(&bios);
 
@@ -1240,25 +1245,30 @@ static void process_deferred_bios(struct
 		process_bio(tc, bio);
 	}
 
+	/*
+	 * If there are any deferred flush bios, we must commit
+	 * the metadata before issuing them.
+	 */
 	bio_list_init(&bios);
 	spin_lock_irqsave(&pool->lock, flags);
-	bio_list_merge(&bios, &pool->awaiting_commit);
-	bio_list_init(&pool->awaiting_commit);
+	bio_list_merge(&bios, &pool->deferred_flush_bios);
+	bio_list_init(&pool->deferred_flush_bios);
 	spin_unlock_irqrestore(&pool->lock, flags);
 
-	if (!bio_list_empty(&bios)) {
-		int r = dm_pool_commit_metadata(pool->pmd);
-		if (r) {
-			DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
-			      __func__, r);
-			while ((bio = bio_list_pop(&bios)))
-				bio_io_error(bio);
-			return;
-		}
+	if (bio_list_empty(&bios))
+		return;
 
+	r = dm_pool_commit_metadata(pool->pmd);
+	if (r) {
+		DMERR("%s: dm_pool_commit_metadata() failed, error = %d",
+		      __func__, r);
 		while ((bio = bio_list_pop(&bios)))
-			generic_make_request(bio);
+			bio_io_error(bio);
+		return;
 	}
+
+	while ((bio = bio_list_pop(&bios)))
+		generic_make_request(bio);
 }
 
 static void do_worker(struct work_struct *ws)
@@ -1477,7 +1487,7 @@ static struct pool *pool_create(struct m
 	INIT_WORK(&pool->worker, do_worker);
 	spin_lock_init(&pool->lock);
 	bio_list_init(&pool->deferred_bios);
-	bio_list_init(&pool->awaiting_commit);
+	bio_list_init(&pool->deferred_flush_bios);
 	INIT_LIST_HEAD(&pool->prepared_mappings);
 	pool->low_water_triggered = 0;
 	pool->no_free_space = 0;
