Btrfs: Create extent_buffer interface for large blocksizes

Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 087074d..750f35a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
+#include <linux/pagemap.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -66,7 +67,9 @@
 		cur_trans->commit_done = 0;
 		cur_trans->start_time = get_seconds();
 		list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
-		init_bit_radix(&cur_trans->dirty_pages);
+		extent_map_tree_init(&cur_trans->dirty_pages,
+				     root->fs_info->btree_inode->i_mapping,
+				     GFP_NOFS);
 	} else {
 		cur_trans->num_writers++;
 		cur_trans->num_joined++;
@@ -88,7 +91,7 @@
 				   (unsigned long)root->root_key.objectid,
 				   BTRFS_ROOT_DEFRAG_TAG);
 			root->commit_root = root->node;
-			get_bh(root->node);
+			extent_buffer_get(root->node);
 		} else {
 			WARN_ON(1);
 		}
@@ -144,29 +147,30 @@
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
 				     struct btrfs_root *root)
 {
-	unsigned long gang[16];
 	int ret;
-	int i;
 	int err;
 	int werr = 0;
+	struct extent_map_tree *dirty_pages;
 	struct page *page;
-	struct radix_tree_root *dirty_pages;
 	struct inode *btree_inode = root->fs_info->btree_inode;
+	u64 start;
+	u64 end;
+	unsigned long index;
 
 	if (!trans || !trans->transaction) {
 		return filemap_write_and_wait(btree_inode->i_mapping);
 	}
 	dirty_pages = &trans->transaction->dirty_pages;
 	while(1) {
-		ret = find_first_radix_bit(dirty_pages, gang,
-					   0, ARRAY_SIZE(gang));
-		if (!ret)
+		ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
+					    EXTENT_DIRTY);
+		if (ret)
 			break;
-		for (i = 0; i < ret; i++) {
-			/* FIXME EIO */
-			clear_radix_bit(dirty_pages, gang[i]);
-			page = find_lock_page(btree_inode->i_mapping,
-					      gang[i]);
+		clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
+		while(start <= end) {
+			index = start >> PAGE_CACHE_SHIFT;
+			start = (index + 1) << PAGE_CACHE_SHIFT;
+			page = find_lock_page(btree_inode->i_mapping, index);
 			if (!page)
 				continue;
 			if (PageWriteback(page)) {
@@ -202,10 +206,11 @@
 	btrfs_write_dirty_block_groups(trans, extent_root);
 	while(1) {
 		old_extent_block = btrfs_root_blocknr(&extent_root->root_item);
-		if (old_extent_block == bh_blocknr(extent_root->node))
+		if (old_extent_block ==
+		    extent_buffer_blocknr(extent_root->node))
 			break;
 		btrfs_set_root_blocknr(&extent_root->root_item,
-				       bh_blocknr(extent_root->node));
+			       extent_buffer_blocknr(extent_root->node));
 		ret = btrfs_update_root(trans, tree_root,
 					&extent_root->root_key,
 					&extent_root->root_item);
@@ -279,9 +284,9 @@
 				     (unsigned long)root->root_key.objectid,
 				     BTRFS_ROOT_TRANS_TAG);
 			if (root->commit_root == root->node) {
-				WARN_ON(bh_blocknr(root->node) !=
+				WARN_ON(extent_buffer_blocknr(root->node) !=
 					btrfs_root_blocknr(&root->root_item));
-				brelse(root->commit_root);
+				free_extent_buffer(root->commit_root);
 				root->commit_root = NULL;
 
 				/* make sure to update the root on disk
@@ -310,7 +315,7 @@
 
 			root->root_key.offset = root->fs_info->generation;
 			btrfs_set_root_blocknr(&root->root_item,
-					       bh_blocknr(root->node));
+				       extent_buffer_blocknr(root->node));
 			err = btrfs_insert_root(trans, root->fs_info->tree_root,
 						&root->root_key,
 						&root->root_item);
@@ -389,10 +394,10 @@
 		for (i = 0; i < ret; i++) {
 			root = gang[i];
 			last = root->root_key.objectid + 1;
-			btrfs_defrag_root(root, 1);
+			// btrfs_defrag_root(root, 1);
 		}
 	}
-	btrfs_defrag_root(info->extent_root, 1);
+	// btrfs_defrag_root(info->extent_root, 1);
 	return err;
 }
 
@@ -414,7 +419,7 @@
 		dirty = list_entry(list->next, struct dirty_root, list);
 		list_del_init(&dirty->list);
 
-		num_blocks = btrfs_root_blocks_used(&dirty->root->root_item);
+		num_blocks = btrfs_root_used(&dirty->root->root_item);
 		root = dirty->latest_root;
 
 		while(1) {
@@ -441,11 +446,11 @@
 		}
 		BUG_ON(ret);
 
-		num_blocks -= btrfs_root_blocks_used(&dirty->root->root_item);
-		blocks_used = btrfs_root_blocks_used(&root->root_item);
+		num_blocks -= btrfs_root_used(&dirty->root->root_item);
+		blocks_used = btrfs_root_used(&root->root_item);
 		if (num_blocks) {
 			record_root_in_trans(root);
-			btrfs_set_root_blocks_used(&root->root_item,
+			btrfs_set_root_used(&root->root_item,
 						   blocks_used - num_blocks);
 		}
 		ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
@@ -553,9 +558,11 @@
 	btrfs_set_super_generation(&root->fs_info->super_copy,
 				   cur_trans->transid);
 	btrfs_set_super_root(&root->fs_info->super_copy,
-			     bh_blocknr(root->fs_info->tree_root->node));
-	memcpy(root->fs_info->disk_super, &root->fs_info->super_copy,
-	       sizeof(root->fs_info->super_copy));
+		     extent_buffer_blocknr(root->fs_info->tree_root->node));
+
+	write_extent_buffer(root->fs_info->sb_buffer,
+			    &root->fs_info->super_copy, 0,
+			    sizeof(root->fs_info->super_copy));
 
 	btrfs_copy_pinned(root, &pinned_copy);