Commit 6cb9c75c authored by Anton Nayshtut's avatar Anton Nayshtut Committed by Konrad Sztyber
Browse files

lib/fsdev: mount and umount API introduced



This patch introduces SPDK fsdev spdk_fsdev_mount and spdk_fsdev_umount
APIs, the SPDK fsdev analogues of FUSE_INIT and FUSE_DESTROY.

The corresponding fsdev module handlers are optional (as any other),
however failing the INIT handler will fail the FUSE_INIT and therefore
the host's mount.

The spdk_fsdev_open() API doesn't get the open_opts parameter anymore.
It became mount_opts now.

Change-Id: I316a31f6999b9fabe6cee51c87fdd0e6e49ed569
Signed-off-by: default avatarAnton Nayshtut <anayshtut@nvidia.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/25009


Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
parent d00039db
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -533,7 +533,7 @@ hello_start(void *arg1)
	 */
	SPDK_NOTICELOG("Opening the fsdev %s\n", hello_context->fsdev_name);
	rc = spdk_fsdev_open(hello_context->fsdev_name,
			     hello_fsdev_event_cb, NULL, NULL,
			     hello_fsdev_event_cb, NULL,
			     &hello_context->fsdev_desc);
	if (rc) {
		SPDK_ERRLOG("Could not open fsdev: %s\n", hello_context->fsdev_name);
+66 −6
Original line number Diff line number Diff line
@@ -72,10 +72,10 @@ struct spdk_fsdev_opts {
} __attribute__((packed));
SPDK_STATIC_ASSERT(sizeof(struct spdk_fsdev_opts) == 12, "Incorrect size");

/** fsdev device options */
struct spdk_fsdev_open_opts {
/** fsdev mount options */
struct spdk_fsdev_mount_opts {
	/**
	 * The size of spdk_fsdev_open_opts according to the caller of this library is used for ABI
	 * The size of spdk_fsdev_mount_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.
	 * New added fields should be put at the end of the struct.
@@ -99,7 +99,7 @@ struct spdk_fsdev_open_opts {
	uint8_t writeback_cache_enabled;

} __attribute__((packed));
SPDK_STATIC_ASSERT(sizeof(struct spdk_fsdev_open_opts) == 9, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_fsdev_mount_opts) == 9, "Incorrect size");

/**
 * Structure with optional fsdev IO parameters
@@ -180,12 +180,11 @@ const char *spdk_fsdev_get_module_name(const struct spdk_fsdev *fsdev);
 * the descriptor will have to be manually closed to make the fsdev unregister
 * proceed.
 * \param event_ctx param for event_cb.
 * \param opts optional open opts.
 * \param desc output parameter for the descriptor when operation is successful
 * \return 0 if operation is successful, suitable errno value otherwise
 */
int spdk_fsdev_open(const char *fsdev_name, spdk_fsdev_event_cb_t event_cb,
		    void *event_ctx, struct spdk_fsdev_open_opts *opts, struct spdk_fsdev_desc **desc);
		    void *event_ctx, struct spdk_fsdev_desc **desc);

/**
 * Close a previously opened filesystem device.
@@ -306,6 +305,67 @@ struct spdk_fsdev_file_statfs {
	uint32_t frsize;
};

/**
 * Mount operation completion callback.
 *
 * \param cb_arg Context passed to the corresponding spdk_fsdev_ API
 * \param ch I/O channel.
 * \param status Operation status, 0 on success or error code otherwise.
 * \param opts Result options.
 * \param root_fobject Root file object
 */
typedef void (spdk_fsdev_mount_cpl_cb)(void *cb_arg, struct spdk_io_channel *ch, int status,
				       const struct spdk_fsdev_mount_opts *opts,
				       struct spdk_fsdev_file_object *root_fobject);

/**
 * Mount the filesystem.
 *
 * \param desc Filesystem device descriptor.
 * \param ch I/O channel.
 * \param unique Unique I/O id.
 * \param opts Requested options.
 * \param cb_fn Completion callback.
 * \param cb_arg Context to be passed to the completion callback.
 *
 * \return 0 on success. On success, the callback will always
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 *
 * Note: the \p opts are the subject of negotiation. An API user provides a desired \p opts here
 * and gets a result \p opts in the \p cb_fn. The result \p opts are filled by the underlying
 * fsdev module which may agree or reduce (but not expand) the desired features set.
 */
int spdk_fsdev_mount(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch,
		     uint64_t unique, const struct spdk_fsdev_mount_opts *opts,
		     spdk_fsdev_mount_cpl_cb cb_fn, void *cb_arg);

/**
 * Umount operation completion callback.
 *
 * \param cb_arg Context passed to the corresponding spdk_fsdev_ API
 * \param ch I/O channel.
 */
typedef void (spdk_fsdev_umount_cpl_cb)(void *cb_arg, struct spdk_io_channel *ch);

/**
 * Unmount the filesystem.
 *
 * \param desc Filesystem device descriptor.
 * \param ch I/O channel.
 * \param unique Unique I/O id.
 * \param cb_fn Completion callback.
 * \param cb_arg Context to be passed to the completion callback.
 *
 * \return 0 on success. On success, the callback will always
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 *
 * NOTE: on unmount the lookup count for all fobjects implicitly drops to zero.
 */
int spdk_fsdev_umount(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch,
		      uint64_t unique, spdk_fsdev_umount_cpl_cb cb_fn, void *cb_arg);

/**
 * Lookup file operation completion callback
 *
+9 −13
Original line number Diff line number Diff line
@@ -93,16 +93,6 @@ struct spdk_fsdev_fn_table {
	/** Get an I/O channel for the specific fsdev for the calling thread. */
	struct spdk_io_channel *(*get_io_channel)(void *ctx);

	/**
	 * Negotiate fsdev device options.
	 *
	 * The function validates the desired options and adjust them to reflect it own capabilities.
	 * The module can only reduce the requested cababilities.
	 *
	 * \return 0 on success or Fsdev specific negative error code.
	 */
	int (*negotiate_opts)(void *ctx, struct spdk_fsdev_open_opts *opts);

	/**
	 * Output fsdev-specific RPC configuration to a JSON stream. Optional - may be NULL.
	 *
@@ -158,9 +148,6 @@ struct spdk_fsdev {
	/** function table for all ops */
	const struct spdk_fsdev_fn_table *fn_table;

	/** Negotiable device ops */
	struct spdk_fsdev_open_opts opts;

	/** Fields that are used internally by the fsdev subsystem. Fsdev modules
	 *  must not read or write to these fields.
	 */
@@ -188,6 +175,8 @@ struct spdk_fsdev {
};

enum spdk_fsdev_io_type {
	SPDK_FSDEV_IO_MOUNT,
	SPDK_FSDEV_IO_UMOUNT,
	SPDK_FSDEV_IO_LOOKUP,
	SPDK_FSDEV_IO_FORGET,
	SPDK_FSDEV_IO_GETATTR,
@@ -234,6 +223,9 @@ struct spdk_fsdev_io {
	struct iovec iov;

	union {
		struct {
			struct spdk_fsdev_mount_opts opts;
		} mount;
		struct {
			struct spdk_fsdev_file_object *parent_fobject;
			char *name;
@@ -416,6 +408,10 @@ struct spdk_fsdev_io {
	} u_in;

	union {
		struct {
			struct spdk_fsdev_mount_opts opts;
			struct spdk_fsdev_file_object *root_fobject;
		} mount;
		struct {
			struct spdk_fsdev_file_object *fobject;
			struct spdk_fsdev_file_attr attr;
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk

SO_VER := 1
SO_VER := 2
SO_MINOR := 0

C_SRCS = fsdev.c fsdev_io.c fsdev_rpc.c
+3 −53
Original line number Diff line number Diff line
@@ -697,45 +697,6 @@ spdk_fsdev_get_opts(struct spdk_fsdev_opts *opts, size_t opts_size)
	return 0;
}

static int
fsdev_set_open_opts(struct spdk_fsdev *fsdev, struct spdk_fsdev_open_opts *opts)
{
	int res;

	assert(opts);

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

	if (!fsdev->fn_table->negotiate_opts) {
		SPDK_ERRLOG("negotiate_opts is NULL for %s\n", spdk_fsdev_get_name(fsdev));
		return -ENOTSUP;
	}

	res = fsdev->fn_table->negotiate_opts(fsdev->ctxt, opts);
	if (res) {
		SPDK_ERRLOG("negotiate_opts failed with %d for %s\n", res, spdk_fsdev_get_name(fsdev));
		return res;
	}

#define SET_FIELD(field) \
	if (offsetof(struct spdk_fsdev_open_opts, field) + sizeof(opts->field) <= opts->opts_size) { \
		fsdev->opts.field = opts->field; \
	}

	SET_FIELD(writeback_cache_enabled);
	SET_FIELD(max_write);

	/* Do not remove this statement, you should always update this statement when you adding a new field,
		* and do not forget to add the SET_FIELD statement for your added field. */
	SPDK_STATIC_ASSERT(sizeof(struct spdk_fsdev_open_opts) == 9, "Incorrect size");
#undef SET_FIELD

	return 0;
}

int
spdk_fsdev_get_memory_domains(struct spdk_fsdev *fsdev, struct spdk_memory_domain **domains,
			      int array_size)
@@ -1027,7 +988,7 @@ spdk_fsdev_unregister_by_name(const char *fsdev_name, struct spdk_fsdev_module *
	struct spdk_fsdev *fsdev;
	int rc;

	rc = spdk_fsdev_open(fsdev_name, _tmp_fsdev_event_cb, NULL, NULL, &desc);
	rc = spdk_fsdev_open(fsdev_name, _tmp_fsdev_event_cb, NULL, &desc);
	if (rc != 0) {
		SPDK_ERRLOG("Failed to open fsdev with name: %s\n", fsdev_name);
		return rc;
@@ -1097,8 +1058,8 @@ fsdev_desc_alloc(struct spdk_fsdev *fsdev, spdk_fsdev_event_cb_t event_cb, void
}

int
spdk_fsdev_open(const char *fsdev_name, spdk_fsdev_event_cb_t event_cb,
		void *event_ctx, struct spdk_fsdev_open_opts *opts, struct spdk_fsdev_desc **_desc)
spdk_fsdev_open(const char *fsdev_name, spdk_fsdev_event_cb_t event_cb, void *event_ctx,
		struct spdk_fsdev_desc **_desc)
{
	struct spdk_fsdev_desc *desc;
	struct spdk_fsdev *fsdev;
@@ -1124,17 +1085,6 @@ spdk_fsdev_open(const char *fsdev_name, spdk_fsdev_event_cb_t event_cb,
		return rc;
	}

	if (opts) {
		rc = fsdev_set_open_opts(fsdev, opts);
		if (rc != 0) {
			SPDK_NOTICELOG("%s: fsdev_set_open_opts failed with %d\n", fsdev_name, rc);
			fsdev_desc_free(desc);
			*_desc = NULL;
			spdk_spin_unlock(&g_fsdev_mgr.spinlock);
			return rc;
		}
	}

	rc = fsdev_open(fsdev, desc);
	if (rc != 0) {
		fsdev_desc_free(desc);
Loading