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 #include "kerncompat.h"
22 #include "convert/common.h"
23 #include "convert/source-fs.h"
25 const struct simple_range btrfs_reserved_ranges
[3] = {
27 { BTRFS_SB_MIRROR_OFFSET(1), SZ_64K
},
28 { BTRFS_SB_MIRROR_OFFSET(2), SZ_64K
}
31 dev_t
decode_dev(u32 dev
)
33 unsigned major
= (dev
& 0xfff00) >> 8;
34 unsigned minor
= (dev
& 0xff) | ((dev
>> 12) & 0xfff00);
36 return MKDEV(major
, minor
);
39 int ext2_acl_count(size_t size
)
43 size
-= sizeof(ext2_acl_header
);
44 s
= size
- 4 * sizeof(ext2_acl_entry_short
);
46 if (size
% sizeof(ext2_acl_entry_short
))
48 return size
/ sizeof(ext2_acl_entry_short
);
50 if (s
% sizeof(ext2_acl_entry
))
52 return s
/ sizeof(ext2_acl_entry
) + 4;
56 static u64
intersect_with_reserved(u64 bytenr
, u64 num_bytes
)
60 for (i
= 0; i
< ARRAY_SIZE(btrfs_reserved_ranges
); i
++) {
61 const struct simple_range
*range
= &btrfs_reserved_ranges
[i
];
63 if (bytenr
< range_end(range
) &&
64 bytenr
+ num_bytes
>= range
->start
)
65 return range_end(range
);
70 void init_convert_context(struct btrfs_convert_context
*cctx
)
72 memset(cctx
, 0, sizeof(*cctx
));
74 cache_tree_init(&cctx
->used_space
);
75 cache_tree_init(&cctx
->data_chunks
);
76 cache_tree_init(&cctx
->free_space
);
79 void clean_convert_context(struct btrfs_convert_context
*cctx
)
81 free_extent_cache_tree(&cctx
->used_space
);
82 free_extent_cache_tree(&cctx
->data_chunks
);
83 free_extent_cache_tree(&cctx
->free_space
);
86 int block_iterate_proc(u64 disk_block
, u64 file_block
,
87 struct blk_iterate_data
*idata
)
90 u64 reserved_boundary
;
92 struct btrfs_root
*root
= idata
->root
;
93 struct btrfs_block_group_cache
*cache
;
94 u32 sectorsize
= root
->fs_info
->sectorsize
;
95 u64 bytenr
= disk_block
* sectorsize
;
97 reserved_boundary
= intersect_with_reserved(bytenr
, sectorsize
);
98 do_barrier
= reserved_boundary
|| disk_block
>= idata
->boundary
;
99 if ((idata
->num_blocks
> 0 && do_barrier
) ||
100 (file_block
> idata
->first_block
+ idata
->num_blocks
) ||
101 (disk_block
!= idata
->disk_block
+ idata
->num_blocks
)) {
102 if (idata
->num_blocks
> 0) {
103 ret
= record_file_blocks(idata
, idata
->first_block
,
108 idata
->first_block
+= idata
->num_blocks
;
109 idata
->num_blocks
= 0;
111 if (file_block
> idata
->first_block
) {
112 ret
= record_file_blocks(idata
, idata
->first_block
,
113 0, file_block
- idata
->first_block
);
118 if (reserved_boundary
) {
119 bytenr
= reserved_boundary
;
121 cache
= btrfs_lookup_block_group(root
->fs_info
, bytenr
);
123 bytenr
= cache
->key
.objectid
+ cache
->key
.offset
;
126 idata
->first_block
= file_block
;
127 idata
->disk_block
= disk_block
;
128 idata
->boundary
= bytenr
/ sectorsize
;
135 void init_blk_iterate_data(struct blk_iterate_data
*data
,
136 struct btrfs_trans_handle
*trans
,
137 struct btrfs_root
*root
,
138 struct btrfs_inode_item
*inode
,
139 u64 objectid
, int checksum
)
141 struct btrfs_key key
;
146 data
->objectid
= objectid
;
147 data
->first_block
= 0;
148 data
->disk_block
= 0;
149 data
->num_blocks
= 0;
150 data
->boundary
= (u64
)-1;
151 data
->checksum
= checksum
;
154 key
.objectid
= CONV_IMAGE_SUBVOL_OBJECTID
;
155 key
.type
= BTRFS_ROOT_ITEM_KEY
;
156 key
.offset
= (u64
)-1;
157 data
->convert_root
= btrfs_read_fs_root(root
->fs_info
, &key
);
158 /* Impossible as we just opened it before */
159 BUG_ON(!data
->convert_root
|| IS_ERR(data
->convert_root
));
160 data
->convert_ino
= BTRFS_FIRST_FREE_OBJECTID
+ 1;
163 int convert_insert_dirent(struct btrfs_trans_handle
*trans
,
164 struct btrfs_root
*root
,
165 const char *name
, size_t name_len
,
166 u64 dir
, u64 objectid
,
167 u8 file_type
, u64 index_cnt
,
168 struct btrfs_inode_item
*inode
)
172 struct btrfs_key location
= {
173 .objectid
= objectid
,
175 .type
= BTRFS_INODE_ITEM_KEY
,
178 ret
= btrfs_insert_dir_item(trans
, root
, name
, name_len
,
179 dir
, &location
, file_type
, index_cnt
);
182 ret
= btrfs_insert_inode_ref(trans
, root
, name
, name_len
,
183 objectid
, dir
, index_cnt
);
186 inode_size
= btrfs_stack_inode_size(inode
) + name_len
* 2;
187 btrfs_set_stack_inode_size(inode
, inode_size
);
192 int read_disk_extent(struct btrfs_root
*root
, u64 bytenr
,
193 u32 num_bytes
, char *buffer
)
196 struct btrfs_fs_devices
*fs_devs
= root
->fs_info
->fs_devices
;
198 ret
= pread(fs_devs
->latest_bdev
, buffer
, num_bytes
, bytenr
);
199 if (ret
!= num_bytes
)
209 * Record a file extent in original filesystem into btrfs one.
210 * The special point is, old disk_block can point to a reserved range.
211 * So here, we don't use disk_block directly but search convert_root
212 * to get the real disk_bytenr.
214 int record_file_blocks(struct blk_iterate_data
*data
,
215 u64 file_block
, u64 disk_block
, u64 num_blocks
)
218 struct btrfs_root
*root
= data
->root
;
219 struct btrfs_root
*convert_root
= data
->convert_root
;
220 struct btrfs_path path
;
221 u32 sectorsize
= root
->fs_info
->sectorsize
;
222 u64 file_pos
= file_block
* sectorsize
;
223 u64 old_disk_bytenr
= disk_block
* sectorsize
;
224 u64 num_bytes
= num_blocks
* sectorsize
;
225 u64 cur_off
= old_disk_bytenr
;
227 /* Hole, pass it to record_file_extent directly */
228 if (old_disk_bytenr
== 0)
229 return btrfs_record_file_extent(data
->trans
, root
,
230 data
->objectid
, data
->inode
, file_pos
, 0,
233 btrfs_init_path(&path
);
236 * Search real disk bytenr from convert root
238 while (cur_off
< old_disk_bytenr
+ num_bytes
) {
239 struct btrfs_key key
;
240 struct btrfs_file_extent_item
*fi
;
241 struct extent_buffer
*node
;
243 u64 extent_disk_bytenr
;
244 u64 extent_num_bytes
;
245 u64 real_disk_bytenr
;
248 key
.objectid
= data
->convert_ino
;
249 key
.type
= BTRFS_EXTENT_DATA_KEY
;
250 key
.offset
= cur_off
;
252 ret
= btrfs_search_slot(NULL
, convert_root
, &key
, &path
, 0, 0);
256 ret
= btrfs_previous_item(convert_root
, &path
,
258 BTRFS_EXTENT_DATA_KEY
);
266 node
= path
.nodes
[0];
267 slot
= path
.slots
[0];
268 btrfs_item_key_to_cpu(node
, &key
, slot
);
269 BUG_ON(key
.type
!= BTRFS_EXTENT_DATA_KEY
||
270 key
.objectid
!= data
->convert_ino
||
271 key
.offset
> cur_off
);
272 fi
= btrfs_item_ptr(node
, slot
, struct btrfs_file_extent_item
);
273 extent_disk_bytenr
= btrfs_file_extent_disk_bytenr(node
, fi
);
274 extent_num_bytes
= btrfs_file_extent_num_bytes(node
, fi
);
275 BUG_ON(cur_off
- key
.offset
>= extent_num_bytes
);
276 btrfs_release_path(&path
);
278 if (extent_disk_bytenr
)
279 real_disk_bytenr
= cur_off
- key
.offset
+
282 real_disk_bytenr
= 0;
283 cur_len
= min(key
.offset
+ extent_num_bytes
,
284 old_disk_bytenr
+ num_bytes
) - cur_off
;
285 ret
= btrfs_record_file_extent(data
->trans
, data
->root
,
286 data
->objectid
, data
->inode
, file_pos
,
287 real_disk_bytenr
, cur_len
);
294 * No need to care about csum
295 * As every byte of old fs image is calculated for csum, no
296 * need to waste CPU cycles now.
299 btrfs_release_path(&path
);