summaryrefslogtreecommitdiff
path: root/fs/bcachefs/subvolume.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-08-05 07:41:41 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:12 +0300
commit18443cb9f005b5563e2e3da9b8ccd374a552c3b1 (patch)
treefb5acd81fb8562bd790263562c65d3cdf45a02d4 /fs/bcachefs/subvolume.h
parent7a7d17b2f7c23c0891b0cbd13fafd3bc805b1b29 (diff)
downloadlinux-18443cb9f005b5563e2e3da9b8ccd374a552c3b1.tar.xz
bcachefs: Update data move path for snapshots
The data move path operates on existing extents, and not within a subvolume as the regular IO paths do. It needs to change because it may cause existing extents to be split, and when splitting an existing extent in an ancestor snapshot we need to make sure the new split has the same visibility in child snapshots as the existing extent. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/subvolume.h')
-rw-r--r--fs/bcachefs/subvolume.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/fs/bcachefs/subvolume.h b/fs/bcachefs/subvolume.h
index cea4c665af32..0740c7b7f772 100644
--- a/fs/bcachefs/subvolume.h
+++ b/fs/bcachefs/subvolume.h
@@ -54,6 +54,44 @@ static inline bool bch2_snapshot_is_ancestor(struct bch_fs *c, u32 id, u32 ances
return id == ancestor;
}
+struct snapshots_seen {
+ struct bpos pos;
+ size_t nr;
+ size_t size;
+ u32 *d;
+};
+
+static inline void snapshots_seen_exit(struct snapshots_seen *s)
+{
+ kfree(s->d);
+ s->d = NULL;
+}
+
+static inline void snapshots_seen_init(struct snapshots_seen *s)
+{
+ memset(s, 0, sizeof(*s));
+}
+
+static inline int snapshots_seen_add(struct bch_fs *c, struct snapshots_seen *s, u32 id)
+{
+ if (s->nr == s->size) {
+ size_t new_size = max(s->size, 128UL) * 2;
+ u32 *d = krealloc(s->d, new_size * sizeof(s->d[0]), GFP_KERNEL);
+
+ if (!d) {
+ bch_err(c, "error reallocating snapshots_seen table (new size %zu)",
+ new_size);
+ return -ENOMEM;
+ }
+
+ s->size = new_size;
+ s->d = d;
+ }
+
+ s->d[s->nr++] = id;
+ return 0;
+}
+
int bch2_fs_snapshots_check(struct bch_fs *);
void bch2_fs_snapshots_exit(struct bch_fs *);
int bch2_fs_snapshots_start(struct bch_fs *);