Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
  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	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
 63struct 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: */
 75static 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 */
 83static 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: */
 92static inline void __bch2_folio_release(struct folio *folio)
 93{
 94	kfree(folio_detach_private(folio));
 95}
 96
 97static inline void bch2_folio_release(struct folio *folio)
 98{
 99	EBUG_ON(!folio_test_locked(folio));
100	__bch2_folio_release(folio);
101}
102
103static 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
110static 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
117struct bch_folio *__bch2_folio_create(struct folio *, gfp_t);
118struct bch_folio *bch2_folio_create(struct folio *, gfp_t);
119
120struct bch2_folio_reservation {
121	struct disk_reservation	disk;
122	struct quota_res	quota;
123};
124
125static 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
133static 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
142int bch2_folio_set(struct bch_fs *, subvol_inum, struct folio **, unsigned);
143void bch2_bio_page_state_set(struct bio *, struct bkey_s_c);
144
145void bch2_mark_pagecache_unallocated(struct bch_inode_info *, u64, u64);
146int bch2_mark_pagecache_reserved(struct bch_inode_info *, u64 *, u64, bool);
147
148int bch2_get_folio_disk_reservation(struct bch_fs *,
149				struct bch_inode_info *,
150				struct folio *, bool);
151
152void bch2_folio_reservation_put(struct bch_fs *,
153			struct bch_inode_info *,
154			struct bch2_folio_reservation *);
155int bch2_folio_reservation_get(struct bch_fs *,
156			struct bch_inode_info *,
157			struct folio *,
158			struct bch2_folio_reservation *,
159			unsigned, unsigned);
160
161void bch2_set_folio_dirty(struct bch_fs *,
162			  struct bch_inode_info *,
163			  struct folio *,
164			  struct bch2_folio_reservation *,
165			  unsigned, unsigned);
166
167vm_fault_t bch2_page_fault(struct vm_fault *);
168vm_fault_t bch2_page_mkwrite(struct vm_fault *);
169void bch2_invalidate_folio(struct folio *, size_t, size_t);
170bool bch2_release_folio(struct folio *, gfp_t);
171
172loff_t bch2_seek_pagecache_data(struct inode *, loff_t, loff_t, unsigned, bool);
173loff_t bch2_seek_pagecache_hole(struct inode *, loff_t, loff_t, unsigned, bool);
174int bch2_clamp_data_hole(struct inode *, u64 *, u64 *, unsigned, bool);
175
176#endif /* _BCACHEFS_FS_IO_PAGECACHE_H */