Commit 3de9887d authored by Ziye Yang's avatar Ziye Yang Committed by Tomasz Zawadzki
Browse files

blob: Make the ABI compatibility for spdk_bs_opts



The purpose of this patch is to make spdk_bs_opts
for compatiblity issue.

Signed-off-by: default avatarZiye Yang <ziye.yang@intel.com>
Change-Id: I26d2a6bc644feede64d48890c7903f224b1fc306
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5681


Community-CI: Broadcom CI
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 304fde15
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -10,6 +10,12 @@ parameter in spdk_bdev_get_opts function. Two fields `small_buf_pool_size` and
`large_buf_pool_size` were added into spdk_bdev_opts, which were used to determine
the small and large buffer pool size of the whole bdev module.

### blob

An `opts_size` element was added in the `spdk_bs_opts` structure to solve the
ABI compatiblity issue between different SPDK version. And also add `opts_size`
parameter in `spdk_bs_opts_init` function.

### event

The pci_whitelist and pci_blacklist members of struct spdk_app_opts have been
+10 −1
Original line number Diff line number Diff line
@@ -225,14 +225,23 @@ struct spdk_bs_opts {

	/** Argument passed to iter_cb_fn for each blob. */
	void *iter_cb_arg;

	/**
	 * The size of spdk_bs_opts according to the caller of this library is used for ABI
	 * compatibility. The library uses this field to know how many fields in this
	 * structure are valid. And the library will populate any remaining fields with default values.
	 * After that, new added fields should be put in the end of the struct.
	 */
	size_t opts_size;
};

/**
 * Initialize a spdk_bs_opts structure to the default blobstore option values.
 *
 * \param opts The spdk_bs_opts structure to be initialized.
 * \param opts_size The opts_size must be the size of spdk_bs_opts structure.
 */
void spdk_bs_opts_init(struct spdk_bs_opts *opts);
void spdk_bs_opts_init(struct spdk_bs_opts *opts, size_t opts_size);

/**
 * Load a blobstore from the given device.
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 3
SO_VER := 4
SO_MINOR := 0

C_SRCS = blobstore.c request.c zeroes.c blob_bs_dev.c
+88 −16
Original line number Diff line number Diff line
@@ -3131,16 +3131,45 @@ bs_free(struct spdk_blob_store *bs)
}

void
spdk_bs_opts_init(struct spdk_bs_opts *opts)
spdk_bs_opts_init(struct spdk_bs_opts *opts, size_t opts_size)
{
	opts->cluster_sz = SPDK_BLOB_OPTS_CLUSTER_SZ;
	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_DEFAULT_CHANNEL_OPS;
	opts->clear_method = BS_CLEAR_WITH_UNMAP;

	if (!opts) {
		SPDK_ERRLOG("opts should not be NULL\n");
		return;
	}

	if (!opts_size) {
		SPDK_ERRLOG("opts_size should not be zero value\n");
		return;
	}

	memset(opts, 0, opts_size);
	opts->opts_size = opts_size;

#define FIELD_OK(field) \
	offsetof(struct spdk_bs_opts, field) + sizeof(opts->field) <= opts_size

#define SET_FIELD(field, value) \
	if (FIELD_OK(field)) { \
		opts->field = value; \
	} \

	SET_FIELD(cluster_sz, SPDK_BLOB_OPTS_CLUSTER_SZ);
	SET_FIELD(num_md_pages, SPDK_BLOB_OPTS_NUM_MD_PAGES);
	SET_FIELD(max_md_ops, SPDK_BLOB_OPTS_NUM_MD_PAGES);
	SET_FIELD(max_channel_ops, SPDK_BLOB_OPTS_DEFAULT_CHANNEL_OPS);
	SET_FIELD(clear_method,  BS_CLEAR_WITH_UNMAP);

	if (FIELD_OK(bstype)) {
		memset(&opts->bstype, 0, sizeof(opts->bstype));
	opts->iter_cb_fn = NULL;
	opts->iter_cb_arg = NULL;
	}

	SET_FIELD(iter_cb_fn, NULL);
	SET_FIELD(iter_cb_arg, NULL);

#undef FIELD_OK
#undef SET_FIELD
}

static int
@@ -4271,6 +4300,47 @@ bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
	}
}

static int
bs_opts_copy(struct spdk_bs_opts *src, struct spdk_bs_opts *dst)
{

	if (!src->opts_size) {
		SPDK_ERRLOG("opts_size should not be zero value\n");
		return -1;
	}

#define FIELD_OK(field) \
        offsetof(struct spdk_bs_opts, field) + sizeof(src->field) <= src->opts_size

#define SET_FIELD(field) \
        if (FIELD_OK(field)) { \
                dst->field = src->field; \
        } \

	SET_FIELD(cluster_sz);
	SET_FIELD(num_md_pages);
	SET_FIELD(max_md_ops);
	SET_FIELD(max_channel_ops);
	SET_FIELD(clear_method);

	if (FIELD_OK(bstype)) {
		memcpy(&dst->bstype, &src->bstype, sizeof(dst->bstype));
	}
	SET_FIELD(iter_cb_fn);
	SET_FIELD(iter_cb_arg);

	dst->opts_size = src->opts_size;

	/* You should not remove this statement, but need to update the assert statement
	 * if you add a new field, and also add a corresponding SET_FIELD statement */
	SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_opts) == 64, "Incorrect size");

#undef FIELD_OK
#undef SET_FIELD

	return 0;
}

void
spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
	     spdk_bs_op_with_handle_complete cb_fn, void *cb_arg)
@@ -4290,10 +4360,11 @@ spdk_bs_load(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
		return;
	}

	spdk_bs_opts_init(&opts, sizeof(opts));
	if (o) {
		opts = *o;
	} else {
		spdk_bs_opts_init(&opts);
		if (bs_opts_copy(o, &opts)) {
			return;
		}
	}

	if (opts.max_md_ops == 0 || opts.max_channel_ops == 0) {
@@ -4549,7 +4620,7 @@ spdk_bs_dump(struct spdk_bs_dev *dev, FILE *fp, spdk_bs_dump_print_xattr print_x

	SPDK_DEBUGLOG(blob, "Dumping blobstore from dev %p\n", dev);

	spdk_bs_opts_init(&opts);
	spdk_bs_opts_init(&opts, sizeof(opts));

	err = bs_alloc(dev, &opts, &bs, &ctx);
	if (err) {
@@ -4634,10 +4705,11 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
		return;
	}

	spdk_bs_opts_init(&opts, sizeof(opts));
	if (o) {
		opts = *o;
	} else {
		spdk_bs_opts_init(&opts);
		if (bs_opts_copy(o, &opts)) {
			return;
		}
	}

	if (bs_opts_verify(&opts) != 0) {
+2 −2
Original line number Diff line number Diff line
@@ -623,7 +623,7 @@ spdk_fs_init(struct spdk_bs_dev *dev, struct spdk_blobfs_opts *opt,
	args->arg = cb_arg;
	args->fs = fs;

	spdk_bs_opts_init(&opts);
	spdk_bs_opts_init(&opts, sizeof(opts));
	snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), SPDK_BLOBFS_SIGNATURE);
	if (opt) {
		opts.cluster_sz = opt->cluster_sz;
@@ -865,7 +865,7 @@ 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_opts_init(&bs_opts);
	spdk_bs_opts_init(&bs_opts, sizeof(bs_opts));
	bs_opts.iter_cb_fn = iter_cb;
	bs_opts.iter_cb_arg = req;
	spdk_bs_load(dev, &bs_opts, load_cb, req);
Loading