numam-spdk/include/spdk/blob.h
Mike Gerdts a6c5feb0a2 blob: add forced recovery
Add the ability to open a blobstore in such a way that recovery happens
even if the superblock says it is clean.

Signed-off-by: Mike Gerdts <mgerdts@nvidia.com>
Change-Id: I475e51beff24428d387446f7785e025294d2f014
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/11253
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
2022-02-03 20:07:58 +00:00

945 lines
31 KiB
C

/*-
* BSD LICENSE
*
* Copyright (c) Intel Corporation.
* All rights reserved.
* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** \file
* Blob Storage System
*
* The blob storage system, or the blobstore for short, is a low level
* library for placing opaque blobs of data onto a storage device such
* that scattered physical blocks on the storage device appear as a
* single, contiguous storage region. These blobs are also persistent,
* which means they are rediscoverable after reboot or power loss.
*
* The blobstore is designed to be very high performance, and thus has
* a few general rules regarding thread safety to avoid taking locks
* in the I/O path. This is primarily done by only allowing most
* functions to be called on the metadata thread. The metadata thread is
* the thread which called spdk_bs_init() or spdk_bs_load().
*
* Functions starting with the prefix "spdk_blob_io" are passed a channel
* as an argument, and channels may only be used from the thread they were
* created on. See \ref spdk_bs_alloc_io_channel. These are the only
* functions that may be called from a thread other than the metadata
* thread.
*
* The blobstore returns errors using negated POSIX errno values, either
* returned in the callback or as a return value. An errno value of 0 means
* success.
*/
#ifndef SPDK_BLOB_H
#define SPDK_BLOB_H
#include "spdk/stdinc.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef uint64_t spdk_blob_id;
#define SPDK_BLOBID_INVALID (uint64_t)-1
#define SPDK_BLOBSTORE_TYPE_LENGTH 16
enum blob_clear_method {
BLOB_CLEAR_WITH_DEFAULT,
BLOB_CLEAR_WITH_NONE,
BLOB_CLEAR_WITH_UNMAP,
BLOB_CLEAR_WITH_WRITE_ZEROES,
};
enum bs_clear_method {
BS_CLEAR_WITH_UNMAP,
BS_CLEAR_WITH_WRITE_ZEROES,
BS_CLEAR_WITH_NONE,
};
struct spdk_blob_store;
struct spdk_io_channel;
struct spdk_blob;
struct spdk_xattr_names;
/**
* Blobstore operation completion callback.
*
* \param cb_arg Callback argument.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
*/
typedef void (*spdk_bs_op_complete)(void *cb_arg, int bserrno);
/**
* Blobstore operation completion callback with handle.
*
* \param cb_arg Callback argument.
* \param bs Handle to a blobstore.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
*/
typedef void (*spdk_bs_op_with_handle_complete)(void *cb_arg, struct spdk_blob_store *bs,
int bserrno);
/**
* Blob operation completion callback.
*
* \param cb_arg Callback argument.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
*/
typedef void (*spdk_blob_op_complete)(void *cb_arg, int bserrno);
/**
* Blob operation completion callback with blob ID.
*
* \param cb_arg Callback argument.
* \param blobid Blob ID.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
*/
typedef void (*spdk_blob_op_with_id_complete)(void *cb_arg, spdk_blob_id blobid, int bserrno);
/**
* Blob operation completion callback with handle.
*
* \param cb_arg Callback argument.
* \param blb Handle to a blob.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
*/
typedef void (*spdk_blob_op_with_handle_complete)(void *cb_arg, struct spdk_blob *blb, int bserrno);
/**
* Blobstore device completion callback.
*
* \param channel I/O channel the operation was initiated on.
* \param cb_arg Callback argument.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
*/
typedef void (*spdk_bs_dev_cpl)(struct spdk_io_channel *channel,
void *cb_arg, int bserrno);
struct spdk_bs_dev_cb_args {
spdk_bs_dev_cpl cb_fn;
struct spdk_io_channel *channel;
void *cb_arg;
};
struct spdk_bs_dev {
/* Create a new channel which is a software construct that is used
* to submit I/O. */
struct spdk_io_channel *(*create_channel)(struct spdk_bs_dev *dev);
/* Destroy a previously created channel */
void (*destroy_channel)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel);
/* Destroy this blobstore device. Applications must not destroy the blobstore device,
* rather the blobstore will destroy it using this function pointer once all
* references to it during unload callback context have been completed.
*/
void (*destroy)(struct spdk_bs_dev *dev);
void (*read)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
void (*write)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
void (*readv)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
void (*writev)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
void (*flush)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct spdk_bs_dev_cb_args *cb_args);
void (*write_zeroes)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
uint64_t lba, uint64_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
void (*unmap)(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
uint64_t lba, uint64_t lba_count,
struct spdk_bs_dev_cb_args *cb_args);
struct spdk_bdev *(*get_base_bdev)(struct spdk_bs_dev *dev);
uint64_t blockcnt;
uint32_t blocklen; /* In bytes */
};
struct spdk_bs_type {
char bstype[SPDK_BLOBSTORE_TYPE_LENGTH];
};
struct spdk_bs_opts {
/** Size of cluster in bytes. Must be multiple of 4KiB page size. */
uint32_t cluster_sz;
/** Count of the number of pages reserved for metadata */
uint32_t num_md_pages;
/** Maximum simultaneous metadata operations */
uint32_t max_md_ops;
/** Maximum simultaneous operations per channel */
uint32_t max_channel_ops;
/** Clear method */
enum bs_clear_method clear_method;
/** Blobstore type */
struct spdk_bs_type bstype;
/** Callback function to invoke for each blob. */
spdk_blob_op_with_handle_complete iter_cb_fn;
/** 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;
/** Force recovery during import. This is a uint64_t for padding reasons, treated as a bool. */
uint64_t force_recover;
};
/**
* 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, size_t opts_size);
/**
* Load a blobstore from the given device.
*
* \param dev Blobstore block device.
* \param opts The structure which contains the option values for the blobstore.
* \param cb_fn Called when the loading is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
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 blobstore on the given device.
*
* \param dev Blobstore block device.
* \param opts The structure which contains the option values for the blobstore.
* \param cb_fn Called when the initialization is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts,
spdk_bs_op_with_handle_complete cb_fn, void *cb_arg);
typedef void (*spdk_bs_dump_print_xattr)(FILE *fp, const char *bstype, const char *name,
const void *value, size_t value_length);
/**
* Dump a blobstore's metadata to a given FILE in human-readable format.
*
* \param dev Blobstore block device.
* \param fp FILE pointer to dump the metadata contents.
* \param print_xattr_fn Callback function to interpret external xattrs.
* \param cb_fn Called when the dump is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_dump(struct spdk_bs_dev *dev, FILE *fp, spdk_bs_dump_print_xattr print_xattr_fn,
spdk_bs_op_complete cb_fn, void *cb_arg);
/**
* Destroy the blobstore.
*
* It will destroy the blobstore by zeroing the super block.
*
* \param bs blobstore to destroy.
* \param cb_fn Called when the destruction is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_destroy(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn,
void *cb_arg);
/**
* Unload the blobstore.
*
* It will flush all volatile data to disk.
*
* \param bs blobstore to unload.
* \param cb_fn Called when the unloading is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_arg);
/**
* Set a super blob on the given blobstore.
*
* This will be retrievable immediately after spdk_bs_load() on the next initialization.
*
* \param bs blobstore.
* \param blobid The id of the blob which will be set as the super blob.
* \param cb_fn Called when the setting is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_set_super(struct spdk_blob_store *bs, spdk_blob_id blobid,
spdk_bs_op_complete cb_fn, void *cb_arg);
/**
* Get the super blob. The obtained blob id will be passed to the callback function.
*
* \param bs blobstore.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_get_super(struct spdk_blob_store *bs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg);
/**
* Get the cluster size in bytes.
*
* \param bs blobstore to query.
*
* \return cluster size.
*/
uint64_t spdk_bs_get_cluster_size(struct spdk_blob_store *bs);
/**
* Get the page size in bytes. This is the write and read granularity of blobs.
*
* \param bs blobstore to query.
*
* \return page size.
*/
uint64_t spdk_bs_get_page_size(struct spdk_blob_store *bs);
/**
* Get the io unit size in bytes.
*
* \param bs blobstore to query.
*
* \return io unit size.
*/
uint64_t spdk_bs_get_io_unit_size(struct spdk_blob_store *bs);
/**
* Get the number of free clusters.
*
* \param bs blobstore to query.
*
* \return the number of free clusters.
*/
uint64_t spdk_bs_free_cluster_count(struct spdk_blob_store *bs);
/**
* Get the total number of clusters accessible by user.
*
* \param bs blobstore to query.
*
* \return the total number of clusters accessible by user.
*/
uint64_t spdk_bs_total_data_cluster_count(struct spdk_blob_store *bs);
/**
* Get the blob id.
*
* \param blob Blob struct to query.
*
* \return blob id.
*/
spdk_blob_id spdk_blob_get_id(struct spdk_blob *blob);
/**
* Get the number of pages allocated to the blob.
*
* \param blob Blob struct to query.
*
* \return the number of pages.
*/
uint64_t spdk_blob_get_num_pages(struct spdk_blob *blob);
/**
* Get the number of io_units allocated to the blob.
*
* \param blob Blob struct to query.
*
* \return the number of io_units.
*/
uint64_t spdk_blob_get_num_io_units(struct spdk_blob *blob);
/**
* Get the number of clusters allocated to the blob.
*
* \param blob Blob struct to query.
*
* \return the number of clusters.
*/
uint64_t spdk_blob_get_num_clusters(struct spdk_blob *blob);
struct spdk_blob_xattr_opts {
/* Number of attributes */
size_t count;
/* Array of attribute names. Caller should free this array after use. */
char **names;
/* User context passed to get_xattr_value function */
void *ctx;
/* Callback that will return value for each attribute name. */
void (*get_value)(void *xattr_ctx, const char *name,
const void **value, size_t *value_len);
};
struct spdk_blob_opts {
uint64_t num_clusters;
bool thin_provision;
enum blob_clear_method clear_method;
struct spdk_blob_xattr_opts xattrs;
/** Enable separate extent pages in metadata */
bool use_extent_table;
/**
* The size of spdk_blob_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.
*/
size_t opts_size;
};
/**
* Initialize a spdk_blob_opts structure to the default blob option values.
*
* \param opts spdk_blob_opts structure to initialize.
* \param opts_size It must be the size of spdk_blob_opts structure.
*/
void spdk_blob_opts_init(struct spdk_blob_opts *opts, size_t opts_size);
/**
* Create a new blob with options on the given blobstore. The new blob id will
* be passed to the callback function.
*
* \param bs blobstore.
* \param opts The structure which contains the option values for the new blob.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to funcion cb_fn.
*/
void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_opts *opts,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg);
/**
* Create a new blob with default option values on the given blobstore.
* The new blob id will be passed to the callback function.
*
* \param bs blobstore.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_create_blob(struct spdk_blob_store *bs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg);
/**
* Create a read-only snapshot of specified blob with provided options.
* This will automatically sync specified blob.
*
* When operation is done, original blob is converted to the thin-provisioned
* blob with a newly created read-only snapshot set as a backing blob.
* Structure snapshot_xattrs as well as anything it references (like e.g. names
* array) must be valid until the completion is called.
*
* \param bs blobstore.
* \param blobid Id of the source blob used to create a snapshot.
* \param snapshot_xattrs xattrs specified for snapshot.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_create_snapshot(struct spdk_blob_store *bs, spdk_blob_id blobid,
const struct spdk_blob_xattr_opts *snapshot_xattrs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg);
/**
* Create a clone of specified read-only blob.
*
* Structure clone_xattrs as well as anything it references (like e.g. names
* array) must be valid until the completion is called.
*
* \param bs blobstore.
* \param blobid Id of the read only blob used as a snapshot for new clone.
* \param clone_xattrs xattrs specified for clone.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_create_clone(struct spdk_blob_store *bs, spdk_blob_id blobid,
const struct spdk_blob_xattr_opts *clone_xattrs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg);
/**
* Provide table with blob id's of clones are dependent on specified snapshot.
*
* Ids array should be allocated and the count parameter set to the number of
* id's it can store, before calling this function.
*
* If ids is NULL or count parameter is not sufficient to handle ids of all
* clones, -ENOMEM error is returned and count parameter is updated to the
* total number of clones.
*
* \param bs blobstore.
* \param blobid Snapshots blob id.
* \param ids Array of the clone ids or NULL to get required size in count.
* \param count Size of ids. After call it is updated to the number of clones.
*
* \return -ENOMEM if count is not sufficient to store all clones.
*/
int spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
size_t *count);
/**
* Get the blob id for the parent snapshot of this blob.
*
* \param bs blobstore.
* \param blobid Blob id.
*
* \return blob id of parent blob or SPDK_BLOBID_INVALID if have no parent
*/
spdk_blob_id spdk_blob_get_parent_snapshot(struct spdk_blob_store *bs, spdk_blob_id blobid);
/**
* Check if blob is read only.
*
* \param blob Blob.
*
* \return true if blob is read only.
*/
bool spdk_blob_is_read_only(struct spdk_blob *blob);
/**
* Check if blob is a snapshot.
*
* \param blob Blob.
*
* \return true if blob is a snapshot.
*/
bool spdk_blob_is_snapshot(struct spdk_blob *blob);
/**
* Check if blob is a clone.
*
* \param blob Blob.
*
* \return true if blob is a clone.
*/
bool spdk_blob_is_clone(struct spdk_blob *blob);
/**
* Check if blob is thin-provisioned.
*
* \param blob Blob.
*
* \return true if blob is thin-provisioned.
*/
bool spdk_blob_is_thin_provisioned(struct spdk_blob *blob);
/**
* Delete an existing blob from the given blobstore.
*
* \param bs blobstore.
* \param blobid The id of the blob to delete.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_delete_blob(struct spdk_blob_store *bs, spdk_blob_id blobid,
spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Allocate all clusters in this blob. Data for allocated clusters is copied
* from backing blob(s) if they exist.
*
* This call removes all dependencies on any backing blobs.
*
* \param bs blobstore.
* \param channel IO channel used to inflate blob.
* \param blobid The id of the blob to inflate.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_inflate_blob(struct spdk_blob_store *bs, struct spdk_io_channel *channel,
spdk_blob_id blobid, spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Remove dependency on parent blob.
*
* This call allocates and copies data for any clusters that are allocated in
* the parent blob, and decouples parent updating dependencies of blob to
* its ancestor.
*
* If blob have no parent -EINVAL error is reported.
*
* \param bs blobstore.
* \param channel IO channel used to inflate blob.
* \param blobid The id of the blob.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_blob_decouple_parent(struct spdk_blob_store *bs, struct spdk_io_channel *channel,
spdk_blob_id blobid, spdk_blob_op_complete cb_fn, void *cb_arg);
struct spdk_blob_open_opts {
enum blob_clear_method clear_method;
/**
* The size of spdk_blob_open_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.
*/
size_t opts_size;
};
/**
* Initialize a spdk_blob_open_opts structure to the default blob option values.
*
* \param opts spdk_blob_open_opts structure to initialize.
* \param opts_size It mus be the size of struct spdk_blob_open_opts.
*/
void spdk_blob_open_opts_init(struct spdk_blob_open_opts *opts, size_t opts_size);
/**
* Open a blob from the given blobstore.
*
* \param bs blobstore.
* \param blobid The id of the blob to open.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid,
spdk_blob_op_with_handle_complete cb_fn, void *cb_arg);
/**
* Open a blob from the given blobstore with additional options.
*
* \param bs blobstore.
* \param blobid The id of the blob to open.
* \param opts The structure which contains the option values for the blob.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_open_blob_ext(struct spdk_blob_store *bs, spdk_blob_id blobid,
struct spdk_blob_open_opts *opts, spdk_blob_op_with_handle_complete cb_fn, void *cb_arg);
/**
* Resize a blob to 'sz' clusters. These changes are not persisted to disk until
* spdk_bs_md_sync_blob() is called.
* If called before previous resize finish, it will fail with errno -EBUSY
*
* \param blob Blob to resize.
* \param sz The new number of clusters.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*
*/
void spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_fn,
void *cb_arg);
/**
* Set blob as read only.
*
* These changes do not take effect until spdk_blob_sync_md() is called.
*
* \param blob Blob to set.
*/
int spdk_blob_set_read_only(struct spdk_blob *blob);
/**
* Sync a blob.
*
* Make a blob persistent. This applies to open, resize, set xattr, and remove
* xattr. These operations will not be persistent until the blob has been synced.
*
* \param blob Blob to sync.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_sync_md(struct spdk_blob *blob, spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Close a blob. This will automatically sync.
*
* \param blob Blob to close.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_close(struct spdk_blob *blob, spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Allocate an I/O channel for the given blobstore.
*
* \param bs blobstore.
* \return a pointer to the allocated I/O channel.
*/
struct spdk_io_channel *spdk_bs_alloc_io_channel(struct spdk_blob_store *bs);
/**
* Free the I/O channel.
*
* \param channel I/O channel to free.
*/
void spdk_bs_free_io_channel(struct spdk_io_channel *channel);
/**
* Write data to a blob.
*
* \param blob Blob to write.
* \param channel The I/O channel used to submit requests.
* \param payload The specified buffer which should contain the data to be written.
* \param offset Offset is in io units from the beginning of the blob.
* \param length Size of data in io units.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_io_write(struct spdk_blob *blob, struct spdk_io_channel *channel,
void *payload, uint64_t offset, uint64_t length,
spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Read data from a blob.
*
* \param blob Blob to read.
* \param channel The I/O channel used to submit requests.
* \param payload The specified buffer which will store the obtained data.
* \param offset Offset is in io units from the beginning of the blob.
* \param length Size of data in io units.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_io_read(struct spdk_blob *blob, struct spdk_io_channel *channel,
void *payload, uint64_t offset, uint64_t length,
spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Write the data described by 'iov' to 'length' io_units beginning at 'offset' io_units
* into the blob.
*
* \param blob Blob to write.
* \param channel I/O channel used to submit requests.
* \param iov The pointer points to an array of iovec structures.
* \param iovcnt The number of buffers.
* \param offset Offset is in io units from the beginning of the blob.
* \param length Size of data in io units.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_io_writev(struct spdk_blob *blob, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Read 'length' io_units starting at 'offset' io_units into the blob into the memory
* described by 'iov'.
*
* \param blob Blob to read.
* \param channel I/O channel used to submit requests.
* \param iov The pointer points to an array of iovec structures.
* \param iovcnt The number of buffers.
* \param offset Offset is in io units from the beginning of the blob.
* \param length Size of data in io units.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_io_readv(struct spdk_blob *blob, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt, uint64_t offset, uint64_t length,
spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Unmap 'length' io_units beginning at 'offset' io_units on the blob as unused. Unmapped
* io_units may allow the underlying storage media to behave more efficiently.
*
* \param blob Blob to unmap.
* \param channel I/O channel used to submit requests.
* \param offset Offset is in io units from the beginning of the blob.
* \param length Size of unmap area in io_units.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_io_unmap(struct spdk_blob *blob, struct spdk_io_channel *channel,
uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Write zeros into area of a blob.
*
* \param blob Blob to write.
* \param channel I/O channel used to submit requests.
* \param offset Offset is in io units from the beginning of the blob.
* \param length Size of data in io units.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_blob_io_write_zeroes(struct spdk_blob *blob, struct spdk_io_channel *channel,
uint64_t offset, uint64_t length, spdk_blob_op_complete cb_fn, void *cb_arg);
/**
* Get the first blob of the blobstore. The obtained blob will be passed to
* the callback function.
*
* The user's cb_fn will be called with rc == -ENOENT when the iteration is
* complete.
*
* When the user's cb_fn is called with rc == 0, the associated blob is open.
* This means that the cb_fn may not attempt to unload the blobstore. It
* must complete the iteration before attempting to unload.
*
* \param bs blobstore to traverse.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_iter_first(struct spdk_blob_store *bs,
spdk_blob_op_with_handle_complete cb_fn, void *cb_arg);
/**
* Get the next blob by using the current blob. The obtained blob will be passed
* to the callback function.
*
* The user's cb_fn will be called with rc == -ENOENT when the iteration is
* complete.
*
* When the user's cb_fn is called with rc == 0, the associated blob is open.
* This means that the cb_fn may not attempt to unload the blobstore. It
* must complete the iteration before attempting to unload.
*
* \param bs blobstore to traverse.
* \param blob The current blob.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Argument passed to function cb_fn.
*/
void spdk_bs_iter_next(struct spdk_blob_store *bs, struct spdk_blob *blob,
spdk_blob_op_with_handle_complete cb_fn, void *cb_arg);
/**
* Set an extended attribute for the given blob.
*
* \param blob Blob to set attribute.
* \param name Name of the extended attribute.
* \param value Value of the extended attribute.
* \param value_len Length of the value.
*
* \return 0 on success, -1 on failure.
*/
int spdk_blob_set_xattr(struct spdk_blob *blob, const char *name, const void *value,
uint16_t value_len);
/**
* Remove the extended attribute from the given blob.
*
* \param blob Blob to remove attribute.
* \param name Name of the extended attribute.
*
* \return 0 on success, negative errno on failure.
*/
int spdk_blob_remove_xattr(struct spdk_blob *blob, const char *name);
/**
* Get the value of the specified extended attribute. The obtained value and its
* size will be stored in value and value_len.
*
* \param blob Blob to query.
* \param name Name of the extended attribute.
* \param value Parameter as output.
* \param value_len Parameter as output.
*
* \return 0 on success, negative errno on failure.
*/
int spdk_blob_get_xattr_value(struct spdk_blob *blob, const char *name,
const void **value, size_t *value_len);
/**
* Iterate through all extended attributes of the blob. Get the names of all extended
* attributes that will be stored in names.
*
* \param blob Blob to query.
* \param names Parameter as output.
*
* \return 0 on success, negative errno on failure.
*/
int spdk_blob_get_xattr_names(struct spdk_blob *blob, struct spdk_xattr_names **names);
/**
* Get the number of extended attributes.
*
* \param names Names of total extended attributes of the blob.
*
* \return the number of extended attributes.
*/
uint32_t spdk_xattr_names_get_count(struct spdk_xattr_names *names);
/**
* Get the attribute name specified by the index.
*
* \param names Names of total extended attributes of the blob.
* \param index Index position of the specified attribute.
*
* \return attribute name.
*/
const char *spdk_xattr_names_get_name(struct spdk_xattr_names *names, uint32_t index);
/**
* Free the attribute names.
*
* \param names Names of total extended attributes of the blob.
*/
void spdk_xattr_names_free(struct spdk_xattr_names *names);
/**
* Get blobstore type of the given device.
*
* \param bs blobstore to query.
*
* \return blobstore type.
*/
struct spdk_bs_type spdk_bs_get_bstype(struct spdk_blob_store *bs);
/**
* Set blobstore type to the given device.
*
* \param bs blobstore to set to.
* \param bstype Type label to set.
*/
void spdk_bs_set_bstype(struct spdk_blob_store *bs, struct spdk_bs_type bstype);
#ifdef __cplusplus
}
#endif
#endif /* SPDK_BLOB_H_ */