mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-16 09:46:55 +00:00
btrfs-progs: convert: move implementation for interal conversion API to own file
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
03c085861b
commit
3a724cbde0
@ -404,17 +404,17 @@ btrfs-image.static: $(static_objects) image/main.static.o $(static_libbtrfs_obje
|
||||
$(Q)$(CC) $(STATIC_CFLAGS) -o $@ image/main.static.o $(static_objects) \
|
||||
$(static_libbtrfs_objects) $(STATIC_LDFLAGS) $(STATIC_LIBS)
|
||||
|
||||
btrfs-convert: $(objects) $(libs_static) convert/main.o convert/common.o convert/source-ext2.o
|
||||
btrfs-convert: $(objects) $(libs_static) convert/main.o convert/common.o convert/source-fs.o convert/source-ext2.o
|
||||
@echo " [LD] $@"
|
||||
$(Q)$(CC) $(CFLAGS) -I$(TOPDIR)/convert -o btrfs-convert $(objects) \
|
||||
convert/main.o convert/common.o convert/source-ext2.o $(libs_static) \
|
||||
convert/main.o convert/common.o convert/source-fs.o convert/source-ext2.o $(libs_static) \
|
||||
$(LDFLAGS) $(btrfs_convert_libs) $(LIBS)
|
||||
|
||||
btrfs-convert.static: $(static_objects) convert/main.static.o convert/common.static.o \
|
||||
convert/source-ext2.static. o $(static_libbtrfs_objects)
|
||||
convert/source-fs.static.o convert/source-ext2.static. o $(static_libbtrfs_objects)
|
||||
@echo " [LD] $@"
|
||||
$(Q)$(CC) $(STATIC_CFLAGS) -o $@ convert/main.static.o convert/common.static.o \
|
||||
convert/source-ext2.static.o $(static_objects) \
|
||||
convert/source-fs.static.o convert/source-ext2.static.o $(static_objects) \
|
||||
$(static_libbtrfs_objects) $(STATIC_LDFLAGS) $(btrfs_convert_libs) $(STATIC_LIBS)
|
||||
|
||||
dir-test: $(objects) $(libs) dir-test.o
|
||||
|
246
convert/main.c
246
convert/main.c
@ -70,20 +70,6 @@ static int after_copied_inodes(void *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_convert_context(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
cache_tree_init(&cctx->used);
|
||||
cache_tree_init(&cctx->data_chunks);
|
||||
cache_tree_init(&cctx->free);
|
||||
}
|
||||
|
||||
void clean_convert_context(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
free_extent_cache_tree(&cctx->used);
|
||||
free_extent_cache_tree(&cctx->data_chunks);
|
||||
free_extent_cache_tree(&cctx->free);
|
||||
}
|
||||
|
||||
static inline int copy_inodes(struct btrfs_convert_context *cctx,
|
||||
struct btrfs_root *root, int datacsum,
|
||||
int packing, int noxattr, struct task_ctx *p)
|
||||
@ -102,67 +88,6 @@ static inline int convert_check_state(struct btrfs_convert_context *cctx)
|
||||
return cctx->convert_ops->check_state(cctx);
|
||||
}
|
||||
|
||||
static int intersect_with_sb(u64 bytenr, u64 num_bytes)
|
||||
{
|
||||
int i;
|
||||
u64 offset;
|
||||
|
||||
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
|
||||
offset = btrfs_sb_offset(i);
|
||||
offset &= ~((u64)BTRFS_STRIPE_LEN - 1);
|
||||
|
||||
if (bytenr < offset + BTRFS_STRIPE_LEN &&
|
||||
bytenr + num_bytes > offset)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int convert_insert_dirent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
const char *name, size_t name_len,
|
||||
u64 dir, u64 objectid,
|
||||
u8 file_type, u64 index_cnt,
|
||||
struct btrfs_inode_item *inode)
|
||||
{
|
||||
int ret;
|
||||
u64 inode_size;
|
||||
struct btrfs_key location = {
|
||||
.objectid = objectid,
|
||||
.offset = 0,
|
||||
.type = BTRFS_INODE_ITEM_KEY,
|
||||
};
|
||||
|
||||
ret = btrfs_insert_dir_item(trans, root, name, name_len,
|
||||
dir, &location, file_type, index_cnt);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = btrfs_insert_inode_ref(trans, root, name, name_len,
|
||||
objectid, dir, index_cnt);
|
||||
if (ret)
|
||||
return ret;
|
||||
inode_size = btrfs_stack_inode_size(inode) + name_len * 2;
|
||||
btrfs_set_stack_inode_size(inode, inode_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_disk_extent(struct btrfs_root *root, u64 bytenr,
|
||||
u32 num_bytes, char *buffer)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_fs_devices *fs_devs = root->fs_info->fs_devices;
|
||||
|
||||
ret = pread(fs_devs->latest_bdev, buffer, num_bytes, bytenr);
|
||||
if (ret != num_bytes)
|
||||
goto fail;
|
||||
ret = 0;
|
||||
fail:
|
||||
if (ret > 0)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int csum_disk_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 disk_bytenr, u64 num_bytes)
|
||||
@ -192,177 +117,6 @@ static int csum_disk_extent(struct btrfs_trans_handle *trans,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void init_blk_iterate_data(struct blk_iterate_data *data,
|
||||
struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_inode_item *inode,
|
||||
u64 objectid, int checksum)
|
||||
{
|
||||
struct btrfs_key key;
|
||||
|
||||
data->trans = trans;
|
||||
data->root = root;
|
||||
data->inode = inode;
|
||||
data->objectid = objectid;
|
||||
data->first_block = 0;
|
||||
data->disk_block = 0;
|
||||
data->num_blocks = 0;
|
||||
data->boundary = (u64)-1;
|
||||
data->checksum = checksum;
|
||||
data->errcode = 0;
|
||||
|
||||
key.objectid = CONV_IMAGE_SUBVOL_OBJECTID;
|
||||
key.type = BTRFS_ROOT_ITEM_KEY;
|
||||
key.offset = (u64)-1;
|
||||
data->convert_root = btrfs_read_fs_root(root->fs_info, &key);
|
||||
/* Impossible as we just opened it before */
|
||||
BUG_ON(!data->convert_root || IS_ERR(data->convert_root));
|
||||
data->convert_ino = BTRFS_FIRST_FREE_OBJECTID + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record a file extent in original filesystem into btrfs one.
|
||||
* The special point is, old disk_block can point to a reserved range.
|
||||
* So here, we don't use disk_block directly but search convert_root
|
||||
* to get the real disk_bytenr.
|
||||
*/
|
||||
int record_file_blocks(struct blk_iterate_data *data,
|
||||
u64 file_block, u64 disk_block, u64 num_blocks)
|
||||
{
|
||||
int ret = 0;
|
||||
struct btrfs_root *root = data->root;
|
||||
struct btrfs_root *convert_root = data->convert_root;
|
||||
struct btrfs_path path;
|
||||
u64 file_pos = file_block * root->sectorsize;
|
||||
u64 old_disk_bytenr = disk_block * root->sectorsize;
|
||||
u64 num_bytes = num_blocks * root->sectorsize;
|
||||
u64 cur_off = old_disk_bytenr;
|
||||
|
||||
/* Hole, pass it to record_file_extent directly */
|
||||
if (old_disk_bytenr == 0)
|
||||
return btrfs_record_file_extent(data->trans, root,
|
||||
data->objectid, data->inode, file_pos, 0,
|
||||
num_bytes);
|
||||
|
||||
btrfs_init_path(&path);
|
||||
|
||||
/*
|
||||
* Search real disk bytenr from convert root
|
||||
*/
|
||||
while (cur_off < old_disk_bytenr + num_bytes) {
|
||||
struct btrfs_key key;
|
||||
struct btrfs_file_extent_item *fi;
|
||||
struct extent_buffer *node;
|
||||
int slot;
|
||||
u64 extent_disk_bytenr;
|
||||
u64 extent_num_bytes;
|
||||
u64 real_disk_bytenr;
|
||||
u64 cur_len;
|
||||
|
||||
key.objectid = data->convert_ino;
|
||||
key.type = BTRFS_EXTENT_DATA_KEY;
|
||||
key.offset = cur_off;
|
||||
|
||||
ret = btrfs_search_slot(NULL, convert_root, &key, &path, 0, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret > 0) {
|
||||
ret = btrfs_previous_item(convert_root, &path,
|
||||
data->convert_ino,
|
||||
BTRFS_EXTENT_DATA_KEY);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = path.nodes[0];
|
||||
slot = path.slots[0];
|
||||
btrfs_item_key_to_cpu(node, &key, slot);
|
||||
BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY ||
|
||||
key.objectid != data->convert_ino ||
|
||||
key.offset > cur_off);
|
||||
fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item);
|
||||
extent_disk_bytenr = btrfs_file_extent_disk_bytenr(node, fi);
|
||||
extent_num_bytes = btrfs_file_extent_num_bytes(node, fi);
|
||||
BUG_ON(cur_off - key.offset >= extent_num_bytes);
|
||||
btrfs_release_path(&path);
|
||||
|
||||
if (extent_disk_bytenr)
|
||||
real_disk_bytenr = cur_off - key.offset +
|
||||
extent_disk_bytenr;
|
||||
else
|
||||
real_disk_bytenr = 0;
|
||||
cur_len = min(key.offset + extent_num_bytes,
|
||||
old_disk_bytenr + num_bytes) - cur_off;
|
||||
ret = btrfs_record_file_extent(data->trans, data->root,
|
||||
data->objectid, data->inode, file_pos,
|
||||
real_disk_bytenr, cur_len);
|
||||
if (ret < 0)
|
||||
break;
|
||||
cur_off += cur_len;
|
||||
file_pos += cur_len;
|
||||
|
||||
/*
|
||||
* No need to care about csum
|
||||
* As every byte of old fs image is calculated for csum, no
|
||||
* need to waste CPU cycles now.
|
||||
*/
|
||||
}
|
||||
btrfs_release_path(&path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int block_iterate_proc(u64 disk_block, u64 file_block,
|
||||
struct blk_iterate_data *idata)
|
||||
{
|
||||
int ret = 0;
|
||||
int sb_region;
|
||||
int do_barrier;
|
||||
struct btrfs_root *root = idata->root;
|
||||
struct btrfs_block_group_cache *cache;
|
||||
u64 bytenr = disk_block * root->sectorsize;
|
||||
|
||||
sb_region = intersect_with_sb(bytenr, root->sectorsize);
|
||||
do_barrier = sb_region || disk_block >= idata->boundary;
|
||||
if ((idata->num_blocks > 0 && do_barrier) ||
|
||||
(file_block > idata->first_block + idata->num_blocks) ||
|
||||
(disk_block != idata->disk_block + idata->num_blocks)) {
|
||||
if (idata->num_blocks > 0) {
|
||||
ret = record_file_blocks(idata, idata->first_block,
|
||||
idata->disk_block,
|
||||
idata->num_blocks);
|
||||
if (ret)
|
||||
goto fail;
|
||||
idata->first_block += idata->num_blocks;
|
||||
idata->num_blocks = 0;
|
||||
}
|
||||
if (file_block > idata->first_block) {
|
||||
ret = record_file_blocks(idata, idata->first_block,
|
||||
0, file_block - idata->first_block);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sb_region) {
|
||||
bytenr += BTRFS_STRIPE_LEN - 1;
|
||||
bytenr &= ~((u64)BTRFS_STRIPE_LEN - 1);
|
||||
} else {
|
||||
cache = btrfs_lookup_block_group(root->fs_info, bytenr);
|
||||
BUG_ON(!cache);
|
||||
bytenr = cache->key.objectid + cache->key.offset;
|
||||
}
|
||||
|
||||
idata->first_block = file_block;
|
||||
idata->disk_block = disk_block;
|
||||
idata->boundary = bytenr / root->sectorsize;
|
||||
}
|
||||
idata->num_blocks++;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int create_image_file_range(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct cache_tree *used,
|
||||
|
270
convert/source-fs.c
Normal file
270
convert/source-fs.c
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License v2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 021110-1307, USA.
|
||||
*/
|
||||
|
||||
#include "kerncompat.h"
|
||||
#include <unistd.h>
|
||||
#include "internal.h"
|
||||
#include "disk-io.h"
|
||||
#include "volumes.h"
|
||||
#include "convert/common.h"
|
||||
#include "convert/source-fs.h"
|
||||
|
||||
static int intersect_with_sb(u64 bytenr, u64 num_bytes)
|
||||
{
|
||||
int i;
|
||||
u64 offset;
|
||||
|
||||
for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
|
||||
offset = btrfs_sb_offset(i);
|
||||
offset &= ~((u64)BTRFS_STRIPE_LEN - 1);
|
||||
|
||||
if (bytenr < offset + BTRFS_STRIPE_LEN &&
|
||||
bytenr + num_bytes > offset)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_convert_context(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
cache_tree_init(&cctx->used);
|
||||
cache_tree_init(&cctx->data_chunks);
|
||||
cache_tree_init(&cctx->free);
|
||||
}
|
||||
|
||||
void clean_convert_context(struct btrfs_convert_context *cctx)
|
||||
{
|
||||
free_extent_cache_tree(&cctx->used);
|
||||
free_extent_cache_tree(&cctx->data_chunks);
|
||||
free_extent_cache_tree(&cctx->free);
|
||||
}
|
||||
|
||||
int block_iterate_proc(u64 disk_block, u64 file_block,
|
||||
struct blk_iterate_data *idata)
|
||||
{
|
||||
int ret = 0;
|
||||
int sb_region;
|
||||
int do_barrier;
|
||||
struct btrfs_root *root = idata->root;
|
||||
struct btrfs_block_group_cache *cache;
|
||||
u64 bytenr = disk_block * root->sectorsize;
|
||||
|
||||
sb_region = intersect_with_sb(bytenr, root->sectorsize);
|
||||
do_barrier = sb_region || disk_block >= idata->boundary;
|
||||
if ((idata->num_blocks > 0 && do_barrier) ||
|
||||
(file_block > idata->first_block + idata->num_blocks) ||
|
||||
(disk_block != idata->disk_block + idata->num_blocks)) {
|
||||
if (idata->num_blocks > 0) {
|
||||
ret = record_file_blocks(idata, idata->first_block,
|
||||
idata->disk_block,
|
||||
idata->num_blocks);
|
||||
if (ret)
|
||||
goto fail;
|
||||
idata->first_block += idata->num_blocks;
|
||||
idata->num_blocks = 0;
|
||||
}
|
||||
if (file_block > idata->first_block) {
|
||||
ret = record_file_blocks(idata, idata->first_block,
|
||||
0, file_block - idata->first_block);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sb_region) {
|
||||
bytenr += BTRFS_STRIPE_LEN - 1;
|
||||
bytenr &= ~((u64)BTRFS_STRIPE_LEN - 1);
|
||||
} else {
|
||||
cache = btrfs_lookup_block_group(root->fs_info, bytenr);
|
||||
BUG_ON(!cache);
|
||||
bytenr = cache->key.objectid + cache->key.offset;
|
||||
}
|
||||
|
||||
idata->first_block = file_block;
|
||||
idata->disk_block = disk_block;
|
||||
idata->boundary = bytenr / root->sectorsize;
|
||||
}
|
||||
idata->num_blocks++;
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void init_blk_iterate_data(struct blk_iterate_data *data,
|
||||
struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_inode_item *inode,
|
||||
u64 objectid, int checksum)
|
||||
{
|
||||
struct btrfs_key key;
|
||||
|
||||
data->trans = trans;
|
||||
data->root = root;
|
||||
data->inode = inode;
|
||||
data->objectid = objectid;
|
||||
data->first_block = 0;
|
||||
data->disk_block = 0;
|
||||
data->num_blocks = 0;
|
||||
data->boundary = (u64)-1;
|
||||
data->checksum = checksum;
|
||||
data->errcode = 0;
|
||||
|
||||
key.objectid = CONV_IMAGE_SUBVOL_OBJECTID;
|
||||
key.type = BTRFS_ROOT_ITEM_KEY;
|
||||
key.offset = (u64)-1;
|
||||
data->convert_root = btrfs_read_fs_root(root->fs_info, &key);
|
||||
/* Impossible as we just opened it before */
|
||||
BUG_ON(!data->convert_root || IS_ERR(data->convert_root));
|
||||
data->convert_ino = BTRFS_FIRST_FREE_OBJECTID + 1;
|
||||
}
|
||||
|
||||
int convert_insert_dirent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
const char *name, size_t name_len,
|
||||
u64 dir, u64 objectid,
|
||||
u8 file_type, u64 index_cnt,
|
||||
struct btrfs_inode_item *inode)
|
||||
{
|
||||
int ret;
|
||||
u64 inode_size;
|
||||
struct btrfs_key location = {
|
||||
.objectid = objectid,
|
||||
.offset = 0,
|
||||
.type = BTRFS_INODE_ITEM_KEY,
|
||||
};
|
||||
|
||||
ret = btrfs_insert_dir_item(trans, root, name, name_len,
|
||||
dir, &location, file_type, index_cnt);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = btrfs_insert_inode_ref(trans, root, name, name_len,
|
||||
objectid, dir, index_cnt);
|
||||
if (ret)
|
||||
return ret;
|
||||
inode_size = btrfs_stack_inode_size(inode) + name_len * 2;
|
||||
btrfs_set_stack_inode_size(inode, inode_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_disk_extent(struct btrfs_root *root, u64 bytenr,
|
||||
u32 num_bytes, char *buffer)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_fs_devices *fs_devs = root->fs_info->fs_devices;
|
||||
|
||||
ret = pread(fs_devs->latest_bdev, buffer, num_bytes, bytenr);
|
||||
if (ret != num_bytes)
|
||||
goto fail;
|
||||
ret = 0;
|
||||
fail:
|
||||
if (ret > 0)
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record a file extent in original filesystem into btrfs one.
|
||||
* The special point is, old disk_block can point to a reserved range.
|
||||
* So here, we don't use disk_block directly but search convert_root
|
||||
* to get the real disk_bytenr.
|
||||
*/
|
||||
int record_file_blocks(struct blk_iterate_data *data,
|
||||
u64 file_block, u64 disk_block, u64 num_blocks)
|
||||
{
|
||||
int ret = 0;
|
||||
struct btrfs_root *root = data->root;
|
||||
struct btrfs_root *convert_root = data->convert_root;
|
||||
struct btrfs_path path;
|
||||
u64 file_pos = file_block * root->sectorsize;
|
||||
u64 old_disk_bytenr = disk_block * root->sectorsize;
|
||||
u64 num_bytes = num_blocks * root->sectorsize;
|
||||
u64 cur_off = old_disk_bytenr;
|
||||
|
||||
/* Hole, pass it to record_file_extent directly */
|
||||
if (old_disk_bytenr == 0)
|
||||
return btrfs_record_file_extent(data->trans, root,
|
||||
data->objectid, data->inode, file_pos, 0,
|
||||
num_bytes);
|
||||
|
||||
btrfs_init_path(&path);
|
||||
|
||||
/*
|
||||
* Search real disk bytenr from convert root
|
||||
*/
|
||||
while (cur_off < old_disk_bytenr + num_bytes) {
|
||||
struct btrfs_key key;
|
||||
struct btrfs_file_extent_item *fi;
|
||||
struct extent_buffer *node;
|
||||
int slot;
|
||||
u64 extent_disk_bytenr;
|
||||
u64 extent_num_bytes;
|
||||
u64 real_disk_bytenr;
|
||||
u64 cur_len;
|
||||
|
||||
key.objectid = data->convert_ino;
|
||||
key.type = BTRFS_EXTENT_DATA_KEY;
|
||||
key.offset = cur_off;
|
||||
|
||||
ret = btrfs_search_slot(NULL, convert_root, &key, &path, 0, 0);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret > 0) {
|
||||
ret = btrfs_previous_item(convert_root, &path,
|
||||
data->convert_ino,
|
||||
BTRFS_EXTENT_DATA_KEY);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret > 0) {
|
||||
ret = -ENOENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = path.nodes[0];
|
||||
slot = path.slots[0];
|
||||
btrfs_item_key_to_cpu(node, &key, slot);
|
||||
BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY ||
|
||||
key.objectid != data->convert_ino ||
|
||||
key.offset > cur_off);
|
||||
fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item);
|
||||
extent_disk_bytenr = btrfs_file_extent_disk_bytenr(node, fi);
|
||||
extent_num_bytes = btrfs_file_extent_num_bytes(node, fi);
|
||||
BUG_ON(cur_off - key.offset >= extent_num_bytes);
|
||||
btrfs_release_path(&path);
|
||||
|
||||
if (extent_disk_bytenr)
|
||||
real_disk_bytenr = cur_off - key.offset +
|
||||
extent_disk_bytenr;
|
||||
else
|
||||
real_disk_bytenr = 0;
|
||||
cur_len = min(key.offset + extent_num_bytes,
|
||||
old_disk_bytenr + num_bytes) - cur_off;
|
||||
ret = btrfs_record_file_extent(data->trans, data->root,
|
||||
data->objectid, data->inode, file_pos,
|
||||
real_disk_bytenr, cur_len);
|
||||
if (ret < 0)
|
||||
break;
|
||||
cur_off += cur_len;
|
||||
file_pos += cur_len;
|
||||
|
||||
/*
|
||||
* No need to care about csum
|
||||
* As every byte of old fs image is calculated for csum, no
|
||||
* need to waste CPU cycles now.
|
||||
*/
|
||||
}
|
||||
btrfs_release_path(&path);
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user