2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public
4 * License v2 as published by the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * General Public License for more details.
11 * You should have received a copy of the GNU General Public
12 * License along with this program; if not, write to the
13 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14 * Boston, MA 021110-1307, USA.
17 #if BTRFSCONVERT_REISERFS
19 #include "kerncompat.h"
20 #include <linux/limits.h>
26 #include "transaction.h"
29 #include "convert/common.h"
30 #include "convert/source-reiserfs.h"
32 static inline u8
mode_to_file_type(u32 mode
)
34 switch (mode
& S_IFMT
) {
35 case S_IFREG
: return BTRFS_FT_REG_FILE
;
36 case S_IFDIR
: return BTRFS_FT_DIR
;
37 case S_IFCHR
: return BTRFS_FT_CHRDEV
;
38 case S_IFBLK
: return BTRFS_FT_BLKDEV
;
39 case S_IFIFO
: return BTRFS_FT_FIFO
;
40 case S_IFSOCK
: return BTRFS_FT_SOCK
;
41 case S_IFLNK
: return BTRFS_FT_SYMLINK
;
44 return BTRFS_FT_UNKNOWN
;
47 static u32
reiserfs_count_objectids(reiserfs_filsys_t fs
)
49 struct reiserfs_super_block
*sb
= fs
->fs_ondisk_sb
;
54 if (fs
->fs_format
== REISERFS_FORMAT_3_6
)
55 map
= (u32
*) (sb
+ 1);
57 map
= (u32
*)((struct reiserfs_super_block_v1
*)sb
+ 1);
59 for (i
= 0; i
< get_sb_oid_cursize(sb
); i
+= 2)
60 count
+= le32_to_cpu(map
[i
+ 1]) - (le32_to_cpu(map
[i
]) + 1);
66 static int reiserfs_open_fs(struct btrfs_convert_context
*cxt
, const char *name
)
68 struct reiserfs_convert_info
*info
;
72 fs
= reiserfs_open(name
, O_RDONLY
, &error
, NULL
, 0);
76 error
= reiserfs_open_ondisk_bitmap(fs
);
83 cxt
->blocksize
= fs
->fs_blocksize
;
84 cxt
->block_count
= get_sb_block_count(fs
->fs_ondisk_sb
);
85 cxt
->total_bytes
= cxt
->blocksize
* cxt
->block_count
;
86 cxt
->volume_name
= strndup(fs
->fs_ondisk_sb
->s_label
, 16);
87 cxt
->first_data_block
= 0;
88 cxt
->inodes_count
= reiserfs_count_objectids(fs
);
89 cxt
->free_inodes_count
= 0;
90 info
= calloc(1, sizeof(*info
));
97 * Inode attributes are somewhat of a hack on reiserfs and it was
98 * once possible to have garbage in the flags field. A superblock
99 * field now indicates that the field has been cleared and can
100 * be considered valid, but only on v3.6 format file systems.
102 if (fs
->fs_format
== REISERFS_FORMAT_3_6
&&
103 get_sb_v2_flag(fs
->fs_ondisk_sb
, reiserfs_attrs_cleared
))
104 info
->copy_attrs
= true;
110 static void reiserfs_close_fs(struct btrfs_convert_context
*cxt
)
112 reiserfs_filsys_t fs
= cxt
->fs_data
;
113 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
117 free(info
->objectids
);
122 /* We don't want changes to be persistent */
123 fs
->fs_bitmap2
->bm_dirty
= 0;
128 static int compare_objectids(const void *p1
, const void *p2
)
140 static int lookup_cached_objectid(reiserfs_filsys_t fs
, u64 objectid
)
142 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
145 if (!info
->objectids
)
147 result
= bsearch(&objectid
, info
->objectids
, info
->used_slots
,
148 sizeof(u64
), compare_objectids
);
149 return result
!= NULL
;
152 static int insert_cached_objectid(reiserfs_filsys_t fs
, u64 objectid
)
154 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
156 if (info
->used_slots
+ 1 >= info
->alloced_slots
) {
157 u64
*objectids
= realloc(info
->objectids
,
158 (info
->alloced_slots
+ 1000) * sizeof(u64
));
162 info
->objectids
= objectids
;
163 info
->alloced_slots
+= 1000;
165 info
->objectids
[info
->used_slots
++] = objectid
;
167 qsort(info
->objectids
, info
->used_slots
, sizeof(u64
), compare_objectids
);
171 static int reiserfs_locate_privroot(reiserfs_filsys_t fs
)
175 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
176 struct reiserfs_key key
= root_dir_key
;
178 err
= reiserfs_find_entry(fs
, &key
, ".reiserfs_priv",
179 &generation
, &info
->privroot_key
);
181 err
= reiserfs_find_entry(fs
, &info
->privroot_key
, "xattrs",
182 &generation
, &info
->xattr_key
);
184 memset(&info
->xattr_key
, 0, sizeof(info
->xattr_key
));
190 static void reiserfs_convert_inode_flags(struct btrfs_inode_item
*inode
,
191 const struct stat_data
*sd
)
193 u16 attrs
= sd_v2_sd_attrs(sd
);
196 if (attrs
& FS_IMMUTABLE_FL
)
197 new_flags
|= BTRFS_INODE_IMMUTABLE
;
199 if (attrs
& FS_APPEND_FL
)
200 new_flags
|= BTRFS_INODE_APPEND
;
202 if (attrs
& FS_SYNC_FL
)
203 new_flags
|= BTRFS_INODE_SYNC
;
205 if (attrs
& FS_NOATIME_FL
)
206 new_flags
|= BTRFS_INODE_NOATIME
;
208 if (attrs
& FS_NODUMP_FL
)
209 new_flags
|= BTRFS_INODE_NODUMP
;
211 if (attrs
& FS_NODUMP_FL
)
212 new_flags
|= BTRFS_INODE_NODUMP
;
214 btrfs_set_stack_inode_flags(inode
, new_flags
);
218 static void reiserfs_copy_inode_item(struct btrfs_inode_item
*inode
,
219 struct item_head
*ih
, void *stat_data
,
220 bool copy_inode_flags
)
225 memset(inode
, 0, sizeof(*inode
));
226 btrfs_set_stack_inode_generation(inode
, 1);
227 if (get_ih_key_format(ih
) == KEY_FORMAT_1
) {
228 struct stat_data_v1
*sd
= stat_data
;
230 mode
= sd_v1_mode(sd
);
231 btrfs_set_stack_inode_size(inode
, sd_v1_size(sd
));
232 btrfs_set_stack_inode_nlink(inode
, sd_v1_nlink(sd
));
233 btrfs_set_stack_inode_uid(inode
, sd_v1_uid(sd
));
234 btrfs_set_stack_inode_gid(inode
, sd_v1_gid(sd
));
235 btrfs_set_stack_timespec_sec(&inode
->atime
, sd_v1_atime(sd
));
236 btrfs_set_stack_timespec_sec(&inode
->ctime
, sd_v1_ctime(sd
));
237 btrfs_set_stack_timespec_sec(&inode
->mtime
, sd_v1_mtime(sd
));
239 if (!S_ISREG(mode
) && !S_ISDIR(mode
) && !S_ISLNK(mode
))
240 rdev
= decode_dev(sd_v1_rdev(sd
));
242 struct stat_data
*sd
= stat_data
;
244 mode
= sd_v2_mode(sd
);
245 btrfs_set_stack_inode_size(inode
, sd_v2_size(sd
));
246 btrfs_set_stack_inode_nlink(inode
, sd_v2_nlink(sd
));
247 btrfs_set_stack_inode_uid(inode
, sd_v2_uid(sd
));
248 btrfs_set_stack_inode_gid(inode
, sd_v2_gid(sd
));
249 btrfs_set_stack_timespec_sec(&inode
->atime
, sd_v2_atime(sd
));
250 btrfs_set_stack_timespec_sec(&inode
->ctime
, sd_v2_ctime(sd
));
251 btrfs_set_stack_timespec_sec(&inode
->mtime
, sd_v2_mtime(sd
));
253 if (!S_ISREG(mode
) && !S_ISDIR(mode
) && !S_ISLNK(mode
))
254 rdev
= decode_dev(sd_v2_rdev(sd
));
256 if (copy_inode_flags
)
257 reiserfs_convert_inode_flags(inode
, sd
);
261 btrfs_set_stack_inode_size(inode
, 0);
262 btrfs_set_stack_inode_nlink(inode
, 1);
264 btrfs_set_stack_inode_mode(inode
, mode
);
265 btrfs_set_stack_inode_rdev(inode
, rdev
);
268 static void init_reiserfs_blk_iterate_data(
269 struct reiserfs_blk_iterate_data
*data
,
270 struct btrfs_trans_handle
*trans
,
271 struct btrfs_root
*root
,
272 struct btrfs_inode_item
*inode
,
273 u64 objectid
, u32 convert_flags
)
275 init_blk_iterate_data(&data
->blk_data
, trans
, root
, inode
, objectid
,
276 convert_flags
& CONVERT_FLAG_DATACSUM
);
277 data
->inline_data
= NULL
;
278 data
->inline_offset
= (u64
)-1;
279 data
->inline_length
= 0;
282 static int reiserfs_record_indirect_extent(reiserfs_filsys_t fs
, u64 position
,
283 u64 size
, int num_ptrs
,
284 u32
*ptrs
, void *data
)
286 struct reiserfs_blk_iterate_data
*bdata
= data
;
287 u32 file_block
= position
/ fs
->fs_blocksize
;
291 for (i
= 0; i
< num_ptrs
; i
++, file_block
++) {
292 u32 block
= d32_get(ptrs
, i
);
294 ret
= block_iterate_proc(block
, file_block
, &bdata
->blk_data
);
303 * Unlike btrfs inline extents, reiserfs can have multiple inline extents.
304 * This handles concatanating multiple tails into one inline extent
307 static int reiserfs_record_direct_extent(reiserfs_filsys_t fs
, __u64 position
,
308 __u64 size
, const char *body
,
309 size_t len
, void *data
)
311 struct reiserfs_blk_iterate_data
*bdata
= data
;
314 if (bdata
->inline_offset
== (u64
)-1)
315 bdata
->inline_offset
= position
;
316 else if (bdata
->inline_offset
+ bdata
->inline_length
!= position
) {
318 * This condition shouldn't actually happen, but better to
319 * catch it than break silently.
322 "source fs contains file with multiple tails but they are not contiguous");
326 inline_data
= realloc(bdata
->inline_data
, bdata
->inline_length
+ len
);
330 bdata
->inline_data
= inline_data
;
331 memcpy(bdata
->inline_data
+ bdata
->inline_length
, body
, len
);
332 bdata
->inline_length
+= len
;
337 static int convert_direct(struct btrfs_trans_handle
*trans
,
338 struct btrfs_root
*root
, u64 objectid
,
339 struct btrfs_inode_item
*inode
, const char *body
,
340 u32 length
, u64 offset
, u32 convert_flags
)
342 struct btrfs_key key
;
343 u32 sectorsize
= root
->fs_info
->sectorsize
;
345 struct extent_buffer
*eb
;
347 BUG_ON(length
> sectorsize
);
348 ret
= btrfs_reserve_extent(trans
, root
, sectorsize
,
349 0, 0, -1ULL, &key
, 1);
353 eb
= alloc_extent_buffer(root
->fs_info
, key
.objectid
, sectorsize
);
358 write_extent_buffer(eb
, body
, 0, length
);
359 ret
= write_and_map_eb(root
->fs_info
, eb
);
360 free_extent_buffer(eb
);
364 return btrfs_record_file_extent(trans
, root
, objectid
, inode
, offset
,
365 key
.objectid
, sectorsize
);
368 static int reiserfs_convert_tail(struct btrfs_trans_handle
*trans
,
369 struct btrfs_root
*root
,
370 struct btrfs_inode_item
*inode
,
371 u64 objectid
, u64 offset
,
372 const void *body
, unsigned length
,
378 if (length
>= BTRFS_MAX_INLINE_DATA_SIZE(root
->fs_info
) ||
379 length
>= root
->fs_info
->sectorsize
)
380 return convert_direct(trans
, root
, objectid
, inode
, body
,
381 length
, offset
, convert_flags
);
383 ret
= btrfs_insert_inline_extent(trans
, root
, objectid
,
384 offset
, body
, length
);
388 isize
= btrfs_stack_inode_nbytes(inode
);
389 btrfs_set_stack_inode_nbytes(inode
, isize
+ length
);
394 static inline u32
block_count(u64 size
, u32 blocksize
)
396 return round_up(size
, blocksize
) / blocksize
;
399 static int reiserfs_record_file_extents(reiserfs_filsys_t fs
,
400 struct btrfs_trans_handle
*trans
,
401 struct btrfs_root
*root
,
403 struct btrfs_inode_item
*inode
,
404 struct reiserfs_key
*sd_key
,
409 u32 blocksize
= fs
->fs_blocksize
;
410 u64 inode_size
= btrfs_stack_inode_size(inode
);
412 struct reiserfs_blk_iterate_data data
;
414 init_reiserfs_blk_iterate_data(&data
, trans
, root
, inode
,
415 objectid
, convert_flags
);
417 ret
= reiserfs_iterate_file_data(fs
, sd_key
,
418 reiserfs_record_indirect_extent
,
419 reiserfs_record_direct_extent
, &data
);
424 * blk_iterate_block has no idea that we're done iterating, so record
425 * the final range if any. This range can end and still have a tail
428 if (data
.blk_data
.num_blocks
) {
429 ret
= record_file_blocks(&data
.blk_data
,
430 data
.blk_data
.first_block
,
431 data
.blk_data
.disk_block
,
432 data
.blk_data
.num_blocks
);
435 data
.blk_data
.first_block
+= data
.blk_data
.num_blocks
;
436 data
.blk_data
.num_blocks
= 0;
440 * Handle a hole at the end of the file. ReiserFS will
441 * not write a tail followed by a hole but it will write a hole
442 * followed by a tail.
444 last_block
= block_count(inode_size
- data
.inline_length
, blocksize
);
445 if (last_block
> data
.blk_data
.first_block
) {
446 ret
= record_file_blocks(&data
.blk_data
,
447 data
.blk_data
.first_block
, 0,
448 last_block
- data
.blk_data
.first_block
);
453 if (data
.inline_length
) {
454 ret
= reiserfs_convert_tail(trans
, root
, inode
, objectid
,
457 data
.inline_length
, convert_flags
);
467 static int reiserfs_copy_meta(reiserfs_filsys_t fs
, struct btrfs_root
*root
,
468 u32 convert_flags
, u32 deh_dirid
,
469 u32 deh_objectid
, u8
*type
);
471 static int reiserfs_copy_dirent(reiserfs_filsys_t fs
,
472 const struct reiserfs_key
*dir_short_key
,
473 const char *name
, size_t len
,
474 __u32 deh_dirid
, __u32 deh_objectid
,
479 struct btrfs_trans_handle
*trans
;
480 u64 objectid
= deh_objectid
+ OID_OFFSET
;
481 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
482 struct reiserfs_dirent_data
*dirent_data
= cb_data
;
483 struct btrfs_root
*root
= dirent_data
->root
;
484 __u32 dir_objectid
= get_key_objectid(dir_short_key
) + OID_OFFSET
;
487 * These are the extended attributes and shouldn't appear as files
488 * in the converted file systems.
490 if (deh_objectid
== get_key_objectid(&info
->privroot_key
))
493 ret
= reiserfs_copy_meta(fs
, root
, dirent_data
->convert_flags
,
494 deh_dirid
, deh_objectid
, &type
);
497 "an error occured while converting \"%.*s\", reiserfs key [%u %u]: %s",
498 (int)len
, name
, deh_dirid
, deh_objectid
,
502 trans
= btrfs_start_transaction(root
, 1);
504 return PTR_ERR(trans
);
506 ret
= convert_insert_dirent(trans
, root
, name
, len
, dir_objectid
,
507 objectid
, type
, dirent_data
->index
++,
509 return btrfs_commit_transaction(trans
, root
);
512 static int reiserfs_copy_symlink(struct btrfs_trans_handle
*trans
,
513 struct btrfs_root
*root
, u64 objectid
,
514 struct btrfs_inode_item
*btrfs_inode
,
515 reiserfs_filsys_t fs
,
516 struct reiserfs_path
*sd_path
)
518 INITIALIZE_REISERFS_PATH(path
);
519 struct item_head
*ih
= tp_item_head(sd_path
);
520 struct reiserfs_key key
= ih
->ih_key
;
525 set_key_uniqueness(&key
, type2uniqueness(TYPE_DIRECT
));
526 set_key_offset_v1(&key
, 1);
528 ret
= reiserfs_search_by_key_3(fs
, &key
, &path
);
529 if (ret
!= ITEM_FOUND
) {
534 symlink
= tp_item_body(&path
);
535 len
= get_ih_item_len(tp_item_head(&path
));
537 ret
= btrfs_insert_inline_extent(trans
, root
, objectid
, 0,
539 btrfs_set_stack_inode_nbytes(btrfs_inode
, len
+ 1);
545 static int reiserfs_copy_meta(reiserfs_filsys_t fs
, struct btrfs_root
*root
,
546 u32 convert_flags
, u32 deh_dirid
,
547 u32 deh_objectid
, u8
*type
)
549 INITIALIZE_REISERFS_PATH(path
);
551 struct item_head
*ih
;
552 struct reiserfs_key key
;
553 struct btrfs_inode_item btrfs_inode
;
554 struct btrfs_trans_handle
*trans
= NULL
;
555 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
557 u64 objectid
= deh_objectid
+ OID_OFFSET
;
558 u64 parent
= deh_dirid
+ OID_OFFSET
;
559 struct reiserfs_dirent_data dirent_data
= {
561 .convert_flags
= convert_flags
,
562 .inode
= &btrfs_inode
,
566 /* The root directory's dirid in reiserfs points to an object
567 * that does't exist. In btrfs it's self-referential.
569 if (deh_dirid
== REISERFS_ROOT_PARENT_OBJECTID
)
572 set_key_dirid(&key
, deh_dirid
);
573 set_key_objectid(&key
, deh_objectid
);
574 set_key_offset_v2(&key
, 0);
575 set_key_type_v2(&key
, TYPE_STAT_DATA
);
577 ret
= reiserfs_search_by_key_3(fs
, &key
, &path
);
578 if (ret
!= ITEM_FOUND
) {
583 ih
= tp_item_head(&path
);
584 if (!is_stat_data_ih(ih
)) {
589 reiserfs_copy_inode_item(&btrfs_inode
, ih
, tp_item_body(&path
),
591 mode
= btrfs_stack_inode_mode(&btrfs_inode
);
592 *type
= mode_to_file_type(mode
);
595 /* Inodes with hardlinks should only be inserted once */
596 if (btrfs_stack_inode_nlink(&btrfs_inode
) > 1) {
597 if (lookup_cached_objectid(fs
, deh_objectid
)) {
599 goto fail
; /* Not a failure */
601 ret
= insert_cached_objectid(fs
, deh_objectid
);
607 if (!(convert_flags
& CONVERT_FLAG_DATACSUM
)) {
608 u32 flags
= btrfs_stack_inode_flags(&btrfs_inode
) |
609 BTRFS_INODE_NODATASUM
;
610 btrfs_set_stack_inode_flags(&btrfs_inode
, flags
);
613 switch (mode
& S_IFMT
) {
615 trans
= btrfs_start_transaction(root
, 1);
617 ret
= PTR_ERR(trans
);
620 ret
= reiserfs_record_file_extents(fs
, trans
, root
, objectid
,
621 &btrfs_inode
, &ih
->ih_key
,
627 ret
= reiserfs_iterate_dir(fs
, &ih
->ih_key
,
628 reiserfs_copy_dirent
, &dirent_data
);
631 trans
= btrfs_start_transaction(root
, 1);
633 ret
= PTR_ERR(trans
);
637 ret
= btrfs_insert_inode_ref(trans
, root
, "..", 2, parent
,
641 trans
= btrfs_start_transaction(root
, 1);
643 ret
= PTR_ERR(trans
);
646 ret
= reiserfs_copy_symlink(trans
, root
, objectid
,
647 &btrfs_inode
, fs
, &path
);
652 trans
= btrfs_start_transaction(root
, 1);
654 ret
= PTR_ERR(trans
);
659 ret
= btrfs_insert_inode(trans
, root
, objectid
, &btrfs_inode
);
662 ret
= btrfs_commit_transaction(trans
, root
);
663 info
->progress
->cur_copy_inodes
++;
670 static int reiserfs_xattr_indirect_fn(reiserfs_filsys_t fs
, u64 position
,
671 u64 size
, int num_blocks
,
672 u32
*blocks
, void *data
)
675 struct reiserfs_xattr_data
*xa_data
= data
;
676 size_t alloc
= min(position
+ num_blocks
* fs
->fs_blocksize
, size
);
679 if (size
> BTRFS_LEAF_DATA_SIZE(xa_data
->root
->fs_info
) -
680 sizeof(struct btrfs_item
) - sizeof(struct btrfs_dir_item
)) {
681 fprintf(stderr
, "skip large xattr on objectid %llu name %.*s\n",
682 xa_data
->target_oid
, (int)xa_data
->namelen
,
687 body
= realloc(xa_data
->body
, alloc
);
691 xa_data
->body
= body
;
692 xa_data
->len
= alloc
;
694 for (i
= 0; i
< num_blocks
; i
++) {
696 u32 block
= d32_get(blocks
, i
);
697 u64 offset
= (u64
)block
* fs
->fs_blocksize
;
698 size_t chunk
= min_t(u64
, size
- position
, fs
->fs_blocksize
);
699 char *buffer
= xa_data
->body
+ position
;
701 ret
= read_disk_extent(xa_data
->root
, offset
, chunk
, buffer
);
710 static int reiserfs_xattr_direct_fn(reiserfs_filsys_t fs
, __u64 position
,
711 __u64 size
, const char *body
, size_t len
,
714 struct reiserfs_xattr_data
*xa_data
= data
;
717 if (size
> BTRFS_LEAF_DATA_SIZE(xa_data
->root
->fs_info
) -
718 sizeof(struct btrfs_item
) - sizeof(struct btrfs_dir_item
)) {
719 fprintf(stderr
, "skip large xattr on objectid %llu name %.*s\n",
720 xa_data
->target_oid
, (int)xa_data
->namelen
,
725 newbody
= realloc(xa_data
->body
, position
+ len
);
728 xa_data
->body
= newbody
;
729 xa_data
->len
= position
+ len
;
730 memcpy(xa_data
->body
+ position
, body
, len
);
734 static int reiserfs_acl_to_xattr(void *dst
, const void *src
,
735 size_t dst_size
, size_t src_size
)
738 const void *end
= src
+ src_size
;
739 acl_ea_header
*ext_acl
= (acl_ea_header
*)dst
;
740 acl_ea_entry
*dst_entry
= ext_acl
->a_entries
;
741 struct reiserfs_acl_entry
*src_entry
;
743 if (src_size
< sizeof(struct reiserfs_acl_header
))
745 if (((struct reiserfs_acl_header
*)src
)->a_version
!=
746 cpu_to_le32(REISERFS_ACL_VERSION
))
748 src
+= sizeof(struct reiserfs_acl_header
);
749 count
= reiserfs_acl_count(src_size
);
753 BUG_ON(dst_size
< acl_ea_size(count
));
754 ext_acl
->a_version
= cpu_to_le32(ACL_EA_VERSION
);
755 for (i
= 0; i
< count
; i
++, dst_entry
++) {
756 src_entry
= (struct reiserfs_acl_entry
*)src
;
757 if (src
+ sizeof(struct reiserfs_acl_entry_short
) > end
)
759 dst_entry
->e_tag
= src_entry
->e_tag
;
760 dst_entry
->e_perm
= src_entry
->e_perm
;
761 switch (le16_to_cpu(src_entry
->e_tag
)) {
766 src
+= sizeof(struct reiserfs_acl_entry_short
);
767 dst_entry
->e_id
= cpu_to_le32(ACL_UNDEFINED_ID
);
771 src
+= sizeof(struct reiserfs_acl_entry
);
774 dst_entry
->e_id
= src_entry
->e_id
;
787 static int reiserfs_copy_one_xattr(reiserfs_filsys_t fs
,
788 const struct reiserfs_key
*dir_short_key
,
789 const char *name
, size_t namelen
,
791 __u32 deh_objectid
, void *cb_data
)
793 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
794 struct reiserfs_xattr_data
*xa_data
= cb_data
;
795 struct reiserfs_key key
= {
796 .k2_dir_id
= deh_dirid
,
797 .k2_objectid
= deh_objectid
,
803 xa_data
->name
= name
;
804 xa_data
->namelen
= namelen
;
806 ret
= reiserfs_iterate_file_data(fs
, &key
, reiserfs_xattr_indirect_fn
,
807 reiserfs_xattr_direct_fn
, cb_data
);
811 if (!reiserfs_check_xattr(xa_data
->body
, xa_data
->len
)) {
813 "skip corrupted xattr on objectid %u name %.*s\n",
814 deh_objectid
, (int)xa_data
->namelen
,
819 body
= xa_data
->body
+ sizeof(struct reiserfs_xattr_header
);
820 len
= xa_data
->len
- sizeof(struct reiserfs_xattr_header
);
822 if (!strncmp("system.posix_acl_default", name
, namelen
) ||
823 !strncmp("system.posix_acl_access", name
, namelen
)) {
824 size_t bufsize
= acl_ea_size(ext2_acl_count(len
));
825 char *databuf
= malloc(bufsize
);
829 ret
= reiserfs_acl_to_xattr(databuf
, body
, bufsize
, len
);
836 ret
= btrfs_insert_xattr_item(xa_data
->trans
, xa_data
->root
,
837 name
, namelen
, body
, len
,
838 xa_data
->target_oid
);
840 info
->progress
->cur_copy_inodes
++;
843 body
!= xa_data
->body
+ sizeof(struct reiserfs_xattr_header
))
847 xa_data
->body
= NULL
;
853 static int reiserfs_copy_xattr_dir(reiserfs_filsys_t fs
,
854 const struct reiserfs_key
*dir_short_key
,
855 const char *name
, size_t len
,
856 __u32 deh_dirid
, __u32 deh_objectid
,
859 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
860 struct reiserfs_xattr_data
*xa_data
= cb_data
;
861 struct reiserfs_key dir_key
= {
862 .k2_dir_id
= deh_dirid
,
863 .k2_objectid
= deh_objectid
,
868 xa_data
->target_oid
= strtoull(name
, NULL
, 16);
869 if (xa_data
->target_oid
== ULLONG_MAX
&& errno
)
872 xa_data
->target_oid
+= OID_OFFSET
;
874 xa_data
->trans
= btrfs_start_transaction(xa_data
->root
, 1);
875 if (IS_ERR(xa_data
->trans
))
876 return PTR_ERR(xa_data
->trans
);
878 ret
= reiserfs_iterate_dir(fs
, &dir_key
,
879 reiserfs_copy_one_xattr
, xa_data
);
881 err
= btrfs_commit_transaction(xa_data
->trans
, xa_data
->root
);
882 info
->progress
->cur_copy_inodes
++;
883 xa_data
->trans
= NULL
;
887 static int reiserfs_copy_xattrs(reiserfs_filsys_t fs
, struct btrfs_root
*root
)
889 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
890 struct reiserfs_xattr_data data
= {
894 if (get_key_objectid(&info
->xattr_key
) == 0)
897 return reiserfs_iterate_dir(fs
, &info
->xattr_key
,
898 reiserfs_copy_xattr_dir
, &data
);
901 static int reiserfs_copy_inodes(struct btrfs_convert_context
*cxt
,
902 struct btrfs_root
*root
,
906 reiserfs_filsys_t fs
= cxt
->fs_data
;
907 struct reiserfs_convert_info
*info
= fs
->fs_vp
;
913 ret
= reiserfs_locate_privroot(fs
);
917 ret
= reiserfs_copy_meta(fs
, root
, convert_flags
,
918 REISERFS_ROOT_PARENT_OBJECTID
,
919 REISERFS_ROOT_OBJECTID
, &type
);
923 if (convert_flags
& CONVERT_FLAG_XATTR
)
924 ret
= reiserfs_copy_xattrs(fs
, root
);
927 info
->progress
= NULL
;
931 static int reiserfs_read_used_space(struct btrfs_convert_context
*cxt
)
933 reiserfs_filsys_t fs
= cxt
->fs_data
;
935 unsigned int size
= get_sb_block_count(fs
->fs_ondisk_sb
);
936 unsigned long *bitmap
= (unsigned long *)fs
->fs_bitmap2
->bm_map
;
940 * We have the entire bitmap loaded so we can just ping pong with
946 start
= find_next_bit(bitmap
, size
, end
);
949 end
= find_next_zero_bit(bitmap
, size
, start
);
952 offset
= start
* fs
->fs_blocksize
;
953 length
= (end
- start
) * fs
->fs_blocksize
;
954 ret
= add_merge_cache_extent(&cxt
->used_space
, offset
, length
);
962 static int reiserfs_check_state(struct btrfs_convert_context
*cxt
)
967 const struct btrfs_convert_operations reiserfs_convert_ops
= {
969 .open_fs
= reiserfs_open_fs
,
970 .read_used_space
= reiserfs_read_used_space
,
971 .copy_inodes
= reiserfs_copy_inodes
,
972 .close_fs
= reiserfs_close_fs
,
973 .check_state
= reiserfs_check_state
,
976 #endif /* BTRFSCONVERT_REISERFS */