summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_update.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-05-28 06:19:13 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:10:03 +0300
commitad520141b155786800261cc7e02ec02f0afe2643 (patch)
treee4057e58691102680f0a988472c06f0cca56e4c8 /fs/bcachefs/btree_update.h
parente47a390aa5946e3c5bea7a4a350a88d3bb3ba5b4 (diff)
downloadlinux-ad520141b155786800261cc7e02ec02f0afe2643.tar.xz
bcachefs: Fix corruption with writeable snapshots
When partially overwriting an extent in an older snapshot, the existing extent has to be split. If the existing extent was overwritten in a different (sibling) snapshot, we have to ensure that the split won't be visible in the sibling snapshot. data_update.c already has code for this, bch2_insert_snapshot_writeouts() - we just need to move it into btree_update_leaf.c and change bch2_trans_update_extent() to use it as well. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_update.h')
-rw-r--r--fs/bcachefs/btree_update.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h
index 1ac3a81e0af6..e90cf292f80b 100644
--- a/fs/bcachefs/btree_update.h
+++ b/fs/bcachefs/btree_update.h
@@ -4,6 +4,7 @@
#include "btree_iter.h"
#include "journal.h"
+#include "journal.h"
struct bch_fs;
struct btree;
@@ -83,6 +84,28 @@ int bch2_btree_node_update_key(struct btree_trans *, struct btree_iter *,
int bch2_btree_node_update_key_get_iter(struct btree_trans *,
struct btree *, struct bkey_i *, bool);
+int __bch2_insert_snapshot_whiteouts(struct btree_trans *, enum btree_id,
+ struct bpos, struct bpos);
+
+/*
+ * For use when splitting extents in existing snapshots:
+ *
+ * If @old_pos is an interior snapshot node, iterate over descendent snapshot
+ * nodes: for every descendent snapshot in whiche @old_pos is overwritten and
+ * not visible, emit a whiteout at @new_pos.
+ */
+static inline int bch2_insert_snapshot_whiteouts(struct btree_trans *trans,
+ enum btree_id btree,
+ struct bpos old_pos,
+ struct bpos new_pos)
+{
+ if (!btree_type_has_snapshots(btree) ||
+ bkey_eq(old_pos, new_pos))
+ return 0;
+
+ return __bch2_insert_snapshot_whiteouts(trans, btree, old_pos, new_pos);
+}
+
int bch2_trans_update_extent(struct btree_trans *, struct btree_iter *,
struct bkey_i *, enum btree_update_flags);