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  
7  void bch2_journal_pos_from_member_info_set(struct bch_fs *);
8  void bch2_journal_pos_from_member_info_resume(struct bch_fs *);
9  
10  struct 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   */
22  struct 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  
journal_replay_ignore(struct journal_replay * i)32  static inline bool journal_replay_ignore(struct journal_replay *i)
33  {
34  	return !i || i->ignore_blacklisted || i->ignore_not_dirty;
35  }
36  
__jset_entry_type_next(struct jset * jset,struct jset_entry * entry,unsigned type)37  static 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  
64  int bch2_journal_entry_validate(struct bch_fs *, struct jset *,
65  				struct jset_entry *, unsigned, int,
66  				enum bch_validate_flags);
67  void bch2_journal_entry_to_text(struct printbuf *, struct bch_fs *,
68  				struct jset_entry *);
69  
70  void bch2_journal_ptrs_to_text(struct printbuf *, struct bch_fs *,
71  			       struct journal_replay *);
72  
73  int bch2_journal_read(struct bch_fs *, u64 *, u64 *, u64 *);
74  
75  CLOSURE_CALLBACK(bch2_journal_write);
76  
jset_entry_init(struct jset_entry ** end,size_t size)77  static 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