-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 *dirent,
- int offset, int blocksize,
- char *buf,void *priv_data)
-{
- int ret;
- int file_type;
- u64 objectid;
- char dotdot[] = "..";
- struct dir_iterate_data *idata = (struct dir_iterate_data *)priv_data;
- int name_len;
-
- name_len = dirent->name_len & 0xFF;
-
- objectid = dirent->inode + INO_OFFSET;
- if (!strncmp(dirent->name, dotdot, name_len)) {
- if (name_len == 2) {
- BUG_ON(idata->parent != 0);
- idata->parent = objectid;
- }
- return 0;
- }
- if (dirent->inode < EXT2_GOOD_OLD_FIRST_INO)
- return 0;
-
- file_type = dirent->name_len >> 8;
- BUG_ON(file_type > EXT2_FT_SYMLINK);
-
- ret = convert_insert_dirent(idata->trans, idata->root, dirent->name,
- name_len, idata->objectid, objectid,
- filetype_conversion_table[file_type],
- idata->index_cnt, idata->inode);
- if (ret < 0) {
- idata->errcode = ret;
- return BLOCK_ABORT;
- }
-
- idata->index_cnt++;
- return 0;
-}
-
-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;
-}
-