+ struct bch_fs *c = trans->c;
+ struct printbuf buf = PRINTBUF;
+ struct btree_iter iter;
+ struct bkey_s_c k;
+ u32 snapshot = min(pos1.snapshot, pos2.p.snapshot);
+ int ret;
+
+ BUG_ON(bkey_le(pos1, bkey_start_pos(&pos2)));
+
+ prt_str(&buf, "\n ");
+ bch2_bpos_to_text(&buf, pos1);
+ prt_str(&buf, "\n ");
+
+ bch2_bkey_to_text(&buf, &pos2);
+ prt_str(&buf, "\n ");
+
+ bch2_trans_iter_init(trans, &iter, btree, SPOS(pos1.inode, pos1.offset - 1, snapshot), 0);
+ k = bch2_btree_iter_peek_upto(&iter, POS(pos1.inode, U64_MAX));
+ ret = bkey_err(k);
+ if (ret)
+ goto err;
+
+ bch2_bkey_val_to_text(&buf, c, k);
+
+ if (!bpos_eq(pos1, k.k->p)) {
+ bch_err(c, "%s: error finding first overlapping extent when repairing%s",
+ __func__, buf.buf);
+ ret = -BCH_ERR_internal_fsck_err;
+ goto err;
+ }
+
+ while (1) {
+ bch2_btree_iter_advance(&iter);
+
+ k = bch2_btree_iter_peek_upto(&iter, POS(pos1.inode, U64_MAX));
+ ret = bkey_err(k);
+ if (ret)
+ goto err;
+
+ if (bkey_ge(k.k->p, pos2.p))
+ break;
+
+ }
+
+ prt_str(&buf, "\n ");
+ bch2_bkey_val_to_text(&buf, c, k);
+
+ if (bkey_gt(k.k->p, pos2.p) ||
+ pos2.size != k.k->size) {
+ bch_err(c, "%s: error finding seconding overlapping extent when repairing%s",
+ __func__, buf.buf);
+ ret = -BCH_ERR_internal_fsck_err;
+ goto err;
+ }
+
+ if (fsck_err(c, "overlapping extents%s", buf.buf)) {
+ struct bpos update_pos = pos1.snapshot < pos2.p.snapshot ? pos1 : pos2.p;
+ struct btree_iter update_iter;
+
+ struct bkey_i *update = bch2_bkey_get_mut(trans, &update_iter,
+ btree, update_pos,
+ BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE);
+ bch2_trans_iter_exit(trans, &update_iter);
+ if ((ret = PTR_ERR_OR_ZERO(update)))
+ goto err;
+
+ *fixed = true;
+ }
+fsck_err:
+err:
+ bch2_trans_iter_exit(trans, &iter);
+ printbuf_exit(&buf);
+ return ret;
+}
+
+static int check_overlapping_extents(struct btree_trans *trans,
+ struct snapshots_seen *seen,
+ struct extent_ends *extent_ends,
+ struct bkey_s_c k,
+ u32 equiv,
+ struct btree_iter *iter)
+{
+ struct bch_fs *c = trans->c;