per Intel policy to include file commit date using git cmd below. The policy does not apply to non-Intel (C) notices. git log --follow -C90% --format=%ad --date default <file> | tail -1 and then pull just the 4 digit year from the result. Intel copyrights were not added to files where Intel either had no contribution ot the contribution lacked substance (ie license header updates, formatting changes, etc). Contribution date used "--follow -C95%" to get the most accurate date. Note that several files in this patch didn't end the license/(c) block with a blank comment line so these were added as the vast majority of files do have this last blank line. Simply there for consistency. Signed-off-by: paul luse <paul.e.luse@intel.com> Change-Id: Id5b7ce4f658fe87132f14139ead58d6e285c04d4 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15192 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Community-CI: Mellanox Build Bot
167 lines
4.2 KiB
C
167 lines
4.2 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright (C) 2022 Intel Corporation.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#ifndef FTL_INTERNAL_H
|
|
#define FTL_INTERNAL_H
|
|
|
|
#include "spdk/stdinc.h"
|
|
#include "spdk/crc32.h"
|
|
#include "spdk/util.h"
|
|
#include "spdk/uuid.h"
|
|
|
|
#include "utils/ftl_bitmap.h"
|
|
|
|
/* Marks address as invalid */
|
|
#define FTL_ADDR_INVALID ((ftl_addr)-1)
|
|
/* Marks LBA as invalid */
|
|
#define FTL_LBA_INVALID ((uint64_t)-1)
|
|
/* Smallest data unit size */
|
|
#define FTL_BLOCK_SIZE 4096ULL
|
|
|
|
#define FTL_P2L_VERSION_0 0
|
|
#define FTL_P2L_VERSION_1 1
|
|
|
|
#define FTL_P2L_VERSION_CURRENT FTL_P2L_VERSION_1
|
|
|
|
/*
|
|
* This type represents address in the ftl address space. Values from 0 to based bdev size are
|
|
* mapped directly to base device lbas. Values above that represent nv cache lbas.
|
|
*/
|
|
typedef uint64_t ftl_addr;
|
|
|
|
struct spdk_ftl_dev;
|
|
|
|
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
|
|
};
|
|
|
|
struct ftl_p2l_map_entry {
|
|
uint64_t lba;
|
|
uint64_t seq_id;
|
|
};
|
|
|
|
/* Number of LBAs that could be stored in a single block */
|
|
#define FTL_NUM_LBA_IN_BLOCK (FTL_BLOCK_SIZE / sizeof(struct ftl_p2l_map_entry))
|
|
|
|
/*
|
|
* Mapping of physical (actual location on disk) to logical (user's POV) addresses. Used in two main scenarios:
|
|
* - during relocation FTL needs to pin L2P pages (this allows to check which pages to pin) and move still valid blocks
|
|
* (valid map allows for preliminary elimination of invalid physical blocks, but user data could invalidate a location
|
|
* during read/write operation, so actual comparision against L2P needs to be done)
|
|
* - After dirty shutdown the state of the L2P is unknown and needs to be rebuilt - it is done by applying all P2L, taking
|
|
* into account ordering of user writes
|
|
*/
|
|
struct ftl_p2l_map {
|
|
/* Number of valid LBAs */
|
|
size_t num_valid;
|
|
|
|
/* P2L map's reference count, prevents premature release of resources during dirty shutdown recovery for open bands */
|
|
size_t ref_cnt;
|
|
|
|
/* Bitmap of valid LBAs */
|
|
struct ftl_bitmap *valid;
|
|
|
|
/* P2L map (only valid for open/relocating bands) */
|
|
union {
|
|
struct ftl_p2l_map_entry *band_map;
|
|
void *chunk_map;
|
|
};
|
|
|
|
/* DMA buffer for region's metadata entry */
|
|
union {
|
|
struct ftl_band_md *band_dma_md;
|
|
|
|
struct ftl_nv_cache_chunk_md *chunk_dma_md;
|
|
};
|
|
|
|
/* P2L checkpointing region */
|
|
struct ftl_p2l_ckpt *p2l_ckpt;
|
|
};
|
|
|
|
struct ftl_p2l_sync_ctx {
|
|
struct ftl_band *band;
|
|
uint64_t page_start;
|
|
uint64_t page_end;
|
|
int md_region;
|
|
};
|
|
|
|
struct ftl_p2l_ckpt_page {
|
|
struct ftl_p2l_map_entry map[FTL_NUM_LBA_IN_BLOCK];
|
|
};
|
|
|
|
struct ftl_p2l_ckpt;
|
|
struct ftl_band;
|
|
struct spdk_ftl_dev;
|
|
struct ftl_mngt_process;
|
|
struct ftl_rq;
|
|
|
|
int ftl_p2l_ckpt_init(struct spdk_ftl_dev *dev);
|
|
|
|
void ftl_p2l_ckpt_deinit(struct spdk_ftl_dev *dev);
|
|
|
|
void ftl_p2l_ckpt_issue(struct ftl_rq *rq);
|
|
|
|
struct ftl_p2l_ckpt *ftl_p2l_ckpt_acquire(struct spdk_ftl_dev *dev);
|
|
|
|
struct ftl_p2l_ckpt *ftl_p2l_ckpt_acquire_region_type(struct spdk_ftl_dev *dev,
|
|
uint32_t region_type);
|
|
|
|
void ftl_p2l_ckpt_release(struct spdk_ftl_dev *dev, struct ftl_p2l_ckpt *ckpt);
|
|
|
|
enum ftl_layout_region_type ftl_p2l_ckpt_region_type(const struct ftl_p2l_ckpt *ckpt);
|
|
|
|
#if defined(DEBUG)
|
|
void ftl_p2l_validate_ckpt(struct ftl_band *band);
|
|
#else
|
|
static inline void
|
|
ftl_p2l_validate_ckpt(struct ftl_band *band)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
int ftl_mngt_p2l_ckpt_get_seq_id(struct spdk_ftl_dev *dev, int md_region);
|
|
|
|
int ftl_mngt_p2l_ckpt_restore(struct ftl_band *band, uint32_t md_region, uint64_t seq_id);
|
|
|
|
int ftl_mngt_p2l_ckpt_restore_clean(struct ftl_band *band);
|
|
|
|
void ftl_mngt_p2l_ckpt_restore_shm_clean(struct ftl_band *band);
|
|
|
|
void ftl_mngt_persist_bands_p2l(struct ftl_mngt_process *mngt);
|
|
|
|
struct ftl_reloc *ftl_reloc_init(struct spdk_ftl_dev *dev);
|
|
|
|
void ftl_reloc_free(struct ftl_reloc *reloc);
|
|
|
|
void ftl_reloc(struct ftl_reloc *reloc);
|
|
|
|
void ftl_reloc_halt(struct ftl_reloc *reloc);
|
|
|
|
void ftl_reloc_resume(struct ftl_reloc *reloc);
|
|
|
|
bool ftl_reloc_is_halted(const struct ftl_reloc *reloc);
|
|
|
|
#endif /* FTL_INTERNAL_H */
|