bcachefs: Check for redundant ec entries/stripe ptrs
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 22 Feb 2023 04:51:19 +0000 (23:51 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:54 +0000 (17:09 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/extents.c

index 2e41545dc1e9574b673cd7c81451481b63fb38a3..a55e0ed75548b229476f8f1ca69fe218798f6586 100644 (file)
@@ -1116,7 +1116,7 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
        unsigned size_ondisk = k.k->size;
        unsigned nonce = UINT_MAX;
        unsigned nr_ptrs = 0;
-       bool unwritten = false, have_ec = false;
+       bool unwritten = false, have_ec = false, crc_since_last_ptr = false;
        int ret;
 
        if (bkey_is_btree_ptr(k.k))
@@ -1159,6 +1159,7 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
 
                        unwritten = entry->ptr.unwritten;
                        have_ec = false;
+                       crc_since_last_ptr = false;
                        nr_ptrs++;
                        break;
                case BCH_EXTENT_ENTRY_crc32:
@@ -1192,18 +1193,43 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
                                        return -BCH_ERR_invalid_bkey;
                                }
                        }
+
+                       if (crc_since_last_ptr) {
+                               prt_printf(err, "redundant crc entry");
+                               return -BCH_ERR_invalid_bkey;
+                       }
+                       crc_since_last_ptr = true;
                        break;
                case BCH_EXTENT_ENTRY_stripe_ptr:
+                       if (have_ec) {
+                               prt_printf(err, "redundant stripe entry");
+                               return -BCH_ERR_invalid_bkey;
+                       }
                        have_ec = true;
                        break;
                }
        }
 
+       if (!nr_ptrs) {
+               prt_str(err, "no ptrs");
+               return -BCH_ERR_invalid_bkey;
+       }
+
        if (nr_ptrs >= BCH_BKEY_PTRS_MAX) {
                prt_str(err, "too many ptrs");
                return -BCH_ERR_invalid_bkey;
        }
 
+       if (crc_since_last_ptr) {
+               prt_printf(err, "redundant crc entry");
+               return -BCH_ERR_invalid_bkey;
+       }
+
+       if (have_ec) {
+               prt_printf(err, "redundant stripe entry");
+               return -BCH_ERR_invalid_bkey;
+       }
+
        return 0;
 }