Skip to content

Commit fb44365

Browse files
adam900710kdave
authored andcommitted
btrfs-progs: tune: add the ability to generate new data checksums
This patch would modify btrfs_csum_file_block() to handle csum type other than the one used in the current fs. The new data checksum would use a different objectid (-13) to distinguish with the existing one (-10). This needs to change tree-checker to skip the item size checks, since new csum can be larger than the original csum. After this stage, the resulted csum tree would look like this: item 0 key (CSUM_CHANGE EXTENT_CSUM 13631488) itemoff 8091 itemsize 8192 range start 13631488 end 22020096 length 8388608 item 1 key (EXTENT_CSUM EXTENT_CSUM 13631488) itemoff 7067 itemsize 1024 range start 13631488 end 14680064 length 1048576 Note the itemsize is 8 times the original one, as the original csum is CRC32, while target csum is SHA256, which is 8 times the size. Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 86eb549 commit fb44365

File tree

7 files changed

+52
-35
lines changed

7 files changed

+52
-35
lines changed

check/mode-common.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,18 +1209,19 @@ static int populate_csum(struct btrfs_trans_handle *trans,
12091209
struct btrfs_root *csum_root, char *buf, u64 start,
12101210
u64 len)
12111211
{
1212+
struct btrfs_fs_info *fs_info = trans->fs_info;
12121213
u64 offset = 0;
1213-
u64 sectorsize;
1214+
u64 sectorsize = fs_info->sectorsize;
12141215
int ret = 0;
12151216

12161217
while (offset < len) {
1217-
sectorsize = gfs_info->sectorsize;
1218-
ret = read_data_from_disk(gfs_info, buf, start + offset,
1218+
ret = read_data_from_disk(fs_info, buf, start + offset,
12191219
&sectorsize, 0);
12201220
if (ret)
12211221
break;
1222-
ret = btrfs_csum_file_block(trans, start + len, start + offset,
1223-
buf, sectorsize);
1222+
ret = btrfs_csum_file_block(trans, start + offset,
1223+
BTRFS_EXTENT_CSUM_OBJECTID,
1224+
fs_info->csum_type, buf);
12241225
if (ret)
12251226
break;
12261227
offset += sectorsize;

convert/main.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ static int csum_disk_extent(struct btrfs_trans_handle *trans,
182182
struct btrfs_root *root,
183183
u64 disk_bytenr, u64 num_bytes)
184184
{
185-
u32 blocksize = root->fs_info->sectorsize;
185+
struct btrfs_fs_info *fs_info = trans->fs_info;
186+
u32 blocksize = fs_info->sectorsize;
186187
u64 offset;
187188
char *buffer;
188189
int ret = 0;
@@ -193,7 +194,7 @@ static int csum_disk_extent(struct btrfs_trans_handle *trans,
193194
for (offset = 0; offset < num_bytes; offset += blocksize) {
194195
u64 read_len = blocksize;
195196

196-
ret = read_data_from_disk(root->fs_info, buffer,
197+
ret = read_data_from_disk(fs_info, buffer,
197198
disk_bytenr + offset, &read_len, 0);
198199
if (ret)
199200
break;
@@ -203,10 +204,9 @@ static int csum_disk_extent(struct btrfs_trans_handle *trans,
203204
ret = -EIO;
204205
break;
205206
}
206-
ret = btrfs_csum_file_block(trans,
207-
disk_bytenr + num_bytes,
208-
disk_bytenr + offset,
209-
buffer, blocksize);
207+
ret = btrfs_csum_file_block(trans, disk_bytenr + offset,
208+
BTRFS_EXTENT_CSUM_OBJECTID,
209+
fs_info->csum_type, buffer);
210210
if (ret)
211211
break;
212212
}

kernel-shared/file-item.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,18 @@ static struct btrfs_csum_item *
134134
btrfs_lookup_csum(struct btrfs_trans_handle *trans,
135135
struct btrfs_root *root,
136136
struct btrfs_path *path,
137-
u64 bytenr, int cow)
137+
u64 bytenr, u64 csum_objectid, u16 csum_type, int cow)
138138
{
139139
int ret;
140140
struct btrfs_key file_key;
141141
struct btrfs_key found_key;
142142
struct btrfs_csum_item *item;
143143
struct extent_buffer *leaf;
144144
u64 csum_offset = 0;
145-
u16 csum_size = root->fs_info->csum_size;
145+
u16 csum_size = btrfs_csum_type_size(csum_type);
146146
int csums_in_item;
147147

148-
file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
148+
file_key.objectid = csum_objectid;
149149
file_key.offset = bytenr;
150150
file_key.type = BTRFS_EXTENT_CSUM_KEY;
151151
ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
@@ -159,7 +159,8 @@ btrfs_lookup_csum(struct btrfs_trans_handle *trans,
159159
goto fail;
160160
path->slots[0]--;
161161
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
162-
if (found_key.type != BTRFS_EXTENT_CSUM_KEY)
162+
if (found_key.type != BTRFS_EXTENT_CSUM_KEY ||
163+
found_key.objectid != csum_objectid)
163164
goto fail;
164165

165166
csum_offset = (bytenr - found_key.offset) /
@@ -182,10 +183,10 @@ btrfs_lookup_csum(struct btrfs_trans_handle *trans,
182183
return ERR_PTR(ret);
183184
}
184185

185-
int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
186-
u64 alloc_end, u64 bytenr, char *data, size_t len)
186+
int btrfs_csum_file_block(struct btrfs_trans_handle *trans, u64 logical,
187+
u64 csum_objectid, u32 csum_type, const char *data)
187188
{
188-
struct btrfs_root *root = btrfs_csum_root(trans->fs_info, bytenr);
189+
struct btrfs_root *root = btrfs_csum_root(trans->fs_info, logical);
189190
int ret = 0;
190191
struct btrfs_key file_key;
191192
struct btrfs_key found_key;
@@ -199,18 +200,18 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
199200
u32 sectorsize = root->fs_info->sectorsize;
200201
u32 nritems;
201202
u32 ins_size;
202-
u16 csum_size = root->fs_info->csum_size;
203-
u16 csum_type = root->fs_info->csum_type;
203+
u16 csum_size = btrfs_csum_type_size(csum_type);
204204

205205
path = btrfs_alloc_path();
206206
if (!path)
207207
return -ENOMEM;
208208

209-
file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
210-
file_key.offset = bytenr;
209+
file_key.objectid = csum_objectid;
210+
file_key.offset = logical;
211211
file_key.type = BTRFS_EXTENT_CSUM_KEY;
212212

213-
item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
213+
item = btrfs_lookup_csum(trans, root, path, logical, csum_objectid,
214+
csum_type, 1);
214215
if (!IS_ERR(item)) {
215216
leaf = path->nodes[0];
216217
ret = 0;
@@ -241,7 +242,7 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
241242
slot = 0;
242243
}
243244
btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
244-
if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
245+
if (found_key.objectid != csum_objectid ||
245246
found_key.type != BTRFS_EXTENT_CSUM_KEY) {
246247
found_next = 1;
247248
goto insert;
@@ -270,7 +271,7 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
270271
leaf = path->nodes[0];
271272
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
272273
csum_offset = (file_key.offset - found_key.offset) / sectorsize;
273-
if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
274+
if (found_key.objectid != csum_objectid ||
274275
found_key.type != BTRFS_EXTENT_CSUM_KEY ||
275276
csum_offset >= MAX_CSUM_ITEMS(root, csum_size)) {
276277
goto insert;
@@ -290,7 +291,7 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
290291
btrfs_release_path(path);
291292
csum_offset = 0;
292293
if (found_next) {
293-
u64 tmp = min(alloc_end, next_offset);
294+
u64 tmp = min(logical + sectorsize, next_offset);
294295
tmp -= file_key.offset;
295296
tmp /= sectorsize;
296297
tmp = max((u64)1, tmp);
@@ -314,7 +315,8 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
314315
item = (struct btrfs_csum_item *)((unsigned char *)item +
315316
csum_offset * csum_size);
316317
found:
317-
btrfs_csum_data(root->fs_info, csum_type, (u8 *)data, csum_result, len);
318+
btrfs_csum_data(root->fs_info, csum_type, (u8 *)data, csum_result,
319+
sectorsize);
318320
write_extent_buffer(leaf, csum_result, (unsigned long)item,
319321
csum_size);
320322
btrfs_mark_buffer_dirty(path->nodes[0]);

kernel-shared/file-item.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
8080
struct btrfs_root *root,
8181
u64 objectid, u64 pos, u64 offset,
8282
u64 disk_num_bytes, u64 num_bytes);
83-
int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
84-
u64 alloc_end, u64 bytenr, char *data, size_t len);
83+
int btrfs_csum_file_block(struct btrfs_trans_handle *trans, u64 logical,
84+
u64 csum_objectid, u32 csum_type, const char *data);
8585
int btrfs_insert_inline_extent(struct btrfs_trans_handle *trans,
8686
struct btrfs_root *root, u64 objectid,
8787
u64 offset, const char *buffer, size_t size);

kernel-shared/tree-checker.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,11 @@ static int check_csum_item(struct extent_buffer *leaf, struct btrfs_key *key,
367367
u32 sectorsize = fs_info->sectorsize;
368368
const u32 csumsize = fs_info->csum_size;
369369

370+
/* For fs under csum change, we should not check the regular csum items. */
371+
if (unlikely(btrfs_super_flags(fs_info->super_copy) &
372+
(BTRFS_SUPER_FLAG_CHANGING_DATA_CSUM |
373+
BTRFS_SUPER_FLAG_CHANGING_META_CSUM)))
374+
return 0;
370375
if (unlikely(key->objectid != BTRFS_EXTENT_CSUM_OBJECTID)) {
371376
generic_err(leaf, slot,
372377
"invalid key objectid for csum item, have %llu expect %llu",

mkfs/rootdir.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,13 @@ static int add_file_items(struct btrfs_trans_handle *trans,
306306
struct btrfs_inode_item *btrfs_inode, u64 objectid,
307307
struct stat *st, const char *path_name)
308308
{
309+
struct btrfs_fs_info *fs_info = trans->fs_info;
309310
int ret = -1;
310311
ssize_t ret_read;
311312
u64 bytes_read = 0;
312313
struct btrfs_key key;
313314
int blocks;
314-
u32 sectorsize = root->fs_info->sectorsize;
315+
u32 sectorsize = fs_info->sectorsize;
315316
u64 first_block = 0;
316317
u64 file_pos = 0;
317318
u64 cur_bytes;
@@ -332,7 +333,7 @@ static int add_file_items(struct btrfs_trans_handle *trans,
332333
if (st->st_size % sectorsize)
333334
blocks += 1;
334335

335-
if (st->st_size <= BTRFS_MAX_INLINE_DATA_SIZE(root->fs_info) &&
336+
if (st->st_size <= BTRFS_MAX_INLINE_DATA_SIZE(fs_info) &&
336337
st->st_size < sectorsize) {
337338
char *buffer = malloc(st->st_size);
338339

@@ -397,9 +398,9 @@ static int add_file_items(struct btrfs_trans_handle *trans,
397398
goto end;
398399
}
399400

400-
ret = btrfs_csum_file_block(trans,
401-
first_block + bytes_read + sectorsize,
402-
first_block + bytes_read, buf, sectorsize);
401+
ret = btrfs_csum_file_block(trans, first_block + bytes_read,
402+
BTRFS_EXTENT_CSUM_OBJECTID,
403+
fs_info->csum_type, buf);
403404
if (ret)
404405
goto end;
405406

tune/change-csum.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "kernel-shared/ctree.h"
2222
#include "kernel-shared/disk-io.h"
2323
#include "kernel-shared/volumes.h"
24+
#include "kernel-shared/file-item.h"
2425
#include "kernel-shared/extent_io.h"
2526
#include "kernel-shared/transaction.h"
2627
#include "common/messages.h"
@@ -180,7 +181,14 @@ static int generate_new_csum_range(struct btrfs_trans_handle *trans,
180181
goto out;
181182
}
182183
/* Calculate new csum and insert it into the csum tree. */
183-
ret = -EOPNOTSUPP;
184+
ret = btrfs_csum_file_block(trans, cur,
185+
BTRFS_CSUM_CHANGE_OBJECTID, new_csum_type, buf);
186+
if (ret < 0) {
187+
errno = -ret;
188+
error("failed to insert new csum for data at logical %llu: %m",
189+
cur);
190+
goto out;
191+
}
184192
}
185193
out:
186194
free(buf);

0 commit comments

Comments
 (0)