Skip to content

Commit ba26352

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 accept such new key objectid and 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 <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 0af979e commit ba26352

File tree

7 files changed

+55
-39
lines changed

7 files changed

+55
-39
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: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,10 +367,12 @@ 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-
if (unlikely(key->objectid != BTRFS_EXTENT_CSUM_OBJECTID)) {
370+
if (unlikely(key->objectid != BTRFS_EXTENT_CSUM_OBJECTID &&
371+
key->objectid != BTRFS_CSUM_CHANGE_OBJECTID)) {
371372
generic_err(leaf, slot,
372-
"invalid key objectid for csum item, have %llu expect %llu",
373-
key->objectid, BTRFS_EXTENT_CSUM_OBJECTID);
373+
"invalid key objectid for csum item, have %llu expect %llu or %llu",
374+
key->objectid, BTRFS_EXTENT_CSUM_OBJECTID,
375+
BTRFS_CSUM_CHANGE_OBJECTID);
374376
return -EUCLEAN;
375377
}
376378
if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) {
@@ -385,7 +387,9 @@ static int check_csum_item(struct extent_buffer *leaf, struct btrfs_key *key,
385387
btrfs_item_size(leaf, slot), csumsize);
386388
return -EUCLEAN;
387389
}
388-
if (slot > 0 && prev_key->type == BTRFS_EXTENT_CSUM_KEY) {
390+
if (slot > 0 && prev_key->type == BTRFS_EXTENT_CSUM_KEY &&
391+
!(key->objectid == BTRFS_CSUM_CHANGE_OBJECTID ||
392+
prev_key->objectid == BTRFS_CSUM_CHANGE_OBJECTID)) {
389393
u64 prev_csum_end;
390394
u32 prev_item_size;
391395

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)