btree_update.h 5.16 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCACHEFS_BTREE_UPDATE_H
#define _BCACHEFS_BTREE_UPDATE_H

#include "btree_iter.h"
#include "journal.h"

struct bch_fs;
struct btree;

Kent Overstreet's avatar
Kent Overstreet committed
11
void bch2_btree_node_lock_for_insert(struct btree_trans *, struct btree_path *,
12
				     struct btree *);
Kent Overstreet's avatar
Kent Overstreet committed
13
bool bch2_btree_bset_insert_key(struct btree_trans *, struct btree_path *,
14 15
				struct btree *, struct btree_node_iter *,
				struct bkey_i *);
16
void bch2_btree_add_journal_pin(struct bch_fs *, struct btree *, u64);
17

18
enum btree_insert_flags {
19 20
	/* First two bits for journal watermark: */
	__BTREE_INSERT_NOFAIL = 2,
21
	__BTREE_INSERT_NOCHECK_RW,
Kent Overstreet's avatar
Kent Overstreet committed
22
	__BTREE_INSERT_LAZY_RW,
23 24
	__BTREE_INSERT_USE_RESERVE,
	__BTREE_INSERT_JOURNAL_REPLAY,
25
	__BTREE_INSERT_JOURNAL_RECLAIM,
26 27 28 29 30 31 32 33 34
	__BTREE_INSERT_NOWAIT,
	__BTREE_INSERT_GC_LOCK_HELD,
	__BCH_HASH_SET_MUST_CREATE,
	__BCH_HASH_SET_MUST_REPLACE,
};

/* Don't check for -ENOSPC: */
#define BTREE_INSERT_NOFAIL		(1 << __BTREE_INSERT_NOFAIL)

35
#define BTREE_INSERT_NOCHECK_RW		(1 << __BTREE_INSERT_NOCHECK_RW)
Kent Overstreet's avatar
Kent Overstreet committed
36
#define BTREE_INSERT_LAZY_RW		(1 << __BTREE_INSERT_LAZY_RW)
37

38 39 40
/* for copygc, or when merging btree nodes */
#define BTREE_INSERT_USE_RESERVE	(1 << __BTREE_INSERT_USE_RESERVE)

41
/* Insert is for journal replay - don't get journal reservations: */
42 43
#define BTREE_INSERT_JOURNAL_REPLAY	(1 << __BTREE_INSERT_JOURNAL_REPLAY)

44 45 46
/* Insert is being called from journal reclaim path: */
#define BTREE_INSERT_JOURNAL_RECLAIM (1 << __BTREE_INSERT_JOURNAL_RECLAIM)

47 48 49 50 51 52 53
/* Don't block on allocation failure (for new btree nodes: */
#define BTREE_INSERT_NOWAIT		(1 << __BTREE_INSERT_NOWAIT)
#define BTREE_INSERT_GC_LOCK_HELD	(1 << __BTREE_INSERT_GC_LOCK_HELD)

#define BCH_HASH_SET_MUST_CREATE	(1 << __BCH_HASH_SET_MUST_CREATE)
#define BCH_HASH_SET_MUST_REPLACE	(1 << __BCH_HASH_SET_MUST_REPLACE)

54 55
int bch2_btree_delete_extent_at(struct btree_trans *, struct btree_iter *,
				unsigned, unsigned);
56
int bch2_btree_delete_at(struct btree_trans *, struct btree_iter *, unsigned);
57

58
int __bch2_btree_insert(struct btree_trans *, enum btree_id, struct bkey_i *);
59
int bch2_btree_insert(struct bch_fs *, enum btree_id, struct bkey_i *,
60
		     struct disk_reservation *, u64 *, int flags);
61

62
int bch2_btree_delete_range_trans(struct btree_trans *, enum btree_id,
63
				  struct bpos, struct bpos, unsigned, u64 *);
64
int bch2_btree_delete_range(struct bch_fs *, enum btree_id,
65
			    struct bpos, struct bpos, unsigned, u64 *);
66

67
int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *,
68
			    struct btree *, unsigned);
69
void bch2_btree_node_rewrite_async(struct bch_fs *, struct btree *);
70
int bch2_btree_node_update_key(struct btree_trans *, struct btree_iter *,
71 72 73
			       struct btree *, struct bkey_i *, bool);
int bch2_btree_node_update_key_get_iter(struct btree_trans *,
				struct btree *, struct bkey_i *, bool);
74

75 76 77
int bch2_trans_update_extent(struct btree_trans *, struct btree_iter *,
			     struct bkey_i *, enum btree_update_flags);

78 79
int __must_check bch2_trans_update(struct btree_trans *, struct btree_iter *,
				   struct bkey_i *, enum btree_update_flags);
80

81 82
void bch2_trans_commit_hook(struct btree_trans *,
			    struct btree_trans_commit_hook *);
83 84
int __bch2_trans_commit(struct btree_trans *);

85 86
int bch2_trans_log_msg(struct btree_trans *, const char *);

87 88 89 90 91 92
/**
 * bch2_trans_commit - insert keys at given iterator positions
 *
 * This is main entry point for btree updates.
 *
 * Return values:
93
 * -EINTR: locking changed, this function should be called again.
94 95 96 97 98 99 100 101 102 103 104 105 106 107
 * -EROFS: filesystem read only
 * -EIO: journal or btree node IO error
 */
static inline int bch2_trans_commit(struct btree_trans *trans,
				    struct disk_reservation *disk_res,
				    u64 *journal_seq,
				    unsigned flags)
{
	trans->disk_res		= disk_res;
	trans->journal_seq	= journal_seq;
	trans->flags		= flags;

	return __bch2_trans_commit(trans);
}
108

109
#define lockrestart_do(_trans, _do)					\
110 111 112
({									\
	int _ret;							\
									\
113
	do {								\
114
		bch2_trans_begin(_trans);				\
115 116
		_ret = (_do);						\
	} while (_ret == -EINTR);					\
117 118 119 120
									\
	_ret;								\
})

121
#define commit_do(_trans, _disk_res, _journal_seq, _flags, _do)	\
122 123 124
	lockrestart_do(_trans, _do ?: bch2_trans_commit(_trans, (_disk_res),\
					(_journal_seq), (_flags)))

125 126 127
#define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do)		\
({									\
	struct btree_trans trans;					\
128
	int _ret;							\
129 130
									\
	bch2_trans_init(&trans, (_c), 0, 0);				\
131
	_ret = commit_do(&trans, _disk_res, _journal_seq, _flags, _do);	\
132
	bch2_trans_exit(&trans);					\
133
									\
134
	_ret;								\
135 136
})

137 138 139 140 141 142 143 144 145 146 147 148
#define bch2_trans_run(_c, _do)						\
({									\
	struct btree_trans trans;					\
	int _ret;							\
									\
	bch2_trans_init(&trans, (_c), 0, 0);				\
	_ret = (_do);							\
	bch2_trans_exit(&trans);					\
									\
	_ret;								\
})

149
#define trans_for_each_update(_trans, _i)				\
150
	for ((_i) = (_trans)->updates;					\
151
	     (_i) < (_trans)->updates + (_trans)->nr_updates;		\
152 153
	     (_i)++)

154 155 156 157 158 159 160 161 162 163 164 165 166
static inline void bch2_trans_reset_updates(struct btree_trans *trans)
{
	struct btree_insert_entry *i;

	trans_for_each_update(trans, i)
		bch2_path_put(trans, i->path, true);

	trans->extra_journal_res	= 0;
	trans->nr_updates		= 0;
	trans->hooks			= NULL;
	trans->extra_journal_entries.nr	= 0;
}

167
#endif /* _BCACHEFS_BTREE_UPDATE_H */