]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_types.h
Update bcachefs sources to 14ce2a2031 bcachefs: fixes for building in userspace
[bcachefs-tools-debian] / libbcachefs / btree_types.h
index 915e42c2f1857deb046640d9cd414172f8f45afd..f0e6896a8a5e4bb2216d58ef8d5ea0e82c4a92ab 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _BCACHE_BTREE_TYPES_H
-#define _BCACHE_BTREE_TYPES_H
+#ifndef _BCACHEFS_BTREE_TYPES_H
+#define _BCACHEFS_BTREE_TYPES_H
 
 #include <linux/list.h>
 #include <linux/rhashtable.h>
@@ -11,7 +11,7 @@
 #include "six.h"
 
 struct open_bucket;
-struct btree_interior_update;
+struct btree_update;
 
 #define MAX_BSETS              3U
 
@@ -55,6 +55,16 @@ struct btree_write {
        struct closure_waitlist         wait;
 };
 
+struct btree_ob_ref {
+       u8                      nr;
+       u8                      refs[BCH_REPLICAS_MAX];
+};
+
+struct btree_alloc {
+       struct btree_ob_ref     ob;
+       BKEY_PADDED(k);
+};
+
 struct btree {
        /* Hottest entries first */
        struct rhash_head       hash;
@@ -105,12 +115,20 @@ struct btree {
         * node to point to them: we update the parent in memory immediately,
         * but then we must wait until the children have been written out before
         * the update to the parent can be written - this is a list of the
-        * btree_interior_updates that are blocking this node from being
+        * btree_updates that are blocking this node from being
         * written:
         */
        struct list_head        write_blocked;
 
-       struct open_bucket      *ob;
+       /*
+        * Also for asynchronous splits/interior node updates:
+        * If a btree node isn't reachable yet, we don't want to kick off
+        * another write - because that write also won't yet be reachable and
+        * marking it as completed before it's reachable would be incorrect:
+        */
+       struct btree_update     *will_make_reachable;
+
+       struct btree_ob_ref     ob;
 
        /* lru list */
        struct list_head        list;
@@ -122,6 +140,42 @@ struct btree {
 #endif
 };
 
+struct btree_cache {
+       struct rhashtable       table;
+       bool                    table_init_done;
+       /*
+        * We never free a struct btree, except on shutdown - we just put it on
+        * the btree_cache_freed list and reuse it later. This simplifies the
+        * code, and it doesn't cost us much memory as the memory usage is
+        * dominated by buffers that hold the actual btree node data and those
+        * can be freed - and the number of struct btrees allocated is
+        * effectively bounded.
+        *
+        * btree_cache_freeable effectively is a small cache - we use it because
+        * high order page allocations can be rather expensive, and it's quite
+        * common to delete and allocate btree nodes in quick succession. It
+        * should never grow past ~2-3 nodes in practice.
+        */
+       struct mutex            lock;
+       struct list_head        live;
+       struct list_head        freeable;
+       struct list_head        freed;
+
+       /* Number of elements in live + freeable lists */
+       unsigned                used;
+       unsigned                reserve;
+       struct shrinker         shrink;
+
+       /*
+        * If we need to allocate memory for a new btree node and that
+        * allocation fails, we can cannibalize another node in the btree cache
+        * to satisfy the allocation - lock to guarantee only one thread does
+        * this at a time:
+        */
+       struct task_struct      *alloc_lock;
+       struct closure_waitlist alloc_wait;
+};
+
 #define BTREE_FLAG(flag)                                               \
 static inline bool btree_node_ ## flag(struct btree *b)                        \
 {      return test_bit(BTREE_NODE_ ## flag, &b->flags); }              \
@@ -133,24 +187,28 @@ static inline void clear_btree_node_ ## flag(struct btree *b)             \
 {      clear_bit(BTREE_NODE_ ## flag, &b->flags); }
 
 enum btree_flags {
+       BTREE_NODE_read_in_flight,
        BTREE_NODE_read_error,
-       BTREE_NODE_write_error,
        BTREE_NODE_dirty,
+       BTREE_NODE_need_write,
        BTREE_NODE_noevict,
        BTREE_NODE_write_idx,
        BTREE_NODE_accessed,
        BTREE_NODE_write_in_flight,
        BTREE_NODE_just_written,
+       BTREE_NODE_dying,
 };
 
+BTREE_FLAG(read_in_flight);
 BTREE_FLAG(read_error);
-BTREE_FLAG(write_error);
 BTREE_FLAG(dirty);
+BTREE_FLAG(need_write);
 BTREE_FLAG(noevict);
 BTREE_FLAG(write_idx);
 BTREE_FLAG(accessed);
 BTREE_FLAG(write_in_flight);
 BTREE_FLAG(just_written);
+BTREE_FLAG(dying);
 
 static inline struct btree_write *btree_current_write(struct btree *b)
 {
@@ -255,7 +313,7 @@ static inline bool btree_node_is_extents(struct btree *b)
 struct btree_root {
        struct btree            *b;
 
-       struct btree_interior_update *as;
+       struct btree_update     *as;
 
        /* On disk root - see async splits: */
        __BKEY_PADDED(key, BKEY_BTREE_PTR_VAL_U64s_MAX);
@@ -271,18 +329,6 @@ struct btree_root {
 struct btree_iter;
 struct btree_node_iter;
 
-enum extent_insert_hook_ret {
-       BTREE_HOOK_DO_INSERT,
-       BTREE_HOOK_NO_INSERT,
-       BTREE_HOOK_RESTART_TRANS,
-};
-
-struct extent_insert_hook {
-       enum extent_insert_hook_ret
-       (*fn)(struct extent_insert_hook *, struct bpos, struct bpos,
-             struct bkey_s_c, const struct bkey_i *);
-};
-
 enum btree_insert_ret {
        BTREE_INSERT_OK,
        /* extent spanned multiple leaf nodes: have to traverse to next node: */
@@ -296,14 +342,25 @@ enum btree_insert_ret {
        BTREE_INSERT_NEED_GC_LOCK,
 };
 
+struct extent_insert_hook {
+       enum btree_insert_ret
+       (*fn)(struct extent_insert_hook *, struct bpos, struct bpos,
+             struct bkey_s_c, const struct bkey_i *);
+};
+
 enum btree_gc_coalesce_fail_reason {
        BTREE_GC_COALESCE_FAIL_RESERVE_GET,
        BTREE_GC_COALESCE_FAIL_KEYLIST_REALLOC,
        BTREE_GC_COALESCE_FAIL_FORMAT_FITS,
 };
 
+enum btree_node_sibling {
+       btree_prev_sib,
+       btree_next_sib,
+};
+
 typedef struct btree_nr_keys (*sort_fix_overlapping_fn)(struct bset *,
                                                        struct btree *,
                                                        struct btree_node_iter *);
 
-#endif /* _BCACHE_BTREE_TYPES_H */
+#endif /* _BCACHEFS_BTREE_TYPES_H */