xref: /spdk/module/bdev/raid/bdev_raid_sb.c (revision cb768e815fd023ef05e77a71df7f0a7fb9557376)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2022 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/bdev_module.h"
7 #include "spdk/crc32.h"
8 #include "spdk/env.h"
9 #include "spdk/log.h"
10 #include "spdk/string.h"
11 #include "spdk/util.h"
12 
13 #include "bdev_raid.h"
14 
15 struct raid_bdev_write_sb_ctx {
16 	struct raid_bdev *raid_bdev;
17 	int status;
18 	uint8_t submitted;
19 	uint8_t remaining;
20 	raid_bdev_write_sb_cb cb;
21 	void *cb_ctx;
22 	struct spdk_bdev_io_wait_entry wait_entry;
23 };
24 
25 struct raid_bdev_read_sb_ctx {
26 	struct spdk_bdev_desc *desc;
27 	struct spdk_io_channel *ch;
28 	raid_bdev_load_sb_cb cb;
29 	void *cb_ctx;
30 	void *buf;
31 	uint32_t buf_size;
32 };
33 
34 int
raid_bdev_alloc_superblock(struct raid_bdev * raid_bdev,uint32_t block_size)35 raid_bdev_alloc_superblock(struct raid_bdev *raid_bdev, uint32_t block_size)
36 {
37 	struct raid_bdev_superblock *sb;
38 
39 	assert(raid_bdev->sb == NULL);
40 
41 	sb = spdk_dma_zmalloc(SPDK_ALIGN_CEIL(RAID_BDEV_SB_MAX_LENGTH, block_size), 0x1000, NULL);
42 	if (!sb) {
43 		SPDK_ERRLOG("Failed to allocate raid bdev sb buffer\n");
44 		return -ENOMEM;
45 	}
46 
47 	raid_bdev->sb = sb;
48 
49 	return 0;
50 }
51 
52 void
raid_bdev_free_superblock(struct raid_bdev * raid_bdev)53 raid_bdev_free_superblock(struct raid_bdev *raid_bdev)
54 {
55 	if (raid_bdev->sb_io_buf != NULL && raid_bdev->sb_io_buf != raid_bdev->sb) {
56 		assert(spdk_bdev_is_md_interleaved(&raid_bdev->bdev));
57 		spdk_dma_free(raid_bdev->sb_io_buf);
58 		raid_bdev->sb_io_buf = NULL;
59 	}
60 	spdk_dma_free(raid_bdev->sb);
61 	raid_bdev->sb = NULL;
62 }
63 
64 void
raid_bdev_init_superblock(struct raid_bdev * raid_bdev)65 raid_bdev_init_superblock(struct raid_bdev *raid_bdev)
66 {
67 	struct raid_bdev_superblock *sb = raid_bdev->sb;
68 	struct raid_base_bdev_info *base_info;
69 	struct raid_bdev_sb_base_bdev *sb_base_bdev;
70 
71 	memcpy(&sb->signature, RAID_BDEV_SB_SIG, sizeof(sb->signature));
72 	sb->version.major = RAID_BDEV_SB_VERSION_MAJOR;
73 	sb->version.minor = RAID_BDEV_SB_VERSION_MINOR;
74 	spdk_uuid_copy(&sb->uuid, &raid_bdev->bdev.uuid);
75 	snprintf(sb->name, RAID_BDEV_SB_NAME_SIZE, "%s", raid_bdev->bdev.name);
76 	sb->raid_size = raid_bdev->bdev.blockcnt;
77 	sb->block_size = spdk_bdev_get_data_block_size(&raid_bdev->bdev);
78 	sb->level = raid_bdev->level;
79 	sb->strip_size = raid_bdev->strip_size;
80 	/* TODO: sb->state */
81 	sb->num_base_bdevs = sb->base_bdevs_size = raid_bdev->num_base_bdevs;
82 	sb->length = sizeof(*sb) + sizeof(*sb_base_bdev) * sb->base_bdevs_size;
83 
84 	sb_base_bdev = &sb->base_bdevs[0];
85 	RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
86 		spdk_uuid_copy(&sb_base_bdev->uuid, &base_info->uuid);
87 		sb_base_bdev->data_offset = base_info->data_offset;
88 		sb_base_bdev->data_size = base_info->data_size;
89 		sb_base_bdev->state = RAID_SB_BASE_BDEV_CONFIGURED;
90 		sb_base_bdev->slot = raid_bdev_base_bdev_slot(base_info);
91 		sb_base_bdev++;
92 	}
93 }
94 
95 static int
raid_bdev_alloc_sb_io_buf(struct raid_bdev * raid_bdev)96 raid_bdev_alloc_sb_io_buf(struct raid_bdev *raid_bdev)
97 {
98 	struct raid_bdev_superblock *sb = raid_bdev->sb;
99 
100 	if (spdk_bdev_is_md_interleaved(&raid_bdev->bdev)) {
101 		raid_bdev->sb_io_buf_size = spdk_divide_round_up(sb->length,
102 					    sb->block_size) * raid_bdev->bdev.blocklen;
103 		raid_bdev->sb_io_buf = spdk_dma_zmalloc(raid_bdev->sb_io_buf_size, 0x1000, NULL);
104 		if (!raid_bdev->sb_io_buf) {
105 			SPDK_ERRLOG("Failed to allocate raid bdev sb io buffer\n");
106 			return -ENOMEM;
107 		}
108 	} else {
109 		raid_bdev->sb_io_buf_size = SPDK_ALIGN_CEIL(sb->length, raid_bdev->bdev.blocklen);
110 		raid_bdev->sb_io_buf = raid_bdev->sb;
111 	}
112 
113 	return 0;
114 }
115 
116 static void
raid_bdev_sb_update_crc(struct raid_bdev_superblock * sb)117 raid_bdev_sb_update_crc(struct raid_bdev_superblock *sb)
118 {
119 	sb->crc = 0;
120 	sb->crc = spdk_crc32c_update(sb, sb->length, 0);
121 }
122 
123 static bool
raid_bdev_sb_check_crc(struct raid_bdev_superblock * sb)124 raid_bdev_sb_check_crc(struct raid_bdev_superblock *sb)
125 {
126 	uint32_t crc, prev = sb->crc;
127 
128 	raid_bdev_sb_update_crc(sb);
129 	crc = sb->crc;
130 	sb->crc = prev;
131 
132 	return crc == prev;
133 }
134 
135 static int
raid_bdev_parse_superblock(struct raid_bdev_read_sb_ctx * ctx)136 raid_bdev_parse_superblock(struct raid_bdev_read_sb_ctx *ctx)
137 {
138 	struct raid_bdev_superblock *sb = ctx->buf;
139 	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(ctx->desc);
140 	struct raid_bdev_sb_base_bdev *sb_base_bdev;
141 	uint8_t i;
142 
143 	if (memcmp(sb->signature, RAID_BDEV_SB_SIG, sizeof(sb->signature))) {
144 		SPDK_DEBUGLOG(bdev_raid_sb, "invalid signature\n");
145 		return -EINVAL;
146 	}
147 
148 	if (spdk_divide_round_up(sb->length, spdk_bdev_get_data_block_size(bdev)) >
149 	    spdk_divide_round_up(ctx->buf_size, bdev->blocklen)) {
150 		if (sb->length > RAID_BDEV_SB_MAX_LENGTH) {
151 			SPDK_WARNLOG("Incorrect superblock length on bdev %s\n",
152 				     spdk_bdev_get_name(bdev));
153 			return -EINVAL;
154 		}
155 
156 		return -EAGAIN;
157 	}
158 
159 	if (!raid_bdev_sb_check_crc(sb)) {
160 		SPDK_WARNLOG("Incorrect superblock crc on bdev %s\n", spdk_bdev_get_name(bdev));
161 		return -EINVAL;
162 	}
163 
164 	if (sb->version.major != RAID_BDEV_SB_VERSION_MAJOR) {
165 		SPDK_ERRLOG("Not supported superblock major version %d on bdev %s\n",
166 			    sb->version.major, spdk_bdev_get_name(bdev));
167 		return -EINVAL;
168 	}
169 
170 	if (sb->version.minor > RAID_BDEV_SB_VERSION_MINOR) {
171 		SPDK_WARNLOG("Superblock minor version %d on bdev %s is higher than the currently supported: %d\n",
172 			     sb->version.minor, spdk_bdev_get_name(bdev), RAID_BDEV_SB_VERSION_MINOR);
173 	}
174 
175 	for (i = 0; i < sb->base_bdevs_size; i++) {
176 		sb_base_bdev = &sb->base_bdevs[i];
177 		if (sb_base_bdev->slot >= sb->num_base_bdevs) {
178 			SPDK_WARNLOG("Invalid superblock base bdev slot number %u on bdev %s\n",
179 				     sb_base_bdev->slot, spdk_bdev_get_name(bdev));
180 			return -EINVAL;
181 		}
182 	}
183 
184 	return 0;
185 }
186 
187 static void
raid_bdev_read_sb_ctx_free(struct raid_bdev_read_sb_ctx * ctx)188 raid_bdev_read_sb_ctx_free(struct raid_bdev_read_sb_ctx *ctx)
189 {
190 	spdk_dma_free(ctx->buf);
191 
192 	free(ctx);
193 }
194 
195 static void raid_bdev_read_sb_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg);
196 
197 static int
raid_bdev_read_sb_remainder(struct raid_bdev_read_sb_ctx * ctx)198 raid_bdev_read_sb_remainder(struct raid_bdev_read_sb_ctx *ctx)
199 {
200 	struct raid_bdev_superblock *sb = ctx->buf;
201 	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(ctx->desc);
202 	uint32_t buf_size_prev;
203 	void *buf;
204 	int rc;
205 
206 	buf_size_prev = ctx->buf_size;
207 	ctx->buf_size = spdk_divide_round_up(spdk_min(sb->length, RAID_BDEV_SB_MAX_LENGTH),
208 					     spdk_bdev_get_data_block_size(bdev)) * bdev->blocklen;
209 	buf = spdk_dma_realloc(ctx->buf, ctx->buf_size, spdk_bdev_get_buf_align(bdev), NULL);
210 	if (buf == NULL) {
211 		SPDK_ERRLOG("Failed to reallocate buffer\n");
212 		return -ENOMEM;
213 	}
214 	ctx->buf = buf;
215 
216 	rc = spdk_bdev_read(ctx->desc, ctx->ch, ctx->buf + buf_size_prev, buf_size_prev,
217 			    ctx->buf_size - buf_size_prev, raid_bdev_read_sb_cb, ctx);
218 	if (rc != 0) {
219 		SPDK_ERRLOG("Failed to read bdev %s superblock remainder: %s\n",
220 			    spdk_bdev_get_name(bdev), spdk_strerror(-rc));
221 		return rc;
222 	}
223 
224 	return 0;
225 }
226 
227 static void
raid_bdev_read_sb_cb(struct spdk_bdev_io * bdev_io,bool success,void * cb_arg)228 raid_bdev_read_sb_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
229 {
230 	struct spdk_bdev *bdev = bdev_io->bdev;
231 	struct raid_bdev_read_sb_ctx *ctx = cb_arg;
232 	struct raid_bdev_superblock *sb = NULL;
233 	int status;
234 
235 	if (spdk_bdev_is_md_interleaved(bdev_io->bdev) && ctx->buf_size > bdev->blocklen) {
236 		const uint32_t data_block_size = spdk_bdev_get_data_block_size(bdev);
237 		uint32_t i;
238 
239 		for (i = 1; i < ctx->buf_size / bdev->blocklen; i++) {
240 			memmove(ctx->buf + (i * data_block_size),
241 				ctx->buf + (i * bdev->blocklen),
242 				data_block_size);
243 		}
244 	}
245 
246 	spdk_bdev_free_io(bdev_io);
247 
248 	if (!success) {
249 		status = -EIO;
250 		goto out;
251 	}
252 
253 	status = raid_bdev_parse_superblock(ctx);
254 	if (status == -EAGAIN) {
255 		status = raid_bdev_read_sb_remainder(ctx);
256 		if (status == 0) {
257 			return;
258 		}
259 	} else if (status != 0) {
260 		SPDK_DEBUGLOG(bdev_raid_sb, "failed to parse bdev %s superblock\n",
261 			      spdk_bdev_get_name(spdk_bdev_desc_get_bdev(ctx->desc)));
262 	} else {
263 		sb = ctx->buf;
264 	}
265 out:
266 	ctx->cb(sb, status, ctx->cb_ctx);
267 
268 	raid_bdev_read_sb_ctx_free(ctx);
269 }
270 
271 int
raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc * desc,struct spdk_io_channel * ch,raid_bdev_load_sb_cb cb,void * cb_ctx)272 raid_bdev_load_base_bdev_superblock(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
273 				    raid_bdev_load_sb_cb cb, void *cb_ctx)
274 {
275 	struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc);
276 	struct raid_bdev_read_sb_ctx *ctx;
277 	int rc;
278 
279 	assert(cb != NULL);
280 
281 	ctx = calloc(1, sizeof(*ctx));
282 	if (!ctx) {
283 		return -ENOMEM;
284 	}
285 
286 	ctx->desc = desc;
287 	ctx->ch = ch;
288 	ctx->cb = cb;
289 	ctx->cb_ctx = cb_ctx;
290 	ctx->buf_size = spdk_divide_round_up(sizeof(struct raid_bdev_superblock),
291 					     spdk_bdev_get_data_block_size(bdev)) * bdev->blocklen;
292 	ctx->buf = spdk_dma_malloc(ctx->buf_size, spdk_bdev_get_buf_align(bdev), NULL);
293 	if (!ctx->buf) {
294 		rc = -ENOMEM;
295 		goto err;
296 	}
297 
298 	rc = spdk_bdev_read(desc, ch, ctx->buf, 0, ctx->buf_size, raid_bdev_read_sb_cb, ctx);
299 	if (rc) {
300 		goto err;
301 	}
302 
303 	return 0;
304 err:
305 	raid_bdev_read_sb_ctx_free(ctx);
306 
307 	return rc;
308 }
309 
310 static void
raid_bdev_write_sb_base_bdev_done(int status,struct raid_bdev_write_sb_ctx * ctx)311 raid_bdev_write_sb_base_bdev_done(int status, struct raid_bdev_write_sb_ctx *ctx)
312 {
313 	if (status != 0) {
314 		ctx->status = status;
315 	}
316 
317 	if (--ctx->remaining == 0) {
318 		ctx->cb(ctx->status, ctx->raid_bdev, ctx->cb_ctx);
319 		free(ctx);
320 	}
321 }
322 
323 static void
raid_bdev_write_superblock_cb(struct spdk_bdev_io * bdev_io,bool success,void * cb_arg)324 raid_bdev_write_superblock_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
325 {
326 	struct raid_bdev_write_sb_ctx *ctx = cb_arg;
327 	int status = 0;
328 
329 	if (!success) {
330 		SPDK_ERRLOG("Failed to save superblock on bdev %s\n", bdev_io->bdev->name);
331 		status = -EIO;
332 	}
333 
334 	spdk_bdev_free_io(bdev_io);
335 
336 	raid_bdev_write_sb_base_bdev_done(status, ctx);
337 }
338 
339 static void
_raid_bdev_write_superblock(void * _ctx)340 _raid_bdev_write_superblock(void *_ctx)
341 {
342 	struct raid_bdev_write_sb_ctx *ctx = _ctx;
343 	struct raid_bdev *raid_bdev = ctx->raid_bdev;
344 	struct raid_base_bdev_info *base_info;
345 	uint8_t i;
346 	int rc;
347 
348 	for (i = ctx->submitted; i < raid_bdev->num_base_bdevs; i++) {
349 		base_info = &raid_bdev->base_bdev_info[i];
350 
351 		if (!base_info->is_configured || base_info->remove_scheduled) {
352 			assert(ctx->remaining > 1);
353 			raid_bdev_write_sb_base_bdev_done(0, ctx);
354 			ctx->submitted++;
355 			continue;
356 		}
357 
358 		rc = spdk_bdev_write(base_info->desc, base_info->app_thread_ch,
359 				     raid_bdev->sb_io_buf, 0, raid_bdev->sb_io_buf_size,
360 				     raid_bdev_write_superblock_cb, ctx);
361 		if (rc != 0) {
362 			struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(base_info->desc);
363 
364 			if (rc == -ENOMEM) {
365 				ctx->wait_entry.bdev = bdev;
366 				ctx->wait_entry.cb_fn = _raid_bdev_write_superblock;
367 				ctx->wait_entry.cb_arg = ctx;
368 				spdk_bdev_queue_io_wait(bdev, base_info->app_thread_ch, &ctx->wait_entry);
369 				return;
370 			}
371 
372 			assert(ctx->remaining > 1);
373 			raid_bdev_write_sb_base_bdev_done(rc, ctx);
374 		}
375 
376 		ctx->submitted++;
377 	}
378 
379 	raid_bdev_write_sb_base_bdev_done(0, ctx);
380 }
381 
382 void
raid_bdev_write_superblock(struct raid_bdev * raid_bdev,raid_bdev_write_sb_cb cb,void * cb_ctx)383 raid_bdev_write_superblock(struct raid_bdev *raid_bdev, raid_bdev_write_sb_cb cb, void *cb_ctx)
384 {
385 	struct raid_bdev_write_sb_ctx *ctx;
386 	struct raid_bdev_superblock *sb = raid_bdev->sb;
387 	int rc;
388 
389 	assert(spdk_get_thread() == spdk_thread_get_app_thread());
390 	assert(sb != NULL);
391 	assert(cb != NULL);
392 
393 	if (raid_bdev->sb_io_buf == NULL) {
394 		rc = raid_bdev_alloc_sb_io_buf(raid_bdev);
395 		if (rc != 0) {
396 			goto err;
397 		}
398 	}
399 
400 	ctx = calloc(1, sizeof(*ctx));
401 	if (!ctx) {
402 		rc = -ENOMEM;
403 		goto err;
404 	}
405 
406 	ctx->raid_bdev = raid_bdev;
407 	ctx->remaining = raid_bdev->num_base_bdevs + 1;
408 	ctx->cb = cb;
409 	ctx->cb_ctx = cb_ctx;
410 
411 	sb->seq_number++;
412 	raid_bdev_sb_update_crc(sb);
413 
414 	if (spdk_bdev_is_md_interleaved(&raid_bdev->bdev)) {
415 		void *sb_buf = sb;
416 		uint32_t i;
417 
418 		for (i = 0; i < raid_bdev->sb_io_buf_size / raid_bdev->bdev.blocklen; i++) {
419 			memcpy(raid_bdev->sb_io_buf + (i * raid_bdev->bdev.blocklen),
420 			       sb_buf + (i * sb->block_size), sb->block_size);
421 		}
422 	}
423 
424 	_raid_bdev_write_superblock(ctx);
425 	return;
426 err:
427 	cb(rc, raid_bdev, cb_ctx);
428 }
429 
430 SPDK_LOG_REGISTER_COMPONENT(bdev_raid_sb)
431