Skip to content

Commit

Permalink
blobstore: export allocated cluster bitmap for a blob
Browse files Browse the repository at this point in the history
Signed-off-by: Tiago Castro <[email protected]>
  • Loading branch information
tiagolobocastro committed Dec 15, 2023
1 parent 42a4b3e commit 226fad7
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 1 deletion.
9 changes: 9 additions & 0 deletions include/spdk/bit_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ struct spdk_bit_array;
*/
uint32_t spdk_bit_array_capacity(const struct spdk_bit_array *ba);

/**
* Return the inner words of the bit array.
*
* \param ba Bit array to query.
*
* \return inner words array.
*/
const uint64_t *spdk_bit_array_words(const struct spdk_bit_array *ba);

/**
* Create a bit array.
*
Expand Down
25 changes: 25 additions & 0 deletions include/spdk/blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "spdk/stdinc.h"
#include "spdk/assert.h"
#include "spdk/bit_array.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -1180,6 +1181,30 @@ bool spdk_blob_is_degraded(const struct spdk_blob *blob);
*/
void spdk_blob_reset_used_clusters_cache(struct spdk_blob *blob);

/**
* Blob get cluster bitmap completion callback.
*
* \param cb_arg Callback argument.
* \param bserrno 0 if it completed successfully, or negative errno if it failed.
* \param bitmap NULL if no memory available, otherwise a bitmap where each bit corresponds
* to a cluster. A set bit indicates the cluster is owned by the blob.
*/
typedef void (*spdk_blob_cluster_bitmap_complete)(void *cb_arg, int bserrno,
struct spdk_bit_array *bitmap);

/**
* Get the allocated cluster bitmap of the given blob.
*
* \param blob Blob to retrieve allocated bitmap from.
* \param cb_fn Called when the operation is complete.
* \param cb_arg Custom cb_arg passed to function cb_fn.
*
* \return 0 if callback was called, or negative errno otherwise.
*/
int
spdk_blob_get_cluster_bitmap(struct spdk_blob *blob, spdk_blob_cluster_bitmap_complete cb_fn,
void *cb_arg);

#ifdef __cplusplus
}
#endif
Expand Down
102 changes: 101 additions & 1 deletion lib/blob/blobstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "spdk/env.h"
#include "spdk/queue.h"
#include "spdk/thread.h"
#include "spdk/bit_array.h"
#include "spdk/bit_pool.h"
#include "spdk/likely.h"
#include "spdk/util.h"
Expand Down Expand Up @@ -5985,6 +5984,107 @@ spdk_blob_reset_used_clusters_cache(struct spdk_blob *blob)
spdk_spin_unlock(&blob->bs->used_lock);
}
}

struct spdk_blob_bitmap_ctx {
spdk_blob_cluster_bitmap_complete cb_fn;
void *cb_arg;
struct spdk_bit_array *bitmap;
struct spdk_blob *blob;
};

static void
spdk_blob_bitmap_cpl(struct spdk_blob_bitmap_ctx *ctx, int rc)
{
ctx->cb_fn(ctx->cb_arg, rc, ctx->bitmap);
spdk_bit_array_free(&ctx->bitmap);
free(ctx);
}

static void
spdk_blob_bitmap_unfreeze_cpl(void *cb_arg, int rc)
{
struct spdk_blob_bitmap_ctx *ctx = (struct spdk_blob_bitmap_ctx *)cb_arg;

if (rc != 0) {
SPDK_ERRLOG("Unfreeze failed, rc=%d\n", rc);
}

ctx->blob->locked_operation_in_progress = false;
spdk_blob_bitmap_cpl(ctx, rc);
}

static void
spdk_blob_create_bitmap(struct spdk_blob_bitmap_ctx *ctx)
{
struct spdk_blob *blob = ctx->blob;
uint64_t i;

ctx->bitmap = spdk_bit_array_create(blob->active.num_clusters);
if (ctx->bitmap == NULL) {
SPDK_ERRLOG("Failed to allocate bit array memory for blob #%ld", blob->id);
return;
}

for (i = 0; i < blob->active.num_clusters; i++) {
if (blob->active.clusters[i]) {
spdk_bit_array_set(ctx->bitmap, i);
}
}
}

static void
spdk_blob_bitmap_freeze_cpl(void *cb_arg, int rc)
{
struct spdk_blob_bitmap_ctx *ctx = (struct spdk_blob_bitmap_ctx *)cb_arg;

if (rc != 0) {
ctx->blob->locked_operation_in_progress = false;
ctx->cb_fn(ctx->cb_arg, rc, NULL);
spdk_bit_array_free(&ctx->bitmap);
free(ctx);
return;
}

spdk_blob_create_bitmap(ctx);
blob_unfreeze_io(ctx->blob, spdk_blob_bitmap_unfreeze_cpl, ctx);
}

int
spdk_blob_get_cluster_bitmap(struct spdk_blob *blob, spdk_blob_cluster_bitmap_complete cb_fn,
void *cb_arg)
{
struct spdk_blob_bitmap_ctx *ctx;

assert(blob != NULL);
if (blob->locked_operation_in_progress) {
return -EBUSY;
}

if (blob->state != SPDK_BLOB_STATE_CLEAN) {
return -EBADFD;
}

ctx = malloc(sizeof(*ctx));
if (!ctx) {
return -ENOMEM;
}

ctx->blob = blob;
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;

if (blob->data_ro && blob->md_ro) {
spdk_blob_create_bitmap(ctx);
spdk_blob_bitmap_cpl(ctx, 0);
return 0;
}

blob->locked_operation_in_progress = true;
blob_freeze_io(blob, spdk_blob_bitmap_freeze_cpl, ctx);

return 0;
}

/* START spdk_bs_create_blob */

static void
Expand Down
5 changes: 5 additions & 0 deletions lib/util/bit_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ spdk_bit_array_capacity(const struct spdk_bit_array *ba)
{
return ba->bit_count;
}
const uint64_t *
spdk_bit_array_words(const struct spdk_bit_array *ba)
{
return ba->words;
}

static inline int
bit_array_get_word(const struct spdk_bit_array *ba, uint32_t bit_index,
Expand Down

0 comments on commit 226fad7

Please sign in to comment.