]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/btree_update.h
Update bcachefs sources to 43a464c9dd bcachefs: Don't BUG_ON() on bucket sector count...
[bcachefs-tools-debian] / libbcachefs / btree_update.h
1 #ifndef _BCACHEFS_BTREE_UPDATE_H
2 #define _BCACHEFS_BTREE_UPDATE_H
3
4 #include "btree_iter.h"
5 #include "journal.h"
6
7 struct bch_fs;
8 struct btree;
9 struct btree_insert;
10
11 void bch2_btree_node_lock_for_insert(struct bch_fs *, struct btree *,
12                                      struct btree_iter *);
13 bool bch2_btree_bset_insert_key(struct btree_iter *, struct btree *,
14                                 struct btree_node_iter *, struct bkey_i *);
15 void bch2_btree_journal_key(struct btree_insert *trans, struct btree_iter *,
16                             struct bkey_i *);
17
18 void bch2_deferred_update_free(struct bch_fs *,
19                                struct deferred_update *);
20 struct deferred_update *
21 bch2_deferred_update_alloc(struct bch_fs *, enum btree_id, unsigned);
22
23 /* Normal update interface: */
24
25 struct btree_insert {
26         struct bch_fs           *c;
27         struct disk_reservation *disk_res;
28         struct journal_res      journal_res;
29         struct journal_preres   journal_preres;
30         u64                     *journal_seq;
31         unsigned                flags;
32         bool                    did_work;
33
34         unsigned short          nr;
35         struct btree_insert_entry  *entries;
36 };
37
38 int __bch2_btree_insert_at(struct btree_insert *);
39
40 #define BTREE_INSERT_ENTRY(_iter, _k)                                   \
41         ((struct btree_insert_entry) {                                  \
42                 .iter           = (_iter),                              \
43                 .k              = (_k),                                 \
44         })
45
46 #define BTREE_INSERT_DEFERRED(_d, _k)                                   \
47         ((struct btree_insert_entry) {                                  \
48                 .k              = (_k),                                 \
49                 .d              = (_d),                                 \
50                 .deferred       = true,                                 \
51         })
52
53 /**
54  * bch_btree_insert_at - insert one or more keys at iterator positions
55  * @iter:               btree iterator
56  * @insert_key:         key to insert
57  * @disk_res:           disk reservation
58  * @hook:               extent insert callback
59  *
60  * Return values:
61  * -EINTR: locking changed, this function should be called again. Only returned
62  *  if passed BTREE_INSERT_ATOMIC.
63  * -EROFS: filesystem read only
64  * -EIO: journal or btree node IO error
65  */
66 #define bch2_btree_insert_at(_c, _disk_res, _journal_seq, _flags, ...)  \
67         __bch2_btree_insert_at(&(struct btree_insert) {                 \
68                 .c              = (_c),                                 \
69                 .disk_res       = (_disk_res),                          \
70                 .journal_seq    = (_journal_seq),                       \
71                 .flags          = (_flags),                             \
72                 .nr             = COUNT_ARGS(__VA_ARGS__),              \
73                 .entries        = (struct btree_insert_entry[]) {       \
74                         __VA_ARGS__                                     \
75                 }})
76
77 enum {
78         __BTREE_INSERT_ATOMIC,
79         __BTREE_INSERT_NOUNLOCK,
80         __BTREE_INSERT_NOFAIL,
81         __BTREE_INSERT_NOCHECK_RW,
82         __BTREE_INSERT_USE_RESERVE,
83         __BTREE_INSERT_USE_ALLOC_RESERVE,
84         __BTREE_INSERT_JOURNAL_REPLAY,
85         __BTREE_INSERT_JOURNAL_RESERVED,
86         __BTREE_INSERT_NOMARK,
87         __BTREE_INSERT_NOWAIT,
88         __BTREE_INSERT_GC_LOCK_HELD,
89         __BCH_HASH_SET_MUST_CREATE,
90         __BCH_HASH_SET_MUST_REPLACE,
91 };
92
93 /*
94  * Don't drop/retake locks before doing btree update, instead return -EINTR if
95  * we had to drop locks for any reason
96  */
97 #define BTREE_INSERT_ATOMIC             (1 << __BTREE_INSERT_ATOMIC)
98
99 /*
100  * Don't drop locks _after_ successfully updating btree:
101  */
102 #define BTREE_INSERT_NOUNLOCK           (1 << __BTREE_INSERT_NOUNLOCK)
103
104 /* Don't check for -ENOSPC: */
105 #define BTREE_INSERT_NOFAIL             (1 << __BTREE_INSERT_NOFAIL)
106
107 #define BTREE_INSERT_NOCHECK_RW         (1 << __BTREE_INSERT_NOCHECK_RW)
108
109 /* for copygc, or when merging btree nodes */
110 #define BTREE_INSERT_USE_RESERVE        (1 << __BTREE_INSERT_USE_RESERVE)
111 #define BTREE_INSERT_USE_ALLOC_RESERVE  (1 << __BTREE_INSERT_USE_ALLOC_RESERVE)
112
113 /* Insert is for journal replay - don't get journal reservations: */
114 #define BTREE_INSERT_JOURNAL_REPLAY     (1 << __BTREE_INSERT_JOURNAL_REPLAY)
115
116 #define BTREE_INSERT_JOURNAL_RESERVED   (1 << __BTREE_INSERT_JOURNAL_RESERVED)
117
118 /* Don't call bch2_mark_key: */
119 #define BTREE_INSERT_NOMARK             (1 << __BTREE_INSERT_NOMARK)
120
121 /* Don't block on allocation failure (for new btree nodes: */
122 #define BTREE_INSERT_NOWAIT             (1 << __BTREE_INSERT_NOWAIT)
123 #define BTREE_INSERT_GC_LOCK_HELD       (1 << __BTREE_INSERT_GC_LOCK_HELD)
124
125 #define BCH_HASH_SET_MUST_CREATE        (1 << __BCH_HASH_SET_MUST_CREATE)
126 #define BCH_HASH_SET_MUST_REPLACE       (1 << __BCH_HASH_SET_MUST_REPLACE)
127
128 int bch2_btree_delete_at(struct btree_iter *, unsigned);
129
130 int bch2_btree_insert_list_at(struct btree_iter *, struct keylist *,
131                              struct disk_reservation *, u64 *, unsigned);
132
133 int bch2_btree_insert(struct bch_fs *, enum btree_id, struct bkey_i *,
134                      struct disk_reservation *, u64 *, int flags);
135
136 int bch2_btree_delete_range(struct bch_fs *, enum btree_id,
137                             struct bpos, struct bpos, u64 *);
138
139 int bch2_btree_node_rewrite(struct bch_fs *c, struct btree_iter *,
140                             __le64, unsigned);
141 int bch2_btree_node_update_key(struct bch_fs *, struct btree_iter *,
142                                struct btree *, struct bkey_i_btree_ptr *);
143
144 /* new transactional interface: */
145
146 static inline void
147 bch2_trans_update(struct btree_trans *trans,
148                   struct btree_insert_entry entry)
149 {
150         BUG_ON(trans->nr_updates >= ARRAY_SIZE(trans->updates));
151
152         trans->updates[trans->nr_updates++] = entry;
153 }
154
155 int bch2_trans_commit(struct btree_trans *,
156                       struct disk_reservation *,
157                       u64 *, unsigned);
158
159 #define bch2_trans_do(_c, _journal_seq, _flags, _do)                    \
160 ({                                                                      \
161         struct btree_trans trans;                                       \
162         int _ret;                                                       \
163                                                                         \
164         bch2_trans_init(&trans, (_c));                                  \
165                                                                         \
166         do {                                                            \
167                 bch2_trans_begin(&trans);                               \
168                                                                         \
169                 _ret = (_do) ?: bch2_trans_commit(&trans, NULL,         \
170                                         (_journal_seq), (_flags));      \
171         } while (_ret == -EINTR);                                       \
172                                                                         \
173         bch2_trans_exit(&trans);                                        \
174         _ret;                                                           \
175 })
176
177 #endif /* _BCACHEFS_BTREE_UPDATE_H */