xref: /spdk/lib/blob/blob_bs_dev.c (revision 12fbe739a31b09aff0d05f354d4f3bbef99afc55)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2018 Intel Corporation.
3  *   All rights reserved.
4  *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5  */
6 
7 #include "spdk/stdinc.h"
8 #include "spdk/blob.h"
9 #include "spdk/log.h"
10 #include "blobstore.h"
11 
12 static void
13 blob_bs_dev_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
14 		  uint64_t lba, uint32_t lba_count,
15 		  struct spdk_bs_dev_cb_args *cb_args)
16 {
17 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
18 	assert(false);
19 }
20 
21 static void
22 blob_bs_dev_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
23 		   struct iovec *iov, int iovcnt,
24 		   uint64_t lba, uint32_t lba_count,
25 		   struct spdk_bs_dev_cb_args *cb_args)
26 {
27 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
28 	assert(false);
29 }
30 
31 static void
32 blob_bs_dev_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
33 		       struct iovec *iov, int iovcnt,
34 		       uint64_t lba, uint32_t lba_count,
35 		       struct spdk_bs_dev_cb_args *cb_args,
36 		       struct spdk_blob_ext_io_opts *ext_opts)
37 {
38 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
39 	assert(false);
40 }
41 
42 static void
43 blob_bs_dev_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
44 			 uint64_t lba, uint64_t lba_count,
45 			 struct spdk_bs_dev_cb_args *cb_args)
46 {
47 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
48 	assert(false);
49 }
50 
51 static void
52 blob_bs_dev_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
53 		  uint64_t lba, uint64_t lba_count,
54 		  struct spdk_bs_dev_cb_args *cb_args)
55 {
56 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
57 	assert(false);
58 }
59 
60 static void
61 blob_bs_dev_read_cpl(void *cb_arg, int bserrno)
62 {
63 	struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)cb_arg;
64 
65 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, bserrno);
66 }
67 
68 static inline void
69 blob_bs_dev_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
70 		 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
71 {
72 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
73 
74 	spdk_blob_io_read(b->blob, channel, payload, lba, lba_count,
75 			  blob_bs_dev_read_cpl, cb_args);
76 }
77 
78 static inline void
79 blob_bs_dev_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
80 		  struct iovec *iov, int iovcnt,
81 		  uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
82 {
83 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
84 
85 	spdk_blob_io_readv(b->blob, channel, iov, iovcnt, lba, lba_count,
86 			   blob_bs_dev_read_cpl, cb_args);
87 }
88 
89 static inline void
90 blob_bs_dev_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
91 		      struct iovec *iov, int iovcnt,
92 		      uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args,
93 		      struct spdk_blob_ext_io_opts *ext_opts)
94 {
95 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
96 
97 	spdk_blob_io_readv_ext(b->blob, channel, iov, iovcnt, lba, lba_count,
98 			       blob_bs_dev_read_cpl, cb_args, ext_opts);
99 }
100 
101 static void
102 blob_bs_dev_destroy_cpl(void *cb_arg, int bserrno)
103 {
104 	if (bserrno != 0) {
105 		SPDK_ERRLOG("Error on blob_bs_dev destroy: %d", bserrno);
106 	}
107 
108 	/* Free blob_bs_dev */
109 	free(cb_arg);
110 }
111 
112 static void
113 blob_bs_dev_destroy(struct spdk_bs_dev *bs_dev)
114 {
115 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)bs_dev;
116 
117 	spdk_blob_close(b->blob, blob_bs_dev_destroy_cpl, b);
118 }
119 
120 static bool
121 blob_bs_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
122 {
123 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
124 	struct spdk_blob *blob = b->blob;
125 
126 	assert(lba == bs_cluster_to_lba(blob->bs, bs_lba_to_cluster(blob->bs, lba)));
127 	assert(lba_count == bs_dev_byte_to_lba(dev, blob->bs->cluster_sz));
128 
129 	if (bs_io_unit_is_allocated(blob, lba)) {
130 		return false;
131 	}
132 
133 	assert(blob->back_bs_dev != NULL);
134 	return blob->back_bs_dev->is_zeroes(blob->back_bs_dev,
135 					    bs_io_unit_to_back_dev_lba(blob, lba),
136 					    bs_io_unit_to_back_dev_lba(blob, lba_count));
137 }
138 
139 static bool
140 blob_bs_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba)
141 {
142 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
143 	struct spdk_blob *blob = b->blob;
144 
145 	assert(base_lba != NULL);
146 	if (bs_io_unit_is_allocated(blob, lba)) {
147 		*base_lba = bs_blob_io_unit_to_lba(blob, lba);
148 		return true;
149 	}
150 
151 	assert(blob->back_bs_dev != NULL);
152 	return blob->back_bs_dev->translate_lba(blob->back_bs_dev,
153 						bs_io_unit_to_back_dev_lba(blob, lba),
154 						base_lba);
155 }
156 
157 static bool
158 blob_bs_is_degraded(struct spdk_bs_dev *dev)
159 {
160 	struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
161 
162 	return spdk_blob_is_degraded(b->blob);
163 }
164 
165 struct spdk_bs_dev *
166 bs_create_blob_bs_dev(struct spdk_blob *blob)
167 {
168 	struct spdk_blob_bs_dev  *b;
169 
170 	b = calloc(1, sizeof(*b));
171 	if (b == NULL) {
172 		return NULL;
173 	}
174 	/* snapshot blob */
175 	b->bs_dev.blockcnt = blob->active.num_clusters *
176 			     blob->bs->pages_per_cluster * bs_io_unit_per_page(blob->bs);
177 	b->bs_dev.blocklen = spdk_bs_get_io_unit_size(blob->bs);
178 	b->bs_dev.create_channel = NULL;
179 	b->bs_dev.destroy_channel = NULL;
180 	b->bs_dev.destroy = blob_bs_dev_destroy;
181 	b->bs_dev.write = blob_bs_dev_write;
182 	b->bs_dev.writev = blob_bs_dev_writev;
183 	b->bs_dev.writev_ext = blob_bs_dev_writev_ext;
184 	b->bs_dev.read = blob_bs_dev_read;
185 	b->bs_dev.readv = blob_bs_dev_readv;
186 	b->bs_dev.readv_ext = blob_bs_dev_readv_ext;
187 	b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes;
188 	b->bs_dev.unmap = blob_bs_dev_unmap;
189 	b->bs_dev.is_zeroes = blob_bs_is_zeroes;
190 	b->bs_dev.translate_lba = blob_bs_translate_lba;
191 	b->bs_dev.is_degraded = blob_bs_is_degraded;
192 	b->blob = blob;
193 
194 	return &b->bs_dev;
195 }
196