/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

#define _XOPEN_SOURCE 600
#define _GNU_SOURCE 1
#ifndef __CHECKER__
#include <sys/ioctl.h>
#include <sys/mount.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/acl.h>
#include <fcntl.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <linux/fs.h>
#include "kerncompat.h"
#include "ctree.h"
#include "disk-io.h"
#include "volumes.h"
#include "transaction.h"
#include "crc32c.h"
#include "utils.h"
#include <ext2fs/ext2_fs.h>
#include <ext2fs/ext2fs.h>
#include <ext2fs/ext2_ext_attr.h>

#define INO_OFFSET (BTRFS_FIRST_FREE_OBJECTID - EXT2_ROOT_INO)
#define STRIPE_LEN (64 * 1024)
#define EXT2_IMAGE_SUBVOL_OBJECTID BTRFS_FIRST_FREE_OBJECTID

/*
 * Open Ext2fs in readonly mode, read block allocation bitmap and
 * inode bitmap into memory.
 */
static int open_ext2fs(const char *name, ext2_filsys *ret_fs)
{
	errcode_t ret;
	ext2_filsys ext2_fs;
	ext2_ino_t ino;
	ret = ext2fs_open(name, 0, 0, 0, unix_io_manager, &ext2_fs);
	if (ret) {
		fprintf(stderr, "ext2fs_open: %s\n", error_message(ret));
		goto fail;
	}
	ret = ext2fs_read_inode_bitmap(ext2_fs);
	if (ret) {
		fprintf(stderr, "ext2fs_read_inode_bitmap: %s\n",
			error_message(ret));
		goto fail;
	}
	ret = ext2fs_read_block_bitmap(ext2_fs);
	if (ret) {
		fprintf(stderr, "ext2fs_read_block_bitmap: %s\n",
			error_message(ret));
		goto fail;
	}
	/*
	 * search each block group for a free inode. this set up
	 * uninit block/inode bitmaps appropriately.
	 */
	ino = 1;
	while (ino <= ext2_fs->super->s_inodes_count) {
		ext2_ino_t foo;
		ext2fs_new_inode(ext2_fs, ino, 0, NULL, &foo);
		ino += EXT2_INODES_PER_GROUP(ext2_fs->super);
	}

	*ret_fs = ext2_fs;
	return 0;
fail:
	return -1;
}

static int close_ext2fs(ext2_filsys fs)
{
	ext2fs_close(fs);
	return 0;
}

static int ext2_alloc_block(ext2_filsys fs, u64 goal, u64 *block_ret)
{
	blk_t block;

	if (!ext2fs_new_block(fs, goal, NULL, &block)) {
		ext2fs_fast_mark_block_bitmap(fs->block_map, block);
		*block_ret = block;
		return 0;
	}
	return -ENOSPC;
}

static int ext2_free_block(ext2_filsys fs, u64 block)
{
	BUG_ON(block != (blk_t)block);
	ext2fs_fast_unmark_block_bitmap(fs->block_map, block);
	return 0;
}

static int cache_free_extents(struct btrfs_root *root, ext2_filsys ext2_fs)

{
	int i, ret = 0;
	blk_t block;
	u64 bytenr;
	u64 blocksize = ext2_fs->blocksize;

	block = ext2_fs->super->s_first_data_block;
	for (; block < ext2_fs->super->s_blocks_count; block++) {
		if (ext2fs_fast_test_block_bitmap(ext2_fs->block_map, block))
			continue;
		bytenr = block * blocksize;
		ret = set_extent_dirty(&root->fs_info->free_space_cache,
				       bytenr, bytenr + blocksize - 1, 0);
		BUG_ON(ret);
	}

	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
		bytenr = btrfs_sb_offset(i);
		bytenr &= ~((u64)STRIPE_LEN - 1);
		if (bytenr >= blocksize * ext2_fs->super->s_blocks_count)
			break;
		clear_extent_dirty(&root->fs_info->free_space_cache, bytenr,
				   bytenr + STRIPE_LEN - 1, 0);
	}

	clear_extent_dirty(&root->fs_info->free_space_cache,
			   0, BTRFS_SUPER_INFO_OFFSET - 1, 0);

	return 0;
}

static int custom_alloc_extent(struct btrfs_root *root, u64 num_bytes,
			       u64 hint_byte, struct btrfs_key *ins)
{
	u64 start;
	u64 end;
	u64 last = hint_byte;
	int ret;
	int wrapped = 0;
	struct btrfs_block_group_cache *cache;

	while(1) {
		ret = find_first_extent_bit(&root->fs_info->free_space_cache,
					    last, &start, &end, EXTENT_DIRTY);
		if (ret) {
			if (wrapped++ == 0) {
				last = 0;
				continue;
			} else {
				goto fail;
			}
		}

		start = max(last, start);
		last = end + 1;
		if (last - start < num_bytes)
			continue;

		last = start + num_bytes;
		if (test_range_bit(&root->fs_info->pinned_extents,
				   start, last - 1, EXTENT_DIRTY, 0))
			continue;

		cache = btrfs_lookup_block_group(root->fs_info, start);
		BUG_ON(!cache);
		if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM ||
		    last > cache->key.objectid + cache->key.offset) {
			last = cache->key.objectid + cache->key.offset;
			continue;
		}

		clear_extent_dirty(&root->fs_info->free_space_cache,
				   start, start + num_bytes - 1, 0);

		ins->objectid = start;
		ins->offset = num_bytes;
		ins->type = BTRFS_EXTENT_ITEM_KEY;
		return 0;
	}
fail:
	fprintf(stderr, "not enough free space\n");
	return -ENOSPC;
}

static int intersect_with_sb(u64 bytenr, u64 num_bytes)
{
	int i;
	u64 offset;

	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
		offset = btrfs_sb_offset(i);
		offset &= ~((u64)STRIPE_LEN - 1);

		if (bytenr < offset + STRIPE_LEN &&
		    bytenr + num_bytes > offset)
			return 1;
	}
	return 0;
}

static int custom_free_extent(struct btrfs_root *root, u64 bytenr,
			      u64 num_bytes)
{
	return intersect_with_sb(bytenr, num_bytes);
}

struct btrfs_extent_ops extent_ops = {
	.alloc_extent = custom_alloc_extent,
	.free_extent = custom_free_extent,
};

struct dir_iterate_data {
	struct btrfs_trans_handle *trans;
	struct btrfs_root *root;
	struct btrfs_inode_item *inode;
	u64 objectid;
	u64 index_cnt;
	u64 parent;
	int errcode;
};

static u8 filetype_conversion_table[EXT2_FT_MAX] = {
	[EXT2_FT_UNKNOWN]	= BTRFS_FT_UNKNOWN,
	[EXT2_FT_REG_FILE]	= BTRFS_FT_REG_FILE,
	[EXT2_FT_DIR]		= BTRFS_FT_DIR,
	[EXT2_FT_CHRDEV]	= BTRFS_FT_CHRDEV,
	[EXT2_FT_BLKDEV]	= BTRFS_FT_BLKDEV,
	[EXT2_FT_FIFO]		= BTRFS_FT_FIFO,
	[EXT2_FT_SOCK]		= BTRFS_FT_SOCK,
	[EXT2_FT_SYMLINK]	= BTRFS_FT_SYMLINK,
};

static int dir_iterate_proc(ext2_ino_t dir, int entry,
			    struct ext2_dir_entry *old,
			    int offset, int blocksize,
			    char *buf,void *priv_data)
{
	int ret;
	int file_type;
	u64 objectid;
        u64 inode_size;
	char dotdot[] = "..";
	struct btrfs_key location;
	struct ext2_dir_entry_2 *dirent = (struct ext2_dir_entry_2 *)old;
	struct dir_iterate_data *idata = (struct dir_iterate_data *)priv_data;

	objectid = dirent->inode + INO_OFFSET;
	if (!strncmp(dirent->name, dotdot, dirent->name_len)) {
		if (dirent->name_len == 2) {
			BUG_ON(idata->parent != 0);
			idata->parent = objectid;
		}
		return 0;
	}
	if (dirent->inode < EXT2_GOOD_OLD_FIRST_INO)
		return 0;

	location.objectid = objectid;
	location.offset = 0;
	btrfs_set_key_type(&location, BTRFS_INODE_ITEM_KEY);

	file_type = dirent->file_type;
	BUG_ON(file_type > EXT2_FT_SYMLINK);
	ret = btrfs_insert_dir_item(idata->trans, idata->root,
				    dirent->name, dirent->name_len,
				    idata->objectid, &location,
				    filetype_conversion_table[file_type],
				    idata->index_cnt);
	if (ret)
		goto fail;
	ret = btrfs_insert_inode_ref(idata->trans, idata->root,
				     dirent->name, dirent->name_len,
				     objectid, idata->objectid,
				     idata->index_cnt);
	if (ret)
		goto fail;
	idata->index_cnt++;
	inode_size = btrfs_stack_inode_size(idata->inode) +
		     dirent->name_len * 2;
	btrfs_set_stack_inode_size(idata->inode, inode_size);
	return 0;
fail:
	idata->errcode = ret;
	return BLOCK_ABORT;
}

static int create_dir_entries(struct btrfs_trans_handle *trans,
			      struct btrfs_root *root, u64 objectid,
			      struct btrfs_inode_item *btrfs_inode,
			      ext2_filsys ext2_fs, ext2_ino_t ext2_ino)
{
	int ret;
	errcode_t err;
	struct dir_iterate_data data = {
		.trans		= trans,
		.root		= root,
		.inode		= btrfs_inode,
		.objectid	= objectid,
		.index_cnt	= 2,
		.parent		= 0,
		.errcode	= 0,
	};

	err = ext2fs_dir_iterate2(ext2_fs, ext2_ino, 0, NULL,
				  dir_iterate_proc, &data);
	if (err)
		goto error;
	ret = data.errcode;
	if (ret == 0 && data.parent == objectid) {
		ret = btrfs_insert_inode_ref(trans, root, "..", 2,
					     objectid, objectid, 0);
	}
	return ret;
error:
	fprintf(stderr, "ext2fs_dir_iterate2: %s\n", error_message(err));
	return -1;
}

static int read_disk_extent(struct btrfs_root *root, u64 bytenr,
		            u32 num_bytes, char *buffer)
{
	int ret;
	struct btrfs_fs_devices *fs_devs = root->fs_info->fs_devices;

	ret = pread(fs_devs->latest_bdev, buffer, num_bytes, bytenr);
	if (ret != num_bytes)
		goto fail;
	ret = 0;
fail:
	if (ret > 0)
		ret = -1;
	return ret;
}
/*
 * Record a file extent. Do all the required works, such as inserting
 * file extent item, inserting extent item and backref item into extent
 * tree and updating block accounting.
 */
static int record_file_extent(struct btrfs_trans_handle *trans,
			      struct btrfs_root *root, u64 objectid,
			      struct btrfs_inode_item *inode,
			      u64 file_pos, u64 disk_bytenr,
			      u64 num_bytes, int checksum)
{
	int ret;
	struct btrfs_fs_info *info = root->fs_info;
	struct btrfs_root *extent_root = info->extent_root;
	struct extent_buffer *leaf;
	struct btrfs_file_extent_item *fi;
	struct btrfs_key ins_key;
	struct btrfs_path path;
	struct btrfs_extent_item *ei;
	u32 blocksize = root->sectorsize;
	u64 nbytes;

	if (disk_bytenr == 0) {
		ret = btrfs_insert_file_extent(trans, root, objectid,
						file_pos, disk_bytenr,
						num_bytes, num_bytes);
		return ret;
	}

	btrfs_init_path(&path);

	if (checksum) {
		u64 offset;
		char *buffer;

		ret = -ENOMEM;
		buffer = malloc(blocksize);
		if (!buffer)
			goto fail;
		for (offset = 0; offset < num_bytes; offset += blocksize) {
			ret = read_disk_extent(root, disk_bytenr + offset,
						blocksize, buffer);
			if (ret)
				break;
			ret = btrfs_csum_file_block(trans,
						    root->fs_info->csum_root,
						    disk_bytenr + num_bytes,
						    disk_bytenr + offset,
						    buffer, blocksize);
			if (ret)
				break;
		}
		free(buffer);
		if (ret)
			goto fail;
	}

	ins_key.objectid = objectid;
	ins_key.offset = file_pos;
	btrfs_set_key_type(&ins_key, BTRFS_EXTENT_DATA_KEY);
	ret = btrfs_insert_empty_item(trans, root, &path, &ins_key,
				      sizeof(*fi));
	if (ret)
		goto fail;
	leaf = path.nodes[0];
	fi = btrfs_item_ptr(leaf, path.slots[0],
			    struct btrfs_file_extent_item);
	btrfs_set_file_extent_generation(leaf, fi, trans->transid);
	btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG);
	btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
	btrfs_set_file_extent_disk_num_bytes(leaf, fi, num_bytes);
	btrfs_set_file_extent_offset(leaf, fi, 0);
	btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
	btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
	btrfs_set_file_extent_compression(leaf, fi, 0);
	btrfs_set_file_extent_encryption(leaf, fi, 0);
	btrfs_set_file_extent_other_encoding(leaf, fi, 0);
	btrfs_mark_buffer_dirty(leaf);

	nbytes = btrfs_stack_inode_nbytes(inode) + num_bytes;
	btrfs_set_stack_inode_nbytes(inode, nbytes);

	btrfs_release_path(root, &path);

	ins_key.objectid = disk_bytenr;
	ins_key.offset = num_bytes;
	ins_key.type = BTRFS_EXTENT_ITEM_KEY;

	ret = btrfs_insert_empty_item(trans, extent_root, &path,
				      &ins_key, sizeof(*ei));
	if (ret == 0) {
		leaf = path.nodes[0];
		ei = btrfs_item_ptr(leaf, path.slots[0],
				    struct btrfs_extent_item);

		btrfs_set_extent_refs(leaf, ei, 0);
		btrfs_set_extent_generation(leaf, ei, 0);
		btrfs_set_extent_flags(leaf, ei, BTRFS_EXTENT_FLAG_DATA);

		btrfs_mark_buffer_dirty(leaf);

		ret = btrfs_update_block_group(trans, root, disk_bytenr,
					       num_bytes, 1, 0);
		if (ret)
			goto fail;
	} else if (ret != -EEXIST) {
		goto fail;
	}
	btrfs_extent_post_op(trans, extent_root);

	ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, num_bytes, 0,
				   root->root_key.objectid,
				   objectid, file_pos);
	if (ret)
		goto fail;
	ret = 0;
fail:
	btrfs_release_path(root, &path);
	return ret;
}

static int record_file_blocks(struct btrfs_trans_handle *trans,
			      struct btrfs_root *root, u64 objectid,
			      struct btrfs_inode_item *inode,
			      u64 file_block, u64 disk_block,
			      u64 num_blocks, int checksum)
{
	u64 file_pos = file_block * root->sectorsize;
	u64 disk_bytenr = disk_block * root->sectorsize;
	u64 num_bytes = num_blocks * root->sectorsize;
	return record_file_extent(trans, root, objectid, inode, file_pos,
				  disk_bytenr, num_bytes, checksum);
}

struct blk_iterate_data {
	struct btrfs_trans_handle *trans;
	struct btrfs_root *root;
	struct btrfs_inode_item *inode;
	u64 objectid;
	u64 first_block;
	u64 disk_block;
	u64 num_blocks;
	u64 boundary;
	int checksum;
	int errcode;
};

static int block_iterate_proc(ext2_filsys ext2_fs,
			      u64 disk_block, u64 file_block,
		              struct blk_iterate_data *idata)
{
	int ret;
	int sb_region;
	int do_barrier;
	struct btrfs_root *root = idata->root;
	struct btrfs_trans_handle *trans = idata->trans;
	struct btrfs_block_group_cache *cache;
	u64 bytenr = disk_block * root->sectorsize;

	sb_region = intersect_with_sb(bytenr, root->sectorsize);
	do_barrier = sb_region || disk_block >= idata->boundary;
	if ((idata->num_blocks > 0 && do_barrier) ||
	    (file_block > idata->first_block + idata->num_blocks) ||
	    (disk_block != idata->disk_block + idata->num_blocks)) {
		if (idata->num_blocks > 0) {
			ret = record_file_blocks(trans, root, idata->objectid,
					idata->inode, idata->first_block,
					idata->disk_block, idata->num_blocks,
					idata->checksum);
			if (ret)
				goto fail;
			idata->first_block += idata->num_blocks;
			idata->num_blocks = 0;
		}
		if (file_block > idata->first_block) {
			ret = record_file_blocks(trans, root, idata->objectid,
					idata->inode, idata->first_block,
					0, file_block - idata->first_block,
					idata->checksum);
			if (ret)
				goto fail;
		}

		if (sb_region) {
			bytenr += STRIPE_LEN - 1;
			bytenr &= ~((u64)STRIPE_LEN - 1);
		} else {
			cache = btrfs_lookup_block_group(root->fs_info, bytenr);
			BUG_ON(!cache);
			bytenr = cache->key.objectid + cache->key.offset;
		}

		idata->first_block = file_block;
		idata->disk_block = disk_block;
		idata->boundary = bytenr / root->sectorsize;
	}
	idata->num_blocks++;
	return 0;
fail:
	idata->errcode = ret;
	return BLOCK_ABORT;
}

static int __block_iterate_proc(ext2_filsys fs, blk_t *blocknr,
			        e2_blkcnt_t blockcnt, blk_t ref_block,
			        int ref_offset, void *priv_data)
{
	struct blk_iterate_data *idata;
	idata = (struct blk_iterate_data *)priv_data;
	return block_iterate_proc(fs, *blocknr, blockcnt, idata);
}

/*
 * traverse file's data blocks, record these data blocks as file extents.
 */
static int create_file_extents(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root, u64 objectid,
			       struct btrfs_inode_item *btrfs_inode,
			       ext2_filsys ext2_fs, ext2_ino_t ext2_ino,
			       int datacsum, int packing)
{
	int ret;
	char *buffer = NULL;
	errcode_t err;
	u32 last_block;
	u32 sectorsize = root->sectorsize;
	u64 inode_size = btrfs_stack_inode_size(btrfs_inode);
	struct blk_iterate_data data = {
		.trans		= trans,
		.root		= root,
		.inode		= btrfs_inode,
		.objectid	= objectid,
		.first_block	= 0,
		.disk_block	= 0,
		.num_blocks	= 0,
		.boundary	= (u64)-1,
		.checksum	= datacsum,
		.errcode	= 0,
	};
	err = ext2fs_block_iterate2(ext2_fs, ext2_ino, BLOCK_FLAG_DATA_ONLY,
				    NULL, __block_iterate_proc, &data);
	if (err)
		goto error;
	ret = data.errcode;
	if (ret)
		goto fail;
	if (packing && data.first_block == 0 && data.num_blocks > 0 &&
	    inode_size <= BTRFS_MAX_INLINE_DATA_SIZE(root)) {
		u64 num_bytes = data.num_blocks * sectorsize;
		u64 disk_bytenr = data.disk_block * sectorsize;
		u64 nbytes;

		buffer = malloc(num_bytes);
		if (!buffer)
			return -ENOMEM;
		ret = read_disk_extent(root, disk_bytenr, num_bytes, buffer);
		if (ret)
			goto fail;
		if (num_bytes > inode_size)
			num_bytes = inode_size;
		ret = btrfs_insert_inline_extent(trans, root, objectid,
						 0, buffer, num_bytes);
		if (ret)
			goto fail;
		nbytes = btrfs_stack_inode_nbytes(btrfs_inode) + num_bytes;
		btrfs_set_stack_inode_nbytes(btrfs_inode, nbytes);
	} else if (data.num_blocks > 0) {
		ret = record_file_blocks(trans, root, objectid, btrfs_inode,
					 data.first_block, data.disk_block,
					 data.num_blocks, data.checksum);
		if (ret)
			goto fail;
	}
	data.first_block += data.num_blocks;
	last_block = (inode_size + sectorsize - 1) / sectorsize;
	if (last_block > data.first_block) {
		ret = record_file_blocks(trans, root, objectid, btrfs_inode,
					 data.first_block, 0, last_block -
					 data.first_block, data.checksum);
	}
fail:
	if (buffer)
		free(buffer);
	return ret;
error:
	fprintf(stderr, "ext2fs_block_iterate2: %s\n", error_message(err));
	return -1;
}

static int create_symbol_link(struct btrfs_trans_handle *trans,
			      struct btrfs_root *root, u64 objectid,
			      struct btrfs_inode_item *btrfs_inode,
			      ext2_filsys ext2_fs, ext2_ino_t ext2_ino,
			      struct ext2_inode *ext2_inode)
{
	int ret;
	char *pathname;
	u64 inode_size = btrfs_stack_inode_size(btrfs_inode);
	if (ext2fs_inode_data_blocks(ext2_fs, ext2_inode)) {
		btrfs_set_stack_inode_size(btrfs_inode, inode_size + 1);
		ret = create_file_extents(trans, root, objectid, btrfs_inode,
					  ext2_fs, ext2_ino, 1, 1);
		btrfs_set_stack_inode_size(btrfs_inode, inode_size);
		return ret;
	}

	pathname = (char *)&(ext2_inode->i_block[0]);
	BUG_ON(pathname[inode_size] != 0);
	ret = btrfs_insert_inline_extent(trans, root, objectid, 0,
					 pathname, inode_size + 1);
	btrfs_set_stack_inode_nbytes(btrfs_inode, inode_size + 1);
	return ret;
}

/*
 * Following xattr/acl related codes are based on codes in
 * fs/ext3/xattr.c and fs/ext3/acl.c
 */
#define EXT2_XATTR_BHDR(ptr) ((struct ext2_ext_attr_header *)(ptr))
#define EXT2_XATTR_BFIRST(ptr) \
	((struct ext2_ext_attr_entry *)(EXT2_XATTR_BHDR(ptr) + 1))
#define EXT2_XATTR_IHDR(inode) \
	((struct ext2_ext_attr_header *) ((void *)(inode) + \
		EXT2_GOOD_OLD_INODE_SIZE + (inode)->i_extra_isize))
#define EXT2_XATTR_IFIRST(inode) \
	((struct ext2_ext_attr_entry *) ((void *)EXT2_XATTR_IHDR(inode) + \
		sizeof(EXT2_XATTR_IHDR(inode)->h_magic)))

static int ext2_xattr_check_names(struct ext2_ext_attr_entry *entry,
				  const void *end)
{
	struct ext2_ext_attr_entry *next;

	while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
		next = EXT2_EXT_ATTR_NEXT(entry);
		if ((void *)next >= end)
			return -EIO;
		entry = next;
	}
	return 0;
}

static int ext2_xattr_check_block(const char *buf, size_t size)
{
	int error;
	struct ext2_ext_attr_header *header = EXT2_XATTR_BHDR(buf);

	if (header->h_magic != EXT2_EXT_ATTR_MAGIC ||
	    header->h_blocks != 1)
		return -EIO;
	error = ext2_xattr_check_names(EXT2_XATTR_BFIRST(buf), buf + size);
	return error;
}

static int ext2_xattr_check_entry(struct ext2_ext_attr_entry *entry,
				  size_t size)
{
	size_t value_size = entry->e_value_size;

	if (entry->e_value_block != 0 || value_size > size ||
	    entry->e_value_offs + value_size > size)
		return -EIO;
	return 0;
}

#define EXT2_ACL_VERSION	0x0001

typedef struct {
	__le16		e_tag;
	__le16		e_perm;
	__le32		e_id;
} ext2_acl_entry;

typedef struct {
	__le16		e_tag;
	__le16		e_perm;
} ext2_acl_entry_short;

typedef struct {
	__le32		a_version;
} ext2_acl_header;

static inline int ext2_acl_count(size_t size)
{
	ssize_t s;
	size -= sizeof(ext2_acl_header);
	s = size - 4 * sizeof(ext2_acl_entry_short);
	if (s < 0) {
		if (size % sizeof(ext2_acl_entry_short))
			return -1;
		return size / sizeof(ext2_acl_entry_short);
	} else {
		if (s % sizeof(ext2_acl_entry))
			return -1;
		return s / sizeof(ext2_acl_entry) + 4;
	}
}

#define ACL_EA_VERSION		0x0002

typedef struct {
	__le16		e_tag;
	__le16		e_perm;
	__le32		e_id;
} acl_ea_entry;

typedef struct {
	__le32		a_version;
	acl_ea_entry	a_entries[0];
} acl_ea_header;

static inline size_t acl_ea_size(int count)
{
	return sizeof(acl_ea_header) + count * sizeof(acl_ea_entry);
}

static int ext2_acl_to_xattr(void *dst, const void *src,
			     size_t dst_size, size_t src_size)
{
	int i, count;
	const void *end = src + src_size;
	acl_ea_header *ext_acl = (acl_ea_header *)dst;
	acl_ea_entry *dst_entry = ext_acl->a_entries;
	ext2_acl_entry *src_entry;

	if (src_size < sizeof(ext2_acl_header))
		goto fail;
	if (((ext2_acl_header *)src)->a_version !=
	    cpu_to_le32(EXT2_ACL_VERSION))
		goto fail;
	src += sizeof(ext2_acl_header);
	count = ext2_acl_count(src_size);
	if (count <= 0)
		goto fail;

	BUG_ON(dst_size < acl_ea_size(count));
	ext_acl->a_version = cpu_to_le32(ACL_EA_VERSION);
	for (i = 0; i < count; i++, dst_entry++) {
		src_entry = (ext2_acl_entry *)src;
		if (src + sizeof(ext2_acl_entry_short) > end)
			goto fail;
		dst_entry->e_tag = src_entry->e_tag;
		dst_entry->e_perm = src_entry->e_perm;
		switch (le16_to_cpu(src_entry->e_tag)) {
		case ACL_USER_OBJ:
		case ACL_GROUP_OBJ:
		case ACL_MASK:
		case ACL_OTHER:
			src += sizeof(ext2_acl_entry_short);
			dst_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
			break;
		case ACL_USER:
		case ACL_GROUP:
			src += sizeof(ext2_acl_entry);
			if (src > end)
				goto fail;
			dst_entry->e_id = src_entry->e_id;
			break;
		default:
			goto fail;
		}
	}
	if (src != end)
		goto fail;
	return 0;
fail:
	return -EINVAL;
}

static char *xattr_prefix_table[] = {
	[1] =	"user.",
	[2] =	"system.posix_acl_access",
	[3] =	"system.posix_acl_default",
	[4] =	"trusted.",
	[6] =	"security.",
};

static int copy_single_xattr(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root, u64 objectid,
			     struct ext2_ext_attr_entry *entry,
			     const void *data, u32 datalen)
{
	int ret = 0;
	int name_len;
	int name_index;
	void *databuf = NULL;
	char namebuf[XATTR_NAME_MAX + 1];

	name_index = entry->e_name_index;
	if (name_index >= ARRAY_SIZE(xattr_prefix_table) ||
	    xattr_prefix_table[name_index] == NULL)
		return -EOPNOTSUPP;
	name_len = strlen(xattr_prefix_table[name_index]) +
		   entry->e_name_len;
	if (name_len >= sizeof(namebuf))
		return -ERANGE;

	if (name_index == 2 || name_index == 3) {
		size_t bufsize = acl_ea_size(ext2_acl_count(datalen));
		databuf = malloc(bufsize);
		if (!databuf)
		       return -ENOMEM;
		ret = ext2_acl_to_xattr(databuf, data, bufsize, datalen);
		if (ret)
			goto out;
		data = databuf;
		datalen = bufsize;
	}
	strncpy(namebuf, xattr_prefix_table[name_index], XATTR_NAME_MAX);
	strncat(namebuf, EXT2_EXT_ATTR_NAME(entry), entry->e_name_len);
	if (name_len + datalen > BTRFS_LEAF_DATA_SIZE(root) -
	    sizeof(struct btrfs_item) - sizeof(struct btrfs_dir_item)) {
		fprintf(stderr, "skip large xattr on inode %Lu name %.*s\n",
			objectid - INO_OFFSET, name_len, namebuf);
		goto out;
	}
	ret = btrfs_insert_xattr_item(trans, root, namebuf, name_len,
				      data, datalen, objectid);
out:
	if (databuf)
		free(databuf);
	return ret;
}

static int copy_extended_attrs(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root, u64 objectid,
			       struct btrfs_inode_item *btrfs_inode,
			       ext2_filsys ext2_fs, ext2_ino_t ext2_ino)
{
	int ret = 0;
	int inline_ea = 0;
	errcode_t err;
	u32 datalen;
	u32 block_size = ext2_fs->blocksize;
	u32 inode_size = EXT2_INODE_SIZE(ext2_fs->super);
	struct ext2_inode_large *ext2_inode;
	struct ext2_ext_attr_entry *entry;
	void *data;
	char *buffer = NULL;
	char inode_buf[EXT2_GOOD_OLD_INODE_SIZE];

	if (inode_size <= EXT2_GOOD_OLD_INODE_SIZE) {
		ext2_inode = (struct ext2_inode_large *)inode_buf;
	} else {
		ext2_inode = (struct ext2_inode_large *)malloc(inode_size);
		if (!ext2_inode)
		       return -ENOMEM;
	}
	err = ext2fs_read_inode_full(ext2_fs, ext2_ino, (void *)ext2_inode,
				     inode_size);
	if (err) {
		fprintf(stderr, "ext2fs_read_inode_full: %s\n",
			error_message(err));
		ret = -1;
		goto out;
	}

	if (ext2_ino > ext2_fs->super->s_first_ino &&
	    inode_size > EXT2_GOOD_OLD_INODE_SIZE) {
		if (EXT2_GOOD_OLD_INODE_SIZE +
		    ext2_inode->i_extra_isize > inode_size) {
			ret = -EIO;
			goto out;
		}
		if (ext2_inode->i_extra_isize != 0 &&
		    EXT2_XATTR_IHDR(ext2_inode)->h_magic ==
		    EXT2_EXT_ATTR_MAGIC) {
			inline_ea = 1;
		}
	}
	if (inline_ea) {
		int total;
		void *end = (void *)ext2_inode + inode_size;
		entry = EXT2_XATTR_IFIRST(ext2_inode);
		total = end - (void *)entry;
		ret = ext2_xattr_check_names(entry, end);
		if (ret)
			goto out;
		while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
			ret = ext2_xattr_check_entry(entry, total);
			if (ret)
				goto out;
			data = (void *)EXT2_XATTR_IFIRST(ext2_inode) +
				entry->e_value_offs;
			datalen = entry->e_value_size;
			ret = copy_single_xattr(trans, root, objectid,
						entry, data, datalen);
			if (ret)
				goto out;
			entry = EXT2_EXT_ATTR_NEXT(entry);
		}
	}

	if (ext2_inode->i_file_acl == 0)
		goto out;

	buffer = malloc(block_size);
	if (!buffer) {
		ret = -ENOMEM;
		goto out;
	}
	err = ext2fs_read_ext_attr(ext2_fs, ext2_inode->i_file_acl, buffer);
	if (err) {
		fprintf(stderr, "ext2fs_read_ext_attr: %s\n",
			error_message(err));
		ret = -1;
		goto out;
	}
	ret = ext2_xattr_check_block(buffer, block_size);
	if (ret)
		goto out;

	entry = EXT2_XATTR_BFIRST(buffer);
	while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
		ret = ext2_xattr_check_entry(entry, block_size);
		if (ret)
			goto out;
		data = buffer + entry->e_value_offs;
		datalen = entry->e_value_size;
		ret = copy_single_xattr(trans, root, objectid,
					entry, data, datalen);
		if (ret)
			goto out;
		entry = EXT2_EXT_ATTR_NEXT(entry);
	}
out:
	if (buffer != NULL)
		free(buffer);
	if ((void *)ext2_inode != inode_buf)
		free(ext2_inode);
	return ret;
}
#define MINORBITS	20
#define MKDEV(ma, mi)	(((ma) << MINORBITS) | (mi))

static inline dev_t old_decode_dev(u16 val)
{
	return MKDEV((val >> 8) & 255, val & 255);
}

static inline dev_t new_decode_dev(u32 dev)
{
	unsigned major = (dev & 0xfff00) >> 8;
	unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
	return MKDEV(major, minor);
}

static int copy_inode_item(struct btrfs_inode_item *dst,
			   struct ext2_inode *src, u32 blocksize)
{
	btrfs_set_stack_inode_generation(dst, 1);
	btrfs_set_stack_inode_size(dst, src->i_size);
	btrfs_set_stack_inode_nbytes(dst, 0);
	btrfs_set_stack_inode_block_group(dst, 0);
	btrfs_set_stack_inode_nlink(dst, src->i_links_count);
	btrfs_set_stack_inode_uid(dst, src->i_uid | (src->i_uid_high << 16));
	btrfs_set_stack_inode_gid(dst, src->i_gid | (src->i_gid_high << 16));
	btrfs_set_stack_inode_mode(dst, src->i_mode);
	btrfs_set_stack_inode_rdev(dst, 0);
	btrfs_set_stack_inode_flags(dst, 0);
	btrfs_set_stack_timespec_sec(&dst->atime, src->i_atime);
	btrfs_set_stack_timespec_nsec(&dst->atime, 0);
	btrfs_set_stack_timespec_sec(&dst->ctime, src->i_ctime);
	btrfs_set_stack_timespec_nsec(&dst->ctime, 0);
	btrfs_set_stack_timespec_sec(&dst->mtime, src->i_mtime);
	btrfs_set_stack_timespec_nsec(&dst->mtime, 0);
	btrfs_set_stack_timespec_sec(&dst->otime, 0);
	btrfs_set_stack_timespec_nsec(&dst->otime, 0);

	if (S_ISDIR(src->i_mode)) {
		btrfs_set_stack_inode_size(dst, 0);
		btrfs_set_stack_inode_nlink(dst, 1);
	}
	if (S_ISREG(src->i_mode)) {
		btrfs_set_stack_inode_size(dst, (u64)src->i_size_high << 32 |
					   (u64)src->i_size);
	}
	if (!S_ISREG(src->i_mode) && !S_ISDIR(src->i_mode) &&
	    !S_ISLNK(src->i_mode)) {
		if (src->i_block[0]) {
			btrfs_set_stack_inode_rdev(dst,
				old_decode_dev(src->i_block[0]));
		} else {
			btrfs_set_stack_inode_rdev(dst,
				new_decode_dev(src->i_block[1]));
		}
	}
	return 0;
}

/*
 * copy a single inode. do all the required works, such as cloning
 * inode item, creating file extents and creating directory entries.
 */
static int copy_single_inode(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root, u64 objectid,
			     ext2_filsys ext2_fs, ext2_ino_t ext2_ino,
			     struct ext2_inode *ext2_inode,
			     int datacsum, int packing, int noxattr)
{
	int ret;
	struct btrfs_key inode_key;
	struct btrfs_inode_item btrfs_inode;

	if (ext2_inode->i_links_count == 0)
		return 0;

	copy_inode_item(&btrfs_inode, ext2_inode, ext2_fs->blocksize);
	if (!datacsum && S_ISREG(ext2_inode->i_mode)) {
		u32 flags = btrfs_stack_inode_flags(&btrfs_inode) |
			    BTRFS_INODE_NODATASUM;
		btrfs_set_stack_inode_flags(&btrfs_inode, flags);
	}

	switch (ext2_inode->i_mode & S_IFMT) {
	case S_IFREG:
		ret = create_file_extents(trans, root, objectid, &btrfs_inode,
					ext2_fs, ext2_ino, datacsum, packing);
		break;
	case S_IFDIR:
		ret = create_dir_entries(trans, root, objectid, &btrfs_inode,
					 ext2_fs, ext2_ino);
		break;
	case S_IFLNK:
		ret = create_symbol_link(trans, root, objectid, &btrfs_inode,
					 ext2_fs, ext2_ino, ext2_inode);
		break;
	default:
		ret = 0;
		break;
	}
	if (ret)
		return ret;

	if (!noxattr) {
		ret = copy_extended_attrs(trans, root, objectid, &btrfs_inode,
					  ext2_fs, ext2_ino);
		if (ret)
			return ret;
	}
	inode_key.objectid = objectid;
	inode_key.offset = 0;
	btrfs_set_key_type(&inode_key, BTRFS_INODE_ITEM_KEY);
	ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
	return ret;
}

static int copy_disk_extent(struct btrfs_root *root, u64 dst_bytenr,
		            u64 src_bytenr, u32 num_bytes)
{
	int ret;
	char *buffer;
	struct btrfs_fs_devices *fs_devs = root->fs_info->fs_devices;

	buffer = malloc(num_bytes);
	if (!buffer)
		return -ENOMEM;
	ret = pread(fs_devs->latest_bdev, buffer, num_bytes, src_bytenr);
	if (ret != num_bytes)
		goto fail;
	ret = pwrite(fs_devs->latest_bdev, buffer, num_bytes, dst_bytenr);
	if (ret != num_bytes)
		goto fail;
	ret = 0;
fail:
	free(buffer);
	if (ret > 0)
		ret = -1;
	return ret;
}
/*
 * scan ext2's inode bitmap and copy all used inodes.
 */
static int copy_inodes(struct btrfs_root *root, ext2_filsys ext2_fs,
		       int datacsum, int packing, int noxattr)
{
	int ret;
	errcode_t err;
	ext2_inode_scan ext2_scan;
	struct ext2_inode ext2_inode;
	ext2_ino_t ext2_ino;
	u64 objectid;
	struct btrfs_trans_handle *trans;

	trans = btrfs_start_transaction(root, 1);
	if (!trans)
		return -ENOMEM;
	err = ext2fs_open_inode_scan(ext2_fs, 0, &ext2_scan);
	if (err) {
		fprintf(stderr, "ext2fs_open_inode_scan: %s\n", error_message(err));
		return -1;
	}
	while (!(err = ext2fs_get_next_inode(ext2_scan, &ext2_ino,
					     &ext2_inode))) {
		/* no more inodes */
		if (ext2_ino == 0)
			break;
		/* skip special inode in ext2fs */
		if (ext2_ino < EXT2_GOOD_OLD_FIRST_INO &&
		    ext2_ino != EXT2_ROOT_INO)
			continue;
		objectid = ext2_ino + INO_OFFSET;
		ret = copy_single_inode(trans, root,
					objectid, ext2_fs, ext2_ino,
					&ext2_inode, datacsum, packing,
					noxattr);
		if (ret)
			return ret;
		if (trans->blocks_used >= 4096) {
			ret = btrfs_commit_transaction(trans, root);
			BUG_ON(ret);
			trans = btrfs_start_transaction(root, 1);
			BUG_ON(!trans);
		}
	}
	if (err) {
		fprintf(stderr, "ext2fs_get_next_inode: %s\n", error_message(err));
		return -1;
	}
	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);

	return ret;
}

/*
 * Construct a range of ext2fs image file.
 * scan block allocation bitmap, find all blocks used by the ext2fs
 * in this range and create file extents that point to these blocks.
 *
 * Note: Before calling the function, no file extent points to blocks
 * 	 in this range
 */
static int create_image_file_range(struct btrfs_trans_handle *trans,
				   struct btrfs_root *root, u64 objectid,
				   struct btrfs_inode_item *inode,
				   u64 start_byte, u64 end_byte,
				   ext2_filsys ext2_fs)
{
	u32 blocksize = ext2_fs->blocksize;
	u32 block = start_byte / blocksize;
	u32 last_block = (end_byte + blocksize - 1) / blocksize;
	int ret = 0;
	struct blk_iterate_data data = {
		.trans		= trans,
		.root		= root,
		.inode		= inode,
		.objectid	= objectid,
		.first_block	= block,
		.disk_block	= 0,
		.num_blocks	= 0,
		.boundary	= (u64)-1,
		.checksum 	= 0,
		.errcode	= 0,
	};
	for (; start_byte < end_byte; block++, start_byte += blocksize) {
		if (!ext2fs_fast_test_block_bitmap(ext2_fs->block_map, block))
			continue;
		ret = block_iterate_proc(NULL, block, block, &data);
		if (ret & BLOCK_ABORT) {
			ret = data.errcode;
			goto fail;
		}
	}
	if (data.num_blocks > 0) {
		ret = record_file_blocks(trans, root, objectid, inode,
					 data.first_block, data.disk_block,
					 data.num_blocks, 0);
		if (ret)
			goto fail;
		data.first_block += data.num_blocks;
	}
	if (last_block > data.first_block) {
		ret = record_file_blocks(trans, root, objectid, inode,
					 data.first_block, 0, last_block -
					 data.first_block, 0);
		if (ret)
			goto fail;
	}
fail:
	return ret;
}
/*
 * Create the ext2fs image file.
 */
static int create_ext2_image(struct btrfs_root *root, ext2_filsys ext2_fs,
			     const char *name)
{
	int ret;
	struct btrfs_key key;
	struct btrfs_key location;
	struct btrfs_path path;
	struct btrfs_inode_item btrfs_inode;
	struct btrfs_inode_item *inode_item;
	struct extent_buffer *leaf;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *extent_root = fs_info->extent_root;
	struct btrfs_trans_handle *trans;
	struct btrfs_extent_item *ei;
	struct btrfs_extent_inline_ref *iref;
	struct btrfs_extent_data_ref *dref;
	u64 bytenr;
	u64 num_bytes;
	u64 objectid;
	u64 last_byte;
	u64 first_free;
	u64 total_bytes;
	u32 sectorsize = root->sectorsize;

	total_bytes = btrfs_super_total_bytes(&fs_info->super_copy);
	first_free =  BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1;
	first_free &= ~((u64)sectorsize - 1);

	memset(&btrfs_inode, 0, sizeof(btrfs_inode));
	btrfs_set_stack_inode_generation(&btrfs_inode, 1);
	btrfs_set_stack_inode_size(&btrfs_inode, total_bytes);
	btrfs_set_stack_inode_nlink(&btrfs_inode, 1);
	btrfs_set_stack_inode_nbytes(&btrfs_inode, 0);
	btrfs_set_stack_inode_mode(&btrfs_inode, S_IFREG | 0400);
	btrfs_set_stack_inode_flags(&btrfs_inode, BTRFS_INODE_NODATASUM |
				    BTRFS_INODE_READONLY);
	btrfs_init_path(&path);
	trans = btrfs_start_transaction(root, 1);
	BUG_ON(!trans);

	objectid = btrfs_root_dirid(&root->root_item);
	ret = btrfs_find_free_objectid(trans, root, objectid, &objectid);
	if (ret)
		goto fail;

	/*
	 * copy blocks covered by extent #0 to new positions. extent #0 is
	 * special, we can't rely on relocate_extents_range to relocate it.
	 */
	for (last_byte = 0; last_byte < first_free; last_byte += sectorsize) {
		ret = custom_alloc_extent(root, sectorsize, 0, &key);
		if (ret)
			goto fail;
		ret = copy_disk_extent(root, key.objectid, last_byte,
				       sectorsize);
		if (ret)
			goto fail;
		ret = record_file_extent(trans, root, objectid,
					 &btrfs_inode, last_byte,
					 key.objectid, sectorsize, 0);
		if (ret)
			goto fail;
	}

	while(1) {
		key.objectid = last_byte;
		key.offset = 0;
		btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
		ret = btrfs_search_slot(trans, fs_info->extent_root,
					&key, &path, 0, 0);
		if (ret < 0)
			goto fail;
next:
		leaf = path.nodes[0];
		if (path.slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(extent_root, &path);
			if (ret < 0)
				goto fail;
			if (ret > 0)
				break;
			leaf = path.nodes[0];
		}
		btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
		if (last_byte > key.objectid ||
		    key.type != BTRFS_EXTENT_ITEM_KEY) {
			path.slots[0]++;
			goto next;
		}

		bytenr = key.objectid;
		num_bytes = key.offset;
		ei = btrfs_item_ptr(leaf, path.slots[0],
				    struct btrfs_extent_item);
		if (!(btrfs_extent_flags(leaf, ei) & BTRFS_EXTENT_FLAG_DATA)) {
			path.slots[0]++;
			goto next;
		}

		BUG_ON(btrfs_item_size_nr(leaf, path.slots[0]) != sizeof(*ei) +
		       btrfs_extent_inline_ref_size(BTRFS_EXTENT_DATA_REF_KEY));

		iref = (struct btrfs_extent_inline_ref *)(ei + 1);
		key.type = btrfs_extent_inline_ref_type(leaf, iref);
		BUG_ON(key.type != BTRFS_EXTENT_DATA_REF_KEY);
		dref = (struct btrfs_extent_data_ref *)(&iref->offset);
		if (btrfs_extent_data_ref_root(leaf, dref) !=
		    BTRFS_FS_TREE_OBJECTID) {
			path.slots[0]++;
			goto next;
		}

		if (bytenr > last_byte) {
			ret = create_image_file_range(trans, root, objectid,
						      &btrfs_inode, last_byte,
						      bytenr, ext2_fs);
			if (ret)
				goto fail;
		}
		ret = record_file_extent(trans, root, objectid, &btrfs_inode,
					 bytenr, bytenr, num_bytes, 0);
		if (ret)
			goto fail;
		last_byte = bytenr + num_bytes;
		btrfs_release_path(extent_root, &path);

		if (trans->blocks_used >= 4096) {
			ret = btrfs_commit_transaction(trans, root);
			BUG_ON(ret);
			trans = btrfs_start_transaction(root, 1);
			BUG_ON(!trans);
		}
	}
	btrfs_release_path(root, &path);
	if (total_bytes > last_byte) {
		ret = create_image_file_range(trans, root, objectid,
					      &btrfs_inode, last_byte,
					      total_bytes, ext2_fs);
		if (ret)
			goto fail;
	}

	ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
	if (ret)
		goto fail;

	location.objectid = objectid;
	location.offset = 0;
	btrfs_set_key_type(&location, BTRFS_INODE_ITEM_KEY);
	ret = btrfs_insert_dir_item(trans, root, name, strlen(name),
				    btrfs_root_dirid(&root->root_item),
				    &location, EXT2_FT_REG_FILE, objectid);
	if (ret)
		goto fail;
	ret = btrfs_insert_inode_ref(trans, root, name, strlen(name),
				     objectid,
				     btrfs_root_dirid(&root->root_item),
				     objectid);
	if (ret)
		goto fail;
	location.objectid = btrfs_root_dirid(&root->root_item);
	location.offset = 0;
	btrfs_set_key_type(&location, BTRFS_INODE_ITEM_KEY);
	ret = btrfs_lookup_inode(trans, root, &path, &location, 1);
	if (ret)
		goto fail;
	leaf = path.nodes[0];
	inode_item = btrfs_item_ptr(leaf, path.slots[0],
				    struct btrfs_inode_item);
	btrfs_set_inode_size(leaf, inode_item, strlen(name) * 2 +
			     btrfs_inode_size(leaf, inode_item));
	btrfs_mark_buffer_dirty(leaf);
	btrfs_release_path(root, &path);
	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);
fail:
	btrfs_release_path(root, &path);
	return ret;
}

struct btrfs_root *link_subvol(struct btrfs_root *root, const char *base,
			       u64 root_objectid)
{
	struct btrfs_trans_handle *trans;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct btrfs_root *tree_root = fs_info->tree_root;
	struct btrfs_root *new_root = NULL;
	struct btrfs_path *path;
	struct btrfs_inode_item *inode_item;
	struct extent_buffer *leaf;
	struct btrfs_key key;
	u64 dirid = btrfs_root_dirid(&root->root_item);
	u64 index = 2;
	char buf[64];
	int i;
	int ret;

	path = btrfs_alloc_path();
	BUG_ON(!path);

	key.objectid = dirid;
	key.type = BTRFS_DIR_INDEX_KEY;
	key.offset = (u64)-1;

	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
	BUG_ON(ret <= 0);

	if (path->slots[0] > 0) {
		path->slots[0]--;
		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
		if (key.objectid == dirid && key.type == BTRFS_DIR_INDEX_KEY)
			index = key.offset + 1;
	}
	btrfs_release_path(root, path);

	trans = btrfs_start_transaction(root, 1);
	BUG_ON(!trans);

	key.objectid = dirid;
	key.offset = 0;
	key.type =  BTRFS_INODE_ITEM_KEY;

	ret = btrfs_lookup_inode(trans, root, path, &key, 1);
	BUG_ON(ret);
	leaf = path->nodes[0];
	inode_item = btrfs_item_ptr(leaf, path->slots[0],
				    struct btrfs_inode_item);

	key.objectid = root_objectid;
	key.offset = (u64)-1;
	key.type = BTRFS_ROOT_ITEM_KEY;

	strcpy(buf, base);
	for (i = 0; i < 1024; i++) {
		ret = btrfs_insert_dir_item(trans, root, buf, strlen(buf),
					    dirid, &key, BTRFS_FT_DIR, index);
		if (ret != -EEXIST)
			break;
		sprintf(buf, "%s%d", base, i);
	}
	if (ret)
		goto fail;

	btrfs_set_inode_size(leaf, inode_item, strlen(buf) * 2 +
			     btrfs_inode_size(leaf, inode_item));
	btrfs_mark_buffer_dirty(leaf);
	btrfs_release_path(root, path);

	/* add the backref first */
	ret = btrfs_add_root_ref(trans, tree_root, root_objectid,
				 BTRFS_ROOT_BACKREF_KEY,
				 root->root_key.objectid,
				 dirid, index, buf, strlen(buf));
	BUG_ON(ret);

	/* now add the forward ref */
	ret = btrfs_add_root_ref(trans, tree_root, root->root_key.objectid,
				 BTRFS_ROOT_REF_KEY, root_objectid,
				 dirid, index, buf, strlen(buf));

	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);

	new_root = btrfs_read_fs_root(fs_info, &key);
	if (IS_ERR(new_root))
		new_root = NULL;
fail:
	btrfs_free_path(path);
	return new_root;
}

/*
 * Fixup block accounting. The initial block accounting created by
 * make_block_groups isn't accuracy in this case.
 */
static int fixup_block_accounting(struct btrfs_trans_handle *trans,
				  struct btrfs_root *root)
{
	int ret;
	int slot;
	u64 start = 0;
	u64 bytes_used = 0;
	struct btrfs_path path;
	struct btrfs_key key;
	struct extent_buffer *leaf;
	struct btrfs_block_group_cache *cache;
	struct btrfs_fs_info *fs_info = root->fs_info;

	while(1) {
		cache = btrfs_lookup_block_group(fs_info, start);
		if (!cache)
			break;
		start = cache->key.objectid + cache->key.offset;
		btrfs_set_block_group_used(&cache->item, 0);
		cache->space_info->bytes_used = 0;
	}

	btrfs_init_path(&path);
	key.offset = 0;
	key.objectid = 0;
	btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
	ret = btrfs_search_slot(trans, root->fs_info->extent_root,
				&key, &path, 0, 0);
	if (ret < 0)
		return ret;
	while(1) {
		leaf = path.nodes[0];
		slot = path.slots[0];
		if (slot >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(root, &path);
			if (ret < 0)
				return ret;
			if (ret > 0)
				break;
			leaf = path.nodes[0];
			slot = path.slots[0];
		}
		btrfs_item_key_to_cpu(leaf, &key, slot);
		if (key.type == BTRFS_EXTENT_ITEM_KEY) {
			bytes_used += key.offset;
			ret = btrfs_update_block_group(trans, root,
				  key.objectid, key.offset, 1, 0);
			BUG_ON(ret);
		}
		path.slots[0]++;
	}
	btrfs_set_super_bytes_used(&root->fs_info->super_copy, bytes_used);
	btrfs_release_path(root, &path);
	return 0;
}

static int create_chunk_mapping(struct btrfs_trans_handle *trans,
				struct btrfs_root *root)
{
	struct btrfs_fs_info *info = root->fs_info;
	struct btrfs_root *chunk_root = info->chunk_root;
	struct btrfs_root *extent_root = info->extent_root;
	struct btrfs_device *device;
	struct btrfs_block_group_cache *cache;
	struct btrfs_dev_extent *extent;
	struct extent_buffer *leaf;
	struct btrfs_chunk chunk;
	struct btrfs_key key;
	struct btrfs_path path;
	u64 cur_start;
	u64 total_bytes;
	u64 chunk_objectid;
	int ret;

	btrfs_init_path(&path);

	total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
	chunk_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;

	BUG_ON(list_empty(&info->fs_devices->devices));
	device = list_entry(info->fs_devices->devices.next,
			    struct btrfs_device, dev_list);
	BUG_ON(device->devid != info->fs_devices->latest_devid);

	/* delete device extent created by make_btrfs */
	key.objectid = device->devid;
	key.offset = 0;
	key.type = BTRFS_DEV_EXTENT_KEY;
	ret = btrfs_search_slot(trans, device->dev_root, &key, &path, -1, 1);
	if (ret < 0)
		goto err;

	BUG_ON(ret > 0);
	ret = btrfs_del_item(trans, device->dev_root, &path);
	if (ret)
		goto err;
	btrfs_release_path(device->dev_root, &path);

	/* delete chunk item created by make_btrfs */
	key.objectid = chunk_objectid;
	key.offset = 0;
	key.type = BTRFS_CHUNK_ITEM_KEY;
	ret = btrfs_search_slot(trans, chunk_root, &key, &path, -1, 1);
	if (ret < 0)
		goto err;

	BUG_ON(ret > 0);
	ret = btrfs_del_item(trans, chunk_root, &path);
	if (ret)
		goto err;
	btrfs_release_path(chunk_root, &path);

	/* for each block group, create device extent and chunk item */
	cur_start = 0;
	while (cur_start < total_bytes) {
		cache = btrfs_lookup_block_group(root->fs_info, cur_start);
		BUG_ON(!cache);

		/* insert device extent */
		key.objectid = device->devid;
		key.offset = cache->key.objectid;
		key.type = BTRFS_DEV_EXTENT_KEY;
		ret = btrfs_insert_empty_item(trans, device->dev_root, &path,
					      &key, sizeof(*extent));
		if (ret)
			goto err;

		leaf = path.nodes[0];
		extent = btrfs_item_ptr(leaf, path.slots[0],
					struct btrfs_dev_extent);

		btrfs_set_dev_extent_chunk_tree(leaf, extent,
						chunk_root->root_key.objectid);
		btrfs_set_dev_extent_chunk_objectid(leaf, extent,
						    chunk_objectid);
		btrfs_set_dev_extent_chunk_offset(leaf, extent,
						  cache->key.objectid);
		btrfs_set_dev_extent_length(leaf, extent, cache->key.offset);
		write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid,
		    (unsigned long)btrfs_dev_extent_chunk_tree_uuid(extent),
		    BTRFS_UUID_SIZE);
		btrfs_mark_buffer_dirty(leaf);
		btrfs_release_path(device->dev_root, &path);

		/* insert chunk item */
		btrfs_set_stack_chunk_length(&chunk, cache->key.offset);
		btrfs_set_stack_chunk_owner(&chunk,
					    extent_root->root_key.objectid);
		btrfs_set_stack_chunk_stripe_len(&chunk, STRIPE_LEN);
		btrfs_set_stack_chunk_type(&chunk, cache->flags);
		btrfs_set_stack_chunk_io_align(&chunk, device->io_align);
		btrfs_set_stack_chunk_io_width(&chunk, device->io_width);
		btrfs_set_stack_chunk_sector_size(&chunk, device->sector_size);
		btrfs_set_stack_chunk_num_stripes(&chunk, 1);
		btrfs_set_stack_chunk_sub_stripes(&chunk, 0);
		btrfs_set_stack_stripe_devid(&chunk.stripe, device->devid);
		btrfs_set_stack_stripe_offset(&chunk.stripe,
					      cache->key.objectid);
		memcpy(&chunk.stripe.dev_uuid, device->uuid, BTRFS_UUID_SIZE);

		key.objectid = chunk_objectid;
		key.offset = cache->key.objectid;
		key.type = BTRFS_CHUNK_ITEM_KEY;

		ret = btrfs_insert_item(trans, chunk_root, &key, &chunk,
					btrfs_chunk_item_size(1));
		if (ret)
			goto err;

		cur_start = cache->key.objectid + cache->key.offset;
	}

	device->bytes_used = total_bytes;
	ret = btrfs_update_device(trans, device);
err:
	btrfs_release_path(device->dev_root, &path);
	return ret;
}

static int create_subvol(struct btrfs_trans_handle *trans,
			 struct btrfs_root *root, u64 root_objectid)
{
	struct extent_buffer *tmp;
	struct btrfs_root *new_root;
	struct btrfs_key key;
	struct btrfs_root_item root_item;
	int ret;

	ret = btrfs_copy_root(trans, root, root->node, &tmp,
			      root_objectid);
	BUG_ON(ret);

	memcpy(&root_item, &root->root_item, sizeof(root_item));
	btrfs_set_root_bytenr(&root_item, tmp->start);
	btrfs_set_root_level(&root_item, btrfs_header_level(tmp));
	btrfs_set_root_generation(&root_item, trans->transid);
	free_extent_buffer(tmp);

	key.objectid = root_objectid;
	key.type = BTRFS_ROOT_ITEM_KEY;
	key.offset = trans->transid;
	ret = btrfs_insert_root(trans, root->fs_info->tree_root,
				&key, &root_item);

	key.offset = (u64)-1;
	new_root = btrfs_read_fs_root(root->fs_info, &key);
	BUG_ON(!new_root || IS_ERR(new_root));

	ret = btrfs_make_root_dir(trans, new_root, BTRFS_FIRST_FREE_OBJECTID);
	BUG_ON(ret);

	return 0;
}

static int init_btrfs(struct btrfs_root *root)
{
	int ret;
	struct btrfs_key location;
	struct btrfs_trans_handle *trans;
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct extent_buffer *tmp;

	trans = btrfs_start_transaction(root, 1);
	BUG_ON(!trans);
	ret = btrfs_make_block_groups(trans, root);
	if (ret)
		goto err;
	ret = fixup_block_accounting(trans, root);
	if (ret)
		goto err;
	ret = create_chunk_mapping(trans, root);
	if (ret)
		goto err;
	ret = btrfs_make_root_dir(trans, fs_info->tree_root,
				  BTRFS_ROOT_TREE_DIR_OBJECTID);
	if (ret)
		goto err;
	memcpy(&location, &root->root_key, sizeof(location));
	location.offset = (u64)-1;
	ret = btrfs_insert_dir_item(trans, fs_info->tree_root, "default", 7,
				btrfs_super_root_dir(&fs_info->super_copy),
				&location, BTRFS_FT_DIR, 0);
	if (ret)
		goto err;
	ret = btrfs_insert_inode_ref(trans, fs_info->tree_root, "default", 7,
				location.objectid,
				btrfs_super_root_dir(&fs_info->super_copy), 0);
	if (ret)
		goto err;
	btrfs_set_root_dirid(&fs_info->fs_root->root_item,
			     BTRFS_FIRST_FREE_OBJECTID);

	/* subvol for ext2 image file */
	ret = create_subvol(trans, root, EXT2_IMAGE_SUBVOL_OBJECTID);
	BUG_ON(ret);
	/* subvol for data relocation */
	ret = create_subvol(trans, root, BTRFS_DATA_RELOC_TREE_OBJECTID);
	BUG_ON(ret);

	ret = __btrfs_cow_block(trans, fs_info->csum_root,
				fs_info->csum_root->node, NULL, 0, &tmp, 0, 0);
	BUG_ON(ret);
	free_extent_buffer(tmp);

	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);
err:
	return ret;
}

/*
 * Migrate super block to it's default position and zero 0 ~ 16k
 */
static int migrate_super_block(int fd, u64 old_bytenr, u32 sectorsize)
{
	int ret;
	struct extent_buffer *buf;
	struct btrfs_super_block *super;
	u32 len;
	u32 bytenr;

	BUG_ON(sectorsize < sizeof(*super));
	buf = malloc(sizeof(*buf) + sectorsize);
	if (!buf)
		return -ENOMEM;

	buf->len = sectorsize;
	ret = pread(fd, buf->data, sectorsize, old_bytenr);
	if (ret != sectorsize)
		goto fail;

	super = (struct btrfs_super_block *)buf->data;
	BUG_ON(btrfs_super_bytenr(super) != old_bytenr);
	btrfs_set_super_bytenr(super, BTRFS_SUPER_INFO_OFFSET);

	csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
	ret = pwrite(fd, buf->data, sectorsize, BTRFS_SUPER_INFO_OFFSET);
	if (ret != sectorsize)
		goto fail;

	ret = fsync(fd);
	if (ret)
		goto fail;

	memset(buf->data, 0, sectorsize);
	for (bytenr = 0; bytenr < BTRFS_SUPER_INFO_OFFSET; ) {
		len = BTRFS_SUPER_INFO_OFFSET - bytenr;
		if (len > sectorsize)
			len = sectorsize;
		ret = pwrite(fd, buf->data, len, bytenr);
		if (ret != len) {
			fprintf(stderr, "unable to zero fill device\n");
			break;
		}
		bytenr += len;
	}
	ret = 0;
	fsync(fd);
fail:
	free(buf);
	if (ret > 0)
		ret = -1;
	return ret;
}

static int prepare_system_chunk_sb(struct btrfs_super_block *super)
{
	struct btrfs_chunk *chunk;
	struct btrfs_disk_key *key;
	u32 sectorsize = btrfs_super_sectorsize(super);

	key = (struct btrfs_disk_key *)(super->sys_chunk_array);
	chunk = (struct btrfs_chunk *)(super->sys_chunk_array +
				       sizeof(struct btrfs_disk_key));

	btrfs_set_disk_key_objectid(key, BTRFS_FIRST_CHUNK_TREE_OBJECTID);
	btrfs_set_disk_key_type(key, BTRFS_CHUNK_ITEM_KEY);
	btrfs_set_disk_key_offset(key, 0);

	btrfs_set_stack_chunk_length(chunk, btrfs_super_total_bytes(super));
	btrfs_set_stack_chunk_owner(chunk, BTRFS_EXTENT_TREE_OBJECTID);
	btrfs_set_stack_chunk_stripe_len(chunk, 64 * 1024);
	btrfs_set_stack_chunk_type(chunk, BTRFS_BLOCK_GROUP_SYSTEM);
	btrfs_set_stack_chunk_io_align(chunk, sectorsize);
	btrfs_set_stack_chunk_io_width(chunk, sectorsize);
	btrfs_set_stack_chunk_sector_size(chunk, sectorsize);
	btrfs_set_stack_chunk_num_stripes(chunk, 1);
	btrfs_set_stack_chunk_sub_stripes(chunk, 0);
	chunk->stripe.devid = super->dev_item.devid;
	chunk->stripe.offset = cpu_to_le64(0);
	memcpy(chunk->stripe.dev_uuid, super->dev_item.uuid, BTRFS_UUID_SIZE);
	btrfs_set_super_sys_array_size(super, sizeof(*key) + sizeof(*chunk));
	return 0;
}

static int prepare_system_chunk(int fd, u64 sb_bytenr, u32 sectorsize)
{
	int ret;
	struct extent_buffer *buf;
	struct btrfs_super_block *super;

	BUG_ON(sectorsize < sizeof(*super));
	buf = malloc(sizeof(*buf) + sectorsize);
	if (!buf)
		return -ENOMEM;

	buf->len = sectorsize;
	ret = pread(fd, buf->data, sectorsize, sb_bytenr);
	if (ret != sectorsize)
		goto fail;

	super = (struct btrfs_super_block *)buf->data;
	BUG_ON(btrfs_super_bytenr(super) != sb_bytenr);
	BUG_ON(btrfs_super_num_devices(super) != 1);

	ret = prepare_system_chunk_sb(super);
	if (ret)
		goto fail;

	csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
	ret = pwrite(fd, buf->data, sectorsize, sb_bytenr);
	if (ret != sectorsize)
		goto fail;

	ret = 0;
fail:
	free(buf);
	if (ret > 0)
		ret = -1;
	return ret;
}

static int relocate_one_reference(struct btrfs_trans_handle *trans,
				  struct btrfs_root *root,
				  u64 extent_start, u64 extent_size,
				  struct btrfs_key *extent_key,
				  struct extent_io_tree *reloc_tree)
{
	struct extent_buffer *leaf;
	struct btrfs_file_extent_item *fi;
	struct btrfs_key key;
	struct btrfs_path path;
	struct btrfs_inode_item inode;
	struct blk_iterate_data data;
	u64 bytenr;
	u64 num_bytes;
	u64 cur_offset;
	u64 new_pos;
	u64 nbytes;
	u64 sector_end;
	u32 sectorsize = root->sectorsize;
	unsigned long ptr;
	int datacsum;
	int fd;
	int ret;

	btrfs_init_path(&path);
	ret = btrfs_search_slot(trans, root, extent_key, &path, -1, 1);
	if (ret)
		goto fail;

	leaf = path.nodes[0];
	fi = btrfs_item_ptr(leaf, path.slots[0],
			    struct btrfs_file_extent_item);
	BUG_ON(btrfs_file_extent_offset(leaf, fi) > 0);
	if (extent_start != btrfs_file_extent_disk_bytenr(leaf, fi) ||
	    extent_size != btrfs_file_extent_disk_num_bytes(leaf, fi)) {
		ret = 1;
		goto fail;
	}

	bytenr = extent_start + btrfs_file_extent_offset(leaf, fi);
	num_bytes = btrfs_file_extent_num_bytes(leaf, fi);

	ret = btrfs_del_item(trans, root, &path);
	if (ret)
		goto fail;

	ret = btrfs_free_extent(trans, root, extent_start, extent_size, 0,
				root->root_key.objectid,
				extent_key->objectid, extent_key->offset);
	if (ret)
		goto fail;

	btrfs_release_path(root, &path);

	key.objectid = extent_key->objectid;
	key.offset = 0;
	key.type =  BTRFS_INODE_ITEM_KEY;
	ret = btrfs_lookup_inode(trans, root, &path, &key, 0);
	if (ret)
		goto fail;

	leaf = path.nodes[0];
	ptr = btrfs_item_ptr_offset(leaf, path.slots[0]);
	read_extent_buffer(leaf, &inode, ptr, sizeof(inode));
	btrfs_release_path(root, &path);

	BUG_ON(num_bytes & (sectorsize - 1));
	nbytes = btrfs_stack_inode_nbytes(&inode) - num_bytes;
	btrfs_set_stack_inode_nbytes(&inode, nbytes);
	datacsum = !(btrfs_stack_inode_flags(&inode) & BTRFS_INODE_NODATASUM);

	data = (struct blk_iterate_data) {
		.trans		= trans,
		.root		= root,
		.inode		= &inode,
		.objectid	= extent_key->objectid,
		.first_block	= extent_key->offset / sectorsize,
		.disk_block	= 0,
		.num_blocks	= 0,
		.boundary	= (u64)-1,
		.checksum	= datacsum,
		.errcode	= 0,
	};

	cur_offset = extent_key->offset;
	while (num_bytes > 0) {
		sector_end = bytenr + sectorsize - 1;
		if (test_range_bit(reloc_tree, bytenr, sector_end,
				   EXTENT_LOCKED, 1)) {
			ret = get_state_private(reloc_tree, bytenr, &new_pos);
			BUG_ON(ret);
		} else {
			ret = custom_alloc_extent(root, sectorsize, 0, &key);
			if (ret)
				goto fail;
			new_pos = key.objectid;

			if (cur_offset == extent_key->offset) {
				fd = root->fs_info->fs_devices->latest_bdev;
				readahead(fd, bytenr, num_bytes);
			}
			ret = copy_disk_extent(root, new_pos, bytenr,
					       sectorsize);
			if (ret)
				goto fail;
			ret = set_extent_bits(reloc_tree, bytenr, sector_end,
					      EXTENT_LOCKED, GFP_NOFS);
			BUG_ON(ret);
			ret = set_state_private(reloc_tree, bytenr, new_pos);
			BUG_ON(ret);
		}

		ret = block_iterate_proc(NULL, new_pos / sectorsize,
					 cur_offset / sectorsize, &data);
		if (ret & BLOCK_ABORT) {
			ret = data.errcode;
			goto fail;
		}

		cur_offset += sectorsize;
		bytenr += sectorsize;
		num_bytes -= sectorsize;
	}

	if (data.num_blocks > 0) {
		ret = record_file_blocks(trans, root,
					 extent_key->objectid, &inode,
					 data.first_block, data.disk_block,
					 data.num_blocks, datacsum);
		if (ret)
			goto fail;
	}

	key.objectid = extent_key->objectid;
	key.offset = 0;
	key.type =  BTRFS_INODE_ITEM_KEY;
	ret = btrfs_lookup_inode(trans, root, &path, &key, 1);
	if (ret)
		goto fail;

	leaf = path.nodes[0];
	ptr = btrfs_item_ptr_offset(leaf, path.slots[0]);
	write_extent_buffer(leaf, &inode, ptr, sizeof(inode));
	btrfs_mark_buffer_dirty(leaf);
	btrfs_release_path(root, &path);

fail:
	btrfs_release_path(root, &path);
	return ret;
}

static int relocate_extents_range(struct btrfs_root *fs_root,
				  struct btrfs_root *ext2_root,
				  u64 start_byte, u64 end_byte)
{
	struct btrfs_fs_info *info = fs_root->fs_info;
	struct btrfs_root *extent_root = info->extent_root;
	struct btrfs_root *cur_root = NULL;
	struct btrfs_trans_handle *trans;
	struct btrfs_extent_data_ref *dref;
	struct btrfs_extent_inline_ref *iref;
	struct btrfs_extent_item *ei;
	struct extent_buffer *leaf;
	struct btrfs_key key;
	struct btrfs_key extent_key;
	struct btrfs_path path;
	struct extent_io_tree reloc_tree;
	unsigned long ptr;
	unsigned long end;
	u64 cur_byte;
	u64 num_bytes;
	u64 ref_root;
	u64 num_extents;
	int pass = 0;
	int ret;

	btrfs_init_path(&path);
	extent_io_tree_init(&reloc_tree);

	key.objectid = start_byte;
	key.offset = 0;
	key.type = BTRFS_EXTENT_ITEM_KEY;
	ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0);
	if (ret < 0)
		goto fail;
	if (ret > 0) {
		ret = btrfs_previous_item(extent_root, &path, 0,
					  BTRFS_EXTENT_ITEM_KEY);
		if (ret < 0)
			goto fail;
		if (ret == 0) {
			leaf = path.nodes[0];
			btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
			if (key.objectid + key.offset > start_byte)
				start_byte = key.objectid;
		}
	}
	btrfs_release_path(extent_root, &path);
again:
	cur_root = (pass % 2 == 0) ? ext2_root : fs_root;
	num_extents = 0;

	trans = btrfs_start_transaction(cur_root, 1);
	BUG_ON(!trans);

	cur_byte = start_byte;
	while (1) {
		key.objectid = cur_byte;
		key.offset = 0;
		key.type = BTRFS_EXTENT_ITEM_KEY;
		ret = btrfs_search_slot(trans, extent_root,
					&key, &path, 0, 0);
		if (ret < 0)
			goto fail;
next:
		leaf = path.nodes[0];
		if (path.slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(extent_root, &path);
			if (ret < 0)
				goto fail;
			if (ret > 0)
				break;
			leaf = path.nodes[0];
		}

		btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
		if (key.objectid < cur_byte ||
		    key.type != BTRFS_EXTENT_ITEM_KEY) {
			path.slots[0]++;
			goto next;
		}
		if (key.objectid >= end_byte)
			break;

		num_extents++;

		cur_byte = key.objectid;
		num_bytes = key.offset;
		ei = btrfs_item_ptr(leaf, path.slots[0],
				    struct btrfs_extent_item);
		BUG_ON(!(btrfs_extent_flags(leaf, ei) &
			 BTRFS_EXTENT_FLAG_DATA));

		ptr = btrfs_item_ptr_offset(leaf, path.slots[0]);
		end = ptr + btrfs_item_size_nr(leaf, path.slots[0]);

		ptr += sizeof(struct btrfs_extent_item);

		while (ptr < end) {
			iref = (struct btrfs_extent_inline_ref *)ptr;
			key.type = btrfs_extent_inline_ref_type(leaf, iref);
			BUG_ON(key.type != BTRFS_EXTENT_DATA_REF_KEY);
			dref = (struct btrfs_extent_data_ref *)(&iref->offset);
			ref_root = btrfs_extent_data_ref_root(leaf, dref);
			extent_key.objectid =
				btrfs_extent_data_ref_objectid(leaf, dref);
			extent_key.offset =
				btrfs_extent_data_ref_offset(leaf, dref);
			extent_key.type = BTRFS_EXTENT_DATA_KEY;
			BUG_ON(btrfs_extent_data_ref_count(leaf, dref) != 1);

			if (ref_root == cur_root->root_key.objectid)
				break;

			ptr += btrfs_extent_inline_ref_size(key.type);
		}

		if (ptr >= end) {
			path.slots[0]++;
			goto next;
		}

		ret = relocate_one_reference(trans, cur_root, cur_byte,
					     num_bytes, &extent_key,
					     &reloc_tree);
		if (ret < 0)
			goto fail;

		cur_byte += num_bytes;
		btrfs_release_path(extent_root, &path);

		if (trans->blocks_used >= 4096) {
			ret = btrfs_commit_transaction(trans, cur_root);
			BUG_ON(ret);
			trans = btrfs_start_transaction(cur_root, 1);
			BUG_ON(!trans);
		}
	}
	btrfs_release_path(cur_root, &path);

	ret = btrfs_commit_transaction(trans, cur_root);
	BUG_ON(ret);

	if (num_extents > 0 && pass++ < 16)
		goto again;

	ret = (num_extents > 0) ? -1 : 0;
fail:
	btrfs_release_path(cur_root, &path);
	extent_io_tree_cleanup(&reloc_tree);
	return ret;
}

/*
 * relocate data in system chunk
 */
static int cleanup_sys_chunk(struct btrfs_root *fs_root,
			     struct btrfs_root *ext2_root)
{
	struct btrfs_block_group_cache *cache;
	int i, ret = 0;
	u64 offset = 0;
	u64 end_byte;

	while(1) {
		cache = btrfs_lookup_block_group(fs_root->fs_info, offset);
		if (!cache)
			break;

		end_byte = cache->key.objectid + cache->key.offset;
		if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
			ret = relocate_extents_range(fs_root, ext2_root,
						     cache->key.objectid,
						     end_byte);
			if (ret)
				goto fail;
		}
		offset = end_byte;
	}
	for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
		offset = btrfs_sb_offset(i);
		offset &= ~((u64)STRIPE_LEN - 1);

		ret = relocate_extents_range(fs_root, ext2_root,
					     offset, offset + STRIPE_LEN);
		if (ret)
			goto fail;
	}
	ret = 0;
fail:
	return ret;
}

static int fixup_chunk_mapping(struct btrfs_root *root)
{
	struct btrfs_trans_handle *trans;
	struct btrfs_fs_info *info = root->fs_info;
	struct btrfs_root *chunk_root = info->chunk_root;
	struct extent_buffer *leaf;
	struct btrfs_key key;
	struct btrfs_path path;
	struct btrfs_chunk chunk;
	unsigned long ptr;
	u32 size;
	u64 type;
	int ret;

	btrfs_init_path(&path);

	trans = btrfs_start_transaction(root, 1);
	BUG_ON(!trans);

	/*
	 * recow the whole chunk tree. this will move all chunk tree blocks
	 * into system block group.
	 */
	memset(&key, 0, sizeof(key));
	while (1) {
		ret = btrfs_search_slot(trans, chunk_root, &key, &path, 0, 1);
		if (ret < 0)
			goto err;

		ret = btrfs_next_leaf(chunk_root, &path);
		if (ret < 0)
			goto err;
		if (ret > 0)
			break;

		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
		btrfs_release_path(chunk_root, &path);
	}
	btrfs_release_path(chunk_root, &path);

	/* fixup the system chunk array in super block */
	btrfs_set_super_sys_array_size(&info->super_copy, 0);

	key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
	key.offset = 0;
	key.type = BTRFS_CHUNK_ITEM_KEY;

	ret = btrfs_search_slot(trans, chunk_root, &key, &path, 0, 0);
	if (ret < 0)
		goto err;
	BUG_ON(ret != 0);
	while(1) {
		leaf = path.nodes[0];
		if (path.slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(chunk_root, &path);
			if (ret < 0)
				goto err;
			if (ret > 0)
				break;
			leaf = path.nodes[0];
		}
		btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
		if (key.type != BTRFS_CHUNK_ITEM_KEY)
			goto next;

		ptr = btrfs_item_ptr_offset(leaf, path.slots[0]);
		size = btrfs_item_size_nr(leaf, path.slots[0]);
		BUG_ON(size != sizeof(chunk));
		read_extent_buffer(leaf, &chunk, ptr, size);
		type = btrfs_stack_chunk_type(&chunk);

		if (!(type & BTRFS_BLOCK_GROUP_SYSTEM))
			goto next;

		ret = btrfs_add_system_chunk(trans, chunk_root, &key,
					     &chunk, size);
		if (ret)
			goto err;
next:
		path.slots[0]++;
	}

	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);
err:
	btrfs_release_path(chunk_root, &path);
	return ret;
}

int do_convert(const char *devname, int datacsum, int packing, int noxattr)
{
	int i, fd, ret;
	u32 blocksize;
	u64 blocks[7];
	u64 total_bytes;
	u64 super_bytenr;
	ext2_filsys ext2_fs;
	struct btrfs_root *root;
	struct btrfs_root *ext2_root;

	ret = open_ext2fs(devname, &ext2_fs);
	if (ret) {
		fprintf(stderr, "unable to open the Ext2fs\n");
		goto fail;
	}
	blocksize = ext2_fs->blocksize;
	total_bytes = (u64)ext2_fs->super->s_blocks_count * blocksize;
	if (blocksize < 4096) {
		fprintf(stderr, "block size is too small\n");
		goto fail;
	}
	if (!(ext2_fs->super->s_feature_incompat &
	      EXT2_FEATURE_INCOMPAT_FILETYPE)) {
		fprintf(stderr, "filetype feature is missing\n");
		goto fail;
	}
	for (i = 0; i < 7; i++) {
		ret = ext2_alloc_block(ext2_fs, 0, blocks + i);
		if (ret) {
			fprintf(stderr, "not enough free space\n");
			goto fail;
		}
		blocks[i] *= blocksize;
	}
	super_bytenr = blocks[0];
	fd = open(devname, O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "unable to open %s\n", devname);
		goto fail;
	}
	ret = make_btrfs(fd, devname, ext2_fs->super->s_volume_name,
			 blocks, total_bytes, blocksize, blocksize,
			 blocksize, blocksize);
	if (ret) {
		fprintf(stderr, "unable to create initial ctree\n");
		goto fail;
	}
	/* create a system chunk that maps the whole device */
	ret = prepare_system_chunk(fd, super_bytenr, blocksize);
	if (ret) {
		fprintf(stderr, "unable to update system chunk\n");
		goto fail;
	}
	root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR);
	if (!root) {
		fprintf(stderr, "unable to open ctree\n");
		goto fail;
	}
	ret = cache_free_extents(root, ext2_fs);
	if (ret) {
		fprintf(stderr, "error during cache_free_extents %d\n", ret);
		goto fail;
	}
	root->fs_info->extent_ops = &extent_ops;
	/* recover block allocation bitmap */
	for (i = 0; i < 7; i++) {
		blocks[i] /= blocksize;
		ext2_free_block(ext2_fs, blocks[i]);
	}
	ret = init_btrfs(root);
	if (ret) {
		fprintf(stderr, "unable to setup the root tree\n");
		goto fail;
	}
	printf("creating btrfs metadata.\n");
	ret = copy_inodes(root, ext2_fs, datacsum, packing, noxattr);
	if (ret) {
		fprintf(stderr, "error during copy_inodes %d\n", ret);
		goto fail;
	}
	printf("creating ext2fs image file.\n");
	ext2_root = link_subvol(root, "ext2_saved", EXT2_IMAGE_SUBVOL_OBJECTID);
	if (!ext2_root) {
		fprintf(stderr, "unable to create subvol\n");
		goto fail;
	}
	ret = create_ext2_image(ext2_root, ext2_fs, "image");
	if (ret) {
		fprintf(stderr, "error during create_ext2_image %d\n", ret);
		goto fail;
	}
	printf("cleaning up system chunk.\n");
	ret = cleanup_sys_chunk(root, ext2_root);
	if (ret) {
		fprintf(stderr, "error during cleanup_sys_chunk %d\n", ret);
		goto fail;
	}
	ret = close_ctree(root);
	if (ret) {
		fprintf(stderr, "error during close_ctree %d\n", ret);
		goto fail;
	}
	close_ext2fs(ext2_fs);

	/*
	 * If this step succeed, we get a mountable btrfs. Otherwise
	 * the ext2fs is left unchanged.
	 */
	ret = migrate_super_block(fd, super_bytenr, blocksize);
	if (ret) {
		fprintf(stderr, "unable to migrate super block\n");
		goto fail;
	}

	root = open_ctree_fd(fd, devname, 0, O_RDWR);
	if (!root) {
		fprintf(stderr, "unable to open ctree\n");
		goto fail;
	}
	/* move chunk tree into system chunk. */
	ret = fixup_chunk_mapping(root);
	if (ret) {
		fprintf(stderr, "error during fixup_chunk_tree\n");
		goto fail;
	}
	ret = close_ctree(root);
	close(fd);

	printf("conversion complete.\n");
	return 0;
fail:
	fprintf(stderr, "conversion aborted.\n");
	return -1;
}

static int may_rollback(struct btrfs_root *root)
{
	struct btrfs_fs_info *info = root->fs_info;
	struct btrfs_multi_bio *multi = NULL;
	u64 bytenr;
	u64 length;
	u64 physical;
	u64 total_bytes;
	int num_stripes;
	int ret;

	if (btrfs_super_num_devices(&info->super_copy) != 1)
		goto fail;

	bytenr = BTRFS_SUPER_INFO_OFFSET;
	total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);

	while (1) {
		ret = btrfs_map_block(&info->mapping_tree, WRITE, bytenr,
				      &length, &multi, 0);
		if (ret)
			goto fail;

		num_stripes = multi->num_stripes;
		physical = multi->stripes[0].physical;
		kfree(multi);

		if (num_stripes != 1 || physical != bytenr)
			goto fail;

		bytenr += length;
		if (bytenr >= total_bytes)
			break;
	}
	return 0;
fail:
	return -1;
}

int do_rollback(const char *devname, int force)
{
	int fd;
	int ret;
	int i;
	struct btrfs_root *root;
	struct btrfs_root *ext2_root;
	struct btrfs_root *chunk_root;
	struct btrfs_dir_item *dir;
	struct btrfs_inode_item *inode;
	struct btrfs_file_extent_item *fi;
	struct btrfs_trans_handle *trans;
	struct extent_buffer *leaf;
	struct btrfs_block_group_cache *cache1;
	struct btrfs_block_group_cache *cache2;
	struct btrfs_key key;
	struct btrfs_path path;
	struct extent_io_tree io_tree;
	char *buf;
	char *name;
	u64 bytenr;
	u64 num_bytes;
	u64 root_dir;
	u64 objectid;
	u64 offset;
	u64 start;
	u64 end;
	u64 sb_bytenr;
	u64 first_free;
	u64 total_bytes;
	u32 sectorsize;

	extent_io_tree_init(&io_tree);

	fd = open(devname, O_RDWR);
	if (fd < 0) {
		fprintf(stderr, "unable to open %s\n", devname);
		goto fail;
	}
	root = open_ctree_fd(fd, devname, 0, O_RDWR);
	if (!root) {
		fprintf(stderr, "unable to open ctree\n");
		goto fail;
	}
	ret = may_rollback(root);
	if (ret < 0) {
		fprintf(stderr, "unable to do rollback\n");
		goto fail;
	}

	sectorsize = root->sectorsize;
	buf = malloc(sectorsize);
	if (!buf) {
		fprintf(stderr, "unable to allocate memory\n");
		goto fail;
	}

	btrfs_init_path(&path);

	key.objectid = EXT2_IMAGE_SUBVOL_OBJECTID;
	key.type = BTRFS_ROOT_ITEM_KEY;
	key.offset = (u64)-1;
	ext2_root = btrfs_read_fs_root(root->fs_info, &key);
	if (!ext2_root || IS_ERR(ext2_root)) {
		fprintf(stderr, "unable to open subvol %llu\n",
			key.objectid);
		goto fail;
	}

	name = "image";
	root_dir = btrfs_root_dirid(&root->root_item);
	dir = btrfs_lookup_dir_item(NULL, ext2_root, &path,
				   root_dir, name, strlen(name), 0);
	if (!dir || IS_ERR(dir)) {
		fprintf(stderr, "unable to find file %s\n", name);
		goto fail;
	}
	leaf = path.nodes[0];
	btrfs_dir_item_key_to_cpu(leaf, dir, &key);
	btrfs_release_path(ext2_root, &path);

	objectid = key.objectid;

	ret = btrfs_lookup_inode(NULL, ext2_root, &path, &key, 0);
	if (ret) {
		fprintf(stderr, "unable to find inode item\n");
		goto fail;
	}
	leaf = path.nodes[0];
	inode = btrfs_item_ptr(leaf, path.slots[0], struct btrfs_inode_item);
	total_bytes = btrfs_inode_size(leaf, inode);
	btrfs_release_path(ext2_root, &path);

	key.objectid = objectid;
	key.offset = 0;
	btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY);
	ret = btrfs_search_slot(NULL, ext2_root, &key, &path, 0, 0);
	if (ret != 0) {
		fprintf(stderr, "unable to find first file extent\n");
		btrfs_release_path(ext2_root, &path);
		goto fail;
	}

	/* build mapping tree for the relocated blocks */
	for (offset = 0; offset < total_bytes; ) {
		leaf = path.nodes[0];
		if (path.slots[0] >= btrfs_header_nritems(leaf)) {
			ret = btrfs_next_leaf(root, &path);
			if (ret != 0)
				break;	
			continue;
		}

		btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
		if (key.objectid != objectid || key.offset != offset ||
		    btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
			break;

		fi = btrfs_item_ptr(leaf, path.slots[0],
				    struct btrfs_file_extent_item);
		if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG)
			break;
		if (btrfs_file_extent_compression(leaf, fi) ||
		    btrfs_file_extent_encryption(leaf, fi) ||
		    btrfs_file_extent_other_encoding(leaf, fi))
			break;

		bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
		/* skip holes and direct mapped extents */
		if (bytenr == 0 || bytenr == offset)
			goto next_extent;

		bytenr += btrfs_file_extent_offset(leaf, fi);
		num_bytes = btrfs_file_extent_num_bytes(leaf, fi);

		cache1 = btrfs_lookup_block_group(root->fs_info, offset);
		cache2 =  btrfs_lookup_block_group(root->fs_info,
						   offset + num_bytes - 1);
		if (!cache1 || cache1 != cache2 ||
		    (!(cache1->flags & BTRFS_BLOCK_GROUP_SYSTEM) &&
		     !intersect_with_sb(offset, num_bytes)))
			break;

		set_extent_bits(&io_tree, offset, offset + num_bytes - 1,
				EXTENT_LOCKED, GFP_NOFS);
		set_state_private(&io_tree, offset, bytenr);
next_extent:
		offset += btrfs_file_extent_num_bytes(leaf, fi);
		path.slots[0]++;
	}
	btrfs_release_path(ext2_root, &path);

	if (offset < total_bytes) {
		fprintf(stderr, "unable to build extent mapping\n");
		goto fail;
	}

	first_free = BTRFS_SUPER_INFO_OFFSET + 2 * sectorsize - 1;
	first_free &= ~((u64)sectorsize - 1);
	/* backup for extent #0 should exist */
	if(!test_range_bit(&io_tree, 0, first_free - 1, EXTENT_LOCKED, 1)) {
		fprintf(stderr, "no backup for the first extent\n");
		goto fail;
	}
	/* force no allocation from system block group */
	root->fs_info->system_allocs = -1;
	trans = btrfs_start_transaction(root, 1);
	BUG_ON(!trans);
	/*
	 * recow the whole chunk tree, this will remove all chunk tree blocks
	 * from system block group
	 */
	chunk_root = root->fs_info->chunk_root;
	memset(&key, 0, sizeof(key));
	while (1) {
		ret = btrfs_search_slot(trans, chunk_root, &key, &path, 0, 1);
		if (ret < 0)
			break;

		ret = btrfs_next_leaf(chunk_root, &path);
		if (ret)
			break;

		btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
		btrfs_release_path(chunk_root, &path);
	}
	btrfs_release_path(chunk_root, &path);

	offset = 0;
	num_bytes = 0;
	while(1) {
		cache1 = btrfs_lookup_block_group(root->fs_info, offset);
		if (!cache1)
			break;

		if (cache1->flags & BTRFS_BLOCK_GROUP_SYSTEM)
			num_bytes += btrfs_block_group_used(&cache1->item);

		offset = cache1->key.objectid + cache1->key.offset;
	}
	/* only extent #0 left in system block group? */
	if (num_bytes > first_free) {
		fprintf(stderr, "unable to empty system block group\n");
		goto fail;
	}
	/* create a system chunk that maps the whole device */
	ret = prepare_system_chunk_sb(&root->fs_info->super_copy);
	if (ret) {
		fprintf(stderr, "unable to update system chunk\n");
		goto fail;
	}

	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);

	ret = close_ctree(root);
	if (ret) {
		fprintf(stderr, "error during close_ctree %d\n", ret);
		goto fail;
	}

	/* zero btrfs super block mirrors */
	memset(buf, 0, sectorsize);
	for (i = 1 ; i < BTRFS_SUPER_MIRROR_MAX; i++) {
		bytenr = btrfs_sb_offset(i);
		if (bytenr >= total_bytes)
			break;
		ret = pwrite(fd, buf, sectorsize, bytenr);
	}

	sb_bytenr = (u64)-1;
	/* copy all relocated blocks back */
	while(1) {
		ret = find_first_extent_bit(&io_tree, 0, &start, &end,
					    EXTENT_LOCKED);
		if (ret)
			break;

		ret = get_state_private(&io_tree, start, &bytenr);
		BUG_ON(ret);

		clear_extent_bits(&io_tree, start, end, EXTENT_LOCKED,
				  GFP_NOFS);

		while (start <= end) {
			if (start == BTRFS_SUPER_INFO_OFFSET) {
				sb_bytenr = bytenr;
				goto next_sector;
			}
			ret = pread(fd, buf, sectorsize, bytenr);
			if (ret < 0) {
				fprintf(stderr, "error during pread %d\n", ret);
				goto fail;
			}
			BUG_ON(ret != sectorsize);
			ret = pwrite(fd, buf, sectorsize, start);
			if (ret < 0) {
				fprintf(stderr, "error during pwrite %d\n", ret);
				goto fail;
			}
			BUG_ON(ret != sectorsize);
next_sector:
			start += sectorsize;
			bytenr += sectorsize;
		}
	}

	ret = fsync(fd);
	if (ret) {
		fprintf(stderr, "error during fsync %d\n", ret);
		goto fail;
	}
	/*
	 * finally, overwrite btrfs super block.
	 */
	ret = pread(fd, buf, sectorsize, sb_bytenr);
	if (ret < 0) {
		fprintf(stderr, "error during pread %d\n", ret);
		goto fail;
	}
	BUG_ON(ret != sectorsize);
	ret = pwrite(fd, buf, sectorsize, BTRFS_SUPER_INFO_OFFSET);
	if (ret < 0) {
		fprintf(stderr, "error during pwrite %d\n", ret);
		goto fail;
	}
	BUG_ON(ret != sectorsize);
	ret = fsync(fd);
	if (ret) {
		fprintf(stderr, "error during fsync %d\n", ret);
		goto fail;
	}

	close(fd);
	free(buf);
	extent_io_tree_cleanup(&io_tree);
	printf("rollback complete.\n");
	return 0;
fail:
	fprintf(stderr, "rollback aborted.\n");
	return -1;
}

static void print_usage(void)
{
	printf("usage: btrfs-convert [-d] [-i] [-n] [-r] device\n");
	printf("\t-d disable data checksum\n");
	printf("\t-i ignore xattrs and ACLs\n");
	printf("\t-n disable packing of small files\n");
	printf("\t-r roll back to ext2fs\n");
}

int main(int argc, char *argv[])
{
	int ret;
	int packing = 1;
	int noxattr = 0;
	int datacsum = 1;
	int rollback = 0;
	char *file;
	while(1) {
		int c = getopt(argc, argv, "dinr");
		if (c < 0)
			break;
		switch(c) {
			case 'd':
				datacsum = 0;
				break;
			case 'i':
				noxattr = 1;
				break;
			case 'n':
				packing = 0;
				break;
			case 'r':
				rollback = 1;
				break;
			default:
				print_usage();
				return 1;
		}
	}
	argc = argc - optind;
	if (argc != 1) {
		print_usage();
		return 1;
	}

	file = argv[optind];
	if (check_mounted(file)) {
		fprintf(stderr, "%s is mounted\n", file);
		return 1;
	}

	if (rollback) {
		ret = do_rollback(file, 0);
	} else {
		ret = do_convert(file, datacsum, packing, noxattr);
	}
	if (ret)
		return 1;
	return 0;
}
