blobstore: add bstype to blobstore super block
Introducing bstype as a way to identify and verify blobstore type. Signed-off-by: Maciej Szwed <maciej.szwed@intel.com> Change-Id: I50267b5408625be10fe0c146ae329016d5509b4a Reviewed-on: https://review.gerrithub.io/380476 Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
1a15ce9b46
commit
eb8b1e20a9
@ -190,12 +190,13 @@ is the remainder of cluster 0 and may extend to additional clusters.
|
||||
The `<sb-params>` data contains parameters specified by the user when the blob
|
||||
store was initially formatted.
|
||||
|
||||
<sb-params> ::= <sb-page-size> <sb-cluster-size>
|
||||
<sb-params> ::= <sb-page-size> <sb-cluster-size> <sb-bs-type>
|
||||
<sb-page-size> ::= u32 # page size, in bytes.
|
||||
# Must be a multiple of the logical block size.
|
||||
# The implementation today requires this to be 4KiB.
|
||||
<sb-cluster-size> ::= u32 # Cluster size, in bytes.
|
||||
# Must be a multiple of the page size.
|
||||
<sb-bs-type> ::= char[16] # Blobstore type
|
||||
|
||||
Each blob is allocated a non-contiguous set of pages inside the metadata region
|
||||
for its metadata. These pages form a linked list. The first page in the list
|
||||
|
@ -867,7 +867,7 @@ load_bs(struct cli_context_t *cli_context)
|
||||
return;
|
||||
}
|
||||
|
||||
spdk_bs_load(bs_dev, cli_context->next_func, cli_context);
|
||||
spdk_bs_load(bs_dev, NULL, cli_context->next_func, cli_context);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -70,6 +70,7 @@
|
||||
|
||||
typedef uint64_t spdk_blob_id;
|
||||
#define SPDK_BLOBID_INVALID (uint64_t)-1
|
||||
#define SPDK_BLOBSTORE_TYPE_LENGTH 16
|
||||
|
||||
struct spdk_blob_store;
|
||||
struct spdk_io_channel;
|
||||
@ -139,18 +140,23 @@ struct spdk_bs_dev {
|
||||
uint32_t blocklen; /* In bytes */
|
||||
};
|
||||
|
||||
struct spdk_bs_type {
|
||||
char bstype[SPDK_BLOBSTORE_TYPE_LENGTH];
|
||||
};
|
||||
|
||||
struct spdk_bs_opts {
|
||||
uint32_t cluster_sz; /* In bytes. Must be multiple of page size. */
|
||||
uint32_t num_md_pages; /* Count of the number of pages reserved for metadata */
|
||||
uint32_t max_md_ops; /* Maximum simultaneous metadata operations */
|
||||
uint32_t max_channel_ops; /* Maximum simultaneous operations per channel */
|
||||
struct spdk_bs_type bstype; /* Blobstore type */
|
||||
};
|
||||
|
||||
/* Initialize an spdk_bs_opts structure to the default blobstore option values. */
|
||||
void spdk_bs_opts_init(struct spdk_bs_opts *opts);
|
||||
|
||||
/* Load a blob store from the given device. This will fail (return NULL) if no blob store is present. */
|
||||
void spdk_bs_load(struct spdk_bs_dev *dev,
|
||||
void spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts,
|
||||
spdk_bs_op_with_handle_complete cb_fn, void *cb_arg);
|
||||
|
||||
/* Initialize a blob store on the given disk. Destroys all data present on the device. */
|
||||
@ -276,4 +282,7 @@ uint32_t spdk_xattr_names_get_count(struct spdk_xattr_names *names);
|
||||
const char *spdk_xattr_names_get_name(struct spdk_xattr_names *names, uint32_t index);
|
||||
void spdk_xattr_names_free(struct spdk_xattr_names *names);
|
||||
|
||||
struct spdk_bs_type spdk_bs_get_bstype(struct spdk_blob_store *bs);
|
||||
void spdk_bs_set_bstype(struct spdk_blob_store *bs, struct spdk_bs_type bstype);
|
||||
|
||||
#endif /* SPDK_BLOB_H_ */
|
||||
|
@ -1380,6 +1380,7 @@ spdk_bs_opts_init(struct spdk_bs_opts *opts)
|
||||
opts->num_md_pages = SPDK_BLOB_OPTS_NUM_MD_PAGES;
|
||||
opts->max_md_ops = SPDK_BLOB_OPTS_MAX_MD_OPS;
|
||||
opts->max_channel_ops = SPDK_BLOB_OPTS_MAX_CHANNEL_OPS;
|
||||
memset(&opts->bstype, 0, sizeof(opts->bstype));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1432,6 +1433,7 @@ _spdk_bs_alloc(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts)
|
||||
bs->md_target.max_md_ops = opts->max_md_ops;
|
||||
bs->io_target.max_channel_ops = opts->max_channel_ops;
|
||||
bs->super_blob = SPDK_BLOBID_INVALID;
|
||||
memcpy(&bs->bstype, &opts->bstype, sizeof(opts->bstype));
|
||||
|
||||
/* The metadata is assumed to be at least 1 page */
|
||||
bs->used_md_pages = spdk_bit_array_create(1);
|
||||
@ -1476,6 +1478,7 @@ _spdk_bs_write_super(spdk_bs_sequence_t *seq, struct spdk_blob_store *bs,
|
||||
{
|
||||
/* Update the values in the super block */
|
||||
super->super_blob = bs->super_blob;
|
||||
memcpy(&super->bstype, &bs->bstype, sizeof(bs->bstype));
|
||||
super->crc = _spdk_blob_md_page_calc_crc(super);
|
||||
spdk_bs_sequence_write(seq, super, _spdk_bs_page_to_lba(bs, 0),
|
||||
_spdk_bs_byte_to_lba(bs, sizeof(*super)),
|
||||
@ -1644,6 +1647,7 @@ _spdk_bs_load_write_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno
|
||||
ctx->bs->md_start = ctx->super->md_start;
|
||||
ctx->bs->md_len = ctx->super->md_len;
|
||||
ctx->bs->super_blob = ctx->super->super_blob;
|
||||
memcpy(&ctx->bs->bstype, &ctx->super->bstype, sizeof(ctx->super->bstype));
|
||||
|
||||
/* Read the used pages mask */
|
||||
mask_size = ctx->super->used_page_mask_len * SPDK_BS_PAGE_SIZE;
|
||||
@ -1667,8 +1671,10 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
{
|
||||
struct spdk_bs_load_ctx *ctx = cb_arg;
|
||||
uint32_t crc;
|
||||
static const char zeros[SPDK_BLOBSTORE_TYPE_LENGTH];
|
||||
|
||||
if (ctx->super->version != SPDK_BS_VERSION) {
|
||||
if (ctx->super->version > SPDK_BS_VERSION ||
|
||||
ctx->super->version < SPDK_BS_INITIAL_VERSION) {
|
||||
spdk_dma_free(ctx->super);
|
||||
_spdk_bs_free(ctx->bs);
|
||||
free(ctx);
|
||||
@ -1694,6 +1700,21 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(&ctx->bs->bstype, &ctx->super->bstype, SPDK_BLOBSTORE_TYPE_LENGTH) == 0) {
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "Bstype matched - loading blobstore\n");
|
||||
} else if (memcmp(&ctx->bs->bstype, zeros, SPDK_BLOBSTORE_TYPE_LENGTH) == 0) {
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "Bstype wildcard used - loading blobstore regardless bstype\n");
|
||||
} else {
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "Unexpected bstype\n");
|
||||
SPDK_TRACEDUMP(SPDK_TRACE_BLOB, "Expected:", ctx->bs->bstype.bstype, SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
SPDK_TRACEDUMP(SPDK_TRACE_BLOB, "Found:", ctx->super->bstype.bstype, SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_dma_free(ctx->super);
|
||||
_spdk_bs_free(ctx->bs);
|
||||
free(ctx);
|
||||
spdk_bs_sequence_finish(seq, -ENXIO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->super->clean != 1) {
|
||||
/* TODO: ONLY CLEAN SHUTDOWN IS CURRENTLY SUPPORTED.
|
||||
* All of the necessary data to recover is available
|
||||
@ -1712,7 +1733,7 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bs_load(struct spdk_bs_dev *dev,
|
||||
spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
||||
spdk_bs_op_with_handle_complete cb_fn, void *cb_arg)
|
||||
{
|
||||
struct spdk_blob_store *bs;
|
||||
@ -1723,7 +1744,16 @@ spdk_bs_load(struct spdk_bs_dev *dev,
|
||||
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "Loading blobstore from dev %p\n", dev);
|
||||
|
||||
spdk_bs_opts_init(&opts);
|
||||
if (o) {
|
||||
opts = *o;
|
||||
} else {
|
||||
spdk_bs_opts_init(&opts);
|
||||
}
|
||||
|
||||
if (opts.max_md_ops == 0 || opts.max_channel_ops == 0) {
|
||||
cb_fn(cb_arg, NULL, -EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
bs = _spdk_bs_alloc(dev, &opts);
|
||||
if (!bs) {
|
||||
@ -1884,6 +1914,7 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
||||
ctx->super->super_blob = bs->super_blob;
|
||||
ctx->super->clean = 0;
|
||||
ctx->super->cluster_size = bs->cluster_sz;
|
||||
memcpy(&ctx->super->bstype, &bs->bstype, sizeof(bs->bstype));
|
||||
|
||||
/* Calculate how many pages the metadata consumes at the front
|
||||
* of the disk.
|
||||
@ -2711,4 +2742,16 @@ spdk_xattr_names_free(struct spdk_xattr_names *names)
|
||||
free(names);
|
||||
}
|
||||
|
||||
struct spdk_bs_type
|
||||
spdk_bs_get_bstype(struct spdk_blob_store *bs)
|
||||
{
|
||||
return bs->bstype;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_bs_set_bstype(struct spdk_blob_store *bs, struct spdk_bs_type bstype)
|
||||
{
|
||||
memcpy(&bs->bstype, &bstype, sizeof(bstype));
|
||||
}
|
||||
|
||||
SPDK_LOG_REGISTER_TRACE_FLAG("blob", SPDK_TRACE_BLOB);
|
||||
|
@ -158,6 +158,7 @@ struct spdk_blob_store {
|
||||
uint32_t pages_per_cluster;
|
||||
|
||||
spdk_blob_id super_blob;
|
||||
struct spdk_bs_type bstype;
|
||||
|
||||
struct spdk_bs_cpl unload_cpl;
|
||||
int unload_err;
|
||||
@ -179,7 +180,8 @@ struct spdk_bs_channel {
|
||||
*
|
||||
* The following data structures exist on disk.
|
||||
*/
|
||||
#define SPDK_BS_VERSION 1
|
||||
#define SPDK_BS_INITIAL_VERSION 1
|
||||
#define SPDK_BS_VERSION 2 /* current version */
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
@ -259,7 +261,9 @@ struct spdk_bs_super_block {
|
||||
uint32_t md_start; /* Offset from beginning of disk, in pages */
|
||||
uint32_t md_len; /* Count, in pages */
|
||||
|
||||
uint8_t reserved[4036];
|
||||
struct spdk_bs_type bstype; /* blobstore type */
|
||||
|
||||
uint8_t reserved[4020];
|
||||
uint32_t crc;
|
||||
};
|
||||
SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block) == 0x1000, "Invalid super block size");
|
||||
|
@ -441,6 +441,7 @@ spdk_fs_init(struct spdk_bs_dev *dev, fs_send_request_fn send_request_fn,
|
||||
struct spdk_filesystem *fs;
|
||||
struct spdk_fs_request *req;
|
||||
struct spdk_fs_cb_args *args;
|
||||
struct spdk_bs_opts opts = {};
|
||||
|
||||
fs = fs_alloc(dev, send_request_fn);
|
||||
if (fs == NULL) {
|
||||
@ -465,7 +466,10 @@ spdk_fs_init(struct spdk_bs_dev *dev, fs_send_request_fn send_request_fn,
|
||||
args->arg = cb_arg;
|
||||
args->fs = fs;
|
||||
|
||||
spdk_bs_init(dev, NULL, init_cb, req);
|
||||
spdk_bs_opts_init(&opts);
|
||||
strncpy(opts.bstype.bstype, "BLOBFS", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
|
||||
spdk_bs_init(dev, &opts, init_cb, req);
|
||||
}
|
||||
|
||||
static struct spdk_file *
|
||||
@ -609,6 +613,9 @@ load_cb(void *ctx, struct spdk_blob_store *bs, int bserrno)
|
||||
struct spdk_fs_request *req = ctx;
|
||||
struct spdk_fs_cb_args *args = &req->args;
|
||||
struct spdk_filesystem *fs = args->fs;
|
||||
struct spdk_bs_type bstype;
|
||||
static const char blobfs_type[SPDK_BLOBSTORE_TYPE_LENGTH] = {"BLOBFS"};
|
||||
static const char zeros[SPDK_BLOBSTORE_TYPE_LENGTH];
|
||||
|
||||
if (bserrno != 0) {
|
||||
args->fn.fs_op_with_handle(args->arg, NULL, bserrno);
|
||||
@ -617,6 +624,20 @@ load_cb(void *ctx, struct spdk_blob_store *bs, int bserrno)
|
||||
return;
|
||||
}
|
||||
|
||||
bstype = spdk_bs_get_bstype(bs);
|
||||
|
||||
if (!memcmp(&bstype, zeros, SPDK_BLOBSTORE_TYPE_LENGTH)) {
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "assigning bstype");
|
||||
snprintf(bstype.bstype, SPDK_BLOBSTORE_TYPE_LENGTH, blobfs_type);
|
||||
spdk_bs_set_bstype(bs, bstype);
|
||||
} else if (strncmp(bstype.bstype, blobfs_type, SPDK_BLOBSTORE_TYPE_LENGTH)) {
|
||||
SPDK_DEBUGLOG(SPDK_TRACE_BLOB, "not blobfs: %s", bstype.bstype);
|
||||
args->fn.fs_op_with_handle(args->arg, NULL, bserrno);
|
||||
free_fs_request(req);
|
||||
free(fs);
|
||||
return;
|
||||
}
|
||||
|
||||
common_fs_bs_init(fs, bs);
|
||||
spdk_bs_md_iter_first(fs->bs, iter_cb, req);
|
||||
}
|
||||
@ -628,6 +649,7 @@ spdk_fs_load(struct spdk_bs_dev *dev, fs_send_request_fn send_request_fn,
|
||||
struct spdk_filesystem *fs;
|
||||
struct spdk_fs_cb_args *args;
|
||||
struct spdk_fs_request *req;
|
||||
struct spdk_bs_opts opts = {};
|
||||
|
||||
fs = fs_alloc(dev, send_request_fn);
|
||||
if (fs == NULL) {
|
||||
@ -652,7 +674,10 @@ spdk_fs_load(struct spdk_bs_dev *dev, fs_send_request_fn send_request_fn,
|
||||
args->arg = cb_arg;
|
||||
args->fs = fs;
|
||||
TAILQ_INIT(&args->op.fs_load.deleted_files);
|
||||
spdk_bs_load(dev, load_cb, req);
|
||||
|
||||
spdk_bs_opts_init(&opts);
|
||||
|
||||
spdk_bs_load(dev, &opts, load_cb, req);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -59,6 +59,29 @@ struct scheduled_ops {
|
||||
|
||||
static TAILQ_HEAD(, scheduled_ops) g_scheduled_ops = TAILQ_HEAD_INITIALIZER(g_scheduled_ops);
|
||||
|
||||
struct spdk_bs_super_block_ver1 {
|
||||
uint8_t signature[8];
|
||||
uint32_t version;
|
||||
uint32_t length;
|
||||
uint32_t clean; /* If there was a clean shutdown, this is 1. */
|
||||
spdk_blob_id super_blob;
|
||||
|
||||
uint32_t cluster_size; /* In bytes */
|
||||
|
||||
uint32_t used_page_mask_start; /* Offset from beginning of disk, in pages */
|
||||
uint32_t used_page_mask_len; /* Count, in pages */
|
||||
|
||||
uint32_t used_cluster_mask_start; /* Offset from beginning of disk, in pages */
|
||||
uint32_t used_cluster_mask_len; /* Count, in pages */
|
||||
|
||||
uint32_t md_start; /* Offset from beginning of disk, in pages */
|
||||
uint32_t md_len; /* Count, in pages */
|
||||
|
||||
uint8_t reserved[4036];
|
||||
uint32_t crc;
|
||||
} __attribute__((packed));
|
||||
SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block_ver1) == 0x1000, "Invalid super block size");
|
||||
|
||||
static void
|
||||
_bs_send_msg(spdk_thread_fn fn, void *ctx, void *thread_ctx)
|
||||
{
|
||||
@ -842,16 +865,21 @@ bs_load(void)
|
||||
struct spdk_bs_dev *dev;
|
||||
spdk_blob_id blobid;
|
||||
struct spdk_blob *blob;
|
||||
struct spdk_bs_super_block *super_blob;
|
||||
struct spdk_bs_super_block *super_block;
|
||||
uint64_t length;
|
||||
int rc;
|
||||
const void *value;
|
||||
size_t value_len;
|
||||
struct spdk_bs_opts opts;
|
||||
|
||||
g_scheduler_delay = true;
|
||||
|
||||
dev = init_dev();
|
||||
spdk_bs_opts_init(&opts);
|
||||
strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
|
||||
/* Initialize a new blob store */
|
||||
spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
|
||||
spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
@ -901,16 +929,19 @@ bs_load(void)
|
||||
g_blob = NULL;
|
||||
g_blobid = 0;
|
||||
|
||||
super_blob = (struct spdk_bs_super_block *)g_dev_buffer;
|
||||
CU_ASSERT(super_blob->clean == 1);
|
||||
dev = init_dev();
|
||||
super_block = (struct spdk_bs_super_block *)g_dev_buffer;
|
||||
CU_ASSERT(super_block->clean == 1);
|
||||
|
||||
|
||||
/* Load an existing blob store */
|
||||
spdk_bs_load(dev, bs_op_with_handle_complete, NULL);
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
super_blob = (struct spdk_bs_super_block *)g_dev_buffer;
|
||||
CU_ASSERT(super_blob->clean == 0);
|
||||
super_block = (struct spdk_bs_super_block *)g_dev_buffer;
|
||||
CU_ASSERT(super_block->clean == 0);
|
||||
|
||||
spdk_bs_md_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
@ -939,6 +970,139 @@ bs_load(void)
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
g_scheduler_delay = false;
|
||||
}
|
||||
|
||||
static void
|
||||
bs_type(void)
|
||||
{
|
||||
struct spdk_bs_dev *dev;
|
||||
struct spdk_bs_opts opts;
|
||||
|
||||
g_scheduler_delay = true;
|
||||
|
||||
dev = init_dev();
|
||||
spdk_bs_opts_init(&opts);
|
||||
strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
|
||||
/* Initialize a new blob store */
|
||||
spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
/* Unload the blob store */
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
g_blob = NULL;
|
||||
g_blobid = 0;
|
||||
|
||||
/* Load non existing blobstore type */
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
/* Load with empty blobstore type */
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
|
||||
/* Initialize a new blob store with empty bstype */
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
|
||||
/* Load non existing blobstore type */
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "NONEXISTING", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
/* Load with empty blobstore type */
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
g_scheduler_delay = false;
|
||||
}
|
||||
|
||||
static void
|
||||
bs_super_block(void)
|
||||
{
|
||||
struct spdk_bs_dev *dev;
|
||||
struct spdk_bs_super_block *super_block;
|
||||
struct spdk_bs_opts opts;
|
||||
struct spdk_bs_super_block_ver1 super_block_v1;
|
||||
|
||||
g_scheduler_delay = true;
|
||||
|
||||
dev = init_dev();
|
||||
spdk_bs_opts_init(&opts);
|
||||
strncpy(opts.bstype.bstype, "TESTTYPE", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
|
||||
/* Initialize a new blob store */
|
||||
spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
/* Unload the blob store */
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
g_blob = NULL;
|
||||
g_blobid = 0;
|
||||
|
||||
/* Load an existing blob store with version newer than supported */
|
||||
super_block = (struct spdk_bs_super_block *)g_dev_buffer;
|
||||
super_block->version++;
|
||||
|
||||
dev = init_dev();
|
||||
strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno != 0);
|
||||
|
||||
/* Create a new blob store with super block version 1 */
|
||||
dev = init_dev();
|
||||
super_block_v1.version = 1;
|
||||
strncpy(super_block_v1.signature, "SPDKBLOB", sizeof(super_block_v1.signature));
|
||||
super_block_v1.length = 0x1000;
|
||||
super_block_v1.clean = 1;
|
||||
super_block_v1.super_blob = 0xFFFFFFFFFFFFFFFF;
|
||||
super_block_v1.cluster_size = 0x100000;
|
||||
super_block_v1.used_page_mask_start = 0x01;
|
||||
super_block_v1.used_page_mask_len = 0x01;
|
||||
super_block_v1.used_cluster_mask_start = 0x02;
|
||||
super_block_v1.used_cluster_mask_len = 0x01;
|
||||
super_block_v1.md_start = 0x03;
|
||||
super_block_v1.md_len = 0x40;
|
||||
memset(super_block_v1.reserved, 0, 4036);
|
||||
super_block_v1.crc = _spdk_blob_md_page_calc_crc(&super_block_v1);
|
||||
memcpy(g_dev_buffer, &super_block_v1, sizeof(struct spdk_bs_super_block_ver1));
|
||||
|
||||
strncpy(opts.bstype.bstype, "", SPDK_BLOBSTORE_TYPE_LENGTH);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
|
||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
g_bs = NULL;
|
||||
g_scheduler_delay = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1017,7 +1181,7 @@ bs_cluster_sz(void)
|
||||
|
||||
dev = init_dev();
|
||||
/* Load an existing blob store */
|
||||
spdk_bs_load(dev, bs_op_with_handle_complete, NULL);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
@ -1077,7 +1241,7 @@ bs_resize_md(void)
|
||||
g_bserrno = -1;
|
||||
g_bs = NULL;
|
||||
dev = init_dev();
|
||||
spdk_bs_load(dev, bs_op_with_handle_complete, NULL);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
|
||||
@ -1178,7 +1342,7 @@ blob_serialize(void)
|
||||
|
||||
dev = init_dev();
|
||||
/* Load an existing blob store */
|
||||
spdk_bs_load(dev, bs_op_with_handle_complete, NULL);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
|
||||
bs = g_bs;
|
||||
@ -1257,8 +1421,10 @@ super_block_crc(void)
|
||||
{
|
||||
struct spdk_bs_dev *dev;
|
||||
struct spdk_bs_super_block *super_block;
|
||||
struct spdk_bs_opts opts;
|
||||
|
||||
dev = init_dev();
|
||||
spdk_bs_opts_init(&opts);
|
||||
|
||||
spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(g_bserrno == 0);
|
||||
@ -1274,7 +1440,7 @@ super_block_crc(void)
|
||||
|
||||
g_scheduler_delay = true;
|
||||
/* Load an existing blob store */
|
||||
spdk_bs_load(dev, bs_op_with_handle_complete, NULL);
|
||||
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
|
||||
|
||||
CU_ASSERT(g_bserrno == -EILSEQ);
|
||||
_bs_flush_scheduler();
|
||||
@ -1316,6 +1482,8 @@ int main(int argc, char **argv)
|
||||
CU_add_test(suite, "bs_unload", bs_unload) == 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, "bs_type", bs_type) == NULL ||
|
||||
CU_add_test(suite, "bs_super_block", bs_super_block) == NULL ||
|
||||
CU_add_test(suite, "blob_serialize", blob_serialize) == NULL ||
|
||||
CU_add_test(suite, "blob_crc", blob_crc) == NULL ||
|
||||
CU_add_test(suite, "super_block_crc", super_block_crc) == NULL
|
||||
|
Loading…
x
Reference in New Issue
Block a user