Skip to content

Commit 63d6e93

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_fpunch_snapshot()
Add a new version of fpunch for operating on a snapshot ID, not a subvolume - and use it for "extent past end of inode" repair. Previously, repair would try to delete everything at once, but deleting too many extents at once can overflow the btree_trans bump allocator, as well as causing other problems - the new helper properly uses bch2_extent_trim_atomic(). Reported-and-tested-by: Edoardo Codeglia <[email protected]> Signed-off-by: Kent Overstreet <[email protected]>
1 parent 94426e4 commit 63d6e93

File tree

3 files changed

+35
-27
lines changed

3 files changed

+35
-27
lines changed

fs/bcachefs/fsck.c

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "fs.h"
1313
#include "fsck.h"
1414
#include "inode.h"
15+
#include "io_misc.h"
1516
#include "keylist.h"
1617
#include "namei.h"
1718
#include "recovery_passes.h"
@@ -1919,33 +1920,11 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
19191920
"extent type past end of inode %llu:%u, i_size %llu\n%s",
19201921
i->inode.bi_inum, i->inode.bi_snapshot, i->inode.bi_size,
19211922
(bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
1922-
struct bkey_i *whiteout = bch2_trans_kmalloc(trans, sizeof(*whiteout));
1923-
ret = PTR_ERR_OR_ZERO(whiteout);
1924-
if (ret)
1925-
goto err;
1926-
1927-
bkey_init(&whiteout->k);
1928-
whiteout->k.p = SPOS(k.k->p.inode,
1929-
last_block,
1930-
i->inode.bi_snapshot);
1931-
bch2_key_resize(&whiteout->k,
1932-
min(KEY_SIZE_MAX & (~0 << c->block_bits),
1933-
U64_MAX - whiteout->k.p.offset));
1934-
1935-
1936-
/*
1937-
* Need a normal (not BTREE_ITER_all_snapshots)
1938-
* iterator, if we're deleting in a different
1939-
* snapshot and need to emit a whiteout
1940-
*/
1941-
struct btree_iter iter2;
1942-
bch2_trans_iter_init(trans, &iter2, BTREE_ID_extents,
1943-
bkey_start_pos(&whiteout->k),
1944-
BTREE_ITER_intent);
1945-
ret = bch2_btree_iter_traverse(trans, &iter2) ?:
1946-
bch2_trans_update(trans, &iter2, whiteout,
1947-
BTREE_UPDATE_internal_snapshot_node);
1948-
bch2_trans_iter_exit(trans, &iter2);
1923+
ret = bch2_fpunch_snapshot(trans,
1924+
SPOS(i->inode.bi_inum,
1925+
last_block,
1926+
i->inode.bi_snapshot),
1927+
POS(i->inode.bi_inum, U64_MAX));
19491928
if (ret)
19501929
goto err;
19511930

fs/bcachefs/io_misc.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,33 @@ int bch2_extent_fallocate(struct btree_trans *trans,
135135
return ret;
136136
}
137137

138+
/* For fsck */
139+
int bch2_fpunch_snapshot(struct btree_trans *trans, struct bpos start, struct bpos end)
140+
{
141+
u32 restart_count = trans->restart_count;
142+
struct bch_fs *c = trans->c;
143+
struct disk_reservation disk_res = bch2_disk_reservation_init(c, 0);
144+
unsigned max_sectors = KEY_SIZE_MAX & (~0 << c->block_bits);
145+
struct bkey_i delete;
146+
147+
int ret = for_each_btree_key_max_commit(trans, iter, BTREE_ID_extents,
148+
start, end, 0, k,
149+
&disk_res, NULL, BCH_TRANS_COMMIT_no_enospc, ({
150+
bkey_init(&delete.k);
151+
delete.k.p = iter.pos;
152+
153+
/* create the biggest key we can */
154+
bch2_key_resize(&delete.k, max_sectors);
155+
bch2_cut_back(end, &delete);
156+
157+
bch2_extent_trim_atomic(trans, &iter, &delete) ?:
158+
bch2_trans_update(trans, &iter, &delete, 0);
159+
}));
160+
161+
bch2_disk_reservation_put(c, &disk_res);
162+
return ret ?: trans_was_restarted(trans, restart_count);
163+
}
164+
138165
/*
139166
* Returns -BCH_ERR_transacton_restart if we had to drop locks:
140167
*/

fs/bcachefs/io_misc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
int bch2_extent_fallocate(struct btree_trans *, subvol_inum, struct btree_iter *,
66
u64, struct bch_io_opts, s64 *,
77
struct write_point_specifier);
8+
9+
int bch2_fpunch_snapshot(struct btree_trans *, struct bpos, struct bpos);
810
int bch2_fpunch_at(struct btree_trans *, struct btree_iter *,
911
subvol_inum, u64, s64 *);
1012
int bch2_fpunch(struct bch_fs *c, subvol_inum, u64, u64, s64 *);

0 commit comments

Comments
 (0)