bcachefs: extent_entry_next_safe()
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 8 Mar 2024 20:25:27 +0000 (15:25 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 10 Mar 2024 19:12:13 +0000 (15:12 -0400)
We need to be able to iterate over extent ptrs that may be corrupted in
order to print them - this fixes a bug where we'd pop an assert in
bch2_bkey_durability_safe().

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/extents.h

index 6bf839d69e84e6e24ed3bf2bf611177fc04676e1..6219f2c08e4c737abd477588419c0f0dbeecbc38 100644 (file)
@@ -43,6 +43,11 @@ enum bkey_invalid_flags;
 #define extent_entry_next(_entry)                                      \
        ((typeof(_entry)) ((void *) (_entry) + extent_entry_bytes(_entry)))
 
+#define extent_entry_next_safe(_entry, _end)                           \
+       (likely(__extent_entry_type(_entry) < BCH_EXTENT_ENTRY_MAX)     \
+        ? extent_entry_next(_entry)                                    \
+        : _end)
+
 static inline unsigned
 __extent_entry_type(const union bch_extent_entry *e)
 {
@@ -280,7 +285,7 @@ static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k)
 #define __bkey_extent_entry_for_each_from(_start, _end, _entry)                \
        for ((_entry) = (_start);                                       \
             (_entry) < (_end);                                         \
-            (_entry) = extent_entry_next(_entry))
+            (_entry) = extent_entry_next_safe(_entry, _end))
 
 #define __bkey_ptr_next(_ptr, _end)                                    \
 ({                                                                     \
@@ -318,7 +323,7 @@ static inline struct bkey_ptrs bch2_bkey_ptrs(struct bkey_s k)
        (_ptr).has_ec   = false;                                        \
                                                                        \
        __bkey_extent_entry_for_each_from(_entry, _end, _entry)         \
-               switch (extent_entry_type(_entry)) {                    \
+               switch (__extent_entry_type(_entry)) {                  \
                case BCH_EXTENT_ENTRY_ptr:                              \
                        (_ptr).ptr              = _entry->ptr;          \
                        goto out;                                       \
@@ -344,7 +349,7 @@ out:                                                                        \
        for ((_ptr).crc = bch2_extent_crc_unpack(_k, NULL),             \
             (_entry) = _start;                                         \
             __bkey_ptr_next_decode(_k, _end, _ptr, _entry);            \
-            (_entry) = extent_entry_next(_entry))
+            (_entry) = extent_entry_next_safe(_entry, _end))
 
 #define bkey_for_each_ptr_decode(_k, _p, _ptr, _entry)                 \
        __bkey_for_each_ptr_decode(_k, (_p).start, (_p).end,            \