blob: Add support for crc of metadata pages.
This patch add support crc for metadata pages, we will also add crc for supper block, used md and used clusters bitmask pages in the following patches. Change-Id: Ie36fcc16b39296d06721f1f8eb5689260194c558 Signed-off-by: Cunyin Chang <cunyin.chang@intel.com> Reviewed-on: https://review.gerrithub.io/377901 Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
2d18887fbd
commit
13ecee44a4
@ -34,6 +34,7 @@
|
||||
#include "spdk/stdinc.h"
|
||||
|
||||
#include "spdk/blob.h"
|
||||
#include "spdk/crc32.h"
|
||||
#include "spdk/env.h"
|
||||
#include "spdk/queue.h"
|
||||
#include "spdk/io_channel.h"
|
||||
@ -45,6 +46,8 @@
|
||||
#include "blobstore.h"
|
||||
#include "request.h"
|
||||
|
||||
#define BLOB_CRC32C_INITIAL 0xffffffffUL
|
||||
|
||||
static inline size_t
|
||||
divide_round_up(size_t num, size_t divisor)
|
||||
{
|
||||
@ -518,6 +521,19 @@ struct spdk_blob_load_ctx {
|
||||
void *cb_arg;
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
_spdk_blob_md_page_calc_crc(void *page)
|
||||
{
|
||||
uint32_t crc;
|
||||
|
||||
crc = BLOB_CRC32C_INITIAL;
|
||||
crc = spdk_crc32c_update(page, SPDK_BS_PAGE_SIZE - 4, crc);
|
||||
crc ^= BLOB_CRC32C_INITIAL;
|
||||
|
||||
return crc;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
_spdk_blob_load_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
{
|
||||
@ -525,8 +541,18 @@ _spdk_blob_load_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
struct spdk_blob *blob = ctx->blob;
|
||||
struct spdk_blob_md_page *page;
|
||||
int rc;
|
||||
uint32_t crc;
|
||||
|
||||
page = &ctx->pages[ctx->num_pages - 1];
|
||||
crc = _spdk_blob_md_page_calc_crc(page);
|
||||
if (crc != page->crc) {
|
||||
SPDK_ERRLOG("Metadata page %d crc mismatch\n", ctx->num_pages);
|
||||
_spdk_blob_free(blob);
|
||||
ctx->cb_fn(seq, NULL, -EINVAL);
|
||||
spdk_dma_free(ctx->pages);
|
||||
free(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (page->next != SPDK_INVALID_MD_PAGE) {
|
||||
uint32_t next_page = page->next;
|
||||
@ -1000,12 +1026,14 @@ _spdk_blob_persist(spdk_bs_sequence_t *seq, struct spdk_blob *blob,
|
||||
for (i = 1; i < blob->active.num_pages; i++) {
|
||||
page_num = spdk_bit_array_find_first_clear(bs->used_md_pages, page_num);
|
||||
ctx->pages[i - 1].next = page_num;
|
||||
/* Now that previous metadata page is complete, calculate the crc for it. */
|
||||
ctx->pages[i - 1].crc = _spdk_blob_md_page_calc_crc(&ctx->pages[i - 1]);
|
||||
blob->active.pages[i] = page_num;
|
||||
spdk_bit_array_set(bs->used_md_pages, page_num);
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "Claiming page %u for blob %lu\n", page_num, blob->id);
|
||||
page_num++;
|
||||
}
|
||||
|
||||
ctx->pages[i - 1].crc = _spdk_blob_md_page_calc_crc(&ctx->pages[i - 1]);
|
||||
/* Start writing the metadata from last page to first */
|
||||
ctx->idx = blob->active.num_pages - 1;
|
||||
_spdk_blob_persist_write_page_chain(seq, ctx, 0);
|
||||
@ -2111,6 +2139,11 @@ _spdk_bs_md_delete_open_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
{
|
||||
struct spdk_blob *blob = cb_arg;
|
||||
|
||||
/* If the blob have crc error, we just return NULL. */
|
||||
if (blob == NULL) {
|
||||
spdk_bs_sequence_finish(seq, bserrno);
|
||||
return;
|
||||
}
|
||||
blob->state = SPDK_BLOB_STATE_DIRTY;
|
||||
blob->active.num_pages = 0;
|
||||
_spdk_resize_blob(blob, 0);
|
||||
@ -2164,6 +2197,13 @@ _spdk_bs_md_open_blob_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
{
|
||||
struct spdk_blob *blob = cb_arg;
|
||||
|
||||
/* If the blob have crc error, we just return NULL. */
|
||||
if (blob == NULL) {
|
||||
seq->cpl.u.blob_handle.blob = NULL;
|
||||
spdk_bs_sequence_finish(seq, bserrno);
|
||||
return;
|
||||
}
|
||||
|
||||
blob->open_ref++;
|
||||
|
||||
TAILQ_INSERT_HEAD(&blob->bs->blobs, blob, link);
|
||||
|
@ -1184,6 +1184,56 @@ blob_serialize(void)
|
||||
g_bs = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
blob_crc(void)
|
||||
{
|
||||
struct spdk_blob_store *bs;
|
||||
struct spdk_bs_dev *dev;
|
||||
struct spdk_blob *blob;
|
||||
spdk_blob_id blobid;
|
||||
uint32_t page_num;
|
||||
int index;
|
||||
struct spdk_blob_md_page *page;
|
||||
|
||||
dev = init_dev();
|
||||
|
||||
spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
bs = g_bs;
|
||||
|
||||
spdk_bs_md_create_blob(bs, blob_op_with_id_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
|
||||
blobid = g_blobid;
|
||||
|
||||
spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(g_blob != NULL);
|
||||
blob = g_blob;
|
||||
|
||||
spdk_bs_md_close_blob(&blob, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
CU_ASSERT(blob == NULL);
|
||||
|
||||
page_num = _spdk_bs_blobid_to_page(blobid);
|
||||
index = DEV_BUFFER_BLOCKLEN * (bs->md_start + page_num);
|
||||
page = (struct spdk_blob_md_page *)&g_dev_buffer[index];
|
||||
page->crc = 0;
|
||||
|
||||
spdk_bs_md_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == -EINVAL);
|
||||
CU_ASSERT(g_blob == NULL);
|
||||
g_bserrno = 0;
|
||||
|
||||
spdk_bs_md_delete_blob(bs, blobid, blob_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == -EINVAL);
|
||||
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CU_pSuite suite = NULL;
|
||||
@ -1217,7 +1267,8 @@ int main(int argc, char **argv)
|
||||
CU_add_test(suite, "bs_unload_delayed", bs_unload_delayed) == NULL ||
|
||||
CU_add_test(suite, "bs_cluster_sz", bs_cluster_sz) == NULL ||
|
||||
CU_add_test(suite, "bs_resize_md", bs_resize_md) == NULL ||
|
||||
CU_add_test(suite, "blob_serialize", blob_serialize) == NULL
|
||||
CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
|
||||
CU_add_test(suite, "blob_crc", blob_crc) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
Loading…
Reference in New Issue
Block a user