diff --git a/lib/ftl/Makefile b/lib/ftl/Makefile index 43b42b7cf..2ade690dd 100644 --- a/lib/ftl/Makefile +++ b/lib/ftl/Makefile @@ -22,7 +22,7 @@ CFLAGS += -I. FTL_SUBDIRS := mngt utils C_SRCS = ftl_core.c ftl_init.c ftl_layout.c ftl_debug.c ftl_io.c ftl_sb.c ftl_l2p.c ftl_l2p_flat.c -C_SRCS += ftl_nv_cache.c +C_SRCS += ftl_nv_cache.c ftl_band.c C_SRCS += mngt/ftl_mngt.c mngt/ftl_mngt_bdev.c mngt/ftl_mngt_shutdown.c mngt/ftl_mngt_startup.c C_SRCS += mngt/ftl_mngt_md.c mngt/ftl_mngt_misc.c mngt/ftl_mngt_ioch.c mngt/ftl_mngt_l2p.c C_SRCS += utils/ftl_conf.c utils/ftl_md.c utils/ftl_mempool.c diff --git a/lib/ftl/ftl_band.c b/lib/ftl/ftl_band.c new file mode 100644 index 000000000..6eaea8f2c --- /dev/null +++ b/lib/ftl/ftl_band.c @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) Intel Corporation. + * All rights reserved. + */ + +#include "spdk/stdinc.h" +#include "spdk/crc32.h" +#include "spdk/likely.h" +#include "spdk/util.h" +#include "spdk/ftl.h" + +#include "ftl_band.h" +#include "ftl_io.h" +#include "ftl_core.h" +#include "ftl_internal.h" +#include "utils/ftl_md.h" +#include "utils/ftl_defs.h" + +static uint64_t +ftl_band_tail_md_offset(const struct ftl_band *band) +{ + return ftl_get_num_blocks_in_band(band->dev) - + ftl_tail_md_num_blocks(band->dev); +} + +int +ftl_band_filled(struct ftl_band *band, size_t offset) +{ + return offset == ftl_band_tail_md_offset(band); +} + +ftl_addr +ftl_band_tail_md_addr(struct ftl_band *band) +{ + ftl_addr addr; + + /* Metadata should be aligned to xfer size */ + assert(ftl_band_tail_md_offset(band) % band->dev->xfer_size == 0); + + addr = ftl_band_tail_md_offset(band) + band->start_addr; + + return addr; +} + +void +ftl_band_set_type(struct ftl_band *band, enum ftl_band_type type) +{ + switch (type) { + case FTL_BAND_TYPE_COMPACTION: + case FTL_BAND_TYPE_GC: + band->md->type = type; + break; + default: + assert(false); + break; + } +} + +size_t +ftl_band_user_blocks_left(const struct ftl_band *band, size_t offset) +{ + size_t tail_md_offset = ftl_band_tail_md_offset(band); + + if (spdk_unlikely(offset > tail_md_offset)) { + return 0; + } + + return tail_md_offset - offset; +} + +struct ftl_band * +ftl_band_from_addr(struct spdk_ftl_dev *dev, ftl_addr addr) +{ + size_t band_id = ftl_addr_get_band(dev, addr); + + assert(band_id < ftl_get_num_bands(dev)); + return &dev->bands[band_id]; +} + +uint64_t +ftl_band_block_offset_from_addr(struct ftl_band *band, ftl_addr addr) +{ + assert(ftl_addr_get_band(band->dev, addr) == band->id); + return addr % ftl_get_num_blocks_in_band(band->dev); +} + +ftl_addr +ftl_band_next_xfer_addr(struct ftl_band *band, ftl_addr addr, size_t num_blocks) +{ + struct spdk_ftl_dev *dev = band->dev; + size_t num_xfers; + uint64_t offset; + + assert(ftl_addr_get_band(dev, addr) == band->id); + + offset = addr - band->start_addr; + + /* In case starting address wasn't aligned to xfer_size, we'll align for consistent calculation + * purposes - the unaligned value will be preserved at the end however. + */ + num_blocks += (offset % dev->xfer_size); + offset -= (offset % dev->xfer_size); + + /* Calculate offset based on xfer_size aligned writes */ + num_xfers = (num_blocks / dev->xfer_size); + offset += num_xfers * dev->xfer_size; + num_blocks -= num_xfers * dev->xfer_size; + + if (offset > ftl_get_num_blocks_in_band(dev)) { + return FTL_ADDR_INVALID; + } + + /* If there's any unalignment (either starting addr value or num_blocks), reintroduce it to the final address + */ + if (num_blocks) { + offset += num_blocks; + if (offset > ftl_get_num_blocks_in_band(dev)) { + return FTL_ADDR_INVALID; + } + } + + addr = band->start_addr + offset; + return addr; +} + +ftl_addr +ftl_band_addr_from_block_offset(struct ftl_band *band, uint64_t block_off) +{ + ftl_addr addr; + + addr = block_off + band->id * ftl_get_num_blocks_in_band(band->dev); + return addr; +} + +ftl_addr +ftl_band_next_addr(struct ftl_band *band, ftl_addr addr, size_t offset) +{ + uint64_t block_off = ftl_band_block_offset_from_addr(band, addr); + + return ftl_band_addr_from_block_offset(band, block_off + offset); +} + +ftl_addr +ftl_band_p2l_map_addr(struct ftl_band *band) +{ + return band->tail_md_addr; +} diff --git a/lib/ftl/ftl_band.h b/lib/ftl/ftl_band.h new file mode 100644 index 000000000..506f2efcf --- /dev/null +++ b/lib/ftl/ftl_band.h @@ -0,0 +1,202 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (c) Intel Corporation. + * All rights reserved. + */ + +#ifndef FTL_BAND_H +#define FTL_BAND_H + +#include "spdk/stdinc.h" +#include "spdk/bit_array.h" +#include "spdk/queue.h" +#include "spdk/crc32.h" + +#include "ftl_io.h" +#include "ftl_internal.h" +#include "ftl_core.h" + +#define FTL_MAX_OPEN_BANDS 4 + +#define FTL_BAND_VERSION_0 0 +#define FTL_BAND_VERSION_1 1 + +#define FTL_BAND_VERSION_CURRENT FTL_BAND_VERSION_1 + +struct spdk_ftl_dev; +struct ftl_band; +struct ftl_rq; +struct ftl_basic_rq; + +enum ftl_band_state { + FTL_BAND_STATE_FREE, + FTL_BAND_STATE_PREP, + FTL_BAND_STATE_OPENING, + FTL_BAND_STATE_OPEN, + FTL_BAND_STATE_FULL, + FTL_BAND_STATE_CLOSING, + FTL_BAND_STATE_CLOSED, + FTL_BAND_STATE_MAX +}; + +typedef void (*ftl_band_state_change_fn)(struct ftl_band *band); +typedef void (*ftl_band_ops_cb)(struct ftl_band *band, void *ctx, bool status); +typedef void (*ftl_band_md_cb)(struct ftl_band *band, void *ctx, enum ftl_md_status status); + +struct ftl_band_md { + /* Band iterator for writing */ + struct { + /* Current physical address of the write pointer */ + ftl_addr addr; + + /* Offset from the band's start of the write pointer */ + uint64_t offset; + } iter; + + /* Band's state */ + enum ftl_band_state state; + + /* Band type set during opening */ + enum ftl_band_type type; + + /* Number of times band was fully written (ie. number of free -> closed state cycles) */ + uint64_t wr_cnt; + + /* CRC32 checksum of the associated P2L map when band is in closed state */ + uint32_t p2l_map_checksum; +} __attribute__((aligned(FTL_BLOCK_SIZE))); + +SPDK_STATIC_ASSERT(sizeof(struct ftl_band_md) == FTL_BLOCK_SIZE, "Incorrect metadata size"); + +struct ftl_band { + /* Device this band belongs to */ + struct spdk_ftl_dev *dev; + + struct ftl_band_md *md; + + /* IO queue depth (outstanding IOs) */ + uint64_t queue_depth; + + /* Fields for owner of the band - compaction, or gc */ + struct { + /* Callback context for the owner */ + void *priv; + + /* State change callback */ + ftl_band_state_change_fn state_change_fn; + + /* Callback for the owner */ + union { + ftl_band_ops_cb ops_fn; + ftl_band_md_cb md_fn; + }; + + /* Reference counter */ + uint64_t cnt; + } owner; + + /* P2L map */ + struct ftl_p2l_map p2l_map; + + /* Band's index */ + uint32_t id; + + /* Band's NAND id - a group multiple bands may be part of the same physical band on base device + * This way the write access pattern will match the actual physical layout more closely, leading + * to lower overall write amplification factor + */ + uint32_t phys_id; + + /* Band start addr */ + ftl_addr start_addr; + + /* End metadata start addr */ + ftl_addr tail_md_addr; + + /* Metadata request */ + struct ftl_basic_rq metadata_rq; + + /* Free/shut bands' lists + * Open bands are kept and managed directly by the writer (either GC or compaction). Each writer only + * needs to keep two bands (one currently written to, and a pre-assigned reserve band to make sure flow + * of data is always ongoing as the current one is closing). + */ + TAILQ_ENTRY(ftl_band) queue_entry; + + /* For writing metadata */ + struct ftl_md_io_entry_ctx md_persist_entry_ctx; +}; + + +uint64_t ftl_band_block_offset_from_addr(struct ftl_band *band, ftl_addr addr); +ftl_addr ftl_band_addr_from_block_offset(struct ftl_band *band, uint64_t block_off); +void ftl_band_set_type(struct ftl_band *band, enum ftl_band_type type); +void ftl_band_set_state(struct ftl_band *band, enum ftl_band_state state); +ftl_addr ftl_band_next_xfer_addr(struct ftl_band *band, ftl_addr addr, size_t num_blocks); +ftl_addr ftl_band_next_addr(struct ftl_band *band, ftl_addr addr, size_t offset); +size_t ftl_band_user_blocks_left(const struct ftl_band *band, size_t offset); +struct ftl_band *ftl_band_from_addr(struct spdk_ftl_dev *dev, ftl_addr addr); +ftl_addr ftl_band_tail_md_addr(struct ftl_band *band); +int ftl_band_filled(struct ftl_band *band, size_t offset); +ftl_addr ftl_band_p2l_map_addr(struct ftl_band *band); + +static inline void +ftl_band_set_owner(struct ftl_band *band, + ftl_band_state_change_fn fn, + void *priv) +{ + assert(NULL == band->owner.priv); + assert(NULL == band->owner.state_change_fn); + + band->owner.state_change_fn = fn; + band->owner.priv = priv; +} + +static inline void +ftl_band_clear_owner(struct ftl_band *band, + ftl_band_state_change_fn fn, + void *priv) +{ + assert(priv == band->owner.priv); + assert(fn == band->owner.state_change_fn); + + band->owner.state_change_fn = NULL; + band->owner.priv = NULL; +} + +static inline int +ftl_band_empty(const struct ftl_band *band) +{ + return band->p2l_map.num_valid == 0; +} + +static inline uint64_t +ftl_band_qd(const struct ftl_band *band) +{ + return band->queue_depth; +} + +static inline void +ftl_band_iter_init(struct ftl_band *band) +{ + /* Initialize band iterator to begin state */ + band->md->iter.addr = band->start_addr; + band->md->iter.offset = 0; +} + +static inline void +ftl_band_iter_advance(struct ftl_band *band, uint64_t num_blocks) +{ + band->md->iter.offset += num_blocks; + band->md->iter.addr = ftl_band_next_xfer_addr(band, band->md->iter.addr, num_blocks); + assert(band->md->iter.addr != FTL_ADDR_INVALID); +} + +static inline void +ftl_band_iter_set(struct ftl_band *band, uint64_t num_blocks) +{ + band->md->iter.offset = num_blocks; + band->md->iter.addr = ftl_band_next_xfer_addr(band, band->md->iter.addr, num_blocks); + assert(band->md->iter.addr != FTL_ADDR_INVALID); +} + +#endif /* FTL_BAND_H */ diff --git a/lib/ftl/ftl_core.c b/lib/ftl/ftl_core.c index f1df1eff0..e32c5e58e 100644 --- a/lib/ftl/ftl_core.c +++ b/lib/ftl/ftl_core.c @@ -13,6 +13,7 @@ #include "spdk/crc32.h" #include "ftl_core.h" +#include "ftl_band.h" #include "ftl_io.h" #include "ftl_debug.h" #include "ftl_internal.h" diff --git a/lib/ftl/ftl_core.h b/lib/ftl/ftl_core.h index 05a012e07..eae7990a8 100644 --- a/lib/ftl/ftl_core.h +++ b/lib/ftl/ftl_core.h @@ -23,6 +23,13 @@ #include "ftl_l2p.h" #include "utils/ftl_log.h" +/* + * We need to reserve at least 2 buffers for band close / open sequence + * alone, plus additional (8) buffers for handling relocations. + * + */ +#define P2L_MEMPOOL_SIZE (2 + 8) + /* When using VSS on nvcache, FTL sometimes doesn't require the contents of metadata. * Some devices have bugs when sending a NULL pointer as part of metadata when namespace * is formatted with VSS. This buffer is passed to such calls to avoid the bug. */ @@ -71,9 +78,21 @@ struct spdk_ftl_dev { 3. base bdev read/write */ uint64_t io_activity_total; + /* Array of bands */ + struct ftl_band *bands; + /* Number of operational bands */ uint64_t num_bands; + /* Next write band */ + struct ftl_band *next_band; + + /* Free band list */ + TAILQ_HEAD(, ftl_band) free_bands; + + /* Closed bands list */ + TAILQ_HEAD(, ftl_band) shut_bands; + /* Number of free bands */ uint64_t num_free; @@ -127,6 +146,12 @@ ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev) return dev->num_blocks_in_band; } +static inline uint64_t +ftl_addr_get_band(const struct spdk_ftl_dev *dev, ftl_addr addr) +{ + return addr / ftl_get_num_blocks_in_band(dev); +} + static inline uint32_t ftl_get_write_unit_size(struct spdk_bdev *bdev) { @@ -182,4 +207,19 @@ ftl_addr_from_nvc_offset(const struct spdk_ftl_dev *dev, uint64_t cache_offset) return cache_offset + dev->layout.base.total_blocks; } +static inline size_t +ftl_p2l_map_num_blocks(const struct spdk_ftl_dev *dev) +{ + return spdk_divide_round_up(ftl_get_num_blocks_in_band(dev) * sizeof(uint64_t), + FTL_BLOCK_SIZE); +} + +static inline size_t +ftl_tail_md_num_blocks(const struct spdk_ftl_dev *dev) +{ + return spdk_divide_round_up( + ftl_p2l_map_num_blocks(dev), + dev->xfer_size) * dev->xfer_size; +} + #endif /* FTL_CORE_H */ diff --git a/lib/ftl/ftl_init.c b/lib/ftl/ftl_init.c index 85e5fcef6..6e9dc51ab 100644 --- a/lib/ftl/ftl_init.c +++ b/lib/ftl/ftl_init.c @@ -16,6 +16,7 @@ #include "ftl_core.h" #include "ftl_io.h" +#include "ftl_band.h" #include "ftl_debug.h" #include "ftl_nv_cache.h" #include "ftl_utils.h" diff --git a/lib/ftl/ftl_internal.h b/lib/ftl/ftl_internal.h index d61696d06..d929f3a1c 100644 --- a/lib/ftl/ftl_internal.h +++ b/lib/ftl/ftl_internal.h @@ -24,6 +24,30 @@ */ typedef uint64_t ftl_addr; +enum ftl_md_type { + FTL_MD_TYPE_BAND, + FTL_MD_TYPE_CHUNK +}; + +enum ftl_band_type { + FTL_BAND_TYPE_GC = 1, + FTL_BAND_TYPE_COMPACTION +}; + +enum ftl_md_status { + FTL_MD_SUCCESS, + /* Metadata read failure */ + FTL_MD_IO_FAILURE, + /* Invalid version */ + FTL_MD_INVALID_VER, + /* UUID doesn't match */ + FTL_MD_NO_MD, + /* UUID and version matches but CRC doesn't */ + FTL_MD_INVALID_CRC, + /* Vld or p2l map size doesn't match */ + FTL_MD_INVALID_SIZE +}; + /* Number of LBAs that could be stored in a single block */ #define FTL_NUM_LBA_IN_BLOCK (FTL_BLOCK_SIZE / sizeof(uint64_t)) diff --git a/lib/ftl/ftl_io.h b/lib/ftl/ftl_io.h index 81d260c5f..cfc620c24 100644 --- a/lib/ftl/ftl_io.h +++ b/lib/ftl/ftl_io.h @@ -17,6 +17,7 @@ #include "utils/ftl_md.h" struct spdk_ftl_dev; +struct ftl_band; struct ftl_io; typedef void (*ftl_io_fn)(struct ftl_io *, void *, int); @@ -147,6 +148,11 @@ struct ftl_rq_entry { void *priv; } owner; + /* If request issued in iterative way, it contains IO information */ + struct { + struct ftl_band *band; + } io; + /* For l2p pinning */ struct ftl_l2p_pin_ctx l2p_pin_ctx; @@ -194,6 +200,10 @@ struct ftl_rq { /* End request callback */ void (*cb)(struct ftl_rq *rq); + /* IO error request callback */ + void (*error)(struct ftl_rq *rq, struct ftl_band *band, + uint64_t idx, uint64_t count); + /* Owner context */ void *priv; @@ -219,6 +229,9 @@ struct ftl_rq { /* Request physical address, on IO completion set for append device */ ftl_addr addr; + /* Band to which IO is issued */ + struct ftl_band *band; + struct spdk_bdev_io_wait_entry bdev_io_wait; } io; @@ -228,7 +241,7 @@ struct ftl_rq { struct ftl_rq_entry entries[]; }; -/* Used for reading/writing LBA map during runtime and recovery */ +/* Used for reading/writing P2L map during runtime and recovery */ struct ftl_basic_rq { struct spdk_ftl_dev *dev; @@ -258,6 +271,9 @@ struct ftl_basic_rq { /* Request physical address, on IO completion set for append device */ ftl_addr addr; + /* Band to which IO is issued */ + struct ftl_band *band; + /* Chunk to which IO is issued */ struct ftl_nv_cache_chunk *chunk; diff --git a/lib/ftl/ftl_l2p.c b/lib/ftl/ftl_l2p.c index e221845e6..e7fa4fd6f 100644 --- a/lib/ftl/ftl_l2p.c +++ b/lib/ftl/ftl_l2p.c @@ -4,9 +4,9 @@ */ #include "ftl_l2p.h" +#include "ftl_band.h" #include "ftl_nv_cache.h" #include "ftl_l2p_flat.h" -#include "ftl_core.h" /* TODO: Verify why function pointers had worse performance than compile time constants */ diff --git a/lib/ftl/ftl_l2p_flat.c b/lib/ftl/ftl_l2p_flat.c index 41c5dbb1a..ce03821f8 100644 --- a/lib/ftl/ftl_l2p_flat.c +++ b/lib/ftl/ftl_l2p_flat.c @@ -5,6 +5,7 @@ #include "ftl_l2p.h" #include "ftl_core.h" +#include "ftl_band.h" #include "ftl_utils.h" #include "ftl_l2p_flat.h" #include "utils/ftl_addr_utils.h" diff --git a/lib/ftl/ftl_layout.c b/lib/ftl/ftl_layout.c index 662932949..367524f11 100644 --- a/lib/ftl/ftl_layout.c +++ b/lib/ftl/ftl_layout.c @@ -7,6 +7,7 @@ #include "ftl_core.h" #include "ftl_utils.h" +#include "ftl_band.h" #include "ftl_layout.h" #include "ftl_nv_cache.h" #include "ftl_sb.h" @@ -158,6 +159,34 @@ setup_layout_nvc(struct spdk_ftl_dev *dev) set_region_bdev_nvc(region, dev); offset += region->current.blocks; + /* Initialize band info metadata */ + if (offset >= layout->nvc.total_blocks) { + goto error; + } + region = &layout->region[FTL_LAYOUT_REGION_TYPE_BAND_MD]; + region->type = FTL_LAYOUT_REGION_TYPE_BAND_MD; + region->mirror_type = FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR; + region->name = "band_md"; + region->current.version = region->prev.version = FTL_BAND_VERSION_CURRENT; + region->current.offset = offset; + region->current.blocks = blocks_region(ftl_get_num_bands(dev) * sizeof(struct ftl_band_md)); + region->entry_size = sizeof(struct ftl_band_md) / FTL_BLOCK_SIZE; + region->num_entries = ftl_get_num_bands(dev); + set_region_bdev_nvc(region, dev); + offset += region->current.blocks; + + /* Initialize band info metadata mirror */ + if (offset >= layout->nvc.total_blocks) { + goto error; + } + mirror = &layout->region[FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR]; + *mirror = *region; + mirror->type = FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR; + mirror->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID; + mirror->name = "band_md_mirror"; + mirror->current.offset += region->current.blocks; + offset += mirror->current.blocks; + if (offset >= layout->nvc.total_blocks) { goto error; } diff --git a/lib/ftl/ftl_layout.h b/lib/ftl/ftl_layout.h index 846efc3da..b1d2b8f75 100644 --- a/lib/ftl/ftl_layout.h +++ b/lib/ftl/ftl_layout.h @@ -23,6 +23,11 @@ enum ftl_layout_region_type { /* If using cached L2P, this region stores the serialized instance of it */ FTL_LAYOUT_REGION_TYPE_L2P, + /* State of bands */ + FTL_LAYOUT_REGION_TYPE_BAND_MD, + /* Mirrored instance of bands state */ + FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR, + /* State of chunks */ FTL_LAYOUT_REGION_TYPE_NVC_MD, /* Mirrored instance of the state of chunks */ @@ -99,6 +104,8 @@ struct ftl_layout { /* Organization for base device */ struct { uint64_t total_blocks; + uint64_t num_usable_blocks; + uint64_t user_blocks; } base; /* Organization for NV cache */ diff --git a/lib/ftl/ftl_nv_cache.c b/lib/ftl/ftl_nv_cache.c index a098ab3e3..195d58980 100644 --- a/lib/ftl/ftl_nv_cache.c +++ b/lib/ftl/ftl_nv_cache.c @@ -12,6 +12,7 @@ #include "ftl_nv_cache.h" #include "ftl_nv_cache_io.h" #include "ftl_core.h" +#include "ftl_band.h" #include "utils/ftl_addr_utils.h" #include "mngt/ftl_mngt.h" diff --git a/lib/ftl/mngt/ftl_mngt_ioch.c b/lib/ftl/mngt/ftl_mngt_ioch.c index aa58c9386..f589f3f55 100644 --- a/lib/ftl/mngt/ftl_mngt_ioch.c +++ b/lib/ftl/mngt/ftl_mngt_ioch.c @@ -8,6 +8,7 @@ #include "ftl_core.h" #include "ftl_mngt.h" #include "ftl_mngt_steps.h" +#include "ftl_band.h" struct ftl_io_channel_ctx { struct ftl_io_channel *ioch; diff --git a/lib/ftl/mngt/ftl_mngt_l2p.c b/lib/ftl/mngt/ftl_mngt_l2p.c index 7a92c76f2..8ee75a506 100644 --- a/lib/ftl/mngt/ftl_mngt_l2p.c +++ b/lib/ftl/mngt/ftl_mngt_l2p.c @@ -8,6 +8,7 @@ #include "ftl_core.h" #include "ftl_mngt.h" #include "ftl_mngt_steps.h" +#include "ftl_band.h" #include "ftl_l2p.h" static void diff --git a/lib/ftl/mngt/ftl_mngt_md.c b/lib/ftl/mngt/ftl_mngt_md.c index e7b24e873..2cb5c70b9 100644 --- a/lib/ftl/mngt/ftl_mngt_md.c +++ b/lib/ftl/mngt/ftl_mngt_md.c @@ -10,6 +10,7 @@ #include "ftl_mngt.h" #include "ftl_mngt_steps.h" #include "ftl_utils.h" +#include "ftl_band.h" #include "ftl_internal.h" #include "ftl_sb.h" @@ -30,12 +31,12 @@ is_buffer_needed(enum ftl_layout_region_type type) #ifdef SPDK_FTL_VSS_EMU case FTL_LAYOUT_REGION_TYPE_VSS: #endif - case FTL_LAYOUT_REGION_TYPE_SB: case FTL_LAYOUT_REGION_TYPE_SB_BASE: case FTL_LAYOUT_REGION_TYPE_DATA_NVC: case FTL_LAYOUT_REGION_TYPE_DATA_BASE: case FTL_LAYOUT_REGION_TYPE_NVC_MD_MIRROR: + case FTL_LAYOUT_REGION_TYPE_BAND_MD_MIRROR: return false; default: diff --git a/lib/ftl/utils/ftl_defs.h b/lib/ftl/utils/ftl_defs.h index 0e62ea9b7..97dc52d46 100644 --- a/lib/ftl/utils/ftl_defs.h +++ b/lib/ftl/utils/ftl_defs.h @@ -37,4 +37,8 @@ } \ } while (0) +#define FTL_INVALID_VALUE ((uint64_t)-1) +#define FTL_BAND_ID_INVALID FTL_INVALID_VALUE +#define FTL_BAND_PHYS_ID_INVALID FTL_INVALID_VALUE + #endif /* FTL_DEFS_H */