Skip to content

Commit 0224d17

Browse files
author
Kent Overstreet
committed
bcachefs: Runtime self healing for keys for deleted snapshots
If snapshot deletion incorrectly missing some keys and leaves keys for deleted snapshots, that causes a bit of a problem for data move - we can't move an extent for a nonexistent snapshot, because the extent might have to be fragmented, and maintaining correct visibility in child snapshots doesn't work if it doesn't have a snapshot. Previously we'd just skip these keys, but it turns out that causes copygc to spin. So we need runtime self healing, i.e. calling check_key_has_snapshot() from the data move path. Snapshot deletion v2 included sentinal values for deleted snapshot nodes, so this is quite safe. Signed-off-by: Kent Overstreet <[email protected]>
1 parent f02d153 commit 0224d17

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

fs/bcachefs/data_update.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -821,13 +821,24 @@ int bch2_data_update_init(struct btree_trans *trans,
821821
struct bch_fs *c = trans->c;
822822
int ret = 0;
823823

824-
/*
825-
* fs is corrupt we have a key for a snapshot node that doesn't exist,
826-
* and we have to check for this because we go rw before repairing the
827-
* snapshots table - just skip it, we can move it later.
828-
*/
829-
if (unlikely(k.k->p.snapshot && !bch2_snapshot_exists(c, k.k->p.snapshot)))
830-
return -BCH_ERR_data_update_done_no_snapshot;
824+
if (k.k->p.snapshot) {
825+
/*
826+
* We'll go ERO if we see a key for a missing snapshot, and if
827+
* we're still in recovery we want to give that a chance to
828+
* repair:
829+
*/
830+
if (unlikely(test_bit(BCH_FS_in_recovery, &c->flags) &&
831+
bch2_snapshot_id_state(c, k.k->p.snapshot) == SNAPSHOT_ID_empty))
832+
return -BCH_ERR_data_update_done_no_snapshot;
833+
834+
ret = bch2_check_key_has_snapshot(trans, iter, k);
835+
if (ret < 0)
836+
return ret;
837+
if (ret) /* key was deleted */
838+
return bch2_trans_commit(trans, NULL, NULL, BCH_TRANS_COMMIT_no_enospc) ?:
839+
-BCH_ERR_data_update_done_no_snapshot;
840+
ret = 0;
841+
}
831842

832843
bch2_bkey_buf_init(&m->k);
833844
bch2_bkey_buf_reassemble(&m->k, c, k);

0 commit comments

Comments
 (0)