ioctls to scan for btrfs filesystems
[btrfs-progs-unstable/devel.git] / convert.c
blob83928f4be5901968d7e01548b08dd70ac95b73ba
1 /*
2 * Copyright (C) 2007 Oracle. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
19 #define _XOPEN_SOURCE 500
20 #ifndef __CHECKER__
21 #include <sys/ioctl.h>
22 #include <sys/mount.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/acl.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <uuid/uuid.h>
32 #include <linux/fs.h>
33 #include "kerncompat.h"
34 #include "ctree.h"
35 #include "disk-io.h"
36 #include "transaction.h"
37 #include "crc32c.h"
38 #include "utils.h"
39 #include <ext2fs/ext2_fs.h>
40 #include <ext2fs/ext2fs.h>
41 #include <ext2fs/ext2_ext_attr.h>
42 #define INO_OFFSET (BTRFS_FIRST_FREE_OBJECTID - EXT2_ROOT_INO)
44 * Open Ext2fs in readonly mode, read block allocation bitmap and
45 * inode bitmap into memory.
47 static int open_ext2fs(const char *name, ext2_filsys *ret_fs)
49 errcode_t ret;
50 ext2_filsys ext2_fs;
51 ret = ext2fs_open(name, 0, 0, 0, unix_io_manager, &ext2_fs);
52 if (ret) {
53 fprintf(stderr, "ext2fs_open: %s\n", error_message(ret));
54 goto fail;
56 ret = ext2fs_read_inode_bitmap(ext2_fs);
57 if (ret) {
58 fprintf(stderr, "ext2fs_read_inode_bitmap: %s\n",
59 error_message(ret));
60 goto fail;
62 ret = ext2fs_read_block_bitmap(ext2_fs);
63 if (ret) {
64 fprintf(stderr, "ext2fs_read_block_bitmap: %s\n",
65 error_message(ret));
66 goto fail;
68 *ret_fs = ext2_fs;
69 return 0;
70 fail:
71 return -1;
74 static int close_ext2fs(ext2_filsys fs)
76 ext2fs_close(fs);
77 return 0;
79 static int ext2_alloc_block(ext2_filsys fs, u64 goal, u64 *block_ret)
81 blk_t block;
83 if (!ext2fs_new_block(fs, goal, NULL, &block)) {
84 ext2fs_fast_mark_block_bitmap(fs->block_map, block);
85 *block_ret = block;
86 return 0;
88 return -ENOSPC;
91 static int ext2_free_block(ext2_filsys fs, u64 block)
93 BUG_ON(block != (blk_t)block);
94 ext2fs_fast_unmark_block_bitmap(fs->block_map, block);
95 return 0;
98 static int custom_alloc_extent(struct btrfs_root *root, u64 num_bytes,
99 u64 hint_byte, struct btrfs_key *ins)
101 ext2_filsys fs = (ext2_filsys)root->fs_info->priv_data;
102 u32 blocksize = fs->blocksize;
103 u64 first = 0;
104 u64 block;
105 u64 bytenr;
106 int ret;
108 block = hint_byte / blocksize;
109 BUG_ON(block != (blk_t)block);
110 BUG_ON(num_bytes != blocksize);
111 while (1) {
112 ret = ext2_alloc_block(fs, block, &block);
113 if (ret)
114 goto fail;
115 /* all free blocks are pinned */
116 if (first == block)
117 goto fail;
118 if (first == 0)
119 first = block;
120 bytenr = block * blocksize;
121 if (!test_range_bit(&root->fs_info->pinned_extents, bytenr,
122 bytenr + blocksize - 1, EXTENT_DIRTY, 0))
123 break;
125 ext2_free_block(fs, block);
126 block++;
128 ins->objectid = bytenr;
129 ins->offset = blocksize;
130 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
131 return 0;
132 fail:
133 fprintf(stderr, "not enough free space\n");
134 return -ENOSPC;
136 static int custom_free_extent(struct btrfs_root *root, u64 bytenr,
137 u64 num_bytes)
139 u64 block;
140 ext2_filsys fs = (ext2_filsys)root->fs_info->priv_data;
142 BUG_ON(bytenr & (fs->blocksize - 1));
143 block = bytenr / fs->blocksize;
144 while (num_bytes > 0) {
145 ext2_free_block(fs, block);
146 block++;
147 num_bytes -= fs->blocksize;
149 return 0;
152 struct btrfs_extent_ops extent_ops = {
153 .alloc_extent = custom_alloc_extent,
154 .free_extent = custom_free_extent,
157 struct dir_iterate_data {
158 struct btrfs_trans_handle *trans;
159 struct btrfs_root *root;
160 struct btrfs_inode_item *inode;
161 u64 objectid;
162 u64 parent;
163 int errcode;
165 static u8 filetype_conversion_table[EXT2_FT_MAX] = {
166 [EXT2_FT_UNKNOWN] = BTRFS_FT_UNKNOWN,
167 [EXT2_FT_REG_FILE] = BTRFS_FT_REG_FILE,
168 [EXT2_FT_DIR] = BTRFS_FT_DIR,
169 [EXT2_FT_CHRDEV] = BTRFS_FT_CHRDEV,
170 [EXT2_FT_BLKDEV] = BTRFS_FT_BLKDEV,
171 [EXT2_FT_FIFO] = BTRFS_FT_FIFO,
172 [EXT2_FT_SOCK] = BTRFS_FT_SOCK,
173 [EXT2_FT_SYMLINK] = BTRFS_FT_SYMLINK,
176 static int dir_iterate_proc(ext2_ino_t dir, int entry,
177 struct ext2_dir_entry *old,
178 int offset, int blocksize,
179 char *buf,void *priv_data)
181 int ret;
182 int file_type;
183 u64 objectid;
184 u64 inode_size;
185 char dotdot[] = "..";
186 struct btrfs_key location;
187 struct ext2_dir_entry_2 *dirent = (struct ext2_dir_entry_2 *)old;
188 struct dir_iterate_data *idata = (struct dir_iterate_data *)priv_data;
190 objectid = dirent->inode + INO_OFFSET;
191 if (!strncmp(dirent->name, dotdot, dirent->name_len)) {
192 if (dirent->name_len == 2) {
193 BUG_ON(idata->parent != 0);
194 idata->parent = objectid;
196 return 0;
198 if (dirent->inode < EXT2_GOOD_OLD_FIRST_INO)
199 return 0;
201 location.objectid = objectid;
202 location.offset = 0;
203 btrfs_set_key_type(&location, BTRFS_INODE_ITEM_KEY);
205 file_type = dirent->file_type;
206 BUG_ON(file_type > EXT2_FT_SYMLINK);
207 ret = btrfs_insert_dir_item(idata->trans, idata->root,
208 dirent->name, dirent->name_len,
209 idata->objectid, &location,
210 filetype_conversion_table[file_type]);
211 if (ret)
212 goto fail;
213 ret = btrfs_insert_inode_ref(idata->trans, idata->root,
214 dirent->name, dirent->name_len,
215 objectid, idata->objectid);
216 if (ret)
217 goto fail;
218 inode_size = btrfs_stack_inode_size(idata->inode) +
219 dirent->name_len * 2;
220 btrfs_set_stack_inode_size(idata->inode, inode_size);
221 return 0;
222 fail:
223 idata->errcode = ret;
224 return BLOCK_ABORT;
227 static int create_dir_entries(struct btrfs_trans_handle *trans,
228 struct btrfs_root *root, u64 objectid,
229 struct btrfs_inode_item *btrfs_inode,
230 ext2_filsys ext2_fs, ext2_ino_t ext2_ino)
232 int ret;
233 errcode_t err;
234 struct dir_iterate_data data = {
235 .trans = trans,
236 .root = root,
237 .inode = btrfs_inode,
238 .objectid = objectid,
239 .parent = 0,
240 .errcode = 0,
243 err = ext2fs_dir_iterate2(ext2_fs, ext2_ino, 0, NULL,
244 dir_iterate_proc, &data);
245 if (err)
246 goto error;
247 ret = data.errcode;
248 if (ret == 0 && data.parent == objectid) {
249 ret = btrfs_insert_inode_ref(trans, root, "..", 2,
250 objectid, objectid);
252 return ret;
253 error:
254 fprintf(stderr, "ext2fs_dir_iterate2: %s\n", error_message(err));
255 return -1;
258 static int read_disk_extent(struct btrfs_root *root, u64 bytenr,
259 u32 num_bytes, char *buffer)
261 int ret;
262 struct btrfs_fs_info *fs_info = root->fs_info;
264 ret = pread(fs_info->fp, buffer, num_bytes, bytenr);
265 if (ret != num_bytes)
266 goto fail;
267 ret = 0;
268 fail:
269 if (ret > 0)
270 ret = -1;
271 return ret;
274 * Record a file extent. Do all the required works, such as inserting
275 * file extent item, inserting extent item and backref item into extent
276 * tree and updating block accounting.
278 static int record_file_extent(struct btrfs_trans_handle *trans,
279 struct btrfs_root *root, u64 objectid,
280 struct btrfs_inode_item *inode,
281 u64 file_pos, u64 disk_bytenr,
282 u64 num_bytes, int checksum)
284 int ret;
285 struct btrfs_fs_info *info = root->fs_info;
286 struct btrfs_root *extent_root = info->extent_root;
287 struct btrfs_key ins_key;
288 struct btrfs_path path;
289 struct btrfs_extent_item extent_item;
290 u32 blocksize = root->sectorsize;
291 u64 nblocks;
292 u64 bytes_used;
294 ret = btrfs_insert_file_extent(trans, root, objectid, file_pos,
295 disk_bytenr, num_bytes, num_bytes);
296 if (ret || disk_bytenr == 0)
297 return ret;
299 nblocks = btrfs_stack_inode_nblocks(inode) + num_bytes / 512;
300 btrfs_set_stack_inode_nblocks(inode, nblocks);
301 if (checksum) {
302 u64 offset;
303 char *buffer;
305 ret = -ENOMEM;
306 buffer = malloc(blocksize);
307 if (!buffer)
308 goto fail;
309 for (offset = 0; offset < num_bytes; offset += blocksize) {
310 ret = read_disk_extent(root, disk_bytenr + offset,
311 blocksize, buffer);
312 if (ret)
313 break;
314 ret = btrfs_csum_file_block(trans, root, inode,
315 objectid, file_pos + offset,
316 buffer, blocksize);
317 if (ret)
318 break;
320 free(buffer);
321 if (ret)
322 goto fail;
325 bytes_used = btrfs_root_used(&root->root_item);
326 btrfs_set_root_used(&root->root_item, bytes_used + num_bytes);
327 ins_key.objectid = disk_bytenr;
328 ins_key.offset = num_bytes;
329 btrfs_set_key_type(&ins_key, BTRFS_EXTENT_ITEM_KEY);
330 btrfs_set_stack_extent_refs(&extent_item, 1);
331 ret = btrfs_insert_item(trans, extent_root, &ins_key,
332 &extent_item, sizeof(extent_item));
333 if (ret == 0) {
334 bytes_used = btrfs_super_bytes_used(&info->super_copy);
335 btrfs_set_super_bytes_used(&info->super_copy, bytes_used +
336 num_bytes);
337 btrfs_init_path(&path);
338 ret = btrfs_insert_extent_backref(trans, extent_root, &path,
339 disk_bytenr, root->root_key.objectid,
340 trans->transid, objectid, file_pos);
341 if (ret)
342 goto fail;
343 ret = btrfs_update_block_group(trans, root, disk_bytenr,
344 num_bytes, 1, 0);
345 } else if (ret == -EEXIST) {
346 ret = btrfs_inc_extent_ref(trans, root, disk_bytenr, num_bytes,
347 root->root_key.objectid,
348 trans->transid, objectid, file_pos);
350 if (ret)
351 goto fail;
352 btrfs_extent_post_op(trans, extent_root);
353 return 0;
354 fail:
355 return ret;
358 static int record_file_blocks(struct btrfs_trans_handle *trans,
359 struct btrfs_root *root, u64 objectid,
360 struct btrfs_inode_item *inode,
361 u64 file_block, u64 disk_block,
362 u64 num_blocks, int checksum)
364 u64 file_pos = file_block * root->sectorsize;
365 u64 disk_bytenr = disk_block * root->sectorsize;
366 u64 num_bytes = num_blocks * root->sectorsize;
367 return record_file_extent(trans, root, objectid, inode, file_pos,
368 disk_bytenr, num_bytes, checksum);
371 struct blk_iterate_data {
372 struct btrfs_trans_handle *trans;
373 struct btrfs_root *root;
374 struct btrfs_inode_item *inode;
375 u64 objectid;
376 u64 first_block;
377 u64 disk_block;
378 u64 num_blocks;
379 int checksum;
380 int errcode;
383 static int block_iterate_proc(ext2_filsys ext2_fs,
384 u64 disk_block, u64 file_block,
385 struct blk_iterate_data *idata)
387 int ret;
388 u32 blocksize = ext2_fs->blocksize;
389 struct btrfs_root *root = idata->root;
390 struct btrfs_trans_handle *trans = idata->trans;
392 if ((file_block > idata->first_block + idata->num_blocks) ||
393 (disk_block != idata->disk_block + idata->num_blocks) ||
394 (idata->num_blocks >= BTRFS_BLOCK_GROUP_SIZE / blocksize)) {
395 if (idata->num_blocks > 0) {
396 ret = record_file_blocks(trans, root, idata->objectid,
397 idata->inode, idata->first_block,
398 idata->disk_block, idata->num_blocks,
399 idata->checksum);
400 if (ret)
401 goto fail;
402 idata->first_block += idata->num_blocks;
403 idata->num_blocks = 0;
405 if (file_block > idata->first_block) {
406 ret = record_file_blocks(trans, root, idata->objectid,
407 idata->inode, idata->first_block,
408 0, file_block - idata->first_block,
409 idata->checksum);
410 if (ret)
411 goto fail;
413 idata->first_block = file_block;
414 idata->disk_block = disk_block;
416 idata->num_blocks++;
417 return 0;
418 fail:
419 idata->errcode = ret;
420 return BLOCK_ABORT;
423 static int __block_iterate_proc(ext2_filsys fs, blk_t *blocknr,
424 e2_blkcnt_t blockcnt, blk_t ref_block,
425 int ref_offset, void *priv_data)
427 struct blk_iterate_data *idata;
428 idata = (struct blk_iterate_data *)priv_data;
429 return block_iterate_proc(fs, *blocknr, blockcnt, idata);
433 * traverse file's data blocks, record these data blocks as file extents.
435 static int create_file_extents(struct btrfs_trans_handle *trans,
436 struct btrfs_root *root, u64 objectid,
437 struct btrfs_inode_item *btrfs_inode,
438 ext2_filsys ext2_fs, ext2_ino_t ext2_ino,
439 int datacsum, int packing)
441 int ret;
442 char *buffer = NULL;
443 errcode_t err;
444 u32 last_block;
445 u32 sectorsize = root->sectorsize;
446 u64 inode_size = btrfs_stack_inode_size(btrfs_inode);
447 struct blk_iterate_data data = {
448 .trans = trans,
449 .root = root,
450 .inode = btrfs_inode,
451 .objectid = objectid,
452 .first_block = 0,
453 .disk_block = 0,
454 .num_blocks = 0,
455 .checksum = datacsum,
456 .errcode = 0,
458 err = ext2fs_block_iterate2(ext2_fs, ext2_ino, BLOCK_FLAG_DATA_ONLY,
459 NULL, __block_iterate_proc, &data);
460 if (err)
461 goto error;
462 ret = data.errcode;
463 if (ret)
464 goto fail;
465 if (packing && data.first_block == 0 && data.num_blocks > 0 &&
466 inode_size <= BTRFS_MAX_INLINE_DATA_SIZE(root)) {
467 u64 num_bytes = data.num_blocks * sectorsize;
468 u64 disk_bytenr = data.disk_block * sectorsize;
470 buffer = malloc(num_bytes);
471 if (!buffer)
472 return -ENOMEM;
473 ret = read_disk_extent(root, disk_bytenr, num_bytes, buffer);
474 if (ret)
475 goto fail;
476 if (num_bytes > inode_size)
477 num_bytes = inode_size;
478 ret = btrfs_insert_inline_extent(trans, root, objectid,
479 0, buffer, num_bytes);
480 if (ret)
481 goto fail;
482 } else if (data.num_blocks > 0) {
483 ret = record_file_blocks(trans, root, objectid, btrfs_inode,
484 data.first_block, data.disk_block,
485 data.num_blocks, data.checksum);
486 if (ret)
487 goto fail;
489 data.first_block += data.num_blocks;
490 last_block = (inode_size + sectorsize - 1) / sectorsize;
491 if (last_block > data.first_block) {
492 ret = record_file_blocks(trans, root, objectid, btrfs_inode,
493 data.first_block, 0, last_block -
494 data.first_block, data.checksum);
496 fail:
497 if (buffer)
498 free(buffer);
499 return ret;
500 error:
501 fprintf(stderr, "ext2fs_block_iterate2: %s\n", error_message(err));
502 return -1;
505 static int create_symbol_link(struct btrfs_trans_handle *trans,
506 struct btrfs_root *root, u64 objectid,
507 struct btrfs_inode_item *btrfs_inode,
508 ext2_filsys ext2_fs, ext2_ino_t ext2_ino,
509 struct ext2_inode *ext2_inode)
511 int ret;
512 char *pathname;
513 u64 inode_size = btrfs_stack_inode_size(btrfs_inode);
514 if (ext2fs_inode_data_blocks(ext2_fs, ext2_inode)) {
515 btrfs_set_stack_inode_size(btrfs_inode, inode_size + 1);
516 ret = create_file_extents(trans, root, objectid, btrfs_inode,
517 ext2_fs, ext2_ino, 1, 1);
518 btrfs_set_stack_inode_size(btrfs_inode, inode_size);
519 return ret;
522 pathname = (char *)&(ext2_inode->i_block[0]);
523 BUG_ON(pathname[inode_size] != 0);
524 ret = btrfs_insert_inline_extent(trans, root, objectid, 0,
525 pathname, inode_size + 1);
526 return ret;
530 * Following xattr/acl related codes are based on codes in
531 * fs/ext3/xattr.c and fs/ext3/acl.c
533 #define EXT2_XATTR_BHDR(ptr) ((struct ext2_ext_attr_header *)(ptr))
534 #define EXT2_XATTR_BFIRST(ptr) \
535 ((struct ext2_ext_attr_entry *)(EXT2_XATTR_BHDR(ptr) + 1))
536 #define EXT2_XATTR_IHDR(inode) \
537 ((struct ext2_ext_attr_header *) ((void *)(inode) + \
538 EXT2_GOOD_OLD_INODE_SIZE + (inode)->i_extra_isize))
539 #define EXT2_XATTR_IFIRST(inode) \
540 ((struct ext2_ext_attr_entry *) ((void *)EXT2_XATTR_IHDR(inode) + \
541 sizeof(EXT2_XATTR_IHDR(inode)->h_magic)))
543 static int ext2_xattr_check_names(struct ext2_ext_attr_entry *entry,
544 const void *end)
546 struct ext2_ext_attr_entry *next;
548 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
549 next = EXT2_EXT_ATTR_NEXT(entry);
550 if ((void *)next >= end)
551 return -EIO;
552 entry = next;
554 return 0;
557 static int ext2_xattr_check_block(const char *buf, size_t size)
559 int error;
560 struct ext2_ext_attr_header *header = EXT2_XATTR_BHDR(buf);
562 if (header->h_magic != EXT2_EXT_ATTR_MAGIC ||
563 header->h_blocks != 1)
564 return -EIO;
565 error = ext2_xattr_check_names(EXT2_XATTR_BFIRST(buf), buf + size);
566 return error;
569 static int ext2_xattr_check_entry(struct ext2_ext_attr_entry *entry,
570 size_t size)
572 size_t value_size = entry->e_value_size;
574 if (entry->e_value_block != 0 || value_size > size ||
575 entry->e_value_offs + value_size > size)
576 return -EIO;
577 return 0;
580 #define EXT2_ACL_VERSION 0x0001
582 typedef struct {
583 __le16 e_tag;
584 __le16 e_perm;
585 __le32 e_id;
586 } ext2_acl_entry;
588 typedef struct {
589 __le16 e_tag;
590 __le16 e_perm;
591 } ext2_acl_entry_short;
593 typedef struct {
594 __le32 a_version;
595 } ext2_acl_header;
597 static inline int ext2_acl_count(size_t size)
599 ssize_t s;
600 size -= sizeof(ext2_acl_header);
601 s = size - 4 * sizeof(ext2_acl_entry_short);
602 if (s < 0) {
603 if (size % sizeof(ext2_acl_entry_short))
604 return -1;
605 return size / sizeof(ext2_acl_entry_short);
606 } else {
607 if (s % sizeof(ext2_acl_entry))
608 return -1;
609 return s / sizeof(ext2_acl_entry) + 4;
613 #define ACL_EA_VERSION 0x0002
615 typedef struct {
616 __le16 e_tag;
617 __le16 e_perm;
618 __le32 e_id;
619 } acl_ea_entry;
621 typedef struct {
622 __le32 a_version;
623 acl_ea_entry a_entries[0];
624 } acl_ea_header;
626 static inline size_t acl_ea_size(int count)
628 return sizeof(acl_ea_header) + count * sizeof(acl_ea_entry);
631 static int ext2_acl_to_xattr(void *dst, const void *src,
632 size_t dst_size, size_t src_size)
634 int i, count;
635 const void *end = src + src_size;
636 acl_ea_header *ext_acl = (acl_ea_header *)dst;
637 acl_ea_entry *dst_entry = ext_acl->a_entries;
638 ext2_acl_entry *src_entry;
640 if (src_size < sizeof(ext2_acl_header))
641 goto fail;
642 if (((ext2_acl_header *)src)->a_version !=
643 cpu_to_le32(EXT2_ACL_VERSION))
644 goto fail;
645 src += sizeof(ext2_acl_header);
646 count = ext2_acl_count(src_size);
647 if (count <= 0)
648 goto fail;
650 BUG_ON(dst_size < acl_ea_size(count));
651 ext_acl->a_version = cpu_to_le32(ACL_EA_VERSION);
652 for (i = 0; i < count; i++, dst_entry++) {
653 src_entry = (ext2_acl_entry *)src;
654 if (src + sizeof(ext2_acl_entry_short) > end)
655 goto fail;
656 dst_entry->e_tag = src_entry->e_tag;
657 dst_entry->e_perm = src_entry->e_perm;
658 switch (le16_to_cpu(src_entry->e_tag)) {
659 case ACL_USER_OBJ:
660 case ACL_GROUP_OBJ:
661 case ACL_MASK:
662 case ACL_OTHER:
663 src += sizeof(ext2_acl_entry_short);
664 dst_entry->e_id = cpu_to_le32(ACL_UNDEFINED_ID);
665 break;
666 case ACL_USER:
667 case ACL_GROUP:
668 src += sizeof(ext2_acl_entry);
669 if (src > end)
670 goto fail;
671 dst_entry->e_id = src_entry->e_id;
672 break;
673 default:
674 goto fail;
677 if (src != end)
678 goto fail;
679 return 0;
680 fail:
681 return -EINVAL;
684 static char *xattr_prefix_table[] = {
685 [1] = "user.",
686 [2] = "system.posix_acl_access",
687 [3] = "system.posix_acl_default",
688 [4] = "trusted.",
689 [6] = "security.",
692 static int copy_single_xattr(struct btrfs_trans_handle *trans,
693 struct btrfs_root *root, u64 objectid,
694 struct ext2_ext_attr_entry *entry,
695 const void *data, u32 datalen)
697 int ret = 0;
698 int name_len;
699 int name_index;
700 void *databuf = NULL;
701 char namebuf[XATTR_NAME_MAX + 1];
703 name_index = entry->e_name_index;
704 if (name_index >= ARRAY_SIZE(xattr_prefix_table) ||
705 xattr_prefix_table[name_index] == NULL)
706 return -EOPNOTSUPP;
707 name_len = strlen(xattr_prefix_table[name_index]) +
708 entry->e_name_len;
709 if (name_len >= sizeof(namebuf))
710 return -ERANGE;
712 if (name_index == 2 || name_index == 3) {
713 size_t bufsize = acl_ea_size(ext2_acl_count(datalen));
714 databuf = malloc(bufsize);
715 if (!databuf)
716 return -ENOMEM;
717 ret = ext2_acl_to_xattr(databuf, data, bufsize, datalen);
718 if (ret)
719 goto out;
720 data = databuf;
721 datalen = bufsize;
723 strcpy(namebuf, xattr_prefix_table[name_index]);
724 strncat(namebuf, EXT2_EXT_ATTR_NAME(entry), entry->e_name_len);
725 if (name_len + datalen > BTRFS_LEAF_DATA_SIZE(root) -
726 sizeof(struct btrfs_item) - sizeof(struct btrfs_dir_item)) {
727 fprintf(stderr, "skip large xattr on inode %Lu name %.*s\n",
728 objectid - INO_OFFSET, name_len, namebuf);
729 goto out;
731 ret = btrfs_insert_xattr_item(trans, root, namebuf, name_len,
732 data, datalen, objectid);
733 out:
734 if (databuf)
735 free(databuf);
736 return ret;
739 static int copy_extended_attrs(struct btrfs_trans_handle *trans,
740 struct btrfs_root *root, u64 objectid,
741 struct btrfs_inode_item *btrfs_inode,
742 ext2_filsys ext2_fs, ext2_ino_t ext2_ino)
744 int ret = 0;
745 int inline_ea = 0;
746 errcode_t err;
747 u32 datalen;
748 u32 block_size = ext2_fs->blocksize;
749 u32 inode_size = EXT2_INODE_SIZE(ext2_fs->super);
750 struct ext2_inode_large *ext2_inode;
751 struct ext2_ext_attr_entry *entry;
752 void *data;
753 char *buffer = NULL;
754 char inode_buf[EXT2_GOOD_OLD_INODE_SIZE];
756 if (inode_size <= EXT2_GOOD_OLD_INODE_SIZE) {
757 ext2_inode = (struct ext2_inode_large *)inode_buf;
758 } else {
759 ext2_inode = (struct ext2_inode_large *)malloc(inode_size);
760 if (!ext2_inode)
761 return -ENOMEM;
763 err = ext2fs_read_inode_full(ext2_fs, ext2_ino, (void *)ext2_inode,
764 inode_size);
765 if (err) {
766 fprintf(stderr, "ext2fs_read_inode_full: %s\n",
767 error_message(err));
768 ret = -1;
769 goto out;
772 if (ext2_ino > ext2_fs->super->s_first_ino &&
773 inode_size > EXT2_GOOD_OLD_INODE_SIZE) {
774 if (EXT2_GOOD_OLD_INODE_SIZE +
775 ext2_inode->i_extra_isize > inode_size) {
776 ret = -EIO;
777 goto out;
779 if (ext2_inode->i_extra_isize != 0 &&
780 EXT2_XATTR_IHDR(ext2_inode)->h_magic ==
781 EXT2_EXT_ATTR_MAGIC) {
782 inline_ea = 1;
785 if (inline_ea) {
786 int total;
787 void *end = (void *)ext2_inode + inode_size;
788 entry = EXT2_XATTR_IFIRST(ext2_inode);
789 total = end - (void *)entry;
790 ret = ext2_xattr_check_names(entry, end);
791 if (ret)
792 goto out;
793 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
794 ret = ext2_xattr_check_entry(entry, total);
795 if (ret)
796 goto out;
797 data = (void *)EXT2_XATTR_IFIRST(ext2_inode) +
798 entry->e_value_offs;
799 datalen = entry->e_value_size;
800 ret = copy_single_xattr(trans, root, objectid,
801 entry, data, datalen);
802 if (ret)
803 goto out;
804 entry = EXT2_EXT_ATTR_NEXT(entry);
808 if (ext2_inode->i_file_acl == 0)
809 goto out;
811 buffer = malloc(block_size);
812 if (!buffer) {
813 ret = -ENOMEM;
814 goto out;
816 err = ext2fs_read_ext_attr(ext2_fs, ext2_inode->i_file_acl, buffer);
817 if (err) {
818 fprintf(stderr, "ext2fs_read_ext_attr: %s\n",
819 error_message(err));
820 ret = -1;
821 goto out;
823 ret = ext2_xattr_check_block(buffer, block_size);
824 if (ret)
825 goto out;
827 entry = EXT2_XATTR_BFIRST(buffer);
828 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
829 ret = ext2_xattr_check_entry(entry, block_size);
830 if (ret)
831 goto out;
832 data = buffer + entry->e_value_offs;
833 datalen = entry->e_value_size;
834 ret = copy_single_xattr(trans, root, objectid,
835 entry, data, datalen);
836 if (ret)
837 goto out;
838 entry = EXT2_EXT_ATTR_NEXT(entry);
840 out:
841 if (buffer != NULL)
842 free(buffer);
843 if ((void *)ext2_inode != inode_buf)
844 free(ext2_inode);
845 return ret;
847 #define MINORBITS 20
848 #define MKDEV(ma, mi) (((ma) << MINORBITS) | (mi))
850 static inline dev_t old_decode_dev(u16 val)
852 return MKDEV((val >> 8) & 255, val & 255);
855 static inline dev_t new_decode_dev(u32 dev)
857 unsigned major = (dev & 0xfff00) >> 8;
858 unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
859 return MKDEV(major, minor);
862 static int copy_inode_item(struct btrfs_inode_item *dst,
863 struct ext2_inode *src)
865 btrfs_set_stack_inode_generation(dst, 1);
866 btrfs_set_stack_inode_size(dst, src->i_size);
867 btrfs_set_stack_inode_nblocks(dst, src->i_blocks);
868 btrfs_set_stack_inode_block_group(dst, 0);
869 btrfs_set_stack_inode_nblocks(dst, 0);
870 btrfs_set_stack_inode_nlink(dst, src->i_links_count);
871 btrfs_set_stack_inode_uid(dst, src->i_uid | (src->i_uid_high << 16));
872 btrfs_set_stack_inode_gid(dst, src->i_gid | (src->i_gid_high << 16));
873 btrfs_set_stack_inode_mode(dst, src->i_mode);
874 btrfs_set_stack_inode_rdev(dst, 0);
875 btrfs_set_stack_inode_flags(dst, 0);
876 btrfs_set_stack_inode_compat_flags(dst, 0);
877 btrfs_set_stack_timespec_sec(&dst->atime, src->i_atime);
878 btrfs_set_stack_timespec_nsec(&dst->atime, 0);
879 btrfs_set_stack_timespec_sec(&dst->ctime, src->i_ctime);
880 btrfs_set_stack_timespec_nsec(&dst->ctime, 0);
881 btrfs_set_stack_timespec_sec(&dst->mtime, src->i_mtime);
882 btrfs_set_stack_timespec_nsec(&dst->mtime, 0);
883 btrfs_set_stack_timespec_sec(&dst->otime, 0);
884 btrfs_set_stack_timespec_nsec(&dst->otime, 0);
886 if (S_ISDIR(src->i_mode)) {
887 btrfs_set_stack_inode_size(dst, 0);
888 btrfs_set_stack_inode_nlink(dst, 1);
890 if (!S_ISREG(src->i_mode) && !S_ISDIR(src->i_mode) &&
891 !S_ISLNK(src->i_mode)) {
892 if (src->i_block[0]) {
893 btrfs_set_stack_inode_rdev(dst,
894 old_decode_dev(src->i_block[0]));
895 } else {
896 btrfs_set_stack_inode_rdev(dst,
897 new_decode_dev(src->i_block[1]));
900 return 0;
904 * copy a single inode. do all the required works, such as cloning
905 * inode item, creating file extents and creating directory entries.
907 static int copy_single_inode(struct btrfs_trans_handle *trans,
908 struct btrfs_root *root, u64 objectid,
909 ext2_filsys ext2_fs, ext2_ino_t ext2_ino,
910 int datacsum, int packing, int noxattr)
912 int ret;
913 errcode_t err;
914 struct ext2_inode ext2_inode;
915 struct btrfs_key inode_key;
916 struct btrfs_inode_item btrfs_inode;
918 err = ext2fs_read_inode(ext2_fs, ext2_ino, &ext2_inode);
919 if (err)
920 goto error;
922 if (!ext2_inode.i_links_count &&
923 (!ext2_inode.i_mode || ext2_inode.i_dtime)) {
924 printf("skip inode %u\n", ext2_ino);
925 return 0;
927 copy_inode_item(&btrfs_inode, &ext2_inode);
928 if (!datacsum && S_ISREG(ext2_inode.i_mode)) {
929 u32 flags = btrfs_stack_inode_flags(&btrfs_inode) |
930 BTRFS_INODE_NODATASUM;
931 btrfs_set_stack_inode_flags(&btrfs_inode, flags);
934 switch (ext2_inode.i_mode & S_IFMT) {
935 case S_IFREG:
936 ret = create_file_extents(trans, root, objectid, &btrfs_inode,
937 ext2_fs, ext2_ino, datacsum, packing);
938 break;
939 case S_IFDIR:
940 ret = create_dir_entries(trans, root, objectid, &btrfs_inode,
941 ext2_fs, ext2_ino);
942 break;
943 case S_IFLNK:
944 ret = create_symbol_link(trans, root, objectid, &btrfs_inode,
945 ext2_fs, ext2_ino, &ext2_inode);
946 break;
947 default:
948 ret = 0;
949 break;
951 if (ret)
952 return ret;
954 if (!noxattr) {
955 ret = copy_extended_attrs(trans, root, objectid, &btrfs_inode,
956 ext2_fs, ext2_ino);
957 if (ret)
958 return ret;
960 inode_key.objectid = objectid;
961 inode_key.offset = 0;
962 btrfs_set_key_type(&inode_key, BTRFS_INODE_ITEM_KEY);
963 ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
964 return ret;
965 error:
966 fprintf(stderr, "ext2fs_read_inode: %s\n", error_message(err));
967 return -1;
970 static int copy_disk_extent(struct btrfs_root *root, u64 dst_bytenr,
971 u64 src_bytenr, u32 num_bytes)
973 int ret;
974 char *buffer;
975 struct btrfs_fs_info *fs_info = root->fs_info;
977 buffer = malloc(num_bytes);
978 if (!buffer)
979 return -ENOMEM;
980 ret = pread(fs_info->fp, buffer, num_bytes, src_bytenr);
981 if (ret != num_bytes)
982 goto fail;
983 ret = pwrite(fs_info->fp, buffer, num_bytes, dst_bytenr);
984 if (ret != num_bytes)
985 goto fail;
986 ret = 0;
987 fail:
988 free(buffer);
989 if (ret > 0)
990 ret = -1;
991 return ret;
994 * scan ext2's inode bitmap and copy all used inode.
996 static int copy_inodes(struct btrfs_root *root, ext2_filsys ext2_fs,
997 int datacsum, int packing, int noxattr)
999 int ret;
1000 ext2_ino_t ext2_ino;
1001 u64 objectid;
1002 struct btrfs_trans_handle *trans;
1004 trans = btrfs_start_transaction(root, 1);
1005 if (!trans)
1006 return -ENOMEM;
1007 ext2_ino = ext2_fs->inode_map->start;
1008 for (; ext2_ino <= ext2_fs->inode_map->end; ext2_ino++) {
1009 if (ext2fs_fast_test_inode_bitmap(ext2_fs->inode_map,
1010 ext2_ino)) {
1011 /* skip special inode in ext2fs */
1012 if (ext2_ino < EXT2_GOOD_OLD_FIRST_INO &&
1013 ext2_ino != EXT2_ROOT_INO)
1014 continue;
1015 objectid = ext2_ino + INO_OFFSET;
1016 ret = copy_single_inode(trans, root,
1017 objectid, ext2_fs, ext2_ino,
1018 datacsum, packing, noxattr);
1019 if (ret)
1020 return ret;
1022 if (trans->blocks_used >= 8192) {
1023 ret = btrfs_commit_transaction(trans, root);
1024 BUG_ON(ret);
1025 trans = btrfs_start_transaction(root, 1);
1026 BUG_ON(!trans);
1029 ret = btrfs_commit_transaction(trans, root);
1030 BUG_ON(ret);
1032 return ret;
1034 static int lookup_extent_item(struct btrfs_trans_handle *trans,
1035 struct btrfs_root *root,
1036 u64 bytenr, u64 num_bytes)
1038 int ret;
1039 struct btrfs_key key;
1040 struct btrfs_path path;
1041 btrfs_init_path(&path);
1042 key.objectid = bytenr;
1043 key.offset = num_bytes;
1044 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
1045 ret = btrfs_search_slot(trans, root->fs_info->extent_root,
1046 &key, &path, 0, 0);
1047 btrfs_release_path(root, &path);
1048 return ret;
1051 * Construct a range of ext2fs image file.
1052 * scan block allocation bitmap, find all blocks used by the ext2fs
1053 * in this range and create file extents that point to these blocks.
1055 * Note: Before calling the function, no file extent points to blocks
1056 * in this range
1058 static int create_image_file_range(struct btrfs_trans_handle *trans,
1059 struct btrfs_root *root, u64 objectid,
1060 struct btrfs_inode_item *inode,
1061 u64 start_byte, u64 end_byte,
1062 ext2_filsys ext2_fs)
1064 u64 bytenr;
1065 u32 blocksize = ext2_fs->blocksize;
1066 u32 block = start_byte / blocksize;
1067 u32 last_block = (end_byte + blocksize - 1) / blocksize;
1068 int ret;
1069 struct blk_iterate_data data = {
1070 .trans = trans,
1071 .root = root,
1072 .inode = inode,
1073 .objectid = objectid,
1074 .first_block = block,
1075 .disk_block = block,
1076 .num_blocks = 0,
1077 .checksum = 0,
1078 .errcode = 0,
1080 for (; start_byte < end_byte; block++, start_byte += blocksize) {
1081 if (!ext2fs_fast_test_block_bitmap(ext2_fs->block_map, block))
1082 continue;
1083 /* the bit may be set by us, check extent tree */
1084 bytenr = (u64)block * blocksize;
1085 ret = lookup_extent_item(trans, root, bytenr, blocksize);
1086 if (ret < 0)
1087 goto fail;
1088 if (ret == 0)
1089 continue;
1091 ret = block_iterate_proc(ext2_fs, block, block, &data);
1092 if (ret & BLOCK_ABORT)
1093 break;
1095 ret = data.errcode;
1096 if (ret)
1097 return ret;
1098 if (data.num_blocks > 0) {
1099 ret = record_file_blocks(trans, root, objectid, inode,
1100 data.first_block, data.disk_block,
1101 data.num_blocks, 0);
1102 if (ret)
1103 return ret;
1104 data.first_block += data.num_blocks;
1106 if (last_block > data.first_block) {
1107 ret = record_file_blocks(trans, root, objectid, inode,
1108 data.first_block, 0, last_block -
1109 data.first_block, 0);
1110 if (ret)
1111 return ret;
1113 fail:
1114 return 0;
1117 * Create the ext2fs image file.
1119 static int create_ext2_image(struct btrfs_root *root, ext2_filsys ext2_fs,
1120 const char *name)
1122 int ret;
1123 struct btrfs_key key;
1124 struct btrfs_key location;
1125 struct btrfs_path path;
1126 struct btrfs_inode_item btrfs_inode;
1127 struct btrfs_inode_item *inode_item;
1128 struct extent_buffer *leaf;
1129 struct btrfs_fs_info *fs_info = root->fs_info;
1130 struct btrfs_root *extent_root = fs_info->extent_root;
1131 struct btrfs_trans_handle *trans;
1132 struct btrfs_extent_ref *ref_item;
1133 u64 bytenr;
1134 u64 num_bytes;
1135 u64 ref_root;
1136 u64 ref_owner;
1137 u64 objectid;
1138 u64 new_block;
1139 u64 last_byte;
1140 u64 first_free;
1141 u64 total_bytes;
1142 u32 sectorsize = root->sectorsize;
1143 int slot;
1144 int file_extent;
1146 total_bytes = btrfs_super_total_bytes(&fs_info->super_copy);
1147 first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1;
1148 first_free &= ~((u64)sectorsize - 1);
1150 memset(&btrfs_inode, 0, sizeof(btrfs_inode));
1151 btrfs_set_stack_inode_generation(&btrfs_inode, 1);
1152 btrfs_set_stack_inode_size(&btrfs_inode, total_bytes);
1153 btrfs_set_stack_inode_nlink(&btrfs_inode, 1);
1154 btrfs_set_stack_inode_nblocks(&btrfs_inode, 0);
1155 btrfs_set_stack_inode_mode(&btrfs_inode, S_IFREG | 0400);
1156 btrfs_set_stack_inode_flags(&btrfs_inode, BTRFS_INODE_NODATASUM |
1157 BTRFS_INODE_READONLY);
1158 btrfs_init_path(&path);
1159 trans = btrfs_start_transaction(root, 1);
1160 BUG_ON(!trans);
1162 objectid = btrfs_root_dirid(&root->root_item);
1163 ret = btrfs_find_free_objectid(trans, root, objectid, &objectid);
1164 if (ret)
1165 goto fail;
1168 * copy the first a few blocks to new positions. the relocation is
1169 * reuqired for block 0 and default btrfs super block.
1171 for (last_byte = 0; last_byte < first_free; last_byte += sectorsize) {
1172 ret = ext2_alloc_block(ext2_fs, 0, &new_block);
1173 if (ret)
1174 goto fail;
1175 new_block *= sectorsize;
1176 ret = copy_disk_extent(root, new_block, last_byte, sectorsize);
1177 if (ret)
1178 goto fail;
1179 ret = record_file_extent(trans, root, objectid,
1180 &btrfs_inode, last_byte,
1181 new_block, sectorsize, 0);
1182 if (ret)
1183 goto fail;
1185 again:
1186 if (trans->blocks_used >= 8192) {
1187 ret = btrfs_commit_transaction(trans, root);
1188 BUG_ON(ret);
1189 trans = btrfs_start_transaction(root, 1);
1190 BUG_ON(!trans);
1193 key.objectid = last_byte;
1194 key.offset = 0;
1195 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
1196 ret = btrfs_search_slot(trans, fs_info->extent_root,
1197 &key, &path, 0, 0);
1198 if (ret < 0)
1199 goto fail;
1201 leaf = path.nodes[0];
1202 slot = path.slots[0];
1203 while(1) {
1204 if (slot >= btrfs_header_nritems(leaf)) {
1205 ret = btrfs_next_leaf(extent_root, &path);
1206 if (ret < 0)
1207 goto fail;
1208 if (ret > 0)
1209 break;
1210 leaf = path.nodes[0];
1211 slot = path.slots[0];
1213 btrfs_item_key_to_cpu(leaf, &key, slot);
1214 if (last_byte > key.objectid ||
1215 key.type != BTRFS_EXTENT_ITEM_KEY) {
1216 slot++;
1217 continue;
1220 * Check backref to distinguish extent items for normal
1221 * files (files that correspond to files in Ext2fs) from
1222 * extent items for ctree blocks.
1224 bytenr = key.objectid;
1225 num_bytes = key.offset;
1226 file_extent = 0;
1227 while (1) {
1228 if (slot >= btrfs_header_nritems(leaf)) {
1229 ret = btrfs_next_leaf(extent_root, &path);
1230 if (ret > 0)
1231 break;
1232 if (ret < 0)
1233 goto fail;
1234 leaf = path.nodes[0];
1235 slot = path.slots[0];
1237 btrfs_item_key_to_cpu(leaf, &key, slot);
1238 if (key.objectid != bytenr)
1239 break;
1240 if (key.type != BTRFS_EXTENT_REF_KEY) {
1241 slot++;
1242 continue;
1244 ref_item = btrfs_item_ptr(leaf, slot,
1245 struct btrfs_extent_ref);
1246 ref_root = btrfs_ref_root(leaf, ref_item);
1247 ref_owner = btrfs_ref_objectid(leaf, ref_item);
1248 if ((ref_root == BTRFS_FS_TREE_OBJECTID) &&
1249 (ref_owner >= BTRFS_FIRST_FREE_OBJECTID)) {
1250 file_extent = 1;
1251 break;
1253 slot++;
1255 if (!file_extent)
1256 continue;
1258 if (bytenr > last_byte) {
1259 ret = create_image_file_range(trans, root, objectid,
1260 &btrfs_inode, last_byte,
1261 bytenr, ext2_fs);
1262 if (ret)
1263 goto fail;
1265 ret = record_file_extent(trans, root, objectid, &btrfs_inode,
1266 bytenr, bytenr, num_bytes, 0);
1267 if (ret)
1268 goto fail;
1269 last_byte = bytenr + num_bytes;
1270 btrfs_release_path(root, &path);
1271 goto again;
1273 btrfs_release_path(root, &path);
1274 if (total_bytes > last_byte) {
1275 ret = create_image_file_range(trans, root, objectid,
1276 &btrfs_inode, last_byte,
1277 total_bytes, ext2_fs);
1278 if (ret)
1279 goto fail;
1282 * otime isn't used currently, so we can store some data in it.
1283 * These data are used by do_rollback to check whether the image
1284 * file has been modified.
1286 btrfs_set_stack_timespec_sec(&btrfs_inode.otime, trans->transid);
1287 btrfs_set_stack_timespec_nsec(&btrfs_inode.otime,
1288 total_bytes / sectorsize);
1289 ret = btrfs_insert_inode(trans, root, objectid, &btrfs_inode);
1290 if (ret)
1291 goto fail;
1293 location.objectid = objectid;
1294 location.offset = 0;
1295 btrfs_set_key_type(&location, BTRFS_INODE_ITEM_KEY);
1296 ret = btrfs_insert_dir_item(trans, root, name, strlen(name),
1297 btrfs_root_dirid(&root->root_item),
1298 &location, EXT2_FT_REG_FILE);
1299 if (ret)
1300 goto fail;
1301 ret = btrfs_insert_inode_ref(trans, root, name, strlen(name),
1302 objectid,
1303 btrfs_root_dirid(&root->root_item));
1304 if (ret)
1305 goto fail;
1306 location.objectid = btrfs_root_dirid(&root->root_item);
1307 location.offset = 0;
1308 btrfs_set_key_type(&location, BTRFS_INODE_ITEM_KEY);
1309 ret = btrfs_lookup_inode(trans, root, &path, &location, 1);
1310 if (ret)
1311 goto fail;
1312 leaf = path.nodes[0];
1313 inode_item = btrfs_item_ptr(leaf, path.slots[0],
1314 struct btrfs_inode_item);
1315 btrfs_set_inode_size(leaf, inode_item, strlen(name) * 2 +
1316 btrfs_inode_size(leaf, inode_item));
1317 btrfs_mark_buffer_dirty(leaf);
1318 btrfs_release_path(root, &path);
1319 ret = btrfs_commit_transaction(trans, root);
1320 BUG_ON(ret);
1321 fail:
1322 btrfs_release_path(root, &path);
1323 return ret;
1325 struct btrfs_root *create_subvol(struct btrfs_root *root, const char *name)
1327 int ret;
1328 u64 objectid;
1329 struct btrfs_key location;
1330 struct btrfs_root_item root_item;
1331 struct btrfs_trans_handle *trans;
1332 struct btrfs_fs_info *fs_info = root->fs_info;
1333 struct btrfs_root *tree_root = fs_info->tree_root;
1334 struct btrfs_root *new_root;
1335 struct extent_buffer *tmp;
1337 trans = btrfs_start_transaction(root, 1);
1338 BUG_ON(!trans);
1340 objectid = btrfs_super_root_dir(&fs_info->super_copy);
1341 ret = btrfs_find_free_objectid(trans, root, objectid, &objectid);
1342 if (ret)
1343 goto fail;
1344 ret = btrfs_copy_root(trans, root, root->node, &tmp, objectid);
1345 if (ret)
1346 goto fail;
1347 memcpy(&root_item, &root->root_item, sizeof(root_item));
1348 btrfs_set_root_bytenr(&root_item, tmp->start);
1349 btrfs_set_root_level(&root_item, btrfs_header_level(tmp));
1350 free_extent_buffer(tmp);
1352 location.objectid = objectid;
1353 location.offset = 1;
1354 btrfs_set_key_type(&location, BTRFS_ROOT_ITEM_KEY);
1355 ret = btrfs_insert_root(trans, root->fs_info->tree_root,
1356 &location, &root_item);
1357 if (ret)
1358 goto fail;
1359 location.offset = (u64)-1;
1360 ret = btrfs_insert_dir_item(trans, tree_root, name, strlen(name),
1361 btrfs_super_root_dir(&fs_info->super_copy),
1362 &location, BTRFS_FT_DIR);
1363 if (ret)
1364 goto fail;
1365 ret = btrfs_insert_inode_ref(trans, tree_root, name, strlen(name),
1366 objectid,
1367 btrfs_super_root_dir(&fs_info->super_copy));
1368 if (ret)
1369 goto fail;
1370 ret = btrfs_commit_transaction(trans, root);
1371 BUG_ON(ret);
1372 new_root = btrfs_read_fs_root(fs_info, &location);
1373 if (!new_root || IS_ERR(new_root))
1374 goto fail;
1375 trans = btrfs_start_transaction(new_root, 1);
1376 BUG_ON(!trans);
1377 ret = btrfs_make_root_dir(trans, new_root, BTRFS_FIRST_FREE_OBJECTID);
1378 if (ret)
1379 goto fail;
1380 ret = btrfs_commit_transaction(trans, new_root);
1381 BUG_ON(ret);
1382 return new_root;
1383 fail:
1384 return NULL;
1387 * Fixup block accounting. The initial block accounting created by
1388 * make_block_groups isn't accuracy in this case.
1390 static int fixup_block_accounting(struct btrfs_trans_handle *trans,
1391 struct btrfs_root *root)
1393 int ret;
1394 int slot;
1395 u64 start = 0;
1396 u64 bytes_used = 0;
1397 struct btrfs_path path;
1398 struct btrfs_key key;
1399 struct extent_buffer *leaf;
1400 struct btrfs_block_group_cache *cache;
1401 struct btrfs_fs_info *fs_info = root->fs_info;
1403 while(1) {
1404 cache = btrfs_lookup_block_group(fs_info, start);
1405 if (!cache)
1406 break;
1407 start = cache->key.objectid + cache->key.offset;
1408 btrfs_set_block_group_used(&cache->item, 0);
1411 btrfs_init_path(&path);
1412 key.offset = 0;
1413 key.objectid = 0;
1414 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
1415 ret = btrfs_search_slot(trans, root->fs_info->extent_root,
1416 &key, &path, 0, 0);
1417 if (ret < 0)
1418 return ret;
1419 while(1) {
1420 leaf = path.nodes[0];
1421 slot = path.slots[0];
1422 if (slot >= btrfs_header_nritems(leaf)) {
1423 ret = btrfs_next_leaf(root, &path);
1424 if (ret < 0)
1425 return ret;
1426 if (ret > 0)
1427 break;
1428 leaf = path.nodes[0];
1429 slot = path.slots[0];
1431 btrfs_item_key_to_cpu(leaf, &key, slot);
1432 if (key.type == BTRFS_EXTENT_ITEM_KEY) {
1433 bytes_used += key.offset;
1434 ret = btrfs_update_block_group(trans, root,
1435 key.objectid, key.offset, 1, 0);
1436 BUG_ON(ret);
1438 path.slots[0]++;
1440 btrfs_set_super_bytes_used(&root->fs_info->super_copy, bytes_used);
1441 btrfs_release_path(root, &path);
1442 return 0;
1445 static int init_btrfs(struct btrfs_root *root)
1447 int ret;
1448 struct btrfs_key location;
1449 struct btrfs_trans_handle *trans;
1450 struct btrfs_fs_info *fs_info = root->fs_info;
1452 trans = btrfs_start_transaction(root, 1);
1453 BUG_ON(!trans);
1454 ret = btrfs_make_block_groups(trans, root);
1455 if (ret)
1456 goto err;
1457 ret = fixup_block_accounting(trans, root);
1458 if (ret)
1459 goto err;
1460 ret = btrfs_make_root_dir(trans, fs_info->tree_root,
1461 BTRFS_ROOT_TREE_DIR_OBJECTID);
1462 if (ret)
1463 goto err;
1464 memcpy(&location, &root->root_key, sizeof(location));
1465 location.offset = (u64)-1;
1466 ret = btrfs_insert_dir_item(trans, fs_info->tree_root, "default", 7,
1467 btrfs_super_root_dir(&fs_info->super_copy),
1468 &location, BTRFS_FT_DIR);
1469 if (ret)
1470 goto err;
1471 ret = btrfs_insert_inode_ref(trans, fs_info->tree_root, "default", 7,
1472 location.objectid,
1473 btrfs_super_root_dir(&fs_info->super_copy));
1474 if (ret)
1475 goto err;
1476 btrfs_set_root_dirid(&fs_info->fs_root->root_item,
1477 BTRFS_FIRST_FREE_OBJECTID);
1478 ret = btrfs_commit_transaction(trans, root);
1479 BUG_ON(ret);
1480 err:
1481 return ret;
1484 * Migrate super block to it's default position and zero 0 ~ 16k
1486 static int migrate_super_block(int fd, u64 old_bytenr, u32 sectorsize)
1488 int ret;
1489 char *buf;
1490 u64 bytenr;
1491 u32 crc = ~(u32)0;
1492 u32 len = 512 - BTRFS_CSUM_SIZE;
1493 struct btrfs_super_block *super;
1495 ret = fsync(fd);
1496 if (ret)
1497 goto fail;
1499 BUG_ON(sectorsize < sizeof(super));
1500 buf = malloc(sectorsize);
1501 if (!buf)
1502 return -ENOMEM;
1503 ret = pread(fd, buf, sectorsize, old_bytenr);
1504 if (ret != sectorsize)
1505 goto fail;
1507 super = (struct btrfs_super_block *)buf;
1508 BUG_ON(btrfs_super_bytenr(super) != old_bytenr);
1509 btrfs_set_super_bytenr(super, BTRFS_SUPER_INFO_OFFSET);
1511 crc = crc32c(crc, buf + BTRFS_CSUM_SIZE, len);
1512 crc = ~cpu_to_le32(crc);
1513 memcpy(super->csum, &crc, BTRFS_CRC32_SIZE);
1515 ret = pwrite(fd, buf, sectorsize, BTRFS_SUPER_INFO_OFFSET);
1516 if (ret < 0)
1517 goto fail;
1518 /* How to handle this case? */
1519 BUG_ON(ret != sectorsize);
1521 ret = fsync(fd);
1522 if (ret)
1523 goto fail;
1525 memset(buf, 0, sectorsize);
1526 for (bytenr = 0; bytenr < BTRFS_SUPER_INFO_OFFSET; ) {
1527 len = BTRFS_SUPER_INFO_OFFSET - bytenr;
1528 if (len > sectorsize)
1529 len = sectorsize;
1530 ret = pwrite(fd, buf, len, bytenr);
1531 if (ret != len) {
1532 fprintf(stderr, "unable to zero fill device\n");
1533 break;
1535 bytenr += len;
1537 ret = 0;
1538 fsync(fd);
1539 fail:
1540 free(buf);
1541 if (ret > 0)
1542 ret = -1;
1543 return ret;
1546 int do_convert(const char *devname, int datacsum, int packing, int noxattr)
1548 int i, fd, ret;
1549 u32 blocksize;
1550 u64 blocks[6];
1551 u64 total_bytes;
1552 u64 super_bytenr;
1553 ext2_filsys ext2_fs;
1554 struct btrfs_root *root;
1555 struct btrfs_root *ext2_root;
1557 ret = open_ext2fs(devname, &ext2_fs);
1558 if (ret) {
1559 fprintf(stderr, "unable to open the Ext2fs\n");
1560 goto fail;
1562 blocksize = ext2_fs->blocksize;
1563 total_bytes = (u64)ext2_fs->super->s_blocks_count * blocksize;
1564 if (blocksize < 4096) {
1565 fprintf(stderr, "block size is too small\n");
1566 goto fail;
1568 if (!(ext2_fs->super->s_feature_incompat &
1569 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
1570 fprintf(stderr, "filetype feature is missing\n");
1571 goto fail;
1573 for (i = 0; i < 4; i++) {
1574 ret = ext2_alloc_block(ext2_fs, 0, blocks + i);
1575 if (ret) {
1576 fprintf(stderr, "not enough free space\n");
1577 goto fail;
1579 blocks[i] *= blocksize;
1581 super_bytenr = blocks[0];
1582 fd = open(devname, O_RDWR);
1583 if (fd < 0) {
1584 fprintf(stderr, "unable to open %s\n", devname);
1585 goto fail;
1587 ret = make_btrfs(fd, blocks, total_bytes, blocksize,
1588 blocksize, blocksize, blocksize);
1589 if (ret) {
1590 fprintf(stderr, "unable to create initial ctree\n");
1591 goto fail;
1593 root = open_ctree_fd(fd, super_bytenr);
1594 if (!root) {
1595 fprintf(stderr, "unable to open ctree\n");
1596 goto fail;
1598 fd = dup(fd);
1599 if (fd < 0) {
1600 fprintf(stderr, "unable to duplicate file descriptor\n");
1601 goto fail;
1603 root->fs_info->priv_data = ext2_fs;
1604 root->fs_info->extent_ops = &extent_ops;
1605 ret = init_btrfs(root);
1606 if (ret) {
1607 fprintf(stderr, "unable to setup the root tree\n");
1608 goto fail;
1610 ext2_root = create_subvol(root, "ext2_saved");
1611 if (!ext2_root) {
1612 fprintf(stderr, "unable to create subvol\n");
1613 goto fail;
1615 printf("creating btrfs metadata.\n");
1616 ret = copy_inodes(root, ext2_fs, datacsum, packing, noxattr);
1617 if (ret) {
1618 fprintf(stderr, "error during copy_inodes %d\n", ret);
1619 goto fail;
1621 printf("creating ext2fs image file.\n");
1622 ret = create_ext2_image(ext2_root, ext2_fs, "image");
1623 if (ret) {
1624 fprintf(stderr, "error during create_ext2_image %d\n", ret);
1625 goto fail;
1627 btrfs_free_fs_root(ext2_root->fs_info, ext2_root);
1628 ret = close_ctree(root);
1629 if (ret) {
1630 fprintf(stderr, "error during close_ctree %d\n", ret);
1631 goto fail;
1633 close_ext2fs(ext2_fs);
1635 /* finally migrate super block to its default postion */
1636 ret = migrate_super_block(fd, super_bytenr, blocksize);
1637 if (ret) {
1638 fprintf(stderr, "unable to migrate super block\n");
1639 goto fail;
1641 close(fd);
1642 printf("conversion complete.\n");
1643 return 0;
1644 fail:
1645 fprintf(stderr, "conversion aborted.\n");
1646 return -1;
1649 int do_rollback(const char *devname, int force)
1651 int fd;
1652 int ret;
1653 int modified = 0;
1654 struct btrfs_root *root;
1655 struct btrfs_root *ext2_root;
1656 struct btrfs_dir_item *dir;
1657 struct btrfs_inode_item *inode;
1658 struct btrfs_file_extent_item *fi;
1659 struct btrfs_timespec *tspec;
1660 struct extent_buffer *leaf;
1661 struct btrfs_key key;
1662 struct btrfs_path path;
1663 char *buf;
1664 char *name;
1665 u64 bytenr;
1666 u64 num_bytes;
1667 u64 root_dir;
1668 u64 objectid;
1669 u64 offset;
1670 u64 first_free;
1671 u64 last_trans;
1672 u64 total_bytes;
1674 fd = open(devname, O_RDWR);
1675 if (fd < 0) {
1676 fprintf(stderr, "unable to open %s\n", devname);
1677 goto fail;
1679 root = open_ctree_fd(fd, 0);
1680 if (!root) {
1681 fprintf(stderr, "unable to open ctree\n");
1682 goto fail;
1684 fd = dup(fd);
1685 if (fd < 0) {
1686 fprintf(stderr, "unable to duplicate file descriptor\n");
1687 goto fail;
1690 first_free = BTRFS_SUPER_INFO_OFFSET + root->sectorsize * 2 - 1;
1691 first_free &= ~((u64)root->sectorsize - 1);
1692 buf = malloc(first_free);
1693 if (!buf) {
1694 fprintf(stderr, "unable to allocate memory\n");
1695 goto fail;
1698 btrfs_init_path(&path);
1699 name = "ext2_saved";
1700 root_dir = btrfs_super_root_dir(&root->fs_info->super_copy);
1701 dir = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, &path,
1702 root_dir, name, strlen(name), 0);
1703 if (!dir || IS_ERR(dir)) {
1704 fprintf(stderr, "unable to find subvol %s\n", name);
1705 goto fail;
1707 leaf = path.nodes[0];
1708 btrfs_dir_item_key_to_cpu(leaf, dir, &key);
1709 btrfs_release_path(root->fs_info->tree_root, &path);
1711 ext2_root = btrfs_read_fs_root(root->fs_info, &key);
1712 if (!ext2_root || IS_ERR(ext2_root)) {
1713 fprintf(stderr, "unable to open subvol %s\n", name);
1714 goto fail;
1717 name = "image";
1718 root_dir = btrfs_root_dirid(&root->root_item);
1719 dir = btrfs_lookup_dir_item(NULL, ext2_root, &path,
1720 root_dir, name, strlen(name), 0);
1721 if (!dir || IS_ERR(dir)) {
1722 fprintf(stderr, "unable to find file %s\n", name);
1723 goto fail;
1725 leaf = path.nodes[0];
1726 btrfs_dir_item_key_to_cpu(leaf, dir, &key);
1727 btrfs_release_path(ext2_root, &path);
1729 objectid = key.objectid;
1731 ret = btrfs_lookup_inode(NULL, ext2_root, &path, &key, 0);
1732 if (ret) {
1733 fprintf(stderr, "unable to find inode item\n");
1734 goto fail;
1736 leaf = path.nodes[0];
1737 inode = btrfs_item_ptr(leaf, path.slots[0], struct btrfs_inode_item);
1738 tspec = btrfs_inode_otime(inode);
1740 * get image file size and transaction id stored in 'otime' field.
1741 * see comments in create_ext2_image.
1743 last_trans = btrfs_timespec_sec(leaf, tspec);
1744 total_bytes = btrfs_timespec_nsec(leaf, tspec);
1745 total_bytes *= root->sectorsize;
1746 btrfs_release_path(ext2_root, &path);
1747 if (total_bytes < first_free ||
1748 total_bytes != btrfs_inode_size(leaf, inode)) {
1749 fprintf(stderr, "image file size mismatch\n");
1750 goto fail;
1753 key.objectid = objectid;
1754 key.offset = 0;
1755 btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY);
1756 ret = btrfs_search_slot(NULL, ext2_root, &key, &path, 0, 0);
1757 if (ret != 0) {
1758 fprintf(stderr, "unable to find first file extent\n");
1759 btrfs_release_path(ext2_root, &path);
1760 goto fail;
1762 for (offset = 0; offset < total_bytes; ) {
1763 leaf = path.nodes[0];
1764 if (path.slots[0] >= btrfs_header_nritems(leaf)) {
1765 ret = btrfs_next_leaf(root, &path);
1766 if (ret != 0)
1767 break;
1768 continue;
1771 btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
1772 if (key.objectid != objectid || key.offset != offset ||
1773 btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
1774 break;
1776 fi = btrfs_item_ptr(leaf, path.slots[0],
1777 struct btrfs_file_extent_item);
1778 if (btrfs_file_extent_generation(leaf, fi) > last_trans) {
1779 modified = 1;
1780 break;
1782 if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG)
1783 break;
1785 if (offset >= first_free)
1786 goto next;
1788 bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
1789 if (bytenr == 0)
1790 break;
1791 bytenr += btrfs_file_extent_offset(leaf, fi);
1792 num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
1793 if (num_bytes > first_free - offset)
1794 num_bytes = first_free - offset;
1796 ret = pread(fd, buf + offset, num_bytes, bytenr);
1797 if (ret != num_bytes) {
1798 fprintf(stderr, "unable to read required data\n");
1799 btrfs_release_path(ext2_root, &path);
1800 goto fail;
1802 next:
1803 offset += btrfs_file_extent_num_bytes(leaf, fi);
1804 path.slots[0]++;
1806 btrfs_release_path(ext2_root, &path);
1808 if (modified) {
1809 fprintf(stderr, "image file has been modified\n");
1810 goto fail;
1812 if (offset < total_bytes) {
1813 fprintf(stderr, "unable to check all file extents\n");
1814 goto fail;
1817 btrfs_free_fs_root(ext2_root->fs_info, ext2_root);
1818 ret = close_ctree(root);
1819 if (ret) {
1820 fprintf(stderr, "error during close_ctree %d\n", ret);
1821 goto fail;
1824 ret = pwrite(fd, buf, first_free, 0);
1825 if (ret < 0) {
1826 fprintf(stderr, "error during pwrite %d\n", ret);
1827 goto fail;
1829 /* How to handle this case? */
1830 BUG_ON(ret != first_free);
1831 ret = fsync(fd);
1832 if (ret) {
1833 fprintf(stderr, "error during fsync %d\n", ret);
1834 goto fail;
1836 close(fd);
1837 free(buf);
1838 printf("rollback complete.\n");
1839 return 0;
1840 fail:
1841 fprintf(stderr, "rollback aborted.\n");
1842 return -1;
1845 static void check_mounted(const char *name)
1847 int mnt_flags;
1848 errcode_t ret;
1850 ret = ext2fs_check_if_mounted(name, &mnt_flags);
1851 if (ret) {
1852 fprintf(stderr, "ext2fs_check_if_mounted: %s\n",
1853 error_message(ret));
1854 exit(1);
1856 if (mnt_flags & EXT2_MF_MOUNTED) {
1857 fprintf(stderr, "%s is mounted\n", name);
1858 exit(1);
1862 static void print_usage(void)
1864 printf("usage: btrfs-convert [-d] [-i] [-n] [-r] device\n");
1865 printf("\t-d disable data checksum\n");
1866 printf("\t-i ignore xattrs and ACLs\n");
1867 printf("\t-n disable packing of small files\n");
1868 printf("\t-r roll back to ext2fs\n");
1869 exit(1);
1872 int main(int argc, char *argv[])
1874 int ret;
1875 int packing = 1;
1876 int noxattr = 0;
1877 int datacsum = 1;
1878 int rollback = 0;
1879 char *file;
1880 while(1) {
1881 int c = getopt(argc, argv, "dinr");
1882 if (c < 0)
1883 break;
1884 switch(c) {
1885 case 'd':
1886 datacsum = 0;
1887 break;
1888 case 'i':
1889 noxattr = 1;
1890 break;
1891 case 'n':
1892 packing = 0;
1893 break;
1894 case 'r':
1895 rollback = 1;
1896 break;
1897 default:
1898 print_usage();
1901 argc = argc - optind;
1902 if (argc == 1) {
1903 file = argv[optind];
1904 check_mounted(file);
1905 } else {
1906 print_usage();
1908 if (rollback) {
1909 ret = do_rollback(file, 0);
1910 } else {
1911 ret = do_convert(file, datacsum, packing, noxattr);
1913 if (ret)
1914 return 1;
1915 return 0;