Commit 08f50005 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Run check_key_has_snapshot in snapshot_delete_keys()



delete_dead_snapshots now runs before the main fsck.c passes which check
for keys for invalid snapshots; thus, it needs those checks as well.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 82af5ceb
Loading
Loading
Loading
Loading
+4 −23
Original line number Diff line number Diff line
@@ -766,25 +766,6 @@ static int get_visible_inodes(struct btree_trans *trans,
	return ret;
}

static int check_key_has_snapshot(struct btree_trans *trans,
				  struct btree_iter *iter,
				  struct bkey_s_c k)
{
	struct bch_fs *c = trans->c;
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	if (mustfix_fsck_err_on(!bch2_snapshot_equiv(c, k.k->p.snapshot), c,
				bkey_in_missing_snapshot,
				"key in missing snapshot: %s",
				(bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
		ret = bch2_btree_delete_at(trans, iter,
					    BTREE_UPDATE_internal_snapshot_node) ?: 1;
fsck_err:
	printbuf_exit(&buf);
	return ret;
}

static int hash_redo_key(struct btree_trans *trans,
			 const struct bch_hash_desc desc,
			 struct bch_hash_info *hash_info,
@@ -979,7 +960,7 @@ static int check_inode(struct btree_trans *trans,
	bool do_update = false;
	int ret;

	ret = check_key_has_snapshot(trans, iter, k);
	ret = bch2_check_key_has_snapshot(trans, iter, k);
	if (ret < 0)
		goto err;
	if (ret)
@@ -1483,7 +1464,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter,
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	ret = check_key_has_snapshot(trans, iter, k);
	ret = bch2_check_key_has_snapshot(trans, iter, k);
	if (ret) {
		ret = ret < 0 ? ret : 0;
		goto out;
@@ -2006,7 +1987,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	ret = check_key_has_snapshot(trans, iter, k);
	ret = bch2_check_key_has_snapshot(trans, iter, k);
	if (ret) {
		ret = ret < 0 ? ret : 0;
		goto out;
@@ -2161,7 +2142,7 @@ static int check_xattr(struct btree_trans *trans, struct btree_iter *iter,
	struct inode_walker_entry *i;
	int ret;

	ret = check_key_has_snapshot(trans, iter, k);
	ret = bch2_check_key_has_snapshot(trans, iter, k);
	if (ret < 0)
		return ret;
	if (ret)
+24 −1
Original line number Diff line number Diff line
@@ -1042,6 +1042,25 @@ int bch2_reconstruct_snapshots(struct bch_fs *c)
	return ret;
}

int bch2_check_key_has_snapshot(struct btree_trans *trans,
				struct btree_iter *iter,
				struct bkey_s_c k)
{
	struct bch_fs *c = trans->c;
	struct printbuf buf = PRINTBUF;
	int ret = 0;

	if (fsck_err_on(!bch2_snapshot_equiv(c, k.k->p.snapshot), c,
			bkey_in_missing_snapshot,
			"key in missing snapshot %s, delete?",
			(bch2_bkey_val_to_text(&buf, c, k), buf.buf)))
		ret = bch2_btree_delete_at(trans, iter,
					    BTREE_UPDATE_internal_snapshot_node) ?: 1;
fsck_err:
	printbuf_exit(&buf);
	return ret;
}

/*
 * Mark a snapshot as deleted, for future cleanup:
 */
@@ -1358,6 +1377,10 @@ static int delete_dead_snapshots_process_key(struct btree_trans *trans,
			       snapshot_id_list *equiv_seen,
			       struct bpos *last_pos)
{
	int ret = bch2_check_key_has_snapshot(trans, iter, k);
	if (ret)
		return ret < 0 ? ret : 0;

	struct bch_fs *c = trans->c;
	u32 equiv = bch2_snapshot_equiv(c, k.k->p.snapshot);
	if (!equiv) /* key for invalid snapshot node, but we chose not to delete */
@@ -1377,7 +1400,7 @@ static int delete_dead_snapshots_process_key(struct btree_trans *trans,

	*last_pos = k.k->p;

	int ret = snapshot_list_add_nodup(c, equiv_seen, equiv);
	ret = snapshot_list_add_nodup(c, equiv_seen, equiv);
	if (ret)
		return ret;

+1 −0
Original line number Diff line number Diff line
@@ -242,6 +242,7 @@ int bch2_snapshot_node_create(struct btree_trans *, u32,
int bch2_check_snapshot_trees(struct bch_fs *);
int bch2_check_snapshots(struct bch_fs *);
int bch2_reconstruct_snapshots(struct bch_fs *);
int bch2_check_key_has_snapshot(struct btree_trans *, struct btree_iter *, struct bkey_s_c);

int bch2_snapshot_node_set_deleted(struct btree_trans *, u32);
void bch2_delete_dead_snapshots_work(struct work_struct *);