bcachefs: bch2_get_snapshot_overwrites()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 28 May 2025 19:08:19 +0000 (15:08 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 1 Jun 2025 02:03:17 +0000 (22:03 -0400)
New helper for getting a list of snapshot IDs that have overwritten a
given key.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_update.c
fs/bcachefs/snapshot.c
fs/bcachefs/snapshot.h

index 5dac09c98026ca27e3e0d4bfd7ed3c77f53184f7..48af3d2e3da90382727eb416bd3498965e8dfb45 100644 (file)
@@ -180,8 +180,19 @@ int __bch2_insert_snapshot_whiteouts(struct btree_trans *trans,
        }
        bch2_trans_iter_exit(trans, &new_iter);
        bch2_trans_iter_exit(trans, &old_iter);
-       darray_exit(&s);
 
+       snapshot_id_list s2;
+       ret = bch2_get_snapshot_overwrites(trans, id, old_pos, &s2);
+       if (ret) {
+               darray_exit(&s);
+               return ret;
+       }
+
+       BUG_ON(s.nr != s2.nr);
+       BUG_ON(memcmp(s.data, s2.data, sizeof(s.data[0]) * s.nr));
+
+       darray_exit(&s2);
+       darray_exit(&s);
        return ret;
 }
 
index 00d62d1190ef060c9b36b440a7a2fed3ea429653..f553fe095f61f45b4722e9763206cf281c8843b8 100644 (file)
@@ -1079,6 +1079,35 @@ fsck_err:
        return ret;
 }
 
+int __bch2_get_snapshot_overwrites(struct btree_trans *trans,
+                                  enum btree_id btree, struct bpos pos,
+                                  snapshot_id_list *s)
+{
+       struct bch_fs *c = trans->c;
+       struct btree_iter iter;
+       struct bkey_s_c k;
+       int ret = 0;
+
+       for_each_btree_key_reverse_norestart(trans, iter, btree, bpos_predecessor(pos),
+                                            BTREE_ITER_all_snapshots, k, ret) {
+               if (!bkey_eq(k.k->p, pos))
+                       break;
+
+               if (!bch2_snapshot_is_ancestor(c, k.k->p.snapshot, pos.snapshot) ||
+                   snapshot_list_has_ancestor(c, s, k.k->p.snapshot))
+                       continue;
+
+               ret = snapshot_list_add(c, s, k.k->p.snapshot);
+               if (ret)
+                       break;
+       }
+       bch2_trans_iter_exit(trans, &iter);
+       if (ret)
+               darray_exit(s);
+
+       return ret;
+}
+
 /*
  * Mark a snapshot as deleted, for future cleanup:
  */
index 382a171f541327f7ce21bf70a16c3ba4c2fc2fce..be7b71c0662124d47c6ec98a01c420c7a42ee157 100644 (file)
@@ -258,6 +258,25 @@ static inline int bch2_check_key_has_snapshot(struct btree_trans *trans,
                : __bch2_check_key_has_snapshot(trans, iter, k);
 }
 
+int __bch2_get_snapshot_overwrites(struct btree_trans *,
+                                  enum btree_id, struct bpos,
+                                  snapshot_id_list *);
+
+/*
+ * Get a list of snapshot IDs that have overwritten a given key:
+ */
+static inline int bch2_get_snapshot_overwrites(struct btree_trans *trans,
+                                              enum btree_id btree, struct bpos pos,
+                                              snapshot_id_list *s)
+{
+       darray_init(s);
+
+       return bch2_snapshot_has_children(trans->c, pos.snapshot)
+               ? __bch2_get_snapshot_overwrites(trans, btree, pos, s)
+               : 0;
+
+}
+
 int bch2_snapshot_node_set_deleted(struct btree_trans *, u32);
 
 int __bch2_key_has_snapshot_overwrites(struct btree_trans *, enum btree_id, struct bpos);