127 lines · 2.9 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0-or-later */#ifndef _BACKING_DEV_H#define _BACKING_DEV_H #include <linux/device-mapper.h> #include "pcache_internal.h" struct pcache_backing_dev_req;typedef void (*backing_req_end_fn_t)(struct pcache_backing_dev_req *backing_req, int ret); #define BACKING_DEV_REQ_TYPE_REQ		1#define BACKING_DEV_REQ_TYPE_KMEM		2 #define BACKING_DEV_REQ_INLINE_BVECS		4 struct pcache_request;struct pcache_backing_dev_req {	u8				type;	struct bio			bio;	struct pcache_backing_dev	*backing_dev; 	void				*priv_data;	backing_req_end_fn_t		end_req; 	struct list_head		node;	int				ret; 	union {		struct {			struct pcache_request		*upper_req;			u32				bio_off;		} req;		struct {			struct bio_vec	inline_bvecs[BACKING_DEV_REQ_INLINE_BVECS];			struct bio_vec	*bvecs;			u32		n_vecs;		} kmem;	};}; struct pcache_backing_dev {	struct pcache_cache		*cache; 	struct dm_dev			*dm_dev;	mempool_t			req_pool;	mempool_t			bvec_pool; 	struct list_head		submit_list;	spinlock_t			submit_lock;	struct work_struct		req_submit_work; 	struct list_head		complete_list;	spinlock_t			complete_lock;	struct work_struct		req_complete_work; 	atomic_t			inflight_reqs;	wait_queue_head_t		inflight_wq; 	u64				dev_size;}; struct dm_pcache;int backing_dev_start(struct dm_pcache *pcache);void backing_dev_stop(struct dm_pcache *pcache); struct pcache_backing_dev_req_opts {	u32 type;	union {		struct {			struct pcache_request *upper_req;			u32 req_off;			u32 len;		} req;		struct {			void *data;			blk_opf_t opf;			u32 len;			u64 backing_off;		} kmem;	}; 	gfp_t gfp_mask;	backing_req_end_fn_t	end_fn;	void			*priv_data;}; static inline u32 backing_dev_req_coalesced_max_len(const void *data, u32 len){	const void *p = data;	u32 done = 0, in_page, to_advance;	struct page *first_page, *next_page; 	if (!is_vmalloc_addr(data))		return len; 	first_page = vmalloc_to_page(p);advance:	in_page = PAGE_SIZE - offset_in_page(p);	to_advance = min_t(u32, in_page, len - done); 	done += to_advance;	p += to_advance; 	if (done == len)		return done; 	next_page = vmalloc_to_page(p);	if (zone_device_pages_have_same_pgmap(first_page, next_page))		goto advance; 	return done;} void backing_dev_req_submit(struct pcache_backing_dev_req *backing_req, bool direct);void backing_dev_req_end(struct pcache_backing_dev_req *backing_req);struct pcache_backing_dev_req *backing_dev_req_create(struct pcache_backing_dev *backing_dev,						struct pcache_backing_dev_req_opts *opts);struct pcache_backing_dev_req *backing_dev_req_alloc(struct pcache_backing_dev *backing_dev,						struct pcache_backing_dev_req_opts *opts);void backing_dev_req_init(struct pcache_backing_dev_req *backing_req,			struct pcache_backing_dev_req_opts *opts);void backing_dev_flush(struct pcache_backing_dev *backing_dev); int pcache_backing_init(void);void pcache_backing_exit(void);#endif /* _BACKING_DEV_H */