xref: /spdk/lib/ftl/ftl_band.c (revision 9889ab2dc80e40dae92dcef361d53dcba722043d)
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 #include "spdk/crc32.h"
35 #include "spdk/likely.h"
36 #include "spdk/util.h"
37 #include "spdk/ftl.h"
38 
39 #include "ftl_band.h"
40 #include "ftl_io.h"
41 #include "ftl_core.h"
42 #include "ftl_reloc.h"
43 #include "ftl_debug.h"
44 
45 /* TODO: define some signature for meta version */
46 #define FTL_MD_VER 1
47 
48 struct __attribute__((packed)) ftl_md_hdr {
49 	/* Device instance */
50 	struct spdk_uuid	uuid;
51 
52 	/* Meta version */
53 	uint8_t			ver;
54 
55 	/* Sequence number */
56 	uint64_t		seq;
57 
58 	/* CRC32 checksum */
59 	uint32_t		checksum;
60 };
61 
62 /* End metadata layout stored on media (with all three being aligned to block size): */
63 /* - header */
64 /* - valid bitmap */
65 /* - LBA map */
66 struct __attribute__((packed)) ftl_tail_md {
67 	struct ftl_md_hdr	hdr;
68 
69 	/* Max number of lbks */
70 	uint64_t		num_lbks;
71 
72 	uint8_t			reserved[4059];
73 };
74 SPDK_STATIC_ASSERT(sizeof(struct ftl_tail_md) == FTL_BLOCK_SIZE, "Incorrect metadata size");
75 
76 struct __attribute__((packed)) ftl_head_md {
77 	struct ftl_md_hdr	hdr;
78 
79 	/* Number of defrag cycles */
80 	uint64_t		wr_cnt;
81 
82 	/* Number of surfaced LBAs */
83 	uint64_t		lba_cnt;
84 
85 	/* Transfer size */
86 	uint32_t		xfer_size;
87 };
88 
89 size_t
90 ftl_tail_md_hdr_num_lbks(void)
91 {
92 	return spdk_divide_round_up(sizeof(struct ftl_tail_md), FTL_BLOCK_SIZE);
93 }
94 
95 size_t
96 ftl_vld_map_num_lbks(const struct spdk_ftl_dev *dev)
97 {
98 	return spdk_divide_round_up(ftl_vld_map_size(dev), FTL_BLOCK_SIZE);
99 }
100 
101 size_t
102 ftl_lba_map_num_lbks(const struct spdk_ftl_dev *dev)
103 {
104 	return spdk_divide_round_up(ftl_num_band_lbks(dev) * sizeof(uint64_t), FTL_BLOCK_SIZE);
105 }
106 
107 size_t
108 ftl_head_md_num_lbks(const struct spdk_ftl_dev *dev)
109 {
110 	return dev->xfer_size;
111 }
112 
113 size_t
114 ftl_tail_md_num_lbks(const struct spdk_ftl_dev *dev)
115 {
116 	return spdk_divide_round_up(ftl_tail_md_hdr_num_lbks() +
117 				    ftl_vld_map_num_lbks(dev) +
118 				    ftl_lba_map_num_lbks(dev),
119 				    dev->xfer_size) * dev->xfer_size;
120 }
121 
122 static uint64_t
123 ftl_band_tail_md_offset(const struct ftl_band *band)
124 {
125 	return ftl_band_num_usable_lbks(band) -
126 	       ftl_tail_md_num_lbks(band->dev);
127 }
128 
129 int
130 ftl_band_full(struct ftl_band *band, size_t offset)
131 {
132 	return offset == ftl_band_tail_md_offset(band);
133 }
134 
135 void
136 ftl_band_write_failed(struct ftl_band *band)
137 {
138 	struct spdk_ftl_dev *dev = band->dev;
139 
140 	band->high_prio = 1;
141 
142 	ftl_reloc_add(dev->reloc, band, 0, ftl_num_band_lbks(dev), 1, true);
143 	ftl_band_set_state(band, FTL_BAND_STATE_CLOSED);
144 }
145 
146 static void
147 ftl_band_free_lba_map(struct ftl_band *band)
148 {
149 	struct spdk_ftl_dev *dev = band->dev;
150 	struct ftl_lba_map *lba_map = &band->lba_map;
151 
152 	assert(band->state == FTL_BAND_STATE_CLOSED ||
153 	       band->state == FTL_BAND_STATE_FREE);
154 	assert(lba_map->ref_cnt == 0);
155 	assert(lba_map->map != NULL);
156 	assert(!band->high_prio);
157 
158 	/* Verify that band's metadata is consistent with l2p */
159 	if (band->num_chunks) {
160 		assert(ftl_band_validate_md(band) == true);
161 	}
162 
163 	spdk_mempool_put(dev->lba_pool, lba_map->dma_buf);
164 	lba_map->map = NULL;
165 	lba_map->dma_buf = NULL;
166 }
167 
168 static void
169 _ftl_band_set_free(struct ftl_band *band)
170 {
171 	struct spdk_ftl_dev *dev = band->dev;
172 	struct ftl_band *lband, *prev;
173 
174 	/* Remove the band from the closed band list */
175 	LIST_REMOVE(band, list_entry);
176 
177 	/* Keep the list sorted by band's write count */
178 	LIST_FOREACH(lband, &dev->free_bands, list_entry) {
179 		if (lband->wr_cnt > band->wr_cnt) {
180 			LIST_INSERT_BEFORE(lband, band, list_entry);
181 			break;
182 		}
183 		prev = lband;
184 	}
185 
186 	if (!lband) {
187 		if (LIST_EMPTY(&dev->free_bands)) {
188 			LIST_INSERT_HEAD(&dev->free_bands, band, list_entry);
189 		} else {
190 			LIST_INSERT_AFTER(prev, band, list_entry);
191 		}
192 	}
193 
194 #if defined(DEBUG)
195 	prev = NULL;
196 	LIST_FOREACH(lband, &dev->free_bands, list_entry) {
197 		if (!prev) {
198 			continue;
199 		}
200 		assert(prev->wr_cnt <= lband->wr_cnt);
201 	}
202 #endif
203 	dev->num_free++;
204 	ftl_apply_limits(dev);
205 }
206 
207 static void
208 _ftl_band_set_preparing(struct ftl_band *band)
209 {
210 	struct spdk_ftl_dev *dev = band->dev;
211 
212 	/* Remove band from free list */
213 	LIST_REMOVE(band, list_entry);
214 
215 	band->wr_cnt++;
216 
217 	assert(dev->num_free > 0);
218 	dev->num_free--;
219 
220 	ftl_apply_limits(dev);
221 }
222 
223 static void
224 _ftl_band_set_closed(struct ftl_band *band)
225 {
226 	struct spdk_ftl_dev *dev = band->dev;
227 	struct ftl_chunk *chunk;
228 
229 	/* Set the state as free_md() checks for that */
230 	band->state = FTL_BAND_STATE_CLOSED;
231 
232 	/* Free the lba map if there are no outstanding IOs */
233 	ftl_band_release_lba_map(band);
234 
235 	if (spdk_likely(band->num_chunks)) {
236 		LIST_INSERT_HEAD(&dev->shut_bands, band, list_entry);
237 		CIRCLEQ_FOREACH(chunk, &band->chunks, circleq) {
238 			chunk->state = FTL_CHUNK_STATE_CLOSED;
239 		}
240 	} else {
241 		LIST_REMOVE(band, list_entry);
242 	}
243 }
244 
245 static uint32_t
246 ftl_md_calc_crc(const struct ftl_md_hdr *hdr, size_t size)
247 {
248 	size_t checkoff = offsetof(struct ftl_md_hdr, checksum);
249 	size_t mdoff = checkoff + sizeof(hdr->checksum);
250 	uint32_t crc;
251 
252 	crc = spdk_crc32c_update(hdr, checkoff, 0);
253 	return spdk_crc32c_update((const char *)hdr + mdoff, size - mdoff, crc);
254 }
255 
256 static void
257 ftl_set_md_hdr(struct ftl_band *band, struct ftl_md_hdr *hdr, size_t size)
258 {
259 	hdr->seq = band->seq;
260 	hdr->ver = FTL_MD_VER;
261 	hdr->uuid = band->dev->uuid;
262 	hdr->checksum = ftl_md_calc_crc(hdr, size);
263 }
264 
265 static int
266 ftl_pack_head_md(struct ftl_band *band)
267 {
268 	struct spdk_ftl_dev *dev = band->dev;
269 	struct ftl_head_md *head = band->lba_map.dma_buf;
270 
271 	head->wr_cnt = band->wr_cnt;
272 	head->lba_cnt = dev->num_lbas;
273 	head->xfer_size = dev->xfer_size;
274 	ftl_set_md_hdr(band, &head->hdr, sizeof(struct ftl_head_md));
275 
276 	return FTL_MD_SUCCESS;
277 }
278 
279 static int
280 ftl_pack_tail_md(struct ftl_band *band)
281 {
282 	struct spdk_ftl_dev *dev = band->dev;
283 	struct ftl_lba_map *lba_map = &band->lba_map;
284 	struct ftl_tail_md *tail = lba_map->dma_buf;
285 	void *vld_offset;
286 
287 	vld_offset = (char *)tail + ftl_tail_md_hdr_num_lbks() * FTL_BLOCK_SIZE;
288 
289 	/* Clear out the buffer */
290 	memset(tail, 0, ftl_tail_md_hdr_num_lbks() * FTL_BLOCK_SIZE);
291 	tail->num_lbks = ftl_num_band_lbks(dev);
292 
293 	pthread_spin_lock(&lba_map->lock);
294 	spdk_bit_array_store_mask(lba_map->vld, vld_offset);
295 	pthread_spin_unlock(&lba_map->lock);
296 
297 	ftl_set_md_hdr(band, &tail->hdr, ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE);
298 
299 	return FTL_MD_SUCCESS;
300 }
301 
302 static int
303 ftl_md_hdr_vld(struct spdk_ftl_dev *dev, const struct ftl_md_hdr *hdr, size_t size)
304 {
305 	if (spdk_uuid_compare(&dev->uuid, &hdr->uuid) != 0) {
306 		return FTL_MD_NO_MD;
307 	}
308 
309 	if (hdr->ver != FTL_MD_VER) {
310 		return FTL_MD_INVALID_VER;
311 	}
312 
313 	if (ftl_md_calc_crc(hdr, size) != hdr->checksum) {
314 		return FTL_MD_INVALID_CRC;
315 	}
316 
317 	return FTL_MD_SUCCESS;
318 }
319 
320 static int
321 ftl_unpack_tail_md(struct ftl_band *band)
322 {
323 	struct spdk_ftl_dev *dev = band->dev;
324 	void *vld_offset;
325 	struct ftl_lba_map *lba_map = &band->lba_map;
326 	struct ftl_tail_md *tail = lba_map->dma_buf;
327 	int rc;
328 
329 	vld_offset = (char *)tail + ftl_tail_md_hdr_num_lbks() * FTL_BLOCK_SIZE;
330 
331 	rc = ftl_md_hdr_vld(dev, &tail->hdr, ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE);
332 	if (rc) {
333 		return rc;
334 	}
335 
336 	/*
337 	 * When restoring from a dirty shutdown it's possible old tail meta wasn't yet cleared -
338 	 * band had saved head meta, but didn't manage to send erase to all chunks.
339 	 * The already found tail md header is valid, but inconsistent with the head meta. Treat
340 	 * such a band as open/without valid tail md.
341 	 */
342 	if (band->seq != tail->hdr.seq) {
343 		return FTL_MD_NO_MD;
344 	}
345 
346 	if (tail->num_lbks != ftl_num_band_lbks(dev)) {
347 		return FTL_MD_INVALID_SIZE;
348 	}
349 
350 	spdk_bit_array_load_mask(lba_map->vld, vld_offset);
351 
352 	return FTL_MD_SUCCESS;
353 }
354 
355 static int
356 ftl_unpack_head_md(struct ftl_band *band)
357 {
358 	struct spdk_ftl_dev *dev = band->dev;
359 	struct ftl_head_md *head = band->lba_map.dma_buf;
360 	int rc;
361 
362 	rc = ftl_md_hdr_vld(dev, &head->hdr, sizeof(struct ftl_head_md));
363 	if (rc) {
364 		return rc;
365 	}
366 
367 	band->seq = head->hdr.seq;
368 	band->wr_cnt = head->wr_cnt;
369 
370 	if (dev->global_md.num_lbas == 0) {
371 		dev->global_md.num_lbas = head->lba_cnt;
372 	}
373 
374 	if (dev->global_md.num_lbas != head->lba_cnt) {
375 		return FTL_MD_INVALID_SIZE;
376 	}
377 
378 	if (dev->xfer_size != head->xfer_size) {
379 		return FTL_MD_INVALID_SIZE;
380 	}
381 
382 	return FTL_MD_SUCCESS;
383 }
384 
385 struct ftl_ppa
386 ftl_band_tail_md_ppa(struct ftl_band *band)
387 {
388 	struct ftl_ppa ppa = {};
389 	struct ftl_chunk *chunk;
390 	struct spdk_ftl_dev *dev = band->dev;
391 	size_t xfer_size = dev->xfer_size;
392 	size_t num_req = ftl_band_tail_md_offset(band) / xfer_size;
393 	size_t i;
394 
395 	if (spdk_unlikely(!band->num_chunks)) {
396 		return ftl_to_ppa(FTL_PPA_INVALID);
397 	}
398 
399 	/* Metadata should be aligned to xfer size */
400 	assert(ftl_band_tail_md_offset(band) % xfer_size == 0);
401 
402 	chunk = CIRCLEQ_FIRST(&band->chunks);
403 	for (i = 0; i < num_req % band->num_chunks; ++i) {
404 		chunk = ftl_band_next_chunk(band, chunk);
405 	}
406 
407 	ppa.lbk = (num_req / band->num_chunks) * xfer_size;
408 	ppa.chk = band->id;
409 	ppa.pu = chunk->punit->start_ppa.pu;
410 	ppa.grp = chunk->punit->start_ppa.grp;
411 
412 	return ppa;
413 }
414 
415 struct ftl_ppa
416 ftl_band_head_md_ppa(struct ftl_band *band)
417 {
418 	struct ftl_ppa ppa;
419 
420 	if (spdk_unlikely(!band->num_chunks)) {
421 		return ftl_to_ppa(FTL_PPA_INVALID);
422 	}
423 
424 	ppa = CIRCLEQ_FIRST(&band->chunks)->punit->start_ppa;
425 	ppa.chk = band->id;
426 
427 	return ppa;
428 }
429 
430 void
431 ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state)
432 {
433 	switch (state) {
434 	case FTL_BAND_STATE_FREE:
435 		assert(band->state == FTL_BAND_STATE_CLOSED);
436 		_ftl_band_set_free(band);
437 		break;
438 
439 	case FTL_BAND_STATE_PREP:
440 		assert(band->state == FTL_BAND_STATE_FREE);
441 		_ftl_band_set_preparing(band);
442 		break;
443 
444 	case FTL_BAND_STATE_CLOSED:
445 		if (band->state != FTL_BAND_STATE_CLOSED) {
446 			assert(band->state == FTL_BAND_STATE_CLOSING || band->high_prio);
447 			_ftl_band_set_closed(band);
448 		}
449 		break;
450 
451 	default:
452 		break;
453 	}
454 
455 	band->state = state;
456 }
457 
458 void
459 ftl_band_set_addr(struct ftl_band *band, uint64_t lba, struct ftl_ppa ppa)
460 {
461 	struct ftl_lba_map *lba_map = &band->lba_map;
462 	uint64_t offset;
463 
464 	assert(lba != FTL_LBA_INVALID);
465 
466 	offset = ftl_band_lbkoff_from_ppa(band, ppa);
467 	pthread_spin_lock(&lba_map->lock);
468 
469 	lba_map->num_vld++;
470 	lba_map->map[offset] = lba;
471 	spdk_bit_array_set(lba_map->vld, offset);
472 
473 	pthread_spin_unlock(&lba_map->lock);
474 }
475 
476 size_t
477 ftl_band_age(const struct ftl_band *band)
478 {
479 	return (size_t)(band->dev->seq - band->seq);
480 }
481 
482 size_t
483 ftl_band_num_usable_lbks(const struct ftl_band *band)
484 {
485 	return band->num_chunks * ftl_dev_lbks_in_chunk(band->dev);
486 }
487 
488 size_t
489 ftl_band_user_lbks_left(const struct ftl_band *band, size_t offset)
490 {
491 	size_t tail_md_offset = ftl_band_tail_md_offset(band);
492 
493 	if (spdk_unlikely(offset <= ftl_head_md_num_lbks(band->dev))) {
494 		return ftl_band_user_lbks(band);
495 	}
496 
497 	if (spdk_unlikely(offset > tail_md_offset)) {
498 		return 0;
499 	}
500 
501 	return tail_md_offset - offset;
502 }
503 
504 size_t
505 ftl_band_user_lbks(const struct ftl_band *band)
506 {
507 	return ftl_band_num_usable_lbks(band) -
508 	       ftl_head_md_num_lbks(band->dev) -
509 	       ftl_tail_md_num_lbks(band->dev);
510 }
511 
512 struct ftl_band *
513 ftl_band_from_ppa(struct spdk_ftl_dev *dev, struct ftl_ppa ppa)
514 {
515 	assert(ppa.chk < ftl_dev_num_bands(dev));
516 	return &dev->bands[ppa.chk];
517 }
518 
519 struct ftl_chunk *
520 ftl_band_chunk_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
521 {
522 	struct spdk_ftl_dev *dev = band->dev;
523 	unsigned int punit;
524 
525 	punit = ftl_ppa_flatten_punit(dev, ppa);
526 	assert(punit < ftl_dev_num_punits(dev));
527 
528 	return &band->chunk_buf[punit];
529 }
530 
531 uint64_t
532 ftl_band_lbkoff_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
533 {
534 	struct spdk_ftl_dev *dev = band->dev;
535 	unsigned int punit;
536 
537 	punit = ftl_ppa_flatten_punit(dev, ppa);
538 	assert(ppa.chk == band->id);
539 
540 	return punit * ftl_dev_lbks_in_chunk(dev) + ppa.lbk;
541 }
542 
543 struct ftl_ppa
544 ftl_band_next_xfer_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t num_lbks)
545 {
546 	struct spdk_ftl_dev *dev = band->dev;
547 	struct ftl_chunk *chunk;
548 	unsigned int punit_num;
549 	size_t num_xfers, num_stripes;
550 
551 	assert(ppa.chk == band->id);
552 
553 	punit_num = ftl_ppa_flatten_punit(dev, ppa);
554 	chunk = &band->chunk_buf[punit_num];
555 
556 	num_lbks += (ppa.lbk % dev->xfer_size);
557 	ppa.lbk  -= (ppa.lbk % dev->xfer_size);
558 
559 #if defined(DEBUG)
560 	/* Check that the number of chunks has not been changed */
561 	struct ftl_chunk *_chunk;
562 	size_t _num_chunks = 0;
563 	CIRCLEQ_FOREACH(_chunk, &band->chunks, circleq) {
564 		if (spdk_likely(_chunk->state != FTL_CHUNK_STATE_BAD)) {
565 			_num_chunks++;
566 		}
567 	}
568 	assert(band->num_chunks == _num_chunks);
569 #endif
570 	assert(band->num_chunks != 0);
571 	num_stripes = (num_lbks / dev->xfer_size) / band->num_chunks;
572 	ppa.lbk  += num_stripes * dev->xfer_size;
573 	num_lbks -= num_stripes * dev->xfer_size * band->num_chunks;
574 
575 	if (ppa.lbk > ftl_dev_lbks_in_chunk(dev)) {
576 		return ftl_to_ppa(FTL_PPA_INVALID);
577 	}
578 
579 	num_xfers = num_lbks / dev->xfer_size;
580 	for (size_t i = 0; i < num_xfers; ++i) {
581 		/* When the last chunk is reached the lbk part of the address */
582 		/* needs to be increased by xfer_size */
583 		if (ftl_band_chunk_is_last(band, chunk)) {
584 			ppa.lbk += dev->xfer_size;
585 			if (ppa.lbk > ftl_dev_lbks_in_chunk(dev)) {
586 				return ftl_to_ppa(FTL_PPA_INVALID);
587 			}
588 		}
589 
590 		chunk = ftl_band_next_operational_chunk(band, chunk);
591 		assert(chunk);
592 		ppa.grp = chunk->start_ppa.grp;
593 		ppa.pu = chunk->start_ppa.pu;
594 
595 		num_lbks -= dev->xfer_size;
596 	}
597 
598 	if (num_lbks) {
599 		ppa.lbk += num_lbks;
600 		if (ppa.lbk > ftl_dev_lbks_in_chunk(dev)) {
601 			return ftl_to_ppa(FTL_PPA_INVALID);
602 		}
603 	}
604 
605 	return ppa;
606 }
607 
608 static size_t
609 ftl_xfer_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
610 {
611 	struct ftl_chunk *chunk, *current_chunk;
612 	unsigned int punit_offset = 0;
613 	size_t off, num_stripes, xfer_size = band->dev->xfer_size;
614 
615 	assert(ppa.chk == band->id);
616 
617 	num_stripes = (ppa.lbk / xfer_size) * band->num_chunks;
618 	off = ppa.lbk % xfer_size;
619 
620 	current_chunk = ftl_band_chunk_from_ppa(band, ppa);
621 	CIRCLEQ_FOREACH(chunk, &band->chunks, circleq) {
622 		if (current_chunk == chunk) {
623 			break;
624 		}
625 		punit_offset++;
626 	}
627 
628 	return xfer_size * (num_stripes + punit_offset) + off;
629 }
630 
631 struct ftl_ppa
632 ftl_band_ppa_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
633 {
634 	struct ftl_ppa ppa = { .ppa = 0 };
635 	struct spdk_ftl_dev *dev = band->dev;
636 	uint64_t punit;
637 
638 	punit = lbkoff / ftl_dev_lbks_in_chunk(dev) + dev->range.begin;
639 
640 	ppa.lbk = lbkoff % ftl_dev_lbks_in_chunk(dev);
641 	ppa.chk = band->id;
642 	ppa.pu = punit / dev->geo.num_grp;
643 	ppa.grp = punit % dev->geo.num_grp;
644 
645 	return ppa;
646 }
647 
648 struct ftl_ppa
649 ftl_band_next_ppa(struct ftl_band *band, struct ftl_ppa ppa, size_t offset)
650 {
651 	uint64_t lbkoff = ftl_band_lbkoff_from_ppa(band, ppa);
652 	return ftl_band_ppa_from_lbkoff(band, lbkoff + offset);
653 }
654 
655 void
656 ftl_band_acquire_lba_map(struct ftl_band *band)
657 {
658 	assert(band->lba_map.map != NULL);
659 	band->lba_map.ref_cnt++;
660 }
661 
662 int
663 ftl_band_alloc_lba_map(struct ftl_band *band)
664 {
665 	struct spdk_ftl_dev *dev = band->dev;
666 	struct ftl_lba_map *lba_map = &band->lba_map;
667 
668 	assert(lba_map->ref_cnt == 0);
669 	assert(lba_map->map == NULL);
670 
671 	lba_map->dma_buf = spdk_mempool_get(dev->lba_pool);
672 
673 	if (!lba_map->dma_buf) {
674 		return -1;
675 	}
676 
677 	memset(lba_map->dma_buf, 0, ftl_lba_map_pool_elem_size(band->dev));
678 
679 	lba_map->map = (uint64_t *)((char *)lba_map->dma_buf + FTL_BLOCK_SIZE *
680 				    (ftl_tail_md_hdr_num_lbks() + ftl_vld_map_num_lbks(dev)));
681 
682 	lba_map->segments = (char *)lba_map->dma_buf + ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE;
683 
684 	ftl_band_acquire_lba_map(band);
685 	return 0;
686 }
687 
688 void
689 ftl_band_release_lba_map(struct ftl_band *band)
690 {
691 	struct ftl_lba_map *lba_map = &band->lba_map;
692 
693 	assert(lba_map->map != NULL);
694 	assert(lba_map->ref_cnt > 0);
695 	lba_map->ref_cnt--;
696 
697 	if (lba_map->ref_cnt == 0) {
698 		ftl_band_free_lba_map(band);
699 	}
700 }
701 
702 static void
703 ftl_read_md_cb(struct ftl_io *io, void *arg, int status)
704 {
705 	struct ftl_md_io *md_io = (struct ftl_md_io *)io;
706 
707 	if (!status) {
708 		status = md_io->pack_fn(md_io->io.band);
709 	} else {
710 		status = FTL_MD_IO_FAILURE;
711 	}
712 
713 	md_io->cb_fn(io, md_io->cb_ctx, status);
714 }
715 
716 static struct ftl_md_io *
717 ftl_io_init_md_read(struct spdk_ftl_dev *dev, struct ftl_ppa ppa,
718 		    struct ftl_band *band, size_t lbk_cnt, void *buf,
719 		    ftl_io_fn fn, ftl_md_pack_fn pack_fn, ftl_io_fn cb_fn, void *cb_ctx)
720 {
721 	struct ftl_md_io *io;
722 	struct ftl_io_init_opts opts = {
723 		.dev		= dev,
724 		.io		= NULL,
725 		.rwb_batch	= NULL,
726 		.band		= band,
727 		.size		= sizeof(*io),
728 		.flags		= FTL_IO_MD | FTL_IO_PPA_MODE,
729 		.type		= FTL_IO_READ,
730 		.lbk_cnt	= lbk_cnt,
731 		.cb_fn		= fn,
732 		.data		= buf,
733 	};
734 
735 	io = (struct ftl_md_io *)ftl_io_init_internal(&opts);
736 	if (!io) {
737 		return NULL;
738 	}
739 
740 	io->io.ppa = ppa;
741 	io->pack_fn = pack_fn;
742 	io->cb_fn = cb_fn;
743 	io->cb_ctx = cb_ctx;
744 
745 	return io;
746 }
747 
748 static struct ftl_io *
749 ftl_io_init_md_write(struct spdk_ftl_dev *dev, struct ftl_band *band,
750 		     void *data, size_t lbk_cnt, ftl_io_fn cb)
751 {
752 	struct ftl_io_init_opts opts = {
753 		.dev		= dev,
754 		.io		= NULL,
755 		.rwb_batch	= NULL,
756 		.band		= band,
757 		.size		= sizeof(struct ftl_io),
758 		.flags		= FTL_IO_MD | FTL_IO_PPA_MODE,
759 		.type		= FTL_IO_WRITE,
760 		.lbk_cnt	= lbk_cnt,
761 		.cb_fn		= cb,
762 		.data		= data,
763 		.md		= NULL,
764 	};
765 
766 	return ftl_io_init_internal(&opts);
767 }
768 
769 static int
770 ftl_band_write_md(struct ftl_band *band, size_t lbk_cnt,
771 		  ftl_md_pack_fn md_fn, ftl_io_fn cb)
772 {
773 	struct spdk_ftl_dev *dev = band->dev;
774 	struct ftl_io *io;
775 
776 	io = ftl_io_init_md_write(dev, band, band->lba_map.dma_buf, lbk_cnt, cb);
777 	if (!io) {
778 		return -ENOMEM;
779 	}
780 
781 	md_fn(band);
782 
783 	ftl_io_write(io);
784 	return 0;
785 }
786 
787 void
788 ftl_band_md_clear(struct ftl_band *band)
789 {
790 	band->seq = 0;
791 	band->wr_cnt = 0;
792 	band->lba_map.num_vld = 0;
793 	band->lba_map.map = NULL;
794 }
795 
796 int
797 ftl_band_write_head_md(struct ftl_band *band, ftl_io_fn cb)
798 {
799 	return ftl_band_write_md(band, ftl_head_md_num_lbks(band->dev),
800 				 ftl_pack_head_md, cb);
801 }
802 
803 int
804 ftl_band_write_tail_md(struct ftl_band *band, ftl_io_fn cb)
805 {
806 	return ftl_band_write_md(band, ftl_tail_md_num_lbks(band->dev),
807 				 ftl_pack_tail_md, cb);
808 }
809 
810 static struct ftl_ppa
811 ftl_band_lba_map_ppa(struct ftl_band *band, size_t offset)
812 {
813 	return ftl_band_next_xfer_ppa(band, band->tail_md_ppa,
814 				      ftl_tail_md_hdr_num_lbks() +
815 				      ftl_vld_map_num_lbks(band->dev) +
816 				      offset);
817 }
818 
819 static int
820 ftl_band_read_md(struct ftl_band *band, size_t lbk_cnt, struct ftl_ppa start_ppa,
821 		 void *buf, ftl_io_fn fn, ftl_md_pack_fn pack_fn, ftl_io_fn cb_fn, void *cb_ctx)
822 {
823 	struct spdk_ftl_dev *dev = band->dev;
824 	struct ftl_md_io *io;
825 
826 	if (spdk_unlikely(!band->num_chunks)) {
827 		return -ENOENT;
828 	}
829 
830 	io = ftl_io_init_md_read(dev, start_ppa, band, lbk_cnt, buf, fn, pack_fn, cb_fn, cb_ctx);
831 	if (!io) {
832 		return -ENOMEM;
833 	}
834 
835 	ftl_io_read((struct ftl_io *)io);
836 	return 0;
837 }
838 
839 int
840 ftl_band_read_tail_md(struct ftl_band *band, struct ftl_ppa ppa, ftl_io_fn cb_fn, void *cb_ctx)
841 {
842 	return ftl_band_read_md(band, ftl_tail_md_num_lbks(band->dev), ppa, band->lba_map.dma_buf,
843 				ftl_read_md_cb, ftl_unpack_tail_md, cb_fn, cb_ctx);
844 }
845 
846 static size_t
847 ftl_lba_map_request_segment_done(struct ftl_lba_map_request *request, size_t offset,
848 				 size_t num_segments)
849 {
850 	size_t i, num_done = 0;
851 
852 	for (i = offset; i < offset + num_segments; ++i) {
853 		if (spdk_bit_array_get(request->segments, i)) {
854 			spdk_bit_array_clear(request->segments, offset);
855 			num_done++;
856 		}
857 	}
858 
859 	assert(request->num_pending >= num_done);
860 	request->num_pending -= num_done;
861 
862 	return num_done;
863 }
864 
865 static void
866 ftl_lba_map_set_segment_state(struct ftl_lba_map *lba_map, size_t offset, size_t num_segments,
867 			      enum ftl_lba_map_seg_state state)
868 {
869 	size_t i;
870 
871 	for (i = offset; i < offset + num_segments; ++i) {
872 		lba_map->segments[i] = state;
873 	}
874 }
875 
876 static void
877 ftl_lba_map_request_free(struct spdk_ftl_dev *dev, struct ftl_lba_map_request *request)
878 {
879 	spdk_bit_array_clear_mask(request->segments);
880 	spdk_mempool_put(dev->lba_request_pool, request);
881 }
882 
883 static void
884 ftl_process_lba_map_requests(struct spdk_ftl_dev *dev, struct ftl_lba_map *lba_map, size_t offset,
885 			     size_t num_segments, int status)
886 {
887 	struct ftl_lba_map_request *request, *trequest;
888 	size_t num_done;
889 
890 	LIST_FOREACH_SAFE(request, &lba_map->request_list, list_entry, trequest) {
891 		num_done = ftl_lba_map_request_segment_done(request, offset, num_segments);
892 		if (request->num_pending == 0 || (status && num_done)) {
893 			request->cb(NULL, request->cb_ctx, status);
894 			LIST_REMOVE(request, list_entry);
895 			ftl_lba_map_request_free(dev, request);
896 		}
897 	}
898 }
899 
900 static size_t
901 ftl_lba_map_offset_from_ppa(struct ftl_band *band, struct ftl_ppa ppa)
902 {
903 	size_t offset;
904 	struct ftl_ppa start_ppa = ftl_band_lba_map_ppa(band, 0);
905 
906 	offset =  ftl_xfer_offset_from_ppa(band, ppa) - ftl_xfer_offset_from_ppa(band, start_ppa);
907 	assert(offset < ftl_lba_map_num_lbks(band->dev));
908 
909 	return offset;
910 }
911 
912 static void
913 ftl_read_lba_map_cb(struct ftl_io *io, void *arg, int status)
914 {
915 	struct ftl_lba_map *lba_map = &io->band->lba_map;
916 	uint64_t lbk_off;
917 
918 	lbk_off = ftl_lba_map_offset_from_ppa(io->band, io->ppa);
919 	assert(lbk_off + io->lbk_cnt <= ftl_lba_map_num_lbks(io->dev));
920 
921 	if (!status) {
922 		ftl_lba_map_set_segment_state(lba_map, lbk_off, io->lbk_cnt,
923 					      FTL_LBA_MAP_SEG_CACHED);
924 	}
925 
926 	ftl_process_lba_map_requests(io->dev, lba_map, lbk_off, io->lbk_cnt, status);
927 }
928 
929 static struct ftl_lba_map_request *
930 ftl_lba_map_alloc_request(struct ftl_band *band, size_t offset, size_t num_segments,
931 			  ftl_io_fn cb, void *cb_ctx)
932 {
933 	struct ftl_lba_map_request *request;
934 	struct spdk_ftl_dev *dev = band->dev;
935 	size_t i;
936 
937 	request = spdk_mempool_get(dev->lba_request_pool);
938 	if (!request) {
939 		return NULL;
940 	}
941 
942 	request->cb = cb;
943 	request->cb_ctx = cb_ctx;
944 	request->num_pending = num_segments;
945 
946 	for (i = offset; i < offset + num_segments; ++i) {
947 		spdk_bit_array_set(request->segments, i);
948 	}
949 
950 	return request;
951 }
952 
953 static size_t
954 ftl_lba_map_num_clear_segments(struct ftl_lba_map *lba_map,
955 			       size_t offset, size_t num_segments)
956 {
957 	size_t i, cnt = 0;
958 
959 	for (i = offset; i < offset + num_segments; ++i) {
960 		if (lba_map->segments[i] != FTL_LBA_MAP_SEG_CLEAR) {
961 			break;
962 		}
963 		cnt++;
964 	}
965 
966 	return cnt;
967 }
968 
969 int
970 ftl_band_read_lba_map(struct ftl_band *band, size_t offset, size_t lba_cnt,
971 		      ftl_io_fn cb_fn, void *cb_ctx)
972 {
973 	size_t lbk_cnt, lbk_off, num_read, num_segments;
974 	struct ftl_lba_map *lba_map = &band->lba_map;
975 	struct ftl_lba_map_request *request;
976 	int rc = 0;
977 
978 	lbk_off = offset / FTL_NUM_LBA_IN_BLOCK;
979 	num_segments = spdk_divide_round_up(offset + lba_cnt, FTL_NUM_LBA_IN_BLOCK);
980 	lbk_cnt = num_segments - lbk_off;
981 	assert(lbk_off + lbk_cnt <= ftl_lba_map_num_lbks(band->dev));
982 
983 	request = ftl_lba_map_alloc_request(band, lbk_off, lbk_cnt, cb_fn, cb_ctx);
984 	if (!request) {
985 		return -ENOMEM;
986 	}
987 
988 	while (lbk_cnt) {
989 		if (lba_map->segments[lbk_off] != FTL_LBA_MAP_SEG_CLEAR) {
990 			if (lba_map->segments[lbk_off] == FTL_LBA_MAP_SEG_CACHED) {
991 				ftl_lba_map_request_segment_done(request, lbk_off, 1);
992 			}
993 			lbk_cnt--;
994 			lbk_off++;
995 			continue;
996 		}
997 
998 		num_read = ftl_lba_map_num_clear_segments(lba_map, lbk_off, lbk_cnt);
999 		ftl_lba_map_set_segment_state(lba_map, lbk_off, num_read,
1000 					      FTL_LBA_MAP_SEG_PENDING);
1001 
1002 		rc = ftl_band_read_md(band, num_read, ftl_band_lba_map_ppa(band, lbk_off),
1003 				      (char *)band->lba_map.map + lbk_off * FTL_BLOCK_SIZE,
1004 				      ftl_read_lba_map_cb, NULL, cb_fn, cb_ctx);
1005 		if (rc) {
1006 			ftl_lba_map_request_free(band->dev, request);
1007 			return rc;
1008 		}
1009 
1010 		assert(lbk_cnt >= num_read);
1011 		lbk_cnt -= num_read;
1012 		lbk_off += num_read;
1013 	}
1014 
1015 	if (request->num_pending) {
1016 		LIST_INSERT_HEAD(&lba_map->request_list, request, list_entry);
1017 	} else {
1018 		cb_fn(NULL, cb_ctx, 0);
1019 		ftl_lba_map_request_free(band->dev, request);
1020 	}
1021 
1022 	return rc;
1023 }
1024 
1025 int
1026 ftl_band_read_head_md(struct ftl_band *band, ftl_io_fn cb_fn, void *cb_ctx)
1027 {
1028 	return ftl_band_read_md(band,
1029 				ftl_head_md_num_lbks(band->dev),
1030 				ftl_band_head_md_ppa(band),
1031 				band->lba_map.dma_buf,
1032 				ftl_read_md_cb,
1033 				ftl_unpack_head_md,
1034 				cb_fn,
1035 				cb_ctx);
1036 }
1037 
1038 static void
1039 ftl_band_remove_chunk(struct ftl_band *band, struct ftl_chunk *chunk)
1040 {
1041 	CIRCLEQ_REMOVE(&band->chunks, chunk, circleq);
1042 	band->num_chunks--;
1043 }
1044 
1045 static void
1046 ftl_erase_fail(struct ftl_io *io, int status)
1047 {
1048 	struct ftl_chunk *chunk;
1049 	struct ftl_band *band = io->band;
1050 	char buf[128];
1051 
1052 	SPDK_ERRLOG("Erase failed @ppa: %s, status: %d\n",
1053 		    ftl_ppa2str(io->ppa, buf, sizeof(buf)), status);
1054 
1055 	chunk = ftl_band_chunk_from_ppa(band, io->ppa);
1056 	chunk->state = FTL_CHUNK_STATE_BAD;
1057 	ftl_band_remove_chunk(band, chunk);
1058 	band->tail_md_ppa = ftl_band_tail_md_ppa(band);
1059 }
1060 
1061 static void
1062 ftl_band_erase_cb(struct ftl_io *io, void *ctx, int status)
1063 {
1064 	struct ftl_chunk *chunk;
1065 
1066 	if (spdk_unlikely(status)) {
1067 		ftl_erase_fail(io, status);
1068 		return;
1069 	}
1070 	chunk = ftl_band_chunk_from_ppa(io->band, io->ppa);
1071 	chunk->state = FTL_CHUNK_STATE_FREE;
1072 	chunk->write_offset = 0;
1073 }
1074 
1075 int
1076 ftl_band_erase(struct ftl_band *band)
1077 {
1078 	struct ftl_chunk *chunk;
1079 	struct ftl_io *io;
1080 	int rc = 0;
1081 
1082 	assert(band->state == FTL_BAND_STATE_CLOSED ||
1083 	       band->state == FTL_BAND_STATE_FREE);
1084 
1085 	ftl_band_set_state(band, FTL_BAND_STATE_PREP);
1086 
1087 	CIRCLEQ_FOREACH(chunk, &band->chunks, circleq) {
1088 		if (chunk->state == FTL_CHUNK_STATE_FREE) {
1089 			continue;
1090 		}
1091 
1092 		io = ftl_io_erase_init(band, 1, ftl_band_erase_cb);
1093 		if (!io) {
1094 			rc = -ENOMEM;
1095 			break;
1096 		}
1097 
1098 		io->ppa = chunk->start_ppa;
1099 		rc = ftl_io_erase(io);
1100 		if (rc) {
1101 			assert(0);
1102 			/* TODO: change band's state back to close? */
1103 			break;
1104 		}
1105 	}
1106 
1107 	return rc;
1108 }
1109 
1110 int
1111 ftl_band_write_prep(struct ftl_band *band)
1112 {
1113 	struct spdk_ftl_dev *dev = band->dev;
1114 
1115 	if (ftl_band_alloc_lba_map(band)) {
1116 		return -1;
1117 	}
1118 
1119 	band->seq = ++dev->seq;
1120 	return 0;
1121 }
1122 
1123 struct ftl_chunk *
1124 ftl_band_next_operational_chunk(struct ftl_band *band, struct ftl_chunk *chunk)
1125 {
1126 	struct ftl_chunk *result = NULL;
1127 	struct ftl_chunk *entry;
1128 
1129 	if (spdk_unlikely(!band->num_chunks)) {
1130 		return NULL;
1131 	}
1132 
1133 	/* Erasing band may fail after it was assigned to wptr. */
1134 	/* In such a case chunk is no longer in band->chunks queue. */
1135 	if (spdk_likely(chunk->state != FTL_CHUNK_STATE_BAD)) {
1136 		result = ftl_band_next_chunk(band, chunk);
1137 	} else {
1138 		CIRCLEQ_FOREACH_REVERSE(entry, &band->chunks, circleq) {
1139 			if (entry->pos > chunk->pos) {
1140 				result = entry;
1141 			} else {
1142 				if (!result) {
1143 					result = CIRCLEQ_FIRST(&band->chunks);
1144 				}
1145 				break;
1146 			}
1147 		}
1148 	}
1149 
1150 	return result;
1151 }
1152 
1153 void
1154 ftl_band_clear_lba_map(struct ftl_band *band)
1155 {
1156 	struct ftl_lba_map *lba_map = &band->lba_map;
1157 	size_t num_segments;
1158 
1159 	spdk_bit_array_clear_mask(lba_map->vld);
1160 	memset(lba_map->map, 0, ftl_lba_map_num_lbks(band->dev) * FTL_BLOCK_SIZE);
1161 
1162 	/* For open band all lba map segments are already cached */
1163 	assert(band->state == FTL_BAND_STATE_PREP);
1164 	num_segments = spdk_divide_round_up(ftl_num_band_lbks(band->dev), FTL_NUM_LBA_IN_BLOCK);
1165 	ftl_lba_map_set_segment_state(&band->lba_map, 0, num_segments, FTL_LBA_MAP_SEG_CACHED);
1166 
1167 	lba_map->num_vld = 0;
1168 }
1169 
1170 size_t
1171 ftl_lba_map_pool_elem_size(struct spdk_ftl_dev *dev)
1172 {
1173 	/* Map pool element holds the whole tail md + segments map */
1174 	return ftl_tail_md_num_lbks(dev) * FTL_BLOCK_SIZE +
1175 	       spdk_divide_round_up(ftl_num_band_lbks(dev), FTL_NUM_LBA_IN_BLOCK);
1176 }
1177