]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_iter.h
btree_write_buffer: ensure atomic64_sub_return_release availability
[bcachefs-tools-debian] / libbcachefs / btree_iter.h
index 13d4e9aac493720e50707839257602e1e0e1e518..5e103f519e62ec280863c389cb765904a6becb91 100644 (file)
@@ -221,6 +221,22 @@ struct btree_path *bch2_path_get(struct btree_trans *, enum btree_id, struct bpo
                                 unsigned, unsigned, unsigned, unsigned long);
 struct bkey_s_c bch2_btree_path_peek_slot(struct btree_path *, struct bkey *);
 
+/*
+ * bch2_btree_path_peek_slot() for a cached iterator might return a key in a
+ * different snapshot:
+ */
+static inline struct bkey_s_c bch2_btree_path_peek_slot_exact(struct btree_path *path, struct bkey *u)
+{
+       struct bkey_s_c k = bch2_btree_path_peek_slot(path, u);
+
+       if (k.k && bpos_eq(path->pos, k.k->p))
+               return k;
+
+       bkey_init(u);
+       u->p = path->pos;
+       return (struct bkey_s_c) { u, NULL };
+}
+
 struct bkey_i *bch2_btree_journal_peek_slot(struct btree_trans *,
                                        struct btree_iter *, struct bpos);
 
@@ -258,14 +274,17 @@ void bch2_path_put(struct btree_trans *, struct btree_path *, bool);
 int bch2_trans_relock(struct btree_trans *);
 int bch2_trans_relock_notrace(struct btree_trans *);
 void bch2_trans_unlock(struct btree_trans *);
+void bch2_trans_unlock_long(struct btree_trans *);
 bool bch2_trans_locked(struct btree_trans *);
 
-static inline bool trans_was_restarted(struct btree_trans *trans, u32 restart_count)
+static inline int trans_was_restarted(struct btree_trans *trans, u32 restart_count)
 {
-       return restart_count != trans->restart_count;
+       return restart_count != trans->restart_count
+               ? -BCH_ERR_transaction_restart_nested
+               : 0;
 }
 
-void bch2_trans_restart_error(struct btree_trans *, u32);
+void __noreturn bch2_trans_restart_error(struct btree_trans *, u32);
 
 static inline void bch2_trans_verify_not_restarted(struct btree_trans *trans,
                                                   u32 restart_count)
@@ -274,7 +293,7 @@ static inline void bch2_trans_verify_not_restarted(struct btree_trans *trans,
                bch2_trans_restart_error(trans, restart_count);
 }
 
-void bch2_trans_in_restart_error(struct btree_trans *);
+void __noreturn bch2_trans_in_restart_error(struct btree_trans *);
 
 static inline void bch2_trans_verify_not_in_restart(struct btree_trans *trans)
 {
@@ -283,7 +302,7 @@ static inline void bch2_trans_verify_not_in_restart(struct btree_trans *trans)
 }
 
 __always_inline
-static inline int btree_trans_restart_nounlock(struct btree_trans *trans, int err)
+static int btree_trans_restart_nounlock(struct btree_trans *trans, int err)
 {
        BUG_ON(err <= 0);
        BUG_ON(!bch2_err_matches(-err, BCH_ERR_transaction_restart));
@@ -294,7 +313,7 @@ static inline int btree_trans_restart_nounlock(struct btree_trans *trans, int er
 }
 
 __always_inline
-static inline int btree_trans_restart(struct btree_trans *trans, int err)
+static int btree_trans_restart(struct btree_trans *trans, int err)
 {
        btree_trans_restart_nounlock(trans, err);
        return -err;
@@ -393,7 +412,7 @@ static inline unsigned __bch2_btree_iter_flags(struct btree_trans *trans,
                flags |= BTREE_ITER_ALL_SNAPSHOTS|__BTREE_ITER_ALL_SNAPSHOTS;
 
        if (!(flags & (BTREE_ITER_ALL_SNAPSHOTS|BTREE_ITER_NOT_EXTENTS)) &&
-           btree_node_type_is_extents(btree_id))
+           btree_id_is_extents(btree_id))
                flags |= BTREE_ITER_IS_EXTENTS;
 
        if (!(flags & __BTREE_ITER_ALL_SNAPSHOTS) &&
@@ -447,7 +466,7 @@ static inline void bch2_trans_iter_init_common(struct btree_trans *trans,
 }
 
 void bch2_trans_iter_init_outlined(struct btree_trans *, struct btree_iter *,
-                         unsigned, struct bpos, unsigned);
+                         enum btree_id, struct bpos, unsigned);
 
 static inline void bch2_trans_iter_init(struct btree_trans *trans,
                          struct btree_iter *iter,
@@ -561,6 +580,9 @@ static inline int __bch2_bkey_get_val_typed(struct btree_trans *trans,
        __bch2_bkey_get_val_typed(_trans, _btree_id, _pos, _flags,      \
                                  KEY_TYPE_##_type, sizeof(*_val), _val)
 
+void bch2_trans_srcu_unlock(struct btree_trans *);
+void bch2_trans_srcu_lock(struct btree_trans *);
+
 u32 bch2_trans_begin(struct btree_trans *);
 
 /*
@@ -656,17 +678,17 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
 #define lockrestart_do(_trans, _do)                                    \
 ({                                                                     \
        u32 _restart_count;                                             \
-       int _ret                                                      \
+       int _ret2;                                                      \
                                                                        \
        do {                                                            \
                _restart_count = bch2_trans_begin(_trans);              \
-               _ret = (_do);                                           \
-       } while (bch2_err_matches(_ret, BCH_ERR_transaction_restart));  \
+               _ret2 = (_do);                                          \
+       } while (bch2_err_matches(_ret2, BCH_ERR_transaction_restart)); \
                                                                        \
-       if (!_ret                                                     \
+       if (!_ret2)                                                     \
                bch2_trans_verify_not_restarted(_trans, _restart_count);\
                                                                        \
-       _ret                                                          \
+       _ret2;                                                          \
 })
 
 /*
@@ -681,26 +703,23 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
 #define nested_lockrestart_do(_trans, _do)                             \
 ({                                                                     \
        u32 _restart_count, _orig_restart_count;                        \
-       int _ret                                                      \
+       int _ret2;                                                      \
                                                                        \
        _restart_count = _orig_restart_count = (_trans)->restart_count; \
                                                                        \
-       while (bch2_err_matches(_ret = (_do), BCH_ERR_transaction_restart))\
+       while (bch2_err_matches(_ret2 = (_do), BCH_ERR_transaction_restart))\
                _restart_count = bch2_trans_begin(_trans);              \
                                                                        \
-       if (!_ret                                                     \
+       if (!_ret2)                                                     \
                bch2_trans_verify_not_restarted(_trans, _restart_count);\
                                                                        \
-       if (!_ret && trans_was_restarted(_trans, _orig_restart_count))  \
-               _ret = -BCH_ERR_transaction_restart_nested;             \
-                                                                       \
-       _ret;                                                           \
+       _ret2 ?: trans_was_restarted(_trans, _restart_count);           \
 })
 
 #define for_each_btree_key2(_trans, _iter, _btree_id,                  \
                            _start, _flags, _k, _do)                    \
 ({                                                                     \
-       int _ret = 0;                                                   \
+       int _ret3 = 0;                                                  \
                                                                        \
        bch2_trans_iter_init((_trans), &(_iter), (_btree_id),           \
                             (_start), (_flags));                       \
@@ -708,15 +727,15 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
        while (1) {                                                     \
                u32 _restart_count = bch2_trans_begin(_trans);          \
                                                                        \
-               _ret = 0;                                               \
+               _ret3 = 0;                                              \
                (_k) = bch2_btree_iter_peek_type(&(_iter), (_flags));   \
                if (!(_k).k)                                            \
                        break;                                          \
                                                                        \
-               _ret = bkey_err(_k) ?: (_do);                           \
-               if (bch2_err_matches(_ret, BCH_ERR_transaction_restart))\
+               _ret3 = bkey_err(_k) ?: (_do);                          \
+               if (bch2_err_matches(_ret3, BCH_ERR_transaction_restart))\
                        continue;                                       \
-               if (_ret                                              \
+               if (_ret3)                                              \
                        break;                                          \
                bch2_trans_verify_not_restarted(_trans, _restart_count);\
                if (!bch2_btree_iter_advance(&(_iter)))                 \
@@ -724,13 +743,13 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
        }                                                               \
                                                                        \
        bch2_trans_iter_exit((_trans), &(_iter));                       \
-       _ret                                                          \
+       _ret3;                                                          \
 })
 
 #define for_each_btree_key2_upto(_trans, _iter, _btree_id,             \
                            _start, _end, _flags, _k, _do)              \
 ({                                                                     \
-       int _ret = 0;                                                   \
+       int _ret3 = 0;                                                  \
                                                                        \
        bch2_trans_iter_init((_trans), &(_iter), (_btree_id),           \
                             (_start), (_flags));                       \
@@ -738,15 +757,15 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
        while (1) {                                                     \
                u32 _restart_count = bch2_trans_begin(_trans);          \
                                                                        \
-               _ret = 0;                                               \
+               _ret3 = 0;                                              \
                (_k) = bch2_btree_iter_peek_upto_type(&(_iter), _end, (_flags));\
                if (!(_k).k)                                            \
                        break;                                          \
                                                                        \
-               _ret = bkey_err(_k) ?: (_do);                           \
-               if (bch2_err_matches(_ret, BCH_ERR_transaction_restart))\
+               _ret3 = bkey_err(_k) ?: (_do);                          \
+               if (bch2_err_matches(_ret3, BCH_ERR_transaction_restart))\
                        continue;                                       \
-               if (_ret                                              \
+               if (_ret3)                                              \
                        break;                                          \
                bch2_trans_verify_not_restarted(_trans, _restart_count);\
                if (!bch2_btree_iter_advance(&(_iter)))                 \
@@ -754,13 +773,13 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
        }                                                               \
                                                                        \
        bch2_trans_iter_exit((_trans), &(_iter));                       \
-       _ret                                                          \
+       _ret3;                                                          \
 })
 
 #define for_each_btree_key_reverse(_trans, _iter, _btree_id,           \
                                   _start, _flags, _k, _do)             \
 ({                                                                     \
-       int _ret = 0;                                                   \
+       int _ret3 = 0;                                                  \
                                                                        \
        bch2_trans_iter_init((_trans), &(_iter), (_btree_id),           \
                             (_start), (_flags));                       \
@@ -769,14 +788,14 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
                u32 _restart_count = bch2_trans_begin(_trans);          \
                (_k) = bch2_btree_iter_peek_prev_type(&(_iter), (_flags));\
                if (!(_k).k) {                                          \
-                       _ret = 0;                                       \
+                       _ret3 = 0;                                      \
                        break;                                          \
                }                                                       \
                                                                        \
-               _ret = bkey_err(_k) ?: (_do);                           \
-               if (bch2_err_matches(_ret, BCH_ERR_transaction_restart))\
+               _ret3 = bkey_err(_k) ?: (_do);                          \
+               if (bch2_err_matches(_ret3, BCH_ERR_transaction_restart))\
                        continue;                                       \
-               if (_ret                                              \
+               if (_ret3)                                              \
                        break;                                          \
                bch2_trans_verify_not_restarted(_trans, _restart_count);\
                if (!bch2_btree_iter_rewind(&(_iter)))                  \
@@ -784,7 +803,7 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
        }                                                               \
                                                                        \
        bch2_trans_iter_exit((_trans), &(_iter));                       \
-       _ret                                                          \
+       _ret3;                                                          \
 })
 
 #define for_each_btree_key_commit(_trans, _iter, _btree_id,            \
@@ -795,6 +814,14 @@ __bch2_btree_iter_peek_upto_and_restart(struct btree_trans *trans,
                            (_do) ?: bch2_trans_commit(_trans, (_disk_res),\
                                        (_journal_seq), (_commit_flags)))
 
+#define for_each_btree_key_reverse_commit(_trans, _iter, _btree_id,    \
+                                 _start, _iter_flags, _k,              \
+                                 _disk_res, _journal_seq, _commit_flags,\
+                                 _do)                                  \
+       for_each_btree_key_reverse(_trans, _iter, _btree_id, _start, _iter_flags, _k,\
+                           (_do) ?: bch2_trans_commit(_trans, (_disk_res),\
+                                       (_journal_seq), (_commit_flags)))
+
 #define for_each_btree_key_upto_commit(_trans, _iter, _btree_id,       \
                                  _start, _end, _iter_flags, _k,        \
                                  _disk_res, _journal_seq, _commit_flags,\
@@ -892,21 +919,21 @@ void bch2_btree_path_to_text(struct printbuf *, struct btree_path *);
 void bch2_trans_paths_to_text(struct printbuf *, struct btree_trans *);
 void bch2_dump_trans_updates(struct btree_trans *);
 void bch2_dump_trans_paths_updates(struct btree_trans *);
-void __bch2_trans_init(struct btree_trans *, struct bch_fs *, unsigned);
-void bch2_trans_exit(struct btree_trans *);
+
+struct btree_trans *__bch2_trans_get(struct bch_fs *, unsigned);
+void bch2_trans_put(struct btree_trans *);
 
 extern const char *bch2_btree_transaction_fns[BCH_TRANSACTIONS_NR];
 unsigned bch2_trans_get_fn_idx(const char *);
 
-#define bch2_trans_init(_trans, _c, _nr_iters, _mem)                   \
-do {                                                                   \
+#define bch2_trans_get(_c)                                             \
+({                                                                     \
        static unsigned trans_fn_idx;                                   \
                                                                        \
        if (unlikely(!trans_fn_idx))                                    \
                trans_fn_idx = bch2_trans_get_fn_idx(__func__);         \
-                                                                       \
-       __bch2_trans_init(_trans, _c, trans_fn_idx);                    \
-} while (0)
+       __bch2_trans_get(_c, trans_fn_idx);                             \
+})
 
 void bch2_btree_trans_to_text(struct printbuf *, struct btree_trans *);