Btrfs: Remove broken optimisations in end_bio functions.

These ended up freeing objects while they were still using them. Under
guidance from Chris, just rip out the 'clever' bits and do things the
simple way.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index f46f886..83ba0c3 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -15,6 +15,8 @@
 #include "extent_io.h"
 #include "extent_map.h"
 #include "compat.h"
+#include "ctree.h"
+#include "btrfs_inode.h"
 
 /* temporary define until extent_map moves out of btrfs */
 struct kmem_cache *btrfs_cache_create(const char *name, size_t size,
@@ -1394,15 +1396,11 @@
 {
 	int uptodate = err == 0;
 	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-	struct extent_state *state = bio->bi_private;
-	struct extent_io_tree *tree = state->tree;
-	struct rb_node *node;
+	struct extent_io_tree *tree;
 	u64 start;
 	u64 end;
-	u64 cur;
 	int whole_page;
 	int ret;
-	unsigned long flags;
 
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
 	if (bio->bi_size)
@@ -1410,6 +1408,8 @@
 #endif
 	do {
 		struct page *page = bvec->bv_page;
+		tree = &BTRFS_I(page->mapping->host)->io_tree;
+
 		start = ((u64)page->index << PAGE_CACHE_SHIFT) +
 			 bvec->bv_offset;
 		end = start + bvec->bv_len - 1;
@@ -1423,7 +1423,7 @@
 			prefetchw(&bvec->bv_page->flags);
 		if (tree->ops && tree->ops->writepage_end_io_hook) {
 			ret = tree->ops->writepage_end_io_hook(page, start,
-						       end, state, uptodate);
+						       end, NULL, uptodate);
 			if (ret)
 				uptodate = 0;
 		}
@@ -1431,9 +1431,8 @@
 		if (!uptodate && tree->ops &&
 		    tree->ops->writepage_io_failed_hook) {
 			ret = tree->ops->writepage_io_failed_hook(bio, page,
-							 start, end, state);
+							 start, end, NULL);
 			if (ret == 0) {
-				state = NULL;
 				uptodate = (err == 0);
 				continue;
 			}
@@ -1445,68 +1444,7 @@
 			SetPageError(page);
 		}
 
-		/*
-		 * bios can get merged in funny ways, and so we need to
-		 * be careful with the state variable.  We know the
-		 * state won't be merged with others because it has
-		 * WRITEBACK set, but we can't be sure each biovec is
-		 * sequential in the file.  So, if our cached state
-		 * doesn't match the expected end, search the tree
-		 * for the correct one.
-		 */
-
-		spin_lock_irqsave(&tree->lock, flags);
-		if (!state || state->end != end) {
-			state = NULL;
-			node = __etree_search(tree, start, NULL, NULL);
-			if (node) {
-				state = rb_entry(node, struct extent_state,
-						 rb_node);
-				if (state->end != end ||
-				    !(state->state & EXTENT_WRITEBACK))
-					state = NULL;
-			}
-			if (!state) {
-				spin_unlock_irqrestore(&tree->lock, flags);
-				clear_extent_writeback(tree, start,
-						       end, GFP_ATOMIC);
-				goto next_io;
-			}
-		}
-		cur = end;
-		while(1) {
-			struct extent_state *clear = state;
-			cur = state->start;
-			node = rb_prev(&state->rb_node);
-			if (node) {
-				state = rb_entry(node,
-						 struct extent_state,
-						 rb_node);
-			} else {
-				state = NULL;
-			}
-
-			clear_state_bit(tree, clear, EXTENT_WRITEBACK,
-					1, 0);
-			if (cur == start)
-				break;
-			if (cur < start) {
-				WARN_ON(1);
-				break;
-			}
-			if (!node)
-				break;
-		}
-		/* before releasing the lock, make sure the next state
-		 * variable has the expected bits set and corresponds
-		 * to the correct offsets in the file
-		 */
-		if (state && (state->end + 1 != start ||
-		    !(state->state & EXTENT_WRITEBACK))) {
-			state = NULL;
-		}
-		spin_unlock_irqrestore(&tree->lock, flags);
-next_io:
+		clear_extent_writeback(tree, start, end, GFP_ATOMIC);
 
 		if (whole_page)
 			end_page_writeback(page);
@@ -1539,13 +1477,9 @@
 {
 	int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
 	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-	struct extent_state *state = bio->bi_private;
-	struct extent_io_tree *tree = state->tree;
-	struct rb_node *node;
+	struct extent_io_tree *tree;
 	u64 start;
 	u64 end;
-	u64 cur;
-	unsigned long flags;
 	int whole_page;
 	int ret;
 
@@ -1556,6 +1490,8 @@
 
 	do {
 		struct page *page = bvec->bv_page;
+		tree = &BTRFS_I(page->mapping->host)->io_tree;
+
 		start = ((u64)page->index << PAGE_CACHE_SHIFT) +
 			bvec->bv_offset;
 		end = start + bvec->bv_len - 1;
@@ -1570,80 +1506,26 @@
 
 		if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) {
 			ret = tree->ops->readpage_end_io_hook(page, start, end,
-							      state);
+							      NULL);
 			if (ret)
 				uptodate = 0;
 		}
 		if (!uptodate && tree->ops &&
 		    tree->ops->readpage_io_failed_hook) {
 			ret = tree->ops->readpage_io_failed_hook(bio, page,
-							 start, end, state);
+							 start, end, NULL);
 			if (ret == 0) {
-				state = NULL;
 				uptodate =
 					test_bit(BIO_UPTODATE, &bio->bi_flags);
 				continue;
 			}
 		}
 
-		spin_lock_irqsave(&tree->lock, flags);
-		if (!state || state->end != end) {
-			state = NULL;
-			node = __etree_search(tree, start, NULL, NULL);
-			if (node) {
-				state = rb_entry(node, struct extent_state,
-						 rb_node);
-				if (state->end != end ||
-				    !(state->state & EXTENT_LOCKED))
-					state = NULL;
-			}
-			if (!state) {
-				spin_unlock_irqrestore(&tree->lock, flags);
-				if (uptodate)
-					set_extent_uptodate(tree, start, end,
-							    GFP_ATOMIC);
-				unlock_extent(tree, start, end, GFP_ATOMIC);
-				goto next_io;
-			}
-		}
+		if (uptodate)
+			set_extent_uptodate(tree, start, end,
+					    GFP_ATOMIC);
+		unlock_extent(tree, start, end, GFP_ATOMIC);
 
-		cur = end;
-		while(1) {
-			struct extent_state *clear = state;
-			cur = state->start;
-			node = rb_prev(&state->rb_node);
-			if (node) {
-				state = rb_entry(node,
-					 struct extent_state,
-					 rb_node);
-			} else {
-				state = NULL;
-			}
-			if (uptodate) {
-				set_state_cb(tree, clear, EXTENT_UPTODATE);
-				clear->state |= EXTENT_UPTODATE;
-			}
-			clear_state_bit(tree, clear, EXTENT_LOCKED,
-					1, 0);
-			if (cur == start)
-				break;
-			if (cur < start) {
-				WARN_ON(1);
-				break;
-			}
-			if (!node)
-				break;
-		}
-		/* before releasing the lock, make sure the next state
-		 * variable has the expected bits set and corresponds
-		 * to the correct offsets in the file
-		 */
-		if (state && (state->end + 1 != start ||
-		    !(state->state & EXTENT_LOCKED))) {
-			state = NULL;
-		}
-		spin_unlock_irqrestore(&tree->lock, flags);
-next_io:
 		if (whole_page) {
 			if (uptodate) {
 				SetPageUptodate(page);
@@ -1683,8 +1565,7 @@
 {
 	const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
 	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-	struct extent_state *state = bio->bi_private;
-	struct extent_io_tree *tree = state->tree;
+	struct extent_io_tree *tree;
 	u64 start;
 	u64 end;
 
@@ -1695,6 +1576,8 @@
 
 	do {
 		struct page *page = bvec->bv_page;
+		tree = &BTRFS_I(page->mapping->host)->io_tree;
+
 		start = ((u64)page->index << PAGE_CACHE_SHIFT) +
 			bvec->bv_offset;
 		end = start + bvec->bv_len - 1;
@@ -1765,7 +1648,7 @@
 	BUG_ON(state->end != end);
 	spin_unlock_irq(&tree->lock);
 
-	bio->bi_private = state;
+	bio->bi_private = NULL;
 
 	bio_get(bio);