1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _BCACHEFS_JOURNAL_IO_H
3#define _BCACHEFS_JOURNAL_IO_H
4
5#include "darray.h"
6
7void bch2_journal_pos_from_member_info_set(struct bch_fs *);
8void bch2_journal_pos_from_member_info_resume(struct bch_fs *);
9
10struct journal_ptr {
11	bool		csum_good;
12	u8		dev;
13	u32		bucket;
14	u32		bucket_offset;
15	u64		sector;
16};
17
18/*
19 * Only used for holding the journal entries we read in btree_journal_read()
20 * during cache_registration
21 */
22struct journal_replay {
23	DARRAY_PREALLOCATED(struct journal_ptr, 8) ptrs;
24
25	bool			csum_good;
26	bool			ignore_blacklisted;
27	bool			ignore_not_dirty;
28	/* must be last: */
29	struct jset		j;
30};
31
32static inline bool journal_replay_ignore(struct journal_replay *i)
33{
34	return !i || i->ignore_blacklisted || i->ignore_not_dirty;
35}
36
37static inline struct jset_entry *__jset_entry_type_next(struct jset *jset,
38					struct jset_entry *entry, unsigned type)
39{
40	while (entry < vstruct_last(jset)) {
41		if (entry->type == type)
42			return entry;
43
44		entry = vstruct_next(entry);
45	}
46
47	return NULL;
48}
49
50#define for_each_jset_entry_type(entry, jset, type)			\
51	for (struct jset_entry *entry = (jset)->start;			\
52	     (entry = __jset_entry_type_next(jset, entry, type));	\
53	     entry = vstruct_next(entry))
54
55#define jset_entry_for_each_key(_e, _k)					\
56	for (struct bkey_i *_k = (_e)->start;				\
57	     _k < vstruct_last(_e);					\
58	     _k = bkey_next(_k))
59
60#define for_each_jset_key(k, entry, jset)				\
61	for_each_jset_entry_type(entry, jset, BCH_JSET_ENTRY_btree_keys)\
62		jset_entry_for_each_key(entry, k)
63
64int bch2_journal_entry_validate(struct bch_fs *, struct jset *,
65				struct jset_entry *, unsigned, int,
66				enum bch_validate_flags);
67void bch2_journal_entry_to_text(struct printbuf *, struct bch_fs *,
68				struct jset_entry *);
69
70void bch2_journal_ptrs_to_text(struct printbuf *, struct bch_fs *,
71			       struct journal_replay *);
72
73int bch2_journal_read(struct bch_fs *, u64 *, u64 *, u64 *);
74
75CLOSURE_CALLBACK(bch2_journal_write);
76
77static inline struct jset_entry *jset_entry_init(struct jset_entry **end, size_t size)
78{
79	struct jset_entry *entry = *end;
80	unsigned u64s = DIV_ROUND_UP(size, sizeof(u64));
81
82	memset(entry, 0, u64s * sizeof(u64));
83	/*
84	 * The u64s field counts from the start of data, ignoring the shared
85	 * fields.
86	 */
87	entry->u64s = cpu_to_le16(u64s - 1);
88
89	*end = vstruct_next(*end);
90	return entry;
91}
92
93#endif /* _BCACHEFS_JOURNAL_IO_H */
94