]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/extents.c
Update bcachefs sources to 95ff72a6c1 fixup! mm: Centralize & improve oom reporting...
[bcachefs-tools-debian] / libbcachefs / extents.c
index 73d756a63572fdbaab4582af6032e62b6bf595f7..2ca13014b9c44537057cddceb1da03065c54cca6 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <trace/events/bcachefs.h>
 
+static union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s, struct bch_extent_ptr *);
+
 static unsigned bch2_crc_field_size_max[] = {
        [BCH_EXTENT_ENTRY_crc32] = CRC32_SIZE_MAX,
        [BCH_EXTENT_ENTRY_crc64] = CRC64_SIZE_MAX,
@@ -688,37 +690,6 @@ unsigned bch2_bkey_durability(struct bch_fs *c, struct bkey_s_c k)
        return durability;
 }
 
-void bch2_bkey_mark_replicas_cached(struct bch_fs *c, struct bkey_s k,
-                                   unsigned target,
-                                   unsigned nr_desired_replicas)
-{
-       struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
-       union bch_extent_entry *entry;
-       struct extent_ptr_decoded p;
-       int extra = bch2_bkey_durability(c, k.s_c) - nr_desired_replicas;
-
-       if (target && extra > 0)
-               bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
-                       int n = bch2_extent_ptr_durability(c, p);
-
-                       if (n && n <= extra &&
-                           !bch2_dev_in_target(c, p.ptr.dev, target)) {
-                               entry->ptr.cached = true;
-                               extra -= n;
-                       }
-               }
-
-       if (extra > 0)
-               bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
-                       int n = bch2_extent_ptr_durability(c, p);
-
-                       if (n && n <= extra) {
-                               entry->ptr.cached = true;
-                               extra -= n;
-                       }
-               }
-}
-
 void bch2_bkey_extent_entry_drop(struct bkey_i *k, union bch_extent_entry *entry)
 {
        union bch_extent_entry *end = bkey_val_end(bkey_i_to_s(k));
@@ -822,8 +793,8 @@ static void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry)
 /*
  * Returns pointer to the next entry after the one being dropped:
  */
-union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s k,
-                                            struct bch_extent_ptr *ptr)
+static union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s k,
+                                          struct bch_extent_ptr *ptr)
 {
        struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
        union bch_extent_entry *entry = to_entry(ptr), *next;
@@ -895,6 +866,14 @@ void bch2_bkey_drop_device(struct bkey_s k, unsigned dev)
        bch2_bkey_drop_ptrs(k, ptr, ptr->dev == dev);
 }
 
+void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev)
+{
+       struct bch_extent_ptr *ptr = (void *) bch2_bkey_has_device(k.s_c, dev);
+
+       if (ptr)
+               __bch2_bkey_drop_ptr(k, ptr);
+}
+
 const struct bch_extent_ptr *
 bch2_bkey_has_device(struct bkey_s_c k, unsigned dev)
 {
@@ -939,6 +918,44 @@ bool bch2_bkey_matches_ptr(struct bch_fs *c, struct bkey_s_c k,
        return false;
 }
 
+/*
+ * Returns true if two extents refer to the same data:
+ */
+bool bch2_extents_match(struct bkey_s_c k1, struct bkey_s_c k2)
+{
+       struct bkey_ptrs_c ptrs1 = bch2_bkey_ptrs_c(k1);
+       struct bkey_ptrs_c ptrs2 = bch2_bkey_ptrs_c(k2);
+       const union bch_extent_entry *entry1, *entry2;
+       struct extent_ptr_decoded p1, p2;
+
+       bkey_for_each_ptr_decode(k1.k, ptrs1, p1, entry1)
+               bkey_for_each_ptr_decode(k2.k, ptrs2, p2, entry2)
+                       if (p1.ptr.dev          == p2.ptr.dev &&
+                           p1.ptr.gen          == p2.ptr.gen &&
+                           (s64) p1.ptr.offset + p1.crc.offset - bkey_start_offset(k1.k) ==
+                           (s64) p2.ptr.offset + p2.crc.offset - bkey_start_offset(k2.k))
+                               return true;
+
+       return false;
+}
+
+bool bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1,
+                        struct bkey_s_c k2)
+{
+       struct bkey_ptrs_c ptrs2 = bch2_bkey_ptrs_c(k2);
+       const union bch_extent_entry *entry2;
+       struct extent_ptr_decoded p2;
+
+       bkey_for_each_ptr_decode(k2.k, ptrs2, p2, entry2)
+               if (p1.ptr.dev          == p2.ptr.dev &&
+                   p1.ptr.gen          == p2.ptr.gen &&
+                   (s64) p1.ptr.offset + p1.crc.offset - bkey_start_offset(k1.k) ==
+                   (s64) p2.ptr.offset + p2.crc.offset - bkey_start_offset(k2.k))
+                       return true;
+
+       return false;
+}
+
 /*
  * bch_extent_normalize - clean up an extent, dropping stale pointers etc.
  *
@@ -1079,6 +1096,7 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
        struct bch_extent_crc_unpacked crc;
        unsigned size_ondisk = k.k->size;
        unsigned nonce = UINT_MAX;
+       unsigned nr_ptrs = 0;
        int ret;
 
        if (bkey_is_btree_ptr(k.k))
@@ -1103,6 +1121,7 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
                                                 false, err);
                        if (ret)
                                return ret;
+                       nr_ptrs++;
                        break;
                case BCH_EXTENT_ENTRY_crc32:
                case BCH_EXTENT_ENTRY_crc64:
@@ -1141,6 +1160,11 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
                }
        }
 
+       if (nr_ptrs >= BCH_BKEY_PTRS_MAX) {
+               prt_str(err, "too many ptrs");
+               return -EINVAL;
+       }
+
        return 0;
 }