]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - fs/bcachefs/fs-io-pagecache.h
KVM: clean up directives to compile out irqfds
[thirdparty/kernel/stable.git] / fs / bcachefs / fs-io-pagecache.h
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
7 typedef DARRAY(struct folio *) folios;
8
9 int bch2_filemap_get_contig_folios_d(struct address_space *, loff_t,
10 u64, int, gfp_t, folios *);
11 int 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 */
19 static inline u64 folio_end_pos(struct folio *folio)
20 {
21 return folio_pos(folio) + folio_size(folio);
22 }
23
24 static inline size_t folio_sectors(struct folio *folio)
25 {
26 return PAGE_SECTORS << folio_order(folio);
27 }
28
29 static inline loff_t folio_sector(struct folio *folio)
30 {
31 return folio_pos(folio) >> 9;
32 }
33
34 static 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
46 enum bch_folio_sector_state {
47 #define x(n) SECTOR_##n,
48 BCH_FOLIO_SECTOR_STATE()
49 #undef x
50 };
51
52 struct bch_folio_sector {
53 /* Uncompressed, fully allocated replicas (or on disk reservation): */
54 unsigned nr_replicas:4;
55
56 /* Owns PAGE_SECTORS * replicas_reserved sized in memory reservation: */
57 unsigned replicas_reserved:4;
58
59 /* i_sectors: */
60 enum bch_folio_sector_state state:8;
61 };
62
63 struct bch_folio {
64 spinlock_t lock;
65 atomic_t write_count;
66 /*
67 * Is the sector state up to date with the btree?
68 * (Not the data itself)
69 */
70 bool uptodate;
71 struct bch_folio_sector s[];
72 };
73
74 /* Helper for when we need to add debug instrumentation: */
75 static inline void bch2_folio_sector_set(struct folio *folio,
76 struct bch_folio *s,
77 unsigned i, unsigned n)
78 {
79 s->s[i].state = n;
80 }
81
82 /* file offset (to folio offset) to bch_folio_sector index */
83 static inline int folio_pos_to_s(struct folio *folio, loff_t pos)
84 {
85 u64 f_offset = pos - folio_pos(folio);
86
87 BUG_ON(pos < folio_pos(folio) || pos >= folio_end_pos(folio));
88 return f_offset >> SECTOR_SHIFT;
89 }
90
91 /* for newly allocated folios: */
92 static inline void __bch2_folio_release(struct folio *folio)
93 {
94 kfree(folio_detach_private(folio));
95 }
96
97 static inline void bch2_folio_release(struct folio *folio)
98 {
99 EBUG_ON(!folio_test_locked(folio));
100 __bch2_folio_release(folio);
101 }
102
103 static inline struct bch_folio *__bch2_folio(struct folio *folio)
104 {
105 return folio_has_private(folio)
106 ? (struct bch_folio *) folio_get_private(folio)
107 : NULL;
108 }
109
110 static inline struct bch_folio *bch2_folio(struct folio *folio)
111 {
112 EBUG_ON(!folio_test_locked(folio));
113
114 return __bch2_folio(folio);
115 }
116
117 struct bch_folio *__bch2_folio_create(struct folio *, gfp_t);
118 struct bch_folio *bch2_folio_create(struct folio *, gfp_t);
119
120 struct bch2_folio_reservation {
121 struct disk_reservation disk;
122 struct quota_res quota;
123 };
124
125 static inline unsigned inode_nr_replicas(struct bch_fs *c, struct bch_inode_info *inode)
126 {
127 /* XXX: this should not be open coded */
128 return inode->ei_inode.bi_data_replicas
129 ? inode->ei_inode.bi_data_replicas - 1
130 : c->opts.data_replicas;
131 }
132
133 static inline void bch2_folio_reservation_init(struct bch_fs *c,
134 struct bch_inode_info *inode,
135 struct bch2_folio_reservation *res)
136 {
137 memset(res, 0, sizeof(*res));
138
139 res->disk.nr_replicas = inode_nr_replicas(c, inode);
140 }
141
142 int bch2_folio_set(struct bch_fs *, subvol_inum, struct folio **, unsigned);
143 void bch2_bio_page_state_set(struct bio *, struct bkey_s_c);
144
145 void bch2_mark_pagecache_unallocated(struct bch_inode_info *, u64, u64);
146 void bch2_mark_pagecache_reserved(struct bch_inode_info *, u64, u64);
147
148 int bch2_get_folio_disk_reservation(struct bch_fs *,
149 struct bch_inode_info *,
150 struct folio *, bool);
151
152 void bch2_folio_reservation_put(struct bch_fs *,
153 struct bch_inode_info *,
154 struct bch2_folio_reservation *);
155 int bch2_folio_reservation_get(struct bch_fs *,
156 struct bch_inode_info *,
157 struct folio *,
158 struct bch2_folio_reservation *,
159 unsigned, unsigned);
160
161 void bch2_set_folio_dirty(struct bch_fs *,
162 struct bch_inode_info *,
163 struct folio *,
164 struct bch2_folio_reservation *,
165 unsigned, unsigned);
166
167 vm_fault_t bch2_page_fault(struct vm_fault *);
168 vm_fault_t bch2_page_mkwrite(struct vm_fault *);
169 void bch2_invalidate_folio(struct folio *, size_t, size_t);
170 bool bch2_release_folio(struct folio *, gfp_t);
171
172 loff_t bch2_seek_pagecache_data(struct inode *, loff_t, loff_t, unsigned, bool);
173 loff_t bch2_seek_pagecache_hole(struct inode *, loff_t, loff_t, unsigned, bool);
174 int bch2_clamp_data_hole(struct inode *, u64 *, u64 *, unsigned, bool);
175
176 #endif /* _BCACHEFS_FS_IO_PAGECACHE_H */