#if BTRFSCONVERT_EXT2
#include "kerncompat.h"
+#include <linux/limits.h>
+#include <pthread.h>
#include "disk-io.h"
#include "transaction.h"
#include "utils.h"
ext2_filsys ext2_fs;
ext2_ino_t ino;
u32 ro_feature;
+ int open_flag = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
- ret = ext2fs_open(name, 0, 0, 0, unix_io_manager, &ext2_fs);
+ ret = ext2fs_open(name, open_flag, 0, 0, unix_io_manager, &ext2_fs);
if (ret) {
- fprintf(stderr, "ext2fs_open: %s\n", error_message(ret));
+ if (ret != EXT2_ET_BAD_MAGIC)
+ fprintf(stderr, "ext2fs_open: %s\n", error_message(ret));
return -1;
}
/*
return 0;
fail:
ext2fs_close(ext2_fs);
+ ext2fs_free(ext2_fs);
return -1;
}
{
ext2_filsys fs = (ext2_filsys)cctx->fs_data;
blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
- struct cache_tree *used_tree = &cctx->used;
+ struct cache_tree *used_tree = &cctx->used_space;
char *block_bitmap = NULL;
unsigned long i;
int block_nbytes;
return -ENOMEM;
for (i = 0; i < fs->group_desc_count; i++) {
- ret = ext2fs_get_block_bitmap_range(fs->block_map, blk_itr,
+ ret = ext2fs_get_block_bitmap_range2(fs->block_map, blk_itr,
block_nbytes * 8, block_bitmap);
if (ret) {
error("fail to get bitmap from ext2, %s",
- strerror(-ret));
+ error_message(ret));
+ ret = -EINVAL;
break;
}
ret = __ext2_add_one_block(fs, block_bitmap, i, used_tree);
cctx->volume_name = NULL;
}
ext2fs_close(cctx->fs_data);
+ ext2fs_free(cctx->fs_data);
}
static u8 ext2_filetype_conversion_table[EXT2_FT_MAX] = {
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)
+ u32 convert_flags)
{
int ret;
char *buffer = NULL;
errcode_t err;
u32 last_block;
- u32 sectorsize = root->sectorsize;
+ u32 sectorsize = root->fs_info->sectorsize;
u64 inode_size = btrfs_stack_inode_size(btrfs_inode);
struct blk_iterate_data data;
init_blk_iterate_data(&data, trans, root, btrfs_inode, objectid,
- datacsum);
+ convert_flags & CONVERT_FLAG_DATACSUM);
err = ext2fs_block_iterate2(ext2_fs, ext2_ino, BLOCK_FLAG_DATA_ONLY,
NULL, ext2_block_iterate_proc, &data);
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)) {
+ if ((convert_flags & CONVERT_FLAG_INLINE_DATA) && data.first_block == 0
+ && data.num_blocks > 0 && inode_size < sectorsize
+ && inode_size <= BTRFS_MAX_INLINE_DATA_SIZE(root->fs_info)) {
u64 num_bytes = data.num_blocks * sectorsize;
u64 disk_bytenr = data.disk_block * sectorsize;
u64 nbytes;
return -1;
}
-static int ext2_create_symbol_link(struct btrfs_trans_handle *trans,
+static int ext2_create_symlink(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;
char *pathname;
u64 inode_size = btrfs_stack_inode_size(btrfs_inode);
- if (ext2fs_inode_data_blocks(ext2_fs, ext2_inode)) {
+ if (ext2fs_inode_data_blocks2(ext2_fs, ext2_inode)) {
btrfs_set_stack_inode_size(btrfs_inode, inode_size + 1);
ret = ext2_create_file_extents(trans, root, objectid,
- btrfs_inode, ext2_fs, ext2_ino, 1, 1);
+ btrfs_inode, ext2_fs, ext2_ino,
+ CONVERT_FLAG_DATACSUM |
+ CONVERT_FLAG_INLINE_DATA);
btrfs_set_stack_inode_size(btrfs_inode, inode_size);
return ret;
}
{
size_t value_size = entry->e_value_size;
- if (entry->e_value_block != 0 || value_size > size ||
- entry->e_value_offs + value_size > size)
+ if (value_size > size || entry->e_value_offs + value_size > size)
return -EIO;
return 0;
}
-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;
- }
-}
-
-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)
{
}
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) -
+ if (name_len + datalen > BTRFS_LEAF_DATA_SIZE(root->fs_info) -
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);
ret = -ENOMEM;
goto out;
}
- err = ext2fs_read_ext_attr(ext2_fs, ext2_inode->i_file_acl, buffer);
+ err = ext2fs_read_ext_attr2(ext2_fs, ext2_inode->i_file_acl, buffer);
if (err) {
- fprintf(stderr, "ext2fs_read_ext_attr: %s\n",
+ fprintf(stderr, "ext2fs_read_ext_attr2: %s\n",
error_message(err));
ret = -1;
goto out;
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 void ext2_copy_inode_item(struct btrfs_inode_item *dst,
struct ext2_inode *src, u32 blocksize)
{
old_decode_dev(src->i_block[0]));
} else {
btrfs_set_stack_inode_rdev(dst,
- new_decode_dev(src->i_block[1]));
+ decode_dev(src->i_block[1]));
}
}
memset(&dst->reserved, 0, sizeof(dst->reserved));
static void ext2_convert_inode_flags(struct btrfs_inode_item *dst,
struct ext2_inode *src)
{
- u64 flags = 0;
+ u64 flags = btrfs_stack_inode_flags(dst);
COPY_ONE_EXT2_FLAG(flags, src, APPEND);
COPY_ONE_EXT2_FLAG(flags, src, SYNC);
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)
+ u32 convert_flags)
{
int ret;
struct btrfs_inode_item btrfs_inode;
return 0;
ext2_copy_inode_item(&btrfs_inode, ext2_inode, ext2_fs->blocksize);
- if (!datacsum && S_ISREG(ext2_inode->i_mode)) {
+ if (!(convert_flags & CONVERT_FLAG_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 = ext2_create_file_extents(trans, root, objectid,
- &btrfs_inode, ext2_fs, ext2_ino, datacsum, packing);
+ &btrfs_inode, ext2_fs, ext2_ino, convert_flags);
break;
case S_IFDIR:
ret = ext2_create_dir_entries(trans, root, objectid,
&btrfs_inode, ext2_fs, ext2_ino);
break;
case S_IFLNK:
- ret = ext2_create_symbol_link(trans, root, objectid,
+ ret = ext2_create_symlink(trans, root, objectid,
&btrfs_inode, ext2_fs, ext2_ino, ext2_inode);
break;
default:
if (ret)
return ret;
- if (!noxattr) {
+ if (convert_flags & CONVERT_FLAG_XATTR) {
ret = ext2_copy_extended_attrs(trans, root, objectid,
&btrfs_inode, ext2_fs, ext2_ino);
if (ret)
*/
static int ext2_copy_inodes(struct btrfs_convert_context *cctx,
struct btrfs_root *root,
- int datacsum, int packing, int noxattr, struct task_ctx *p)
+ u32 convert_flags, struct task_ctx *p)
{
ext2_filsys ext2_fs = cctx->fs_data;
int ret;
struct btrfs_trans_handle *trans;
trans = btrfs_start_transaction(root, 1);
- if (!trans)
- return -ENOMEM;
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
err = ext2fs_open_inode_scan(ext2_fs, 0, &ext2_scan);
if (err) {
fprintf(stderr, "ext2fs_open_inode_scan: %s\n", error_message(err));
objectid = ext2_ino + INO_OFFSET;
ret = ext2_copy_single_inode(trans, root,
objectid, ext2_fs, ext2_ino,
- &ext2_inode, datacsum, packing,
- noxattr);
+ &ext2_inode, convert_flags);
+ pthread_mutex_lock(&p->mutex);
p->cur_copy_inodes++;
+ pthread_mutex_unlock(&p->mutex);
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);
+ BUG_ON(IS_ERR(trans));
}
}
if (err) {