xref: /spdk/test/unit/lib/blob/bs_dev_common.c (revision 161a3002750e4acd9e9da110b1dc70c0730e37e8)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #define DEV_BUFFER_SIZE (64 * 1024 * 1024)
35 #define DEV_BUFFER_BLOCKLEN (4096)
36 #define DEV_BUFFER_BLOCKCNT (DEV_BUFFER_SIZE / DEV_BUFFER_BLOCKLEN)
37 uint8_t *g_dev_buffer;
38 
39 /* Define here for UT only. */
40 struct spdk_io_channel {
41 	struct spdk_thread		*thread;
42 } g_io_channel;
43 
44 static struct spdk_io_channel *
45 dev_create_channel(struct spdk_bs_dev *dev)
46 {
47 	return &g_io_channel;
48 }
49 
50 static void
51 dev_destroy_channel(struct spdk_bs_dev *dev, struct spdk_io_channel *channel)
52 {
53 }
54 
55 static void
56 dev_destroy(struct spdk_bs_dev *dev)
57 {
58 	free(dev);
59 }
60 
61 static void
62 dev_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
63 	 uint64_t lba, uint32_t lba_count,
64 	 struct spdk_bs_dev_cb_args *cb_args)
65 {
66 	uint64_t offset, length;
67 
68 	offset = lba * DEV_BUFFER_BLOCKLEN;
69 	length = lba_count * DEV_BUFFER_BLOCKLEN;
70 	SPDK_CU_ASSERT_FATAL(offset + length <= DEV_BUFFER_SIZE);
71 	memcpy(payload, &g_dev_buffer[offset], length);
72 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
73 }
74 
75 static void
76 dev_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
77 	  uint64_t lba, uint32_t lba_count,
78 	  struct spdk_bs_dev_cb_args *cb_args)
79 {
80 	uint64_t offset, length;
81 
82 	offset = lba * DEV_BUFFER_BLOCKLEN;
83 	length = lba_count * DEV_BUFFER_BLOCKLEN;
84 	SPDK_CU_ASSERT_FATAL(offset + length <= DEV_BUFFER_SIZE);
85 	memcpy(&g_dev_buffer[offset], payload, length);
86 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
87 }
88 
89 static void
90 __check_iov(struct iovec *iov, int iovcnt, uint64_t length)
91 {
92 	int i;
93 
94 	for (i = 0; i < iovcnt; i++) {
95 		length -= iov[i].iov_len;
96 	}
97 
98 	CU_ASSERT(length == 0);
99 }
100 
101 static void
102 dev_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
103 	  struct iovec *iov, int iovcnt,
104 	  uint64_t lba, uint32_t lba_count,
105 	  struct spdk_bs_dev_cb_args *cb_args)
106 {
107 	uint64_t offset, length;
108 	int i;
109 
110 	offset = lba * DEV_BUFFER_BLOCKLEN;
111 	length = lba_count * DEV_BUFFER_BLOCKLEN;
112 	SPDK_CU_ASSERT_FATAL(offset + length <= DEV_BUFFER_SIZE);
113 	__check_iov(iov, iovcnt, length);
114 
115 	for (i = 0; i < iovcnt; i++) {
116 		memcpy(iov[i].iov_base, &g_dev_buffer[offset], iov[i].iov_len);
117 		offset += iov[i].iov_len;
118 	}
119 
120 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
121 }
122 
123 static void
124 dev_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
125 	   struct iovec *iov, int iovcnt,
126 	   uint64_t lba, uint32_t lba_count,
127 	   struct spdk_bs_dev_cb_args *cb_args)
128 {
129 	uint64_t offset, length;
130 	int i;
131 
132 	offset = lba * DEV_BUFFER_BLOCKLEN;
133 	length = lba_count * DEV_BUFFER_BLOCKLEN;
134 	SPDK_CU_ASSERT_FATAL(offset + length <= DEV_BUFFER_SIZE);
135 	__check_iov(iov, iovcnt, length);
136 
137 	for (i = 0; i < iovcnt; i++) {
138 		memcpy(&g_dev_buffer[offset], iov[i].iov_base, iov[i].iov_len);
139 		offset += iov[i].iov_len;
140 	}
141 
142 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
143 }
144 
145 static void
146 dev_flush(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
147 	  struct spdk_bs_dev_cb_args *cb_args)
148 {
149 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
150 }
151 
152 static void
153 dev_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
154 	  uint64_t lba, uint32_t lba_count,
155 	  struct spdk_bs_dev_cb_args *cb_args)
156 {
157 	uint64_t offset, length;
158 
159 	offset = lba * DEV_BUFFER_BLOCKLEN;
160 	length = lba_count * DEV_BUFFER_BLOCKLEN;
161 	SPDK_CU_ASSERT_FATAL(offset + length <= DEV_BUFFER_SIZE);
162 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
163 }
164 
165 static void
166 dev_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
167 		 uint64_t lba, uint32_t lba_count,
168 		 struct spdk_bs_dev_cb_args *cb_args)
169 {
170 	uint64_t offset, length;
171 
172 	offset = lba * DEV_BUFFER_BLOCKLEN;
173 	length = lba_count * DEV_BUFFER_BLOCKLEN;
174 	SPDK_CU_ASSERT_FATAL(offset + length <= DEV_BUFFER_SIZE);
175 	memset(&g_dev_buffer[offset], 0, length);
176 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
177 }
178 
179 static struct spdk_bs_dev *
180 init_dev(void)
181 {
182 	struct spdk_bs_dev *dev = calloc(1, sizeof(*dev));
183 
184 	SPDK_CU_ASSERT_FATAL(dev != NULL);
185 
186 	dev->create_channel = dev_create_channel;
187 	dev->destroy_channel = dev_destroy_channel;
188 	dev->destroy = dev_destroy;
189 	dev->read = dev_read;
190 	dev->write = dev_write;
191 	dev->readv = dev_readv;
192 	dev->writev = dev_writev;
193 	dev->flush = dev_flush;
194 	dev->unmap = dev_unmap;
195 	dev->write_zeroes = dev_write_zeroes;
196 	dev->blockcnt = DEV_BUFFER_BLOCKCNT;
197 	dev->blocklen = DEV_BUFFER_BLOCKLEN;
198 
199 	return dev;
200 }
201