summaryrefslogtreecommitdiff
path: root/btrfs-convert.c
diff options
context:
space:
mode:
authorQu Wenruo <quwenruo@cn.fujitsu.com>2015-04-02 10:21:35 +0800
committerDavid Sterba <dsterba@suse.cz>2015-04-02 17:33:37 +0200
commitffe9554b7888846e374cedba0e9f21142d988d8f (patch)
tree14dac786fa4c93e2e0249c110e7f2e6804efb6fc /btrfs-convert.c
parent153bbb93ec7de97ad9d2c8dd1bc5d2141623f17a (diff)
btrfs-progs: convert: Make ext*_image file obey datacsum setting.
Before this patch, ext*_image is always set NODATACSUM inode flag. However btrfs-convert will set normal file with DATACUSM flag by default, and generate checksum for regular file extent. Now, a regular file extent is shared by a btrfs file inode with DATACSUM and ext*_image with NODATACSUM, and it has checksum in csum tree. This will cause btrfsck complain about odd checksum, since ext*_image is set NODATACSUM but has checksum generated from regular file extent. This patch makes convert completely obey datacsum setting, meaning btrfs-convert will generate csum for every file extent by default. Reported-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.cz>
Diffstat (limited to 'btrfs-convert.c')
-rw-r--r--btrfs-convert.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/btrfs-convert.c b/btrfs-convert.c
index 4dc33b3c..d742307d 100644
--- a/btrfs-convert.c
+++ b/btrfs-convert.c
@@ -1161,7 +1161,7 @@ static int create_image_file_range(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 objectid,
struct btrfs_inode_item *inode,
u64 start_byte, u64 end_byte,
- ext2_filsys ext2_fs)
+ ext2_filsys ext2_fs, int datacsum)
{
u32 blocksize = ext2_fs->blocksize;
u32 block = start_byte / blocksize;
@@ -1176,7 +1176,7 @@ static int create_image_file_range(struct btrfs_trans_handle *trans,
.disk_block = 0,
.num_blocks = 0,
.boundary = (u64)-1,
- .checksum = 0,
+ .checksum = datacsum,
.errcode = 0,
};
for (; start_byte < end_byte; block++, start_byte += blocksize) {
@@ -1191,7 +1191,7 @@ static int create_image_file_range(struct btrfs_trans_handle *trans,
if (data.num_blocks > 0) {
ret = record_file_blocks(trans, root, objectid, inode,
data.first_block, data.disk_block,
- data.num_blocks, 0);
+ data.num_blocks, datacsum);
if (ret)
goto fail;
data.first_block += data.num_blocks;
@@ -1199,7 +1199,7 @@ static int create_image_file_range(struct btrfs_trans_handle *trans,
if (last_block > data.first_block) {
ret = record_file_blocks(trans, root, objectid, inode,
data.first_block, 0, last_block -
- data.first_block, 0);
+ data.first_block, datacsum);
if (ret)
goto fail;
}
@@ -1210,7 +1210,7 @@ fail:
* Create the ext2fs image file.
*/
static int create_ext2_image(struct btrfs_root *root, ext2_filsys ext2_fs,
- const char *name)
+ const char *name, int datacsum)
{
int ret;
struct btrfs_key key;
@@ -1231,11 +1231,14 @@ static int create_ext2_image(struct btrfs_root *root, ext2_filsys ext2_fs,
u64 last_byte;
u64 first_free;
u64 total_bytes;
+ u64 flags = BTRFS_INODE_READONLY;
u32 sectorsize = root->sectorsize;
total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1;
first_free &= ~((u64)sectorsize - 1);
+ if (!datacsum)
+ flags |= BTRFS_INODE_NODATASUM;
memset(&btrfs_inode, 0, sizeof(btrfs_inode));
btrfs_set_stack_inode_generation(&btrfs_inode, 1);
@@ -1243,8 +1246,7 @@ static int create_ext2_image(struct btrfs_root *root, ext2_filsys ext2_fs,
btrfs_set_stack_inode_nlink(&btrfs_inode, 1);
btrfs_set_stack_inode_nbytes(&btrfs_inode, 0);
btrfs_set_stack_inode_mode(&btrfs_inode, S_IFREG | 0400);
- btrfs_set_stack_inode_flags(&btrfs_inode, BTRFS_INODE_NODATASUM |
- BTRFS_INODE_READONLY);
+ btrfs_set_stack_inode_flags(&btrfs_inode, flags);
btrfs_init_path(&path);
trans = btrfs_start_transaction(root, 1);
BUG_ON(!trans);
@@ -1271,6 +1273,12 @@ static int create_ext2_image(struct btrfs_root *root, ext2_filsys ext2_fs,
key.objectid, sectorsize);
if (ret)
goto fail;
+ if (datacsum) {
+ ret = csum_disk_extent(trans, root, key.objectid,
+ sectorsize);
+ if (ret)
+ goto fail;
+ }
}
while(1) {
@@ -1323,7 +1331,8 @@ next:
if (bytenr > last_byte) {
ret = create_image_file_range(trans, root, objectid,
&btrfs_inode, last_byte,
- bytenr, ext2_fs);
+ bytenr, ext2_fs,
+ datacsum);
if (ret)
goto fail;
}
@@ -1346,7 +1355,8 @@ next:
if (total_bytes > last_byte) {
ret = create_image_file_range(trans, root, objectid,
&btrfs_inode, last_byte,
- total_bytes, ext2_fs);
+ total_bytes, ext2_fs,
+ datacsum);
if (ret)
goto fail;
}
@@ -2374,7 +2384,7 @@ static int do_convert(const char *devname, int datacsum, int packing, int noxatt
fprintf(stderr, "unable to create subvol\n");
goto fail;
}
- ret = create_ext2_image(ext2_root, ext2_fs, "image");
+ ret = create_ext2_image(ext2_root, ext2_fs, "image", datacsum);
if (ret) {
fprintf(stderr, "error during create_ext2_image %d\n", ret);
goto fail;