Skip to content

Commit

Permalink
fix(snapshot): reset num_used_clusters_cache when snapshot created fr…
Browse files Browse the repository at this point in the history
…om thin provisioned lvol

Signed-off-by: Hrudaya <[email protected]>
  • Loading branch information
hrudaya21 committed Jul 17, 2023
1 parent 7ca587a commit c793a20
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 16 deletions.
4 changes: 2 additions & 2 deletions include/spdk/blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,8 @@ void spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid,
* \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);
int 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
Expand Down
12 changes: 11 additions & 1 deletion include/spdk_internal/lvolstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ struct spdk_lvol {
TAILQ_ENTRY(spdk_lvol) link;
};

struct spdk_lvol_snapshot_req {
struct spdk_lvol *parent;
struct spdk_lvol_with_handle_req *req;
};

struct lvol_store_bdev *vbdev_lvol_store_first(void);
struct lvol_store_bdev *vbdev_lvol_store_next(struct lvol_store_bdev *prev);

Expand All @@ -108,5 +113,10 @@ void spdk_lvol_set_read_only(struct spdk_lvol *lvol, spdk_lvol_op_complete cb_fn
void *cb_arg);
int vbdev_lvs_examine(struct spdk_bdev *bdev,
spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg);

/**
* Reset num_used_clusters_cache, if blob is thin provisioned and snapshot is
* created from it. New snapshot will own the data, hence the clusted information
* present in the blob cache can be cleared.
*/
void blob_reset_used_clusters_cache(struct spdk_blob *blob);
#endif /* SPDK_INTERNAL_LVOLSTORE_H */
26 changes: 19 additions & 7 deletions lib/blob/blobstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "spdk/bdev_module.h"

#include "spdk_internal/assert.h"
#include "spdk_internal/lvolstore.h"
#include "spdk/log.h"

#include "blobstore.h"
Expand Down Expand Up @@ -5789,6 +5790,16 @@ spdk_blob_calc_used_clusters(struct spdk_blob *blob)
return num;
}

void
blob_reset_used_clusters_cache(struct spdk_blob *blob)
{
assert(blob != NULL);
if (spdk_blob_is_thin_provisioned(blob)) {
spdk_spin_lock(&blob->bs->used_lock);
blob->num_used_clusters_cache = 0;
spdk_spin_unlock(&blob->bs->used_lock);
}
}
/* START spdk_bs_create_blob */

static void
Expand Down Expand Up @@ -7414,7 +7425,7 @@ blob_open_opts_copy(const struct spdk_blob_open_opts *src, struct spdk_blob_open
#undef SET_FIELD
}

static void
static int
bs_open_blob(struct spdk_blob_store *bs,
spdk_blob_id blobid,
struct spdk_blob_open_opts *opts,
Expand All @@ -7434,20 +7445,20 @@ bs_open_blob(struct spdk_blob_store *bs,
if (spdk_bit_array_get(bs->used_blobids, page_num) == false) {
/* Invalid blobid */
cb_fn(cb_arg, NULL, -ENOENT);
return;
return -ENOENT;
}

blob = blob_lookup(bs, blobid);
if (blob) {
blob->open_ref++;
cb_fn(cb_arg, blob, 0);
return;
return 0;
}

blob = blob_alloc(bs, blobid);
if (!blob) {
cb_fn(cb_arg, NULL, -ENOMEM);
return;
return -ENOMEM;
}

spdk_blob_open_opts_init(&opts_local, sizeof(opts_local));
Expand All @@ -7466,10 +7477,11 @@ bs_open_blob(struct spdk_blob_store *bs,
if (!seq) {
blob_free(blob);
cb_fn(cb_arg, NULL, -ENOMEM);
return;
return -ENOMEM;
}

blob_load(seq, blob, bs_open_blob_cpl, blob);
return 0;
}

void
Expand All @@ -7479,11 +7491,11 @@ spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid,
bs_open_blob(bs, blobid, NULL, cb_fn, cb_arg);
}

void
int
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)
{
bs_open_blob(bs, blobid, opts, cb_fn, cb_arg);
return bs_open_blob(bs, blobid, opts, cb_fn, cb_arg);
}

/* END spdk_bs_open_blob */
Expand Down
54 changes: 48 additions & 6 deletions lib/lvol/lvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,39 @@ lvol_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno)
spdk_bs_open_blob_ext(bs, blobid, &opts, lvol_create_open_cb, req);
}

static void
lvol_create_snapshot_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno)
{
struct spdk_lvol_snapshot_req *snap_req = cb_arg;
struct spdk_blob_store *bs;
struct spdk_blob_open_opts opts;

if (lvolerrno < 0) {
TAILQ_REMOVE(&snap_req->req->lvol->lvol_store->pending_lvols, snap_req->req->lvol, link);
free(snap_req->req->lvol);
assert(snap_req->req->cb_fn != NULL);
snap_req->req->cb_fn(snap_req->req->cb_arg, NULL, lvolerrno);
free(snap_req->req);
free(snap_req);
return;
}

spdk_blob_open_opts_init(&opts, sizeof(opts));
opts.clear_method = snap_req->req->lvol->clear_method;
bs = snap_req->req->lvol->lvol_store->blobstore;

lvolerrno = spdk_bs_open_blob_ext(bs, blobid, &opts, lvol_create_open_cb, snap_req->req);
/*
* Reset used clusters cache if blob is thin provisioned and new snapshot
* is created from it.
*/
if (lvolerrno == 0) {
blob_reset_used_clusters_cache(snap_req->parent->blob);
}

free(snap_req);
}

static void
lvol_get_xattr_value(void *xattr_ctx, const char *name,
const void **value, size_t *value_len)
Expand Down Expand Up @@ -1153,6 +1186,7 @@ create_lvol_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name,
struct spdk_lvol *newlvol;
struct spdk_blob *origblob;
struct spdk_lvol_with_handle_req *req;
struct spdk_lvol_snapshot_req *snap_req;
struct xattr_value_ext_arg xattr_args;
char *xattr_names[SPDK_LVOL_MAX_SNAPSHOT_ATTRS + 2]; /* Extra default attributes. */
int rc;
Expand Down Expand Up @@ -1225,18 +1259,25 @@ create_lvol_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name,
cb_fn(cb_arg, NULL, rc);
return;
}

snap_req = calloc(1, sizeof(*snap_req));
if (!snap_req) {
SPDK_ERRLOG("Cannot alloc memory for snapshot request pointer\n");
cb_fn(cb_arg, NULL, -ENOMEM);
return;
}
req = calloc(1, sizeof(*req));
if (!req) {
SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
cb_fn(cb_arg, NULL, -ENOMEM);
free(snap_req);
return;
}

snap_req->req = req;
newlvol = calloc(1, sizeof(*newlvol));
if (!newlvol) {
SPDK_ERRLOG("Cannot alloc memory for lvol base pointer\n");
free(req);
free(snap_req);
cb_fn(cb_arg, NULL, -ENOMEM);
return;
}
Expand Down Expand Up @@ -1265,12 +1306,13 @@ create_lvol_snapshot(struct spdk_lvol *origlvol, const char *snapshot_name,
xattr_args.user_xattrs = xattrs;
xattr_args.user_xattrs_count = xattrs_count;

req->lvol = newlvol;
req->cb_fn = cb_fn;
req->cb_arg = cb_arg;
snap_req->req->lvol = newlvol;
snap_req->req->cb_fn = cb_fn;
snap_req->req->cb_arg = cb_arg;
snap_req->parent = origlvol;

spdk_bs_create_snapshot(lvs->blobstore, spdk_blob_get_id(origblob), &xattr_args.lvol_xattrs,
lvol_create_cb, req);
lvol_create_snapshot_cb, snap_req);
}

void
Expand Down

0 comments on commit c793a20

Please sign in to comment.