Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 30 additions & 13 deletions include/spdk/blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -727,25 +727,42 @@ int spdk_blob_get_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_b
size_t *count);

/**
* Provide table with blob id's of clones are dependent on specified snapshot.
* Get a count of all snapshot clones.
* If the clone_attr exists in the blob xattr, then it's a clone.
*
* Ids array should be allocated and the count parameter set to the number of
* id's it can store, before calling this function.
* \param bs blobstore.
* \param clone_attr Name of the attribute which denotes a clone.
* \param snap_uuid Uuid of the snapshot.
*
* 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.
* \return count of all clones from snapshots.
*/
size_t
spdk_blob_count_real_clones(struct spdk_blob_store *bs, const char *clone_attr,
const char *snap_uuid);

/**
* Callback definition for spdk_bs_blob_clone_iter_cb.
*
* \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.
* \param lvol An iterated lvol.
* \param cb_arg Opaque context passed to spdk_bs_blob_clone_iter_cb().
* \param blob_id The blob id of the clone.
*/
typedef void (*spdk_bs_blob_clone_iter_cb)(void *cb_arg, spdk_blob_id blob_id);

/**
* Iterate all snapshot clones.
* If the clone_attr exists in the blob xattr, then it's a clone.
*
* \return -ENOMEM if count is not sufficient to store all clones.
* \param bs blobstore.
* \param clone_attr Name of the attribute which denotes a clone.
* \param snap_uuid Uuid of the snapshot.
* \param cb_fn Callback for each clone.
* \param cb_arg Context for each callback.
*/
int spdk_blob_get_real_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
size_t *count, const char *clone_attr);
void
spdk_blob_get_real_clones(struct spdk_blob_store *bs, const char *clone_attr,
const char *snap_uuid,
spdk_bs_blob_clone_iter_cb cb_fn, void *cb_arg);

/**
* Get the blob id for the parent snapshot of this blob.
Expand Down
10 changes: 10 additions & 0 deletions include/spdk/lvol.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,16 @@ void spdk_lvol_close(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn, void *
*/
int spdk_lvol_iter_immediate_clones(struct spdk_lvol *lvol, spdk_lvol_iter_cb cb_fn, void *cb_arg);

/**
* Get the lvol that has a particular blob id, from the specified lvolstore.
*
* \param lvs The lvol's lvolstore.
* \param uuid The lvol's blobstore blob id.
* \return A pointer to the requested lvol on success, else NULL.
*/
struct spdk_lvol *
lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id);

/**
* Get the lvol that has a particular UUID.
*
Expand Down
63 changes: 33 additions & 30 deletions lib/blob/blobstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -9804,7 +9804,8 @@ blob_get_xattr_value(struct spdk_blob *blob, const char *name,
}

static bool
blob_xattr_exists(struct spdk_blob *blob, const char *name, bool internal)
blob_xattr_matches(struct spdk_blob *blob, const char *name, const char *value, int len,
bool internal)
{
struct spdk_xattr *xattr;
struct spdk_xattr_tailq *xattrs;
Expand All @@ -9813,7 +9814,11 @@ blob_xattr_exists(struct spdk_blob *blob, const char *name, bool internal)

TAILQ_FOREACH(xattr, xattrs, link) {
if (!strcmp(name, xattr->name)) {
return true;
if (xattr->value_len != len) {
SPDK_ERRLOG("Invalid xattr->value_len for %s\n", name);
} else if (!strncmp(value, xattr->value, len)) {
return true;
}
}
}
return false;
Expand Down Expand Up @@ -9986,43 +9991,41 @@ spdk_blob_get_parent_snapshot(struct spdk_blob_store *bs, spdk_blob_id blob_id)
return SPDK_BLOBID_INVALID;
}

int
spdk_blob_get_real_clones(struct spdk_blob_store *bs, spdk_blob_id blobid, spdk_blob_id *ids,
size_t *count, const char *clone_attr)
void
spdk_blob_get_real_clones(struct spdk_blob_store *bs, const char *clone_attr, const char *snap_uuid,
spdk_bs_blob_clone_iter_cb cb_fn, void *cb_arg)
{
struct spdk_blob_list *snapshot_entry, *clone_entry;
size_t n;
struct spdk_blob *blob;
int uuid_len = SPDK_UUID_STRING_LEN - 1;

snapshot_entry = bs_get_snapshot_entry(bs, blobid);
if (snapshot_entry == NULL) {
*count = 0;
return 0;
}

if (ids == NULL || *count < snapshot_entry->clone_count) {
n = 0;
TAILQ_FOREACH(clone_entry, &snapshot_entry->clones, link) {
blob = blob_lookup(bs, clone_entry->id);
if (blob && blob_xattr_exists(blob, clone_attr, false)) {
n++;
}
RB_FOREACH(blob, spdk_blob_tree, &bs->open_blobs) {
if (!spdk_blob_is_clone(blob)) {
continue;
}
if (blob_xattr_matches(blob, clone_attr, snap_uuid, uuid_len, false)) {
cb_fn(cb_arg, blob->id);
}
*count = n;

return -ENOMEM;
}
*count = snapshot_entry->clone_count;
}

n = 0;
TAILQ_FOREACH(clone_entry, &snapshot_entry->clones, link) {
blob = blob_lookup(bs, clone_entry->id);
if (blob && blob_xattr_exists(blob, clone_attr, false)) {
ids[n++] = clone_entry->id;
size_t
spdk_blob_count_real_clones(struct spdk_blob_store *bs, const char *clone_attr,
const char *snap_uuid)
{
size_t count = 0;
struct spdk_blob *blob;
int uuid_len = SPDK_UUID_STRING_LEN - 1;

RB_FOREACH(blob, spdk_blob_tree, &bs->open_blobs) {
if (!spdk_blob_is_clone(blob)) {
continue;
}
if (blob_xattr_matches(blob, clone_attr, snap_uuid, uuid_len, false)) {
count++;
}
}

return 0;
return count;
}

int
Expand Down
3 changes: 1 addition & 2 deletions lib/lvol/lvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ static inline int lvs_opts_copy(const struct spdk_lvs_opts *src, struct spdk_lvs
static int lvs_esnap_bs_dev_create(void *bs_ctx, void *blob_ctx, struct spdk_blob *blob,
const void *esnap_id, uint32_t id_len,
struct spdk_bs_dev **_bs_dev);
static struct spdk_lvol *lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id);
static void lvs_degraded_lvol_set_add(struct spdk_lvs_degraded_lvol_set *degraded_set,
struct spdk_lvol *lvol);
static void lvs_degraded_lvol_set_remove(struct spdk_lvs_degraded_lvol_set *degraded_set,
Expand Down Expand Up @@ -2102,7 +2101,7 @@ spdk_lvs_grow(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn
spdk_bs_grow(bs_dev, &opts, lvs_load_cb, req);
}

static struct spdk_lvol *
struct spdk_lvol *
lvs_get_lvol_by_blob_id(struct spdk_lvol_store *lvs, spdk_blob_id blob_id)
{
struct spdk_lvol *lvol;
Expand Down
Loading