Skip to content

Commit 46226c4

Browse files
adam900710kdave
authored andcommitted
btrfs-progs: tune: add the ability to delete old data csums
The new helper function, delete_old_data_csums(), would delete the old data csums while keep the new one untouched. Since the new data csums have a key objectid (-13) smaller than the old data csums (-10), we can safely delete from the tail of the btree. Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent fb44365 commit 46226c4

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

tune/change-csum.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,68 @@ static int generate_new_data_csums(struct btrfs_fs_info *fs_info, u16 new_csum_t
326326
return ret;
327327
}
328328

329+
static int delete_old_data_csums(struct btrfs_fs_info *fs_info)
330+
{
331+
struct btrfs_root *csum_root = btrfs_csum_root(fs_info, 0);
332+
struct btrfs_trans_handle *trans;
333+
struct btrfs_path path = { 0 };
334+
struct btrfs_key last_key;
335+
int ret;
336+
337+
last_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
338+
last_key.type = BTRFS_EXTENT_CSUM_KEY;
339+
last_key.offset = (u64)-1;
340+
341+
trans = btrfs_start_transaction(csum_root, 1);
342+
if (IS_ERR(trans)) {
343+
ret = PTR_ERR(trans);
344+
errno = -ret;
345+
error("failed to start transaction to delete old data csums: %m");
346+
return ret;
347+
}
348+
while (true) {
349+
int start_slot;
350+
int nr;
351+
352+
ret = btrfs_search_slot(trans, csum_root, &last_key, &path, -1, 1);
353+
354+
nr = btrfs_header_nritems(path.nodes[0]);
355+
/* No item left (empty csum tree), exit. */
356+
if (!nr)
357+
break;
358+
for (start_slot = 0; start_slot < nr; start_slot++) {
359+
struct btrfs_key found_key;
360+
361+
btrfs_item_key_to_cpu(path.nodes[0], &found_key, start_slot);
362+
/* Break from the for loop, we found the first old csum. */
363+
if (found_key.objectid == BTRFS_EXTENT_CSUM_OBJECTID)
364+
break;
365+
}
366+
/* No more old csum item detected, exit. */
367+
if (start_slot == nr)
368+
break;
369+
370+
/* Delete items starting from @start_slot to the end. */
371+
ret = btrfs_del_items(trans, csum_root, &path, start_slot,
372+
nr - start_slot);
373+
if (ret < 0) {
374+
errno = -ret;
375+
error("failed to delete items: %m");
376+
break;
377+
}
378+
btrfs_release_path(&path);
379+
}
380+
btrfs_release_path(&path);
381+
if (ret < 0)
382+
btrfs_abort_transaction(trans, ret);
383+
ret = btrfs_commit_transaction(trans, csum_root);
384+
if (ret < 0) {
385+
errno = -ret;
386+
error("failed to commit transaction after deleting the old data csums: %m");
387+
}
388+
return ret;
389+
}
390+
329391
int btrfs_change_csum_type(struct btrfs_fs_info *fs_info, u16 new_csum_type)
330392
{
331393
int ret;
@@ -350,6 +412,9 @@ int btrfs_change_csum_type(struct btrfs_fs_info *fs_info, u16 new_csum_type)
350412
}
351413

352414
/* Phase 2, delete the old data csums. */
415+
ret = delete_old_data_csums(fs_info);
416+
if (ret < 0)
417+
return ret;
353418

354419
/* Phase 3, change the new csum key objectid */
355420

0 commit comments

Comments
 (0)