lib/ftl: Represent ftl_addr just with the offset value
This patch removes parallel unit and zone id fields from ftl_addr struct. Change-Id: Ica42208eafdbbecab60430708197f5f3ba6167d6 Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/468701 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com> Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
59acbc91c2
commit
d6234332fb
@ -45,20 +45,13 @@
|
||||
|
||||
/* This structure represents on-disk address. It can have one of the following */
|
||||
/* formats: */
|
||||
/* - addr describing the raw address */
|
||||
/* - offset inside the disk */
|
||||
/* - cache_offset inside the cache (indicated by the cached flag) */
|
||||
/* - packed version of the two formats above (can be only used when the */
|
||||
/* raw address can be represented in less than 32 bits) */
|
||||
/* offset can be represented in less than 32 bits) */
|
||||
/* Packed format is used, when possible, to avoid wasting RAM on the L2P table. */
|
||||
struct ftl_addr {
|
||||
union {
|
||||
struct {
|
||||
uint64_t offset : 32;
|
||||
uint64_t zone_id : 16;
|
||||
uint64_t pu : 15;
|
||||
uint64_t rsvd : 1;
|
||||
};
|
||||
|
||||
struct {
|
||||
uint64_t cache_offset : 63;
|
||||
uint64_t cached : 1;
|
||||
@ -71,12 +64,12 @@ struct ftl_addr {
|
||||
uint32_t cached : 1;
|
||||
};
|
||||
|
||||
uint32_t addr;
|
||||
uint32_t offset;
|
||||
};
|
||||
uint32_t rsvd;
|
||||
} pack;
|
||||
|
||||
uint64_t addr;
|
||||
uint64_t offset;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -405,8 +405,7 @@ ftl_band_tail_md_addr(struct ftl_band *band)
|
||||
}
|
||||
|
||||
addr.offset = (num_req / band->num_zones) * xfer_size;
|
||||
addr.zone_id = band->id;
|
||||
addr.pu = zone->start_addr.pu;
|
||||
addr.offset += zone->start_addr.offset;
|
||||
|
||||
return addr;
|
||||
}
|
||||
@ -414,16 +413,11 @@ ftl_band_tail_md_addr(struct ftl_band *band)
|
||||
struct ftl_addr
|
||||
ftl_band_head_md_addr(struct ftl_band *band)
|
||||
{
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
if (spdk_unlikely(!band->num_zones)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
|
||||
addr.pu = CIRCLEQ_FIRST(&band->zones)->start_addr.pu;
|
||||
addr.zone_id = band->id;
|
||||
|
||||
return addr;
|
||||
return CIRCLEQ_FIRST(&band->zones)->start_addr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -511,23 +505,27 @@ ftl_band_user_lbks(const struct ftl_band *band)
|
||||
struct ftl_band *
|
||||
ftl_band_from_addr(struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
assert(addr.zone_id < ftl_get_num_bands(dev));
|
||||
return &dev->bands[addr.zone_id];
|
||||
size_t band_id = ftl_addr_get_band(dev, addr);
|
||||
|
||||
assert(band_id < ftl_get_num_bands(dev));
|
||||
return &dev->bands[band_id];
|
||||
}
|
||||
|
||||
struct ftl_zone *
|
||||
ftl_band_zone_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
assert(addr.pu < ftl_get_num_punits(band->dev));
|
||||
return &band->zone_buf[addr.pu];
|
||||
size_t pu_id = ftl_addr_get_punit(band->dev, addr);
|
||||
|
||||
assert(pu_id < ftl_get_num_punits(band->dev));
|
||||
return &band->zone_buf[pu_id];
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ftl_band_lbkoff_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
assert(addr.zone_id == band->id);
|
||||
assert(addr.pu < ftl_get_num_punits(band->dev));
|
||||
return addr.pu * ftl_get_num_blocks_in_zone(band->dev) + addr.offset;
|
||||
assert(ftl_addr_get_band(band->dev, addr) == band->id);
|
||||
assert(ftl_addr_get_punit(band->dev, addr) < ftl_get_num_punits(band->dev));
|
||||
return addr.offset % ftl_get_num_blocks_in_band(band->dev);
|
||||
}
|
||||
|
||||
struct ftl_addr
|
||||
@ -536,13 +534,15 @@ ftl_band_next_xfer_addr(struct ftl_band *band, struct ftl_addr addr, size_t num_
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
struct ftl_zone *zone;
|
||||
size_t num_xfers, num_stripes;
|
||||
uint64_t offset;
|
||||
|
||||
assert(addr.zone_id == band->id);
|
||||
assert(ftl_addr_get_band(dev, addr) == band->id);
|
||||
|
||||
offset = ftl_addr_get_zone_offset(dev, addr);
|
||||
zone = ftl_band_zone_from_addr(band, addr);
|
||||
|
||||
num_lbks += (addr.offset % dev->xfer_size);
|
||||
addr.offset -= (addr.offset % dev->xfer_size);
|
||||
num_lbks += (offset % dev->xfer_size);
|
||||
offset -= (offset % dev->xfer_size);
|
||||
|
||||
#if defined(DEBUG)
|
||||
/* Check that the number of zones has not been changed */
|
||||
@ -557,10 +557,10 @@ ftl_band_next_xfer_addr(struct ftl_band *band, struct ftl_addr addr, size_t num_
|
||||
#endif
|
||||
assert(band->num_zones != 0);
|
||||
num_stripes = (num_lbks / dev->xfer_size) / band->num_zones;
|
||||
addr.offset += num_stripes * dev->xfer_size;
|
||||
offset += num_stripes * dev->xfer_size;
|
||||
num_lbks -= num_stripes * dev->xfer_size * band->num_zones;
|
||||
|
||||
if (addr.offset > ftl_get_num_blocks_in_zone(dev)) {
|
||||
if (offset > ftl_get_num_blocks_in_zone(dev)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
|
||||
@ -569,26 +569,26 @@ ftl_band_next_xfer_addr(struct ftl_band *band, struct ftl_addr addr, size_t num_
|
||||
/* When the last zone is reached the lbk part of the address */
|
||||
/* needs to be increased by xfer_size */
|
||||
if (ftl_band_zone_is_last(band, zone)) {
|
||||
addr.offset += dev->xfer_size;
|
||||
if (addr.offset > ftl_get_num_blocks_in_zone(dev)) {
|
||||
offset += dev->xfer_size;
|
||||
if (offset > ftl_get_num_blocks_in_zone(dev)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
zone = ftl_band_next_operational_zone(band, zone);
|
||||
assert(zone);
|
||||
addr.pu = zone->start_addr.pu;
|
||||
|
||||
num_lbks -= dev->xfer_size;
|
||||
}
|
||||
|
||||
if (num_lbks) {
|
||||
addr.offset += num_lbks;
|
||||
if (addr.offset > ftl_get_num_blocks_in_zone(dev)) {
|
||||
offset += num_lbks;
|
||||
if (offset > ftl_get_num_blocks_in_zone(dev)) {
|
||||
return ftl_to_addr(FTL_ADDR_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
addr.offset = zone->start_addr.offset + offset;
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -597,12 +597,13 @@ ftl_xfer_offset_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
{
|
||||
struct ftl_zone *zone, *current_zone;
|
||||
unsigned int punit_offset = 0;
|
||||
size_t off, num_stripes, xfer_size = band->dev->xfer_size;
|
||||
size_t num_stripes, xfer_size = band->dev->xfer_size;
|
||||
uint64_t offset;
|
||||
|
||||
assert(addr.zone_id == band->id);
|
||||
assert(ftl_addr_get_band(band->dev, addr) == band->id);
|
||||
|
||||
num_stripes = (addr.offset / xfer_size) * band->num_zones;
|
||||
off = addr.offset % xfer_size;
|
||||
offset = ftl_addr_get_zone_offset(band->dev, addr);
|
||||
num_stripes = (offset / xfer_size) * band->num_zones;
|
||||
|
||||
current_zone = ftl_band_zone_from_addr(band, addr);
|
||||
CIRCLEQ_FOREACH(zone, &band->zones, circleq) {
|
||||
@ -612,22 +613,15 @@ ftl_xfer_offset_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
punit_offset++;
|
||||
}
|
||||
|
||||
return xfer_size * (num_stripes + punit_offset) + off;
|
||||
return xfer_size * (num_stripes + punit_offset) + offset % xfer_size;
|
||||
}
|
||||
|
||||
struct ftl_addr
|
||||
ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
|
||||
{
|
||||
struct ftl_addr addr = { .addr = 0 };
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
uint64_t punit;
|
||||
|
||||
punit = lbkoff / ftl_get_num_blocks_in_zone(dev);
|
||||
|
||||
addr.offset = lbkoff % ftl_get_num_blocks_in_zone(dev);
|
||||
addr.zone_id = band->id;
|
||||
addr.pu = punit;
|
||||
struct ftl_addr addr = { .offset = 0 };
|
||||
|
||||
addr.offset = lbkoff + band->id * ftl_get_num_blocks_in_band(band->dev);
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -1055,7 +1049,7 @@ ftl_band_erase_cb(struct ftl_io *io, void *ctx, int status)
|
||||
}
|
||||
zone = ftl_band_zone_from_addr(io->band, io->addr);
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_EMPTY;
|
||||
zone->write_offset = 0;
|
||||
zone->write_offset = zone->start_addr.offset;
|
||||
}
|
||||
|
||||
int
|
||||
@ -1122,7 +1116,7 @@ ftl_band_next_operational_zone(struct ftl_band *band, struct ftl_zone *zone)
|
||||
result = ftl_band_next_zone(band, zone);
|
||||
} else {
|
||||
CIRCLEQ_FOREACH_REVERSE(entry, &band->zones, circleq) {
|
||||
if (entry->start_addr.pu > zone->start_addr.pu) {
|
||||
if (entry->start_addr.offset > zone->start_addr.offset) {
|
||||
result = entry;
|
||||
} else {
|
||||
if (!result) {
|
||||
|
@ -356,11 +356,10 @@ ftl_submit_erase(struct ftl_io *io)
|
||||
addr = zone->start_addr;
|
||||
}
|
||||
|
||||
assert(addr.offset == 0);
|
||||
assert(ftl_addr_get_zone_offset(dev, addr) == 0);
|
||||
|
||||
ftl_trace_submission(dev, io, addr, 1);
|
||||
rc = spdk_bdev_zone_management(dev->base_bdev_desc, ioch->base_ioch,
|
||||
ftl_block_offset_from_addr(dev, addr),
|
||||
rc = spdk_bdev_zone_management(dev->base_bdev_desc, ioch->base_ioch, addr.offset,
|
||||
SPDK_BDEV_ZONE_RESET, ftl_io_cmpl_cb, io);
|
||||
if (spdk_unlikely(rc)) {
|
||||
ftl_io_fail(io, rc);
|
||||
@ -590,8 +589,10 @@ ftl_wptr_advance(struct ftl_wptr *wptr, size_t xfer_size)
|
||||
|
||||
assert(!ftl_addr_invalid(wptr->addr));
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "wptr: pu:%d zone:%d, lbk:%u\n",
|
||||
wptr->addr.pu, wptr->addr.zone_id, wptr->addr.offset);
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "wptr: pu:%lu band:%lu, offset:%lu\n",
|
||||
ftl_addr_get_punit(dev, wptr->addr),
|
||||
ftl_addr_get_band(dev, wptr->addr),
|
||||
wptr->addr.offset);
|
||||
|
||||
if (wptr->offset >= next_thld && !dev->next_band) {
|
||||
dev->next_band = ftl_next_write_band(dev);
|
||||
@ -917,7 +918,7 @@ ftl_cache_read(struct ftl_io *io, uint64_t lba,
|
||||
pthread_spin_lock(&entry->lock);
|
||||
|
||||
naddr = ftl_l2p_get(io->dev, lba);
|
||||
if (addr.addr != naddr.addr) {
|
||||
if (addr.offset != naddr.offset) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@ -938,7 +939,7 @@ ftl_read_next_logical_addr(struct ftl_io *io, struct ftl_addr *addr)
|
||||
*addr = ftl_l2p_get(dev, ftl_io_current_lba(io));
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Read addr:%lx, lba:%lu\n",
|
||||
addr->addr, ftl_io_current_lba(io));
|
||||
addr->offset, ftl_io_current_lba(io));
|
||||
|
||||
/* If the address is invalid, skip it (the buffer should already be zero'ed) */
|
||||
if (ftl_addr_invalid(*addr)) {
|
||||
@ -961,8 +962,7 @@ ftl_read_next_logical_addr(struct ftl_io *io, struct ftl_addr *addr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ftl_block_offset_from_addr(dev, *addr) + i !=
|
||||
ftl_block_offset_from_addr(dev, next_addr)) {
|
||||
if (addr->offset + i != next_addr.offset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1010,7 +1010,7 @@ ftl_submit_read(struct ftl_io *io)
|
||||
ftl_trace_submission(dev, io, addr, lbk_cnt);
|
||||
rc = spdk_bdev_read_blocks(dev->base_bdev_desc, ioch->base_ioch,
|
||||
ftl_io_iovec_addr(io),
|
||||
ftl_block_offset_from_addr(dev, addr),
|
||||
addr.offset,
|
||||
lbk_cnt, ftl_io_cmpl_cb, io);
|
||||
if (spdk_unlikely(rc)) {
|
||||
if (rc == -ENOMEM) {
|
||||
@ -1157,7 +1157,7 @@ ftl_nv_cache_submit_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
|
||||
struct ftl_nv_cache *nv_cache = &io->dev->nv_cache;
|
||||
|
||||
if (spdk_unlikely(!success)) {
|
||||
SPDK_ERRLOG("Non-volatile cache write failed at %"PRIx64"\n", io->addr.addr);
|
||||
SPDK_ERRLOG("Non-volatile cache write failed at %"PRIx64"\n", io->addr.offset);
|
||||
io->status = -EIO;
|
||||
}
|
||||
|
||||
@ -1184,14 +1184,14 @@ ftl_submit_nv_cache(void *ctx)
|
||||
thread = spdk_io_channel_get_thread(io->ioch);
|
||||
|
||||
rc = spdk_bdev_write_blocks_with_md(nv_cache->bdev_desc, ioch->cache_ioch,
|
||||
ftl_io_iovec_addr(io), io->md, io->addr.addr,
|
||||
ftl_io_iovec_addr(io), io->md, io->addr.offset,
|
||||
io->lbk_cnt, ftl_nv_cache_submit_cb, io);
|
||||
if (rc == -ENOMEM) {
|
||||
spdk_thread_send_msg(thread, ftl_submit_nv_cache, io);
|
||||
return;
|
||||
} else if (rc) {
|
||||
SPDK_ERRLOG("Write to persistent cache failed: %s (%"PRIu64", %"PRIu64")\n",
|
||||
spdk_strerror(-rc), io->addr.addr, io->lbk_cnt);
|
||||
spdk_strerror(-rc), io->addr.offset, io->lbk_cnt);
|
||||
spdk_mempool_put(nv_cache->md_pool, io->md);
|
||||
io->status = -EIO;
|
||||
ftl_io_complete(io);
|
||||
@ -1247,8 +1247,8 @@ _ftl_write_nv_cache(void *ctx)
|
||||
}
|
||||
|
||||
/* Reserve area on the write buffer cache */
|
||||
child->addr.addr = ftl_reserve_nv_cache(&dev->nv_cache, &num_lbks, &phase);
|
||||
if (child->addr.addr == FTL_LBA_INVALID) {
|
||||
child->addr.offset = ftl_reserve_nv_cache(&dev->nv_cache, &num_lbks, &phase);
|
||||
if (child->addr.offset == FTL_LBA_INVALID) {
|
||||
spdk_mempool_put(dev->nv_cache.md_pool, child->md);
|
||||
ftl_io_free(child);
|
||||
spdk_thread_send_msg(thread, _ftl_write_nv_cache, io);
|
||||
@ -1371,7 +1371,7 @@ ftl_write_cb(struct ftl_io *io, void *arg, int status)
|
||||
}
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write addr:%lu, lba:%lu\n",
|
||||
entry->addr.addr, entry->lba);
|
||||
entry->addr.offset, entry->lba);
|
||||
}
|
||||
|
||||
ftl_process_flush(dev, batch);
|
||||
@ -1515,7 +1515,7 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
|
||||
addr = wptr->addr;
|
||||
} else {
|
||||
assert(io->flags & FTL_IO_DIRECT_ACCESS);
|
||||
assert(io->addr.zone_id == wptr->band->id);
|
||||
assert(ftl_addr_get_band(dev, io->addr) == wptr->band->id);
|
||||
addr = io->addr;
|
||||
}
|
||||
|
||||
@ -1530,14 +1530,14 @@ ftl_submit_child_write(struct ftl_wptr *wptr, struct ftl_io *io, int lbk_cnt)
|
||||
|
||||
rc = spdk_bdev_write_blocks(dev->base_bdev_desc, ioch->base_ioch,
|
||||
ftl_io_iovec_addr(child),
|
||||
ftl_block_offset_from_addr(dev, addr),
|
||||
addr.offset,
|
||||
lbk_cnt, ftl_io_cmpl_cb, child);
|
||||
if (rc) {
|
||||
wptr->num_outstanding--;
|
||||
ftl_io_fail(child, rc);
|
||||
ftl_io_complete(child);
|
||||
SPDK_ERRLOG("spdk_bdev_write_blocks_with_md failed with status:%d, addr:%lu\n",
|
||||
rc, addr.addr);
|
||||
rc, addr.offset);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -1687,8 +1687,7 @@ ftl_wptr_process_writes(struct ftl_wptr *wptr)
|
||||
addr = ftl_band_next_addr(wptr->band, addr, 1);
|
||||
}
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write addr:%lx, %lx\n", wptr->addr.addr,
|
||||
ftl_block_offset_from_addr(dev, wptr->addr));
|
||||
SPDK_DEBUGLOG(SPDK_LOG_FTL_CORE, "Write addr:%lx\n", wptr->addr.offset);
|
||||
|
||||
if (ftl_submit_write(wptr, io)) {
|
||||
/* TODO: we need some recovery here */
|
||||
|
@ -279,10 +279,10 @@ struct spdk_io_channel *
|
||||
ftl_get_io_channel(const struct spdk_ftl_dev *dev);
|
||||
|
||||
#define ftl_to_addr(address) \
|
||||
(struct ftl_addr) { .addr = (uint64_t)(address) }
|
||||
(struct ftl_addr) { .offset = (uint64_t)(address) }
|
||||
|
||||
#define ftl_to_addr_packed(address) \
|
||||
(struct ftl_addr) { .pack.addr = (uint32_t)(address) }
|
||||
(struct ftl_addr) { .pack.offset = (uint32_t)(address) }
|
||||
|
||||
static inline struct spdk_thread *
|
||||
ftl_get_core_thread(const struct spdk_ftl_dev *dev)
|
||||
@ -326,6 +326,24 @@ ftl_get_num_blocks_in_band(const struct spdk_ftl_dev *dev)
|
||||
return ftl_get_num_punits(dev) * ftl_get_num_blocks_in_zone(dev);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_addr_get_band(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
return addr.offset / ftl_get_num_blocks_in_band(dev);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_addr_get_punit(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
return (addr.offset / ftl_get_num_blocks_in_zone(dev)) % ftl_get_num_punits(dev);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_addr_get_zone_offset(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
return addr.offset % ftl_get_num_blocks_in_zone(dev);
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
ftl_vld_map_size(const struct spdk_ftl_dev *dev)
|
||||
{
|
||||
@ -341,7 +359,7 @@ ftl_addr_packed(const struct spdk_ftl_dev *dev)
|
||||
static inline int
|
||||
ftl_addr_invalid(struct ftl_addr addr)
|
||||
{
|
||||
return addr.addr == ftl_to_addr(FTL_ADDR_INVALID).addr;
|
||||
return addr.offset == ftl_to_addr(FTL_ADDR_INVALID).offset;
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -350,27 +368,6 @@ ftl_addr_cached(struct ftl_addr addr)
|
||||
return !ftl_addr_invalid(addr) && addr.cached;
|
||||
}
|
||||
|
||||
static inline struct ftl_addr
|
||||
ftl_addr_from_block_offset(const struct spdk_ftl_dev *dev, uint64_t offset)
|
||||
{
|
||||
struct ftl_addr addr = {};
|
||||
uint64_t zone_num;
|
||||
|
||||
addr.offset = offset % ftl_get_num_blocks_in_zone(dev);
|
||||
zone_num = offset / ftl_get_num_blocks_in_zone(dev);
|
||||
addr.pu = zone_num % ftl_get_num_punits(dev);
|
||||
addr.zone_id = zone_num / ftl_get_num_punits(dev);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
ftl_block_offset_from_addr(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
return (addr.zone_id * ftl_get_num_punits(dev) + addr.pu) *
|
||||
ftl_get_num_blocks_in_zone(dev) + addr.offset;
|
||||
}
|
||||
|
||||
static inline struct ftl_addr
|
||||
ftl_addr_to_packed(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
{
|
||||
@ -382,7 +379,7 @@ ftl_addr_to_packed(const struct spdk_ftl_dev *dev, struct ftl_addr addr)
|
||||
p.pack.cached = 1;
|
||||
p.pack.cache_offset = (uint32_t) addr.cache_offset;
|
||||
} else {
|
||||
p.pack.addr = (uint32_t) ftl_block_offset_from_addr(dev, addr);
|
||||
p.pack.offset = (uint32_t) addr.offset;
|
||||
}
|
||||
|
||||
return p;
|
||||
@ -393,13 +390,13 @@ ftl_addr_from_packed(const struct spdk_ftl_dev *dev, struct ftl_addr p)
|
||||
{
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
if (p.pack.addr == (uint32_t)FTL_ADDR_INVALID) {
|
||||
if (p.pack.offset == (uint32_t)FTL_ADDR_INVALID) {
|
||||
addr = ftl_to_addr(FTL_ADDR_INVALID);
|
||||
} else if (p.pack.cached) {
|
||||
addr.cached = 1;
|
||||
addr.cache_offset = p.pack.cache_offset;
|
||||
} else {
|
||||
addr = ftl_addr_from_block_offset(dev, p.pack.addr);
|
||||
addr = p;
|
||||
}
|
||||
|
||||
return addr;
|
||||
@ -424,7 +421,7 @@ ftl_addr_from_packed(const struct spdk_ftl_dev *dev, struct ftl_addr p)
|
||||
_ftl_l2p_get(l2p, off, 64)
|
||||
|
||||
#define ftl_addr_cmp(p1, p2) \
|
||||
((p1).addr == (p2).addr)
|
||||
((p1).offset == (p2).offset)
|
||||
|
||||
static inline void
|
||||
ftl_l2p_set(struct spdk_ftl_dev *dev, uint64_t lba, struct ftl_addr addr)
|
||||
@ -432,9 +429,9 @@ ftl_l2p_set(struct spdk_ftl_dev *dev, uint64_t lba, struct ftl_addr addr)
|
||||
assert(dev->num_lbas > lba);
|
||||
|
||||
if (ftl_addr_packed(dev)) {
|
||||
_ftl_l2p_set32(dev->l2p, lba, ftl_addr_to_packed(dev, addr).addr);
|
||||
_ftl_l2p_set32(dev->l2p, lba, ftl_addr_to_packed(dev, addr).offset);
|
||||
} else {
|
||||
_ftl_l2p_set64(dev->l2p, lba, addr.addr);
|
||||
_ftl_l2p_set64(dev->l2p, lba, addr.offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,6 +447,7 @@ ftl_l2p_get(struct spdk_ftl_dev *dev, uint64_t lba)
|
||||
return ftl_to_addr(_ftl_l2p_get64(dev->l2p, lba));
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
ftl_dev_has_nv_cache(const struct spdk_ftl_dev *dev)
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ ftl_band_validate_md(struct ftl_band *band)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addr_l2p.addr != addr_md.addr) {
|
||||
if (addr_l2p.offset != addr_md.offset) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
@ -53,8 +53,7 @@
|
||||
static inline const char *
|
||||
ftl_addr2str(struct ftl_addr addr, char *buf, size_t size)
|
||||
{
|
||||
snprintf(buf, size, "(pu: %u, chk: %u, lbk: %u)",
|
||||
addr.pu, addr.zone_id, addr.offset);
|
||||
snprintf(buf, size, "(%"PRIu64")", addr.offset);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -819,13 +819,12 @@ ftl_dev_get_zone_info_cb(struct spdk_bdev_io *bdev_io, bool success, void *cb_ar
|
||||
num_zones = spdk_min(zones_left, FTL_ZONE_INFO_COUNT);
|
||||
|
||||
for (i = 0; i < num_zones; ++i) {
|
||||
addr = ftl_addr_from_block_offset(dev, init_ctx->info[i].zone_id);
|
||||
band = &dev->bands[addr.zone_id];
|
||||
zone = &band->zone_buf[addr.pu];
|
||||
addr.offset = init_ctx->info[i].zone_id;
|
||||
band = &dev->bands[ftl_addr_get_band(dev, addr)];
|
||||
zone = &band->zone_buf[ftl_addr_get_punit(dev, addr)];
|
||||
zone->state = init_ctx->info[i].state;
|
||||
zone->start_addr = addr;
|
||||
addr = ftl_addr_from_block_offset(dev, init_ctx->info[i].write_pointer);
|
||||
zone->write_offset = addr.offset;
|
||||
zone->write_offset = init_ctx->info[i].write_pointer;
|
||||
|
||||
/* TODO: add support for zone capacity less than zone size */
|
||||
if (init_ctx->info[i].capacity != ftl_get_num_blocks_in_zone(dev)) {
|
||||
|
@ -263,7 +263,7 @@ ftl_io_init(struct ftl_io *io, struct spdk_ftl_dev *dev,
|
||||
io->type = type;
|
||||
io->dev = dev;
|
||||
io->lba.single = FTL_LBA_INVALID;
|
||||
io->addr.addr = FTL_ADDR_INVALID;
|
||||
io->addr.offset = FTL_ADDR_INVALID;
|
||||
io->cb_fn = fn;
|
||||
io->cb_ctx = ctx;
|
||||
io->trace = ftl_trace_alloc_id(dev);
|
||||
|
@ -1156,6 +1156,7 @@ ftl_pad_zone_cb(struct ftl_io *io, void *arg, int status)
|
||||
struct ftl_band *band = io->band;
|
||||
struct ftl_zone *zone;
|
||||
struct ftl_io *new_io;
|
||||
uint64_t offset;
|
||||
|
||||
restore->num_ios--;
|
||||
/* TODO check for next unit error vs early close error */
|
||||
@ -1164,7 +1165,8 @@ ftl_pad_zone_cb(struct ftl_io *io, void *arg, int status)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (io->addr.offset + io->lbk_cnt == ftl_get_num_blocks_in_zone(restore->dev)) {
|
||||
offset = io->addr.offset % ftl_get_num_blocks_in_zone(restore->dev);
|
||||
if (offset + io->lbk_cnt == ftl_get_num_blocks_in_zone(restore->dev)) {
|
||||
zone = ftl_band_zone_from_addr(band, io->addr);
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_CLOSED;
|
||||
} else {
|
||||
|
@ -249,7 +249,7 @@ ftl_trace_rwb_pop(struct spdk_ftl_dev *dev, const struct ftl_rwb_entry *entry)
|
||||
tpoint_id = FTL_TRACE_RWB_POP(FTL_TRACE_SOURCE_USER);
|
||||
}
|
||||
|
||||
spdk_trace_record(tpoint_id, entry->trace, 0, entry->addr.addr, entry->lba);
|
||||
spdk_trace_record(tpoint_id, entry->trace, 0, entry->addr.offset, entry->lba);
|
||||
}
|
||||
|
||||
void
|
||||
@ -337,7 +337,7 @@ ftl_trace_submission(struct spdk_ftl_dev *dev, const struct ftl_io *io, struct f
|
||||
}
|
||||
}
|
||||
|
||||
spdk_trace_record(tpoint_id, io->trace, addr_cnt, 0, addr.addr);
|
||||
spdk_trace_record(tpoint_id, io->trace, addr_cnt, 0, addr.offset);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -46,7 +46,7 @@ struct base_bdev_geometry {
|
||||
extern struct base_bdev_geometry g_geo;
|
||||
|
||||
struct spdk_ftl_dev *test_init_ftl_dev(const struct base_bdev_geometry *geo);
|
||||
struct ftl_band *test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id);
|
||||
struct ftl_band *test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id, size_t zone_size);
|
||||
void test_free_ftl_dev(struct spdk_ftl_dev *dev);
|
||||
void test_free_ftl_band(struct ftl_band *band);
|
||||
uint64_t test_offset_from_addr(struct ftl_addr addr, struct ftl_band *band);
|
||||
@ -94,7 +94,7 @@ test_init_ftl_dev(const struct base_bdev_geometry *geo)
|
||||
}
|
||||
|
||||
struct ftl_band *
|
||||
test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id)
|
||||
test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id, size_t zone_size)
|
||||
{
|
||||
struct ftl_band *band;
|
||||
struct ftl_zone *zone;
|
||||
@ -122,8 +122,7 @@ test_init_ftl_band(struct spdk_ftl_dev *dev, size_t id)
|
||||
for (size_t i = 0; i < ftl_get_num_punits(dev); ++i) {
|
||||
zone = &band->zone_buf[i];
|
||||
zone->state = SPDK_BDEV_ZONE_STATE_CLOSED;
|
||||
zone->start_addr.pu = i;
|
||||
zone->start_addr.zone_id = band->id;
|
||||
zone->start_addr.offset = zone_size * (id * ftl_get_num_punits(dev) + i);
|
||||
CIRCLEQ_INSERT_TAIL(&band->zones, zone, circleq);
|
||||
band->num_zones++;
|
||||
}
|
||||
@ -160,7 +159,7 @@ test_offset_from_addr(struct ftl_addr addr, struct ftl_band *band)
|
||||
{
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
|
||||
CU_ASSERT_EQUAL(addr.zone_id, band->id);
|
||||
CU_ASSERT_EQUAL(ftl_addr_get_band(dev, addr), band->id);
|
||||
|
||||
return addr.pu * ftl_get_num_blocks_in_zone(dev) + addr.offset;
|
||||
return addr.offset - band->id * ftl_get_num_blocks_in_band(dev);
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ setup_band(void)
|
||||
int rc;
|
||||
|
||||
g_dev = test_init_ftl_dev(&g_geo);
|
||||
g_band = test_init_ftl_band(g_dev, TEST_BAND_IDX);
|
||||
g_band = test_init_ftl_band(g_dev, TEST_BAND_IDX, g_geo.zone_size);
|
||||
rc = ftl_band_alloc_lba_map(g_band);
|
||||
CU_ASSERT_EQUAL_FATAL(rc, 0);
|
||||
}
|
||||
@ -76,7 +76,7 @@ addr_from_punit(uint64_t punit)
|
||||
{
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
addr.pu = punit;
|
||||
addr.offset = punit * g_geo.zone_size;
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ test_band_lbkoff_from_addr_base(void)
|
||||
setup_band();
|
||||
for (i = 0; i < ftl_get_num_punits(g_dev); ++i) {
|
||||
addr = addr_from_punit(i);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
|
||||
offset = ftl_band_lbkoff_from_addr(g_band, addr);
|
||||
CU_ASSERT_EQUAL(offset, flat_lun * ftl_get_num_blocks_in_zone(g_dev));
|
||||
@ -108,8 +108,7 @@ test_band_lbkoff_from_addr_offset(void)
|
||||
for (i = 0; i < ftl_get_num_punits(g_dev); ++i) {
|
||||
for (j = 0; j < g_geo.zone_size; ++j) {
|
||||
addr = addr_from_punit(i);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset = j;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev) + j;
|
||||
|
||||
offset = ftl_band_lbkoff_from_addr(g_band, addr);
|
||||
|
||||
@ -130,13 +129,12 @@ test_band_addr_from_lbkoff(void)
|
||||
for (i = 0; i < ftl_get_num_punits(g_dev); ++i) {
|
||||
for (j = 0; j < g_geo.zone_size; ++j) {
|
||||
expect = addr_from_punit(i);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = j;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev) + j;
|
||||
|
||||
offset = ftl_band_lbkoff_from_addr(g_band, expect);
|
||||
addr = ftl_band_addr_from_lbkoff(g_band, offset);
|
||||
|
||||
CU_ASSERT_EQUAL(addr.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(addr.offset, expect.offset);
|
||||
}
|
||||
}
|
||||
cleanup_band();
|
||||
@ -152,7 +150,7 @@ test_band_set_addr(void)
|
||||
setup_band();
|
||||
lba_map = &g_band->lba_map;
|
||||
addr = addr_from_punit(0);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 0);
|
||||
|
||||
@ -163,13 +161,13 @@ test_band_set_addr(void)
|
||||
CU_ASSERT_EQUAL(lba_map->map[offset], TEST_LBA);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset));
|
||||
|
||||
addr.pu++;
|
||||
addr.offset += g_geo.zone_size;
|
||||
offset = test_offset_from_addr(addr, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA + 1, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 2);
|
||||
CU_ASSERT_EQUAL(lba_map->map[offset], TEST_LBA + 1);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset));
|
||||
addr.pu--;
|
||||
addr.offset -= g_geo.zone_size;
|
||||
offset = test_offset_from_addr(addr, g_band);
|
||||
CU_ASSERT_TRUE(spdk_bit_array_get(lba_map->vld, offset));
|
||||
cleanup_band();
|
||||
@ -185,7 +183,7 @@ test_invalidate_addr(void)
|
||||
setup_band();
|
||||
lba_map = &g_band->lba_map;
|
||||
addr = addr_from_punit(0);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
offset[0] = test_offset_from_addr(addr, g_band);
|
||||
|
||||
ftl_band_set_addr(g_band, TEST_LBA, addr);
|
||||
@ -197,7 +195,7 @@ test_invalidate_addr(void)
|
||||
|
||||
offset[0] = test_offset_from_addr(addr, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA, addr);
|
||||
addr.pu++;
|
||||
addr.offset += g_geo.zone_size;
|
||||
offset[1] = test_offset_from_addr(addr, g_band);
|
||||
ftl_band_set_addr(g_band, TEST_LBA + 1, addr);
|
||||
CU_ASSERT_EQUAL(lba_map->num_vld, 2);
|
||||
@ -218,69 +216,66 @@ test_next_xfer_addr(void)
|
||||
setup_band();
|
||||
/* Verify simple one lbk incremention */
|
||||
addr = addr_from_punit(0);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset = 0;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
expect = addr;
|
||||
expect.offset = 1;
|
||||
expect.offset += 1;
|
||||
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, 1);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
|
||||
/* Verify jumping between zones */
|
||||
expect = addr_from_punit(1);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
|
||||
/* Verify jumping works with unaligned offsets */
|
||||
expect = addr_from_punit(1);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = 3;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev) + 3;
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size + 3);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
|
||||
/* Verify jumping from last zone to the first one */
|
||||
expect = addr_from_punit(0);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev) + g_dev->xfer_size;
|
||||
addr = addr_from_punit(ftl_get_num_punits(g_dev) - 1);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
|
||||
/* Verify jumping from last zone to the first one with unaligned offset */
|
||||
expect = addr_from_punit(0);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size + 2;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
expect.offset += g_dev->xfer_size + 2;
|
||||
addr = addr_from_punit(ftl_get_num_punits(g_dev) - 1);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, g_dev->xfer_size + 2);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
|
||||
/* Verify large offset spanning across the whole band multiple times */
|
||||
expect = addr_from_punit(0);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size * 5 + 4;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
expect.offset += g_dev->xfer_size * 5 + 4;
|
||||
addr = addr_from_punit(0);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset = g_dev->xfer_size * 2 + 1;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
addr.offset += g_dev->xfer_size * 2 + 1;
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, 3 * g_dev->xfer_size *
|
||||
ftl_get_num_punits(g_dev) + 3);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
|
||||
/* Remove one zone and verify it's skipped properly */
|
||||
g_band->zone_buf[1].state = SPDK_BDEV_ZONE_STATE_OFFLINE;
|
||||
CIRCLEQ_REMOVE(&g_band->zones, &g_band->zone_buf[1], circleq);
|
||||
g_band->num_zones--;
|
||||
expect = addr_from_punit(2);
|
||||
expect.zone_id = TEST_BAND_IDX;
|
||||
expect.offset = g_dev->xfer_size * 5 + 4;
|
||||
expect.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
expect.offset += g_dev->xfer_size * 5 + 4;
|
||||
addr = addr_from_punit(0);
|
||||
addr.zone_id = TEST_BAND_IDX;
|
||||
addr.offset = g_dev->xfer_size * 2 + 1;
|
||||
addr.offset += TEST_BAND_IDX * ftl_get_num_blocks_in_band(g_dev);
|
||||
addr.offset += g_dev->xfer_size * 2 + 1;
|
||||
result = ftl_band_next_xfer_addr(g_band, addr, 3 * g_dev->xfer_size *
|
||||
(ftl_get_num_punits(g_dev) - 1) + g_dev->xfer_size + 3);
|
||||
CU_ASSERT_EQUAL(result.addr, expect.addr);
|
||||
CU_ASSERT_EQUAL(result.offset, expect.offset);
|
||||
cleanup_band();
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ setup_band(struct ftl_band **band, const struct base_bdev_geometry *geo)
|
||||
struct spdk_ftl_dev *dev;
|
||||
|
||||
dev = test_init_ftl_dev(&g_geo);
|
||||
*band = test_init_ftl_band(dev, 0);
|
||||
*band = test_init_ftl_band(dev, 0, geo->zone_size);
|
||||
rc = ftl_band_alloc_lba_map(*band);
|
||||
SPDK_CU_ASSERT_FATAL(rc == 0);
|
||||
(*band)->state = FTL_BAND_STATE_PREP;
|
||||
|
@ -118,19 +118,17 @@ test_addr_pack32(void)
|
||||
|
||||
/* Check valid address transformation */
|
||||
orig.offset = 4;
|
||||
orig.zone_id = 3;
|
||||
orig.pu = 2;
|
||||
addr = ftl_addr_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(addr.addr <= UINT32_MAX);
|
||||
CU_ASSERT_TRUE(addr.offset <= UINT32_MAX);
|
||||
CU_ASSERT_FALSE(addr.pack.cached);
|
||||
addr = ftl_addr_from_packed(g_dev, addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
CU_ASSERT_EQUAL(addr.offset, orig.offset);
|
||||
|
||||
/* Check invalid address transformation */
|
||||
orig = ftl_to_addr(FTL_ADDR_INVALID);
|
||||
addr = ftl_addr_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(addr.addr <= UINT32_MAX);
|
||||
CU_ASSERT_TRUE(addr.offset <= UINT32_MAX);
|
||||
addr = ftl_addr_from_packed(g_dev, addr);
|
||||
CU_ASSERT_TRUE(ftl_addr_invalid(addr));
|
||||
|
||||
@ -138,48 +136,12 @@ test_addr_pack32(void)
|
||||
orig.cached = 1;
|
||||
orig.cache_offset = 1024;
|
||||
addr = ftl_addr_to_packed(g_dev, orig);
|
||||
CU_ASSERT_TRUE(addr.addr <= UINT32_MAX);
|
||||
CU_ASSERT_TRUE(addr.offset <= UINT32_MAX);
|
||||
CU_ASSERT_TRUE(addr.pack.cached);
|
||||
addr = ftl_addr_from_packed(g_dev, addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_TRUE(ftl_addr_cached(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
clean_l2p();
|
||||
}
|
||||
|
||||
static void
|
||||
test_addr_pack64(void)
|
||||
{
|
||||
struct ftl_addr orig = {}, addr;
|
||||
|
||||
orig.offset = 4;
|
||||
orig.zone_id = 3;
|
||||
orig.pu = 2;
|
||||
|
||||
/* Check valid address transformation */
|
||||
addr.addr = ftl_block_offset_from_addr(g_dev, orig);
|
||||
addr = ftl_addr_from_block_offset(g_dev, addr.addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
|
||||
orig.offset = 0x7ea0be0f;
|
||||
orig.zone_id = 0x6;
|
||||
orig.pu = 0x4;
|
||||
|
||||
addr.addr = ftl_block_offset_from_addr(g_dev, orig);
|
||||
addr = ftl_addr_from_block_offset(g_dev, addr.addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
|
||||
/* Check maximum valid address */
|
||||
orig.offset = 0xffffffff;
|
||||
orig.zone_id = 0xf;
|
||||
orig.pu = 0x7;
|
||||
|
||||
addr.addr = ftl_block_offset_from_addr(g_dev, orig);
|
||||
addr = ftl_addr_from_block_offset(g_dev, addr.addr);
|
||||
CU_ASSERT_FALSE(ftl_addr_invalid(addr));
|
||||
CU_ASSERT_EQUAL(addr.addr, orig.addr);
|
||||
CU_ASSERT_EQUAL(addr.offset, orig.offset);
|
||||
clean_l2p();
|
||||
}
|
||||
|
||||
@ -267,8 +229,6 @@ main(int argc, char **argv)
|
||||
test_addr_invalid) == NULL
|
||||
|| CU_add_test(suite64, "test_addr64_cached",
|
||||
test_addr_cached) == NULL
|
||||
|| CU_add_test(suite64, "test_addr64_pack",
|
||||
test_addr_pack64) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
@ -105,16 +105,9 @@ ftl_band_lbkoff_from_addr(struct ftl_band *band, struct ftl_addr addr)
|
||||
struct ftl_addr
|
||||
ftl_band_addr_from_lbkoff(struct ftl_band *band, uint64_t lbkoff)
|
||||
{
|
||||
struct ftl_addr addr = { .addr = 0 };
|
||||
struct spdk_ftl_dev *dev = band->dev;
|
||||
uint64_t punit;
|
||||
|
||||
punit = lbkoff / ftl_get_num_blocks_in_zone(dev);
|
||||
|
||||
addr.offset = lbkoff % ftl_get_num_blocks_in_zone(dev);
|
||||
addr.zone_id = band->id;
|
||||
addr.pu = punit;
|
||||
struct ftl_addr addr = {};
|
||||
|
||||
addr.offset = lbkoff + band->id * ftl_get_num_blocks_in_band(band->dev);
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -211,7 +204,7 @@ setup_reloc(struct spdk_ftl_dev **_dev, struct ftl_reloc **_reloc,
|
||||
SPDK_CU_ASSERT_FATAL(ftl_get_num_bands(dev) > 0);
|
||||
|
||||
for (i = 0; i < ftl_get_num_bands(dev); ++i) {
|
||||
test_init_ftl_band(dev, i);
|
||||
test_init_ftl_band(dev, i, geo->zone_size);
|
||||
}
|
||||
|
||||
reloc = ftl_reloc_init(dev);
|
||||
|
@ -109,7 +109,7 @@ setup_wptr_test(struct spdk_ftl_dev **dev, const struct base_bdev_geometry *geo)
|
||||
|
||||
t_dev = test_init_ftl_dev(geo);
|
||||
for (i = 0; i < ftl_get_num_bands(t_dev); ++i) {
|
||||
test_init_ftl_band(t_dev, i);
|
||||
test_init_ftl_band(t_dev, i, geo->zone_size);
|
||||
t_dev->bands[i].state = FTL_BAND_STATE_CLOSED;
|
||||
ftl_band_set_state(&t_dev->bands[i], FTL_BAND_STATE_FREE);
|
||||
}
|
||||
@ -155,7 +155,6 @@ test_wptr(void)
|
||||
|
||||
for (lbk = 0, offset = 0; lbk < ftl_get_num_blocks_in_zone(dev) / xfer_size; ++lbk) {
|
||||
for (zone = 0; zone < band->num_zones; ++zone) {
|
||||
CU_ASSERT_EQUAL(wptr->addr.offset, (lbk * xfer_size));
|
||||
CU_ASSERT_EQUAL(wptr->offset, offset);
|
||||
ftl_wptr_advance(wptr, xfer_size);
|
||||
offset += xfer_size;
|
||||
@ -163,7 +162,6 @@ test_wptr(void)
|
||||
}
|
||||
|
||||
CU_ASSERT_EQUAL(band->state, FTL_BAND_STATE_FULL);
|
||||
CU_ASSERT_EQUAL(wptr->addr.offset, ftl_get_num_blocks_in_zone(dev));
|
||||
|
||||
ftl_band_set_state(band, FTL_BAND_STATE_CLOSING);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user