1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _BCACHEFS_FS_IO_PAGECACHE_H
3#define _BCACHEFS_FS_IO_PAGECACHE_H
4
5#include <linux/pagemap.h>
6
7typedef DARRAY(struct folio *) folios;
8
9int bch2_filemap_get_contig_folios_d(struct address_space *, loff_t,
10				     u64, fgf_t, gfp_t, folios *);
11int bch2_write_invalidate_inode_pages_range(struct address_space *, loff_t, loff_t);
12
13/*
14 * Use u64 for the end pos and sector helpers because if the folio covers the
15 * max supported range of the mapping, the start offset of the next folio
16 * overflows loff_t. This breaks much of the range based processing in the
17 * buffered write path.
18 */
19static inline u64 folio_end_pos(struct folio *folio)
20{
21	return folio_pos(folio) + folio_size(folio);
22}
23
24static inline size_t folio_sectors(struct folio *folio)
25{
26	return PAGE_SECTORS << folio_order(folio);
27}
28
29static inline loff_t folio_sector(struct folio *folio)
30{
31	return folio_pos(folio) >> 9;
32}
33
34static inline u64 folio_end_sector(struct folio *folio)
35{
36	return folio_end_pos(folio) >> 9;
37}
38
39#define BCH_FOLIO_SECTOR_STATE()	\
40	x(unallocated)			\
41	x(reserved)			\
42	x(dirty)			\
43	x(dirty_reserved)		\
44	x(allocated)
45
46enum bch_folio_sector_state {
47#define x(n)	SECTOR_##n,
48	BCH_FOLIO_SECTOR_STATE()
49#undef x
50};
51
52struct bch_folio_sector {
53	/* Uncompressed, fully allocated replicas (or on disk reservation): */
54	u8			nr_replicas:4,
55	/* Owns PAGE_SECTORS * replicas_reserved sized in memory reservation: */
56				replicas_reserved:4;
57	u8			state;
58};
59
60struct bch_folio {
61	spinlock_t		lock;
62	atomic_t		write_count;
63	/*
64	 * Is the sector state up to date with the btree?
65	 * (Not the data itself)
66	 */
67	bool			uptodate;
68	struct bch_folio_sector	s[];
69};
70
71/* Helper for when we need to add debug instrumentation: */
72static inline void bch2_folio_sector_set(struct folio *folio,
73			     struct bch_folio *s,
74			     unsigned i, unsigned n)
75{
76	s->s[i].state = n;
77}
78
79/* file offset (to folio offset) to bch_folio_sector index */
80static inline int folio_pos_to_s(struct folio *folio, loff_t pos)
81{
82	u64 f_offset = pos - folio_pos(folio);
83
84	BUG_ON(pos < folio_pos(folio) || pos >= folio_end_pos(folio));
85	return f_offset >> SECTOR_SHIFT;
86}
87
88/* for newly allocated folios: */
89static inline void __bch2_folio_release(struct folio *folio)
90{
91	kfree(folio_detach_private(folio));
92}
93
94static inline void bch2_folio_release(struct folio *folio)
95{
96	EBUG_ON(!folio_test_locked(folio));
97	__bch2_folio_release(folio);
98}
99
100static inline struct bch_folio *__bch2_folio(struct folio *folio)
101{
102	return folio_has_private(folio)
103		? (struct bch_folio *) folio_get_private(folio)
104		: NULL;
105}
106
107static inline struct bch_folio *bch2_folio(struct folio *folio)
108{
109	EBUG_ON(!folio_test_locked(folio));
110
111	return __bch2_folio(folio);
112}
113
114struct bch_folio *__bch2_folio_create(struct folio *, gfp_t);
115struct bch_folio *bch2_folio_create(struct folio *, gfp_t);
116
117struct bch2_folio_reservation {
118	struct disk_reservation	disk;
119	struct quota_res	quota;
120};
121
122static inline unsigned inode_nr_replicas(struct bch_fs *c, struct bch_inode_info *inode)
123{
124	/* XXX: this should not be open coded */
125	return inode->ei_inode.bi_data_replicas
126		? inode->ei_inode.bi_data_replicas - 1
127		: c->opts.data_replicas;
128}
129
130static inline void bch2_folio_reservation_init(struct bch_fs *c,
131			struct bch_inode_info *inode,
132			struct bch2_folio_reservation *res)
133{
134	memset(res, 0, sizeof(*res));
135
136	res->disk.nr_replicas = inode_nr_replicas(c, inode);
137}
138
139int bch2_folio_set(struct bch_fs *, subvol_inum, struct folio **, unsigned);
140void bch2_bio_page_state_set(struct bio *, struct bkey_s_c);
141
142void bch2_mark_pagecache_unallocated(struct bch_inode_info *, u64, u64);
143int bch2_mark_pagecache_reserved(struct bch_inode_info *, u64 *, u64, bool);
144
145int bch2_get_folio_disk_reservation(struct bch_fs *,
146				struct bch_inode_info *,
147				struct folio *, bool);
148
149void bch2_folio_reservation_put(struct bch_fs *,
150			struct bch_inode_info *,
151			struct bch2_folio_reservation *);
152int bch2_folio_reservation_get(struct bch_fs *,
153			struct bch_inode_info *,
154			struct folio *,
155			struct bch2_folio_reservation *,
156			unsigned, unsigned);
157
158void bch2_set_folio_dirty(struct bch_fs *,
159			  struct bch_inode_info *,
160			  struct folio *,
161			  struct bch2_folio_reservation *,
162			  unsigned, unsigned);
163
164vm_fault_t bch2_page_fault(struct vm_fault *);
165vm_fault_t bch2_page_mkwrite(struct vm_fault *);
166void bch2_invalidate_folio(struct folio *, size_t, size_t);
167bool bch2_release_folio(struct folio *, gfp_t);
168
169loff_t bch2_seek_pagecache_data(struct inode *, loff_t, loff_t, unsigned, bool);
170loff_t bch2_seek_pagecache_hole(struct inode *, loff_t, loff_t, unsigned, bool);
171int bch2_clamp_data_hole(struct inode *, u64 *, u64 *, unsigned, bool);
172
173#endif /* _BCACHEFS_FS_IO_PAGECACHE_H */
174