blobstore: Use RB_TREE to do blob lookup

If blobs held in a blobstore are opened a lot, lookup
by RB_TREE will be much more efficient.

Change-Id: I7075b95c597a958e7bb10890f803191309532021
Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/10917
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
This commit is contained in:
Liu Xiaodong 2021-12-29 15:32:39 -05:00 committed by Tomasz Zawadzki
parent 97b3fb1758
commit 7de351f1d7
2 changed files with 23 additions and 19 deletions

View File

@ -66,6 +66,14 @@ static int blob_remove_xattr(struct spdk_blob *blob, const char *name, bool inte
static void blob_write_extent_page(struct spdk_blob *blob, uint32_t extent, uint64_t cluster_num,
spdk_blob_op_complete cb_fn, void *cb_arg);
static int
blob_id_cmp(struct spdk_blob *blob1, struct spdk_blob *blob2)
{
return (blob1->id < blob2->id ? -1 : blob1->id > blob2->id);
}
RB_GENERATE_STATIC(spdk_blob_tree, spdk_blob, link, blob_id_cmp);
static void
blob_verify_md_op(struct spdk_blob *blob)
{
@ -2991,19 +2999,14 @@ blob_request_submit_rw_iov(struct spdk_blob *blob, struct spdk_io_channel *_chan
static struct spdk_blob *
blob_lookup(struct spdk_blob_store *bs, spdk_blob_id blobid)
{
struct spdk_blob *blob;
struct spdk_blob find;
if (spdk_bit_array_get(bs->open_blobids, blobid) == 0) {
return NULL;
}
TAILQ_FOREACH(blob, &bs->blobs, link) {
if (blob->id == blobid) {
return blob;
}
}
return NULL;
find.id = blobid;
return RB_FIND(spdk_blob_tree, &bs->open_blobs, &find);
}
static void
@ -3103,8 +3106,8 @@ bs_dev_destroy(void *io_device)
bs->dev->destroy(bs->dev);
TAILQ_FOREACH_SAFE(blob, &bs->blobs, link, blob_tmp) {
TAILQ_REMOVE(&bs->blobs, blob, link);
RB_FOREACH_SAFE(blob, spdk_blob_tree, &bs->open_blobs, blob_tmp) {
RB_REMOVE(spdk_blob_tree, &bs->open_blobs, blob);
spdk_bit_array_clear(bs->open_blobids, blob->id);
blob_free(blob);
}
@ -3349,7 +3352,7 @@ bs_alloc(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts, struct spdk_blob_st
return -ENOMEM;
}
TAILQ_INIT(&bs->blobs);
RB_INIT(&bs->open_blobs);
TAILQ_INIT(&bs->snapshots);
bs->dev = dev;
bs->md_thread = spdk_get_thread();
@ -5006,7 +5009,7 @@ spdk_bs_destroy(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn,
SPDK_DEBUGLOG(blob, "Destroying blobstore\n");
if (!TAILQ_EMPTY(&bs->blobs)) {
if (!RB_EMPTY(&bs->open_blobs)) {
SPDK_ERRLOG("Blobstore still has open blobs\n");
cb_fn(cb_arg, -EBUSY);
return;
@ -5141,7 +5144,7 @@ spdk_bs_unload(struct spdk_blob_store *bs, spdk_bs_op_complete cb_fn, void *cb_a
SPDK_DEBUGLOG(blob, "Syncing blobstore\n");
if (!TAILQ_EMPTY(&bs->blobs)) {
if (!RB_EMPTY(&bs->open_blobs)) {
SPDK_ERRLOG("Blobstore still has open blobs\n");
cb_fn(cb_arg, -EBUSY);
return;
@ -6449,7 +6452,7 @@ delete_snapshot_cleanup_snapshot(void *cb_arg, int bserrno)
if (ctx->bserrno != 0) {
assert(blob_lookup(ctx->snapshot->bs, ctx->snapshot->id) == NULL);
TAILQ_INSERT_HEAD(&ctx->snapshot->bs->blobs, ctx->snapshot, link);
RB_INSERT(spdk_blob_tree, &ctx->snapshot->bs->open_blobs, ctx->snapshot);
spdk_bit_array_set(ctx->snapshot->bs->open_blobids, ctx->snapshot->id);
}
@ -6876,7 +6879,7 @@ bs_delete_open_cpl(void *cb_arg, struct spdk_blob *blob, int bserrno)
* get returned after this point by blob_lookup().
*/
spdk_bit_array_clear(blob->bs->open_blobids, blob->id);
TAILQ_REMOVE(&blob->bs->blobs, blob, link);
RB_REMOVE(spdk_blob_tree, &blob->bs->open_blobs, blob);
if (update_clone) {
/* This blob is a snapshot with active clone - update clone first */
@ -6942,7 +6945,7 @@ bs_open_blob_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
blob->open_ref++;
spdk_bit_array_set(blob->bs->open_blobids, blob->id);
TAILQ_INSERT_HEAD(&blob->bs->blobs, blob, link);
RB_INSERT(spdk_blob_tree, &blob->bs->open_blobs, blob);
bs_sequence_finish(seq, bserrno);
}
@ -7276,7 +7279,7 @@ blob_close_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
*/
if (blob->active.num_pages > 0) {
spdk_bit_array_clear(blob->bs->open_blobids, blob->id);
TAILQ_REMOVE(&blob->bs->blobs, blob, link);
RB_REMOVE(spdk_blob_tree, &blob->bs->open_blobs, blob);
}
blob_free(blob);
}

View File

@ -38,6 +38,7 @@
#include "spdk/blob.h"
#include "spdk/queue.h"
#include "spdk/util.h"
#include "spdk/tree.h"
#include "request.h"
@ -157,7 +158,7 @@ struct spdk_blob {
struct spdk_xattr_tailq xattrs;
struct spdk_xattr_tailq xattrs_internal;
TAILQ_ENTRY(spdk_blob) link;
RB_ENTRY(spdk_blob) link;
uint32_t frozen_refcnt;
bool locked_operation_in_progress;
@ -207,7 +208,7 @@ struct spdk_blob_store {
struct spdk_bs_cpl unload_cpl;
int unload_err;
TAILQ_HEAD(, spdk_blob) blobs;
RB_HEAD(spdk_blob_tree, spdk_blob) open_blobs;
TAILQ_HEAD(, spdk_blob_list) snapshots;
bool clean;