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 Keith Lucas
parent 043559e5cc
commit 65ea3d2987
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, 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); 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 static void
blob_verify_md_op(struct spdk_blob *blob) 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 * static struct spdk_blob *
blob_lookup(struct spdk_blob_store *bs, spdk_blob_id blobid) 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) { if (spdk_bit_array_get(bs->open_blobids, blobid) == 0) {
return NULL; return NULL;
} }
TAILQ_FOREACH(blob, &bs->blobs, link) { find.id = blobid;
if (blob->id == blobid) { return RB_FIND(spdk_blob_tree, &bs->open_blobs, &find);
return blob;
}
}
return NULL;
} }
static void static void
@ -3103,8 +3106,8 @@ bs_dev_destroy(void *io_device)
bs->dev->destroy(bs->dev); bs->dev->destroy(bs->dev);
TAILQ_FOREACH_SAFE(blob, &bs->blobs, link, blob_tmp) { RB_FOREACH_SAFE(blob, spdk_blob_tree, &bs->open_blobs, blob_tmp) {
TAILQ_REMOVE(&bs->blobs, blob, link); RB_REMOVE(spdk_blob_tree, &bs->open_blobs, blob);
spdk_bit_array_clear(bs->open_blobids, blob->id); spdk_bit_array_clear(bs->open_blobids, blob->id);
blob_free(blob); 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; return -ENOMEM;
} }
TAILQ_INIT(&bs->blobs); RB_INIT(&bs->open_blobs);
TAILQ_INIT(&bs->snapshots); TAILQ_INIT(&bs->snapshots);
bs->dev = dev; bs->dev = dev;
bs->md_thread = spdk_get_thread(); 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"); 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"); SPDK_ERRLOG("Blobstore still has open blobs\n");
cb_fn(cb_arg, -EBUSY); cb_fn(cb_arg, -EBUSY);
return; 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"); 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"); SPDK_ERRLOG("Blobstore still has open blobs\n");
cb_fn(cb_arg, -EBUSY); cb_fn(cb_arg, -EBUSY);
return; return;
@ -6449,7 +6452,7 @@ delete_snapshot_cleanup_snapshot(void *cb_arg, int bserrno)
if (ctx->bserrno != 0) { if (ctx->bserrno != 0) {
assert(blob_lookup(ctx->snapshot->bs, ctx->snapshot->id) == NULL); 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); 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(). * get returned after this point by blob_lookup().
*/ */
spdk_bit_array_clear(blob->bs->open_blobids, blob->id); 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) { if (update_clone) {
/* This blob is a snapshot with active clone - update clone first */ /* 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++; blob->open_ref++;
spdk_bit_array_set(blob->bs->open_blobids, blob->id); 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); 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) { if (blob->active.num_pages > 0) {
spdk_bit_array_clear(blob->bs->open_blobids, blob->id); 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); blob_free(blob);
} }

View File

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