bcachefs: Fix bpos_diff()
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 4 Mar 2021 21:26:19 +0000 (16:26 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:55 +0000 (17:08 -0400)
Previously, bpos_diff() did not handle borrows correctly. Minor thing
considering how it was used, but worth fixing.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bkey.h
fs/bcachefs/btree_iter.c

index 25cb5e985109f9dc4aa7e4d6f08eee2f74fb9d7f..77d9d871adfbd57d51f809cdc10ec7527608a54a 100644 (file)
@@ -183,6 +183,37 @@ static inline struct bpos bpos_max(struct bpos l, struct bpos r)
        return bkey_cmp(l, r) > 0 ? l : r;
 }
 
+#define sbb(a, b, borrow)                              \
+do {                                                   \
+       typeof(a) d1, d2;                               \
+                                                       \
+       d1 = a - borrow;                                \
+       borrow  = d1 > a;                               \
+                                                       \
+       d2 = d1 - b;                                    \
+       borrow += d2 > d1;                              \
+       a = d2;                                         \
+} while (0)
+
+/* returns a - b: */
+static inline struct bpos bpos_sub(struct bpos a, struct bpos b)
+{
+       int borrow = 0;
+
+       sbb(a.snapshot, b.snapshot,     borrow);
+       sbb(a.offset,   b.offset,       borrow);
+       sbb(a.inode,    b.inode,        borrow);
+       return a;
+}
+
+static inline struct bpos bpos_diff(struct bpos l, struct bpos r)
+{
+       if (bkey_cmp(l, r) > 0)
+               swap(l, r);
+
+       return bpos_sub(r, l);
+}
+
 void bch2_bpos_swab(struct bpos *);
 void bch2_bkey_swab_key(const struct bkey_format *, struct bkey_packed *);
 
index 69d15bb20c7cf96bcb8b8fe4bed94b1bb1625ea7..bf59678b609e2786f834a95a087f7e19fc626a10 100644 (file)
@@ -2067,14 +2067,6 @@ static inline void btree_iter_copy(struct btree_iter *dst,
        dst->flags &= ~BTREE_ITER_SET_POS_AFTER_COMMIT;
 }
 
-static inline struct bpos bpos_diff(struct bpos l, struct bpos r)
-{
-       if (bkey_cmp(l, r) > 0)
-               swap(l, r);
-
-       return POS(r.inode - l.inode, r.offset - l.offset);
-}
-
 static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans,
                                                 unsigned btree_id, struct bpos pos,
                                                 unsigned flags)