summaryrefslogtreecommitdiff
path: root/fs/bcachefs/subvolume.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-06-25 18:04:46 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:10:06 -0400
commitf26c67f4a7c4951a312547790b11066bc510822e (patch)
treea5f23a05f9a59dce45ffd1e9e354f73bd7279a2d /fs/bcachefs/subvolume.h
parent065bd3356ce490ae9454d8b3c98ff298e13d09ac (diff)
bcachefs: Snapshot depth, skiplist fields
This extents KEY_TYPE_snapshot to include some new fields: - depth, to indicate depth of this particular node from the root - skip[3], skiplist entries for quickly walking back up to the root These are to improve bch2_snapshot_is_ancestor(), making it O(ln(n)) instead of O(n) in the snapshot tree depth. Skiplist nodes are picked at random from the set of ancestor nodes, not some fixed fraction. This introduces bcachefs_metadata_version 1.1, snapshot_skiplists. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/subvolume.h')
-rw-r--r--fs/bcachefs/subvolume.h33
1 files changed, 26 insertions, 7 deletions
diff --git a/fs/bcachefs/subvolume.h b/fs/bcachefs/subvolume.h
index daa9a6b0819b..ab0b4a6de255 100644
--- a/fs/bcachefs/subvolume.h
+++ b/fs/bcachefs/subvolume.h
@@ -37,9 +37,34 @@ static inline struct snapshot_t *snapshot_t(struct bch_fs *c, u32 id)
return genradix_ptr(&c->snapshots, U32_MAX - id);
}
+static inline u32 bch2_snapshot_parent_early(struct bch_fs *c, u32 id)
+{
+ return snapshot_t(c, id)->parent;
+}
+
static inline u32 bch2_snapshot_parent(struct bch_fs *c, u32 id)
{
+#ifdef CONFIG_BCACHEFS_DEBUG
+ u32 parent = snapshot_t(c, id)->parent;
+
+ if (parent &&
+ snapshot_t(c, id)->depth != snapshot_t(c, parent)->depth + 1)
+ panic("id %u depth=%u parent %u depth=%u\n",
+ id, snapshot_t(c, id)->depth,
+ parent, snapshot_t(c, parent)->depth);
+
+ return parent;
+#else
return snapshot_t(c, id)->parent;
+#endif
+}
+
+static inline u32 bch2_snapshot_nth_parent(struct bch_fs *c, u32 id, u32 n)
+{
+ while (n--)
+ id = bch2_snapshot_parent(c, id);
+
+ return id;
}
static inline u32 bch2_snapshot_root(struct bch_fs *c, u32 id)
@@ -84,13 +109,7 @@ static inline u32 bch2_snapshot_sibling(struct bch_fs *c, u32 id)
return 0;
}
-static inline bool bch2_snapshot_is_ancestor(struct bch_fs *c, u32 id, u32 ancestor)
-{
- while (id && id < ancestor)
- id = bch2_snapshot_parent(c, id);
-
- return id == ancestor;
-}
+bool bch2_snapshot_is_ancestor(struct bch_fs *, u32, u32);
static inline bool bch2_snapshot_has_children(struct bch_fs *c, u32 id)
{