Branch data Line data Source code
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 : 0 : 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 : 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
18 : 0 : assert(false);
19 : : }
20 : :
21 : : static void
22 : 0 : 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 : 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
28 : 0 : assert(false);
29 : : }
30 : :
31 : : static void
32 : 0 : 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 : 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
39 : 0 : assert(false);
40 : : }
41 : :
42 : : static void
43 : 0 : 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 : 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
48 : 0 : assert(false);
49 : : }
50 : :
51 : : static void
52 : 0 : 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 : 0 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
57 : 0 : assert(false);
58 : : }
59 : :
60 : : static void
61 : 24224 : blob_bs_dev_read_cpl(void *cb_arg, int bserrno)
62 : : {
63 : 24224 : struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)cb_arg;
64 : :
65 : 24224 : cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, bserrno);
66 : 24224 : }
67 : :
68 : : static inline void
69 : 1142 : 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 : 1142 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
73 : :
74 : 1142 : spdk_blob_io_read(b->blob, channel, payload, lba, lba_count,
75 : : blob_bs_dev_read_cpl, cb_args);
76 : 1142 : }
77 : :
78 : : static inline void
79 : 320 : 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 : 320 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
84 : :
85 : 320 : spdk_blob_io_readv(b->blob, channel, iov, iovcnt, lba, lba_count,
86 : : blob_bs_dev_read_cpl, cb_args);
87 : 320 : }
88 : :
89 : : static inline void
90 : 22762 : 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 : 22762 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
96 : :
97 : 22762 : spdk_blob_io_readv_ext(b->blob, channel, iov, iovcnt, lba, lba_count,
98 : : blob_bs_dev_read_cpl, cb_args, ext_opts);
99 : 22762 : }
100 : :
101 : : static void
102 : 2537 : blob_bs_dev_destroy_cpl(void *cb_arg, int bserrno)
103 : : {
104 [ - + ]: 2537 : if (bserrno != 0) {
105 : 0 : SPDK_ERRLOG("Error on blob_bs_dev destroy: %d", bserrno);
106 : : }
107 : :
108 : : /* Free blob_bs_dev */
109 : 2537 : free(cb_arg);
110 : 2537 : }
111 : :
112 : : static void
113 : 2537 : blob_bs_dev_destroy(struct spdk_bs_dev *bs_dev)
114 : : {
115 : 2537 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)bs_dev;
116 : :
117 : 2537 : spdk_blob_close(b->blob, blob_bs_dev_destroy_cpl, b);
118 : 2537 : }
119 : :
120 : : static bool
121 : 1546 : blob_bs_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
122 : : {
123 : 1546 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
124 : 1546 : struct spdk_blob *blob = b->blob;
125 : :
126 [ - + ]: 1546 : assert(lba == bs_cluster_to_lba(blob->bs, bs_lba_to_cluster(blob->bs, lba)));
127 [ - + ]: 1546 : assert(lba_count == bs_dev_byte_to_lba(dev, blob->bs->cluster_sz));
128 : :
129 [ + + ]: 1546 : if (bs_io_unit_is_allocated(blob, lba)) {
130 : 966 : return false;
131 : : }
132 : :
133 [ - + ]: 580 : assert(blob->back_bs_dev != NULL);
134 : 580 : 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 : 772 : blob_bs_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba)
141 : : {
142 : 772 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
143 : 772 : struct spdk_blob *blob = b->blob;
144 : :
145 [ - + ]: 772 : assert(base_lba != NULL);
146 [ + + ]: 772 : if (bs_io_unit_is_allocated(blob, lba)) {
147 : 480 : *base_lba = bs_blob_io_unit_to_lba(blob, lba);
148 : 480 : return true;
149 : : }
150 : :
151 [ - + ]: 292 : assert(blob->back_bs_dev != NULL);
152 : 292 : 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 : 94 : blob_bs_is_degraded(struct spdk_bs_dev *dev)
159 : : {
160 : 94 : struct spdk_blob_bs_dev *b = (struct spdk_blob_bs_dev *)dev;
161 : :
162 : 94 : return spdk_blob_is_degraded(b->blob);
163 : : }
164 : :
165 : : struct spdk_bs_dev *
166 : 2537 : bs_create_blob_bs_dev(struct spdk_blob *blob)
167 : : {
168 : : struct spdk_blob_bs_dev *b;
169 : :
170 : 2537 : b = calloc(1, sizeof(*b));
171 [ - + ]: 2537 : if (b == NULL) {
172 : 0 : return NULL;
173 : : }
174 : : /* snapshot blob */
175 : 5074 : b->bs_dev.blockcnt = blob->active.num_clusters *
176 : 2537 : blob->bs->pages_per_cluster * bs_io_unit_per_page(blob->bs);
177 : 2537 : b->bs_dev.blocklen = spdk_bs_get_io_unit_size(blob->bs);
178 : 2537 : b->bs_dev.create_channel = NULL;
179 : 2537 : b->bs_dev.destroy_channel = NULL;
180 : 2537 : b->bs_dev.destroy = blob_bs_dev_destroy;
181 : 2537 : b->bs_dev.write = blob_bs_dev_write;
182 : 2537 : b->bs_dev.writev = blob_bs_dev_writev;
183 : 2537 : b->bs_dev.writev_ext = blob_bs_dev_writev_ext;
184 : 2537 : b->bs_dev.read = blob_bs_dev_read;
185 : 2537 : b->bs_dev.readv = blob_bs_dev_readv;
186 : 2537 : b->bs_dev.readv_ext = blob_bs_dev_readv_ext;
187 : 2537 : b->bs_dev.write_zeroes = blob_bs_dev_write_zeroes;
188 : 2537 : b->bs_dev.unmap = blob_bs_dev_unmap;
189 : 2537 : b->bs_dev.is_zeroes = blob_bs_is_zeroes;
190 : 2537 : b->bs_dev.translate_lba = blob_bs_translate_lba;
191 : 2537 : b->bs_dev.is_degraded = blob_bs_is_degraded;
192 : 2537 : b->blob = blob;
193 : :
194 : 2537 : return &b->bs_dev;
195 : : }
|