Btrfs: Add run time btree defrag, and an ioctl to force btree defrag

This adds two types of btree defrag, a run time form that tries to
defrag recently allocated blocks in the btree when they are still in ram,
and an ioctl that forces defrag of all btree blocks.

File data blocks are not defragged yet, but this can make a huge difference
in sequential btree reads.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3889032..12aa043 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -554,7 +554,7 @@
 				 &alloc_hint);
 	if (ret)
 		goto out;
-	ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1,
+	ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1, 0,
 				 alloc_hint, (u64)-1, &ins, 1);
 	if (ret)
 		goto out;
@@ -1360,7 +1360,7 @@
 	if (create & BTRFS_GET_BLOCK_CREATE) {
 		struct btrfs_key ins;
 		ret = btrfs_alloc_extent(trans, root, inode->i_ino,
-					 1, alloc_hint, (u64)-1,
+					 1, 0, alloc_hint, (u64)-1,
 					 &ins, 1);
 		if (ret) {
 			err = ret;
@@ -1998,7 +1998,7 @@
 	trans = btrfs_start_transaction(root, 1);
 	BUG_ON(!trans);
 
-	subvol = btrfs_alloc_free_block(trans, root, 0);
+	subvol = btrfs_alloc_free_block(trans, root, 0, 0);
 	if (IS_ERR(subvol))
 		return PTR_ERR(subvol);
 	leaf = btrfs_buffer_leaf(subvol);
@@ -2159,7 +2159,9 @@
 {
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct btrfs_ioctl_vol_args vol_args;
+	struct btrfs_trans_handle *trans;
 	int ret = 0;
+	int err;
 	struct btrfs_dir_item *di;
 	int namelen;
 	struct btrfs_path *path;
@@ -2196,6 +2198,31 @@
 		else
 			ret = create_snapshot(root, vol_args.name, namelen);
 		break;
+
+	case BTRFS_IOC_DEFRAG:
+		mutex_lock(&root->fs_info->fs_mutex);
+		trans = btrfs_start_transaction(root, 1);
+		memset(&root->defrag_progress, 0,
+		       sizeof(root->defrag_progress));
+		while (1) {
+			root->defrag_running = 1;
+			err = btrfs_defrag_leaves(trans, root, 0);
+
+			btrfs_end_transaction(trans, root);
+			mutex_unlock(&root->fs_info->fs_mutex);
+
+			btrfs_btree_balance_dirty(root);
+
+			mutex_lock(&root->fs_info->fs_mutex);
+			trans = btrfs_start_transaction(root, 1);
+			if (err != -EAGAIN)
+				break;
+		}
+		root->defrag_running = 0;
+		btrfs_end_transaction(trans, root);
+		mutex_unlock(&root->fs_info->fs_mutex);
+		ret = 0;
+		break;
 	default:
 		return -ENOTTY;
 	}