xref: /linux/drivers/md/dm-pcache/segment.c (revision 1d57628ff95b32d5cfa8d8f50e07690c161e9cf0)
1*1d57628fSDongsheng Yang // SPDX-License-Identifier: GPL-2.0-or-later
2*1d57628fSDongsheng Yang #include <linux/dax.h>
3*1d57628fSDongsheng Yang 
4*1d57628fSDongsheng Yang #include "pcache_internal.h"
5*1d57628fSDongsheng Yang #include "cache_dev.h"
6*1d57628fSDongsheng Yang #include "segment.h"
7*1d57628fSDongsheng Yang 
8*1d57628fSDongsheng Yang int segment_copy_to_bio(struct pcache_segment *segment,
9*1d57628fSDongsheng Yang 		u32 data_off, u32 data_len, struct bio *bio, u32 bio_off)
10*1d57628fSDongsheng Yang {
11*1d57628fSDongsheng Yang 	struct iov_iter iter;
12*1d57628fSDongsheng Yang 	size_t copied;
13*1d57628fSDongsheng Yang 	void *src;
14*1d57628fSDongsheng Yang 
15*1d57628fSDongsheng Yang 	iov_iter_bvec(&iter, ITER_DEST, &bio->bi_io_vec[bio->bi_iter.bi_idx],
16*1d57628fSDongsheng Yang 			bio_segments(bio), bio->bi_iter.bi_size);
17*1d57628fSDongsheng Yang 	iter.iov_offset = bio->bi_iter.bi_bvec_done;
18*1d57628fSDongsheng Yang 	if (bio_off)
19*1d57628fSDongsheng Yang 		iov_iter_advance(&iter, bio_off);
20*1d57628fSDongsheng Yang 
21*1d57628fSDongsheng Yang 	src = segment->data + data_off;
22*1d57628fSDongsheng Yang 	copied = _copy_mc_to_iter(src, data_len, &iter);
23*1d57628fSDongsheng Yang 	if (copied != data_len)
24*1d57628fSDongsheng Yang 		return -EIO;
25*1d57628fSDongsheng Yang 
26*1d57628fSDongsheng Yang 	return 0;
27*1d57628fSDongsheng Yang }
28*1d57628fSDongsheng Yang 
29*1d57628fSDongsheng Yang int segment_copy_from_bio(struct pcache_segment *segment,
30*1d57628fSDongsheng Yang 		u32 data_off, u32 data_len, struct bio *bio, u32 bio_off)
31*1d57628fSDongsheng Yang {
32*1d57628fSDongsheng Yang 	struct iov_iter iter;
33*1d57628fSDongsheng Yang 	size_t copied;
34*1d57628fSDongsheng Yang 	void *dst;
35*1d57628fSDongsheng Yang 
36*1d57628fSDongsheng Yang 	iov_iter_bvec(&iter, ITER_SOURCE, &bio->bi_io_vec[bio->bi_iter.bi_idx],
37*1d57628fSDongsheng Yang 			bio_segments(bio), bio->bi_iter.bi_size);
38*1d57628fSDongsheng Yang 	iter.iov_offset = bio->bi_iter.bi_bvec_done;
39*1d57628fSDongsheng Yang 	if (bio_off)
40*1d57628fSDongsheng Yang 		iov_iter_advance(&iter, bio_off);
41*1d57628fSDongsheng Yang 
42*1d57628fSDongsheng Yang 	dst = segment->data + data_off;
43*1d57628fSDongsheng Yang 	copied = _copy_from_iter_flushcache(dst, data_len, &iter);
44*1d57628fSDongsheng Yang 	if (copied != data_len)
45*1d57628fSDongsheng Yang 		return -EIO;
46*1d57628fSDongsheng Yang 	pmem_wmb();
47*1d57628fSDongsheng Yang 
48*1d57628fSDongsheng Yang 	return 0;
49*1d57628fSDongsheng Yang }
50*1d57628fSDongsheng Yang 
51*1d57628fSDongsheng Yang void pcache_segment_init(struct pcache_cache_dev *cache_dev, struct pcache_segment *segment,
52*1d57628fSDongsheng Yang 		      struct pcache_segment_init_options *options)
53*1d57628fSDongsheng Yang {
54*1d57628fSDongsheng Yang 	segment->seg_info = options->seg_info;
55*1d57628fSDongsheng Yang 	segment_info_set_type(segment->seg_info, options->type);
56*1d57628fSDongsheng Yang 
57*1d57628fSDongsheng Yang 	segment->cache_dev = cache_dev;
58*1d57628fSDongsheng Yang 	segment->seg_id = options->seg_id;
59*1d57628fSDongsheng Yang 	segment->data_size = PCACHE_SEG_SIZE - options->data_off;
60*1d57628fSDongsheng Yang 	segment->data = CACHE_DEV_SEGMENT(cache_dev, options->seg_id) + options->data_off;
61*1d57628fSDongsheng Yang }
62