Btrfs: Introduce contexts for metadata reservation

Introducing metadata reseravtion contexts has two major advantages.
First, it makes metadata reseravtion more traceable. Second, it can
reclaim freed space and re-add them to the itself after transaction
committed.

Besides add btrfs_block_rsv structure and related helper functions,
This patch contains following changes:

Move code that decides if freed tree block should be pinned into
btrfs_free_tree_block().

Make space accounting more accurate, mainly for handling read only
block groups.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index e558dd9..d565b45 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3514,6 +3514,7 @@
 	struct btrfs_fs_info *fs_info = extent_root->fs_info;
 	struct reloc_control *rc;
 	int ret;
+	int rw = 0;
 	int err = 0;
 
 	rc = kzalloc(sizeof(*rc), GFP_NOFS);
@@ -3524,15 +3525,22 @@
 	extent_io_tree_init(&rc->processed_blocks, NULL, GFP_NOFS);
 	INIT_LIST_HEAD(&rc->reloc_roots);
 
+	rc->extent_root = extent_root;
 	rc->block_group = btrfs_lookup_block_group(fs_info, group_start);
 	BUG_ON(!rc->block_group);
 
+	if (!rc->block_group->ro) {
+		ret = btrfs_set_block_group_ro(extent_root, rc->block_group);
+		if (ret) {
+			err = ret;
+			goto out;
+		}
+		rw = 1;
+	}
+
 	btrfs_init_workers(&rc->workers, "relocate",
 			   fs_info->thread_pool_size, NULL);
 
-	rc->extent_root = extent_root;
-	btrfs_prepare_block_group_relocation(extent_root, rc->block_group);
-
 	rc->data_inode = create_reloc_inode(fs_info, rc->block_group);
 	if (IS_ERR(rc->data_inode)) {
 		err = PTR_ERR(rc->data_inode);
@@ -3597,6 +3605,8 @@
 	WARN_ON(rc->block_group->reserved > 0);
 	WARN_ON(btrfs_block_group_used(&rc->block_group->item) > 0);
 out:
+	if (err && rw)
+		btrfs_set_block_group_rw(extent_root, rc->block_group);
 	iput(rc->data_inode);
 	btrfs_stop_workers(&rc->workers);
 	btrfs_put_block_group(rc->block_group);