Commit eb8b1e20 authored by Maciej Szwed's avatar Maciej Szwed Committed by Jim Harris
Browse files

blobstore: add bstype to blobstore super block



Introducing bstype as a way to identify and verify
 blobstore type.

Signed-off-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Change-Id: I50267b5408625be10fe0c146ae329016d5509b4a
Reviewed-on: https://review.gerrithub.io/380476


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent 1a15ce9b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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);
}

/*
+10 −1
Original line number Diff line number Diff line
@@ -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_ */
+46 −3
Original line number Diff line number Diff line
@@ -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);

	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);
+6 −2
Original line number Diff line number Diff line
@@ -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");
Loading