147 lines
3.6 KiB
C
147 lines
3.6 KiB
C
|
#include "spdk/stdinc.h"
|
||
|
#include "spdk/env.h"
|
||
|
#include "spdk/jsonrpc.h"
|
||
|
#include "spdk/thread.h"
|
||
|
#include "spdk_internal/lvolstore.h"
|
||
|
#include "../lvol/vbdev_lvol.h"
|
||
|
#include "lib/blob/blobstore.h"
|
||
|
|
||
|
#define ALIGN_4K 4096
|
||
|
|
||
|
|
||
|
struct sync_context {
|
||
|
struct spdk_bdev *snapshot_bdev;
|
||
|
struct spdk_bdev_desc *snapshot_desc;
|
||
|
struct spdk_io_channel *snapshot_channel;
|
||
|
|
||
|
uint64_t num_clusters;
|
||
|
uint64_t allocated_clusters;
|
||
|
uint32_t cluster_size;
|
||
|
uint32_t io_unit_size;
|
||
|
uint32_t *table;
|
||
|
|
||
|
uint64_t io_units_per_cluster;
|
||
|
|
||
|
uint8_t *cluster;
|
||
|
uint64_t pos;
|
||
|
struct iovec iov;
|
||
|
|
||
|
int iovcnt;
|
||
|
|
||
|
struct spdk_lvol *lvol;
|
||
|
struct spdk_io_channel *channel;
|
||
|
|
||
|
};
|
||
|
|
||
|
static void longhorn_snapshot_read_cluster(struct sync_context *ctx);
|
||
|
|
||
|
static uint64_t longhorn_get_cluster_offset(struct sync_context *ctx) {
|
||
|
uint64_t offset = ctx->table[ctx->pos] * ctx->io_units_per_cluster;
|
||
|
|
||
|
return offset;
|
||
|
}
|
||
|
|
||
|
static void lvol_close_cb(void *cb_arg, int lvolerrno) {
|
||
|
}
|
||
|
|
||
|
static void longhorn_snapshot_write_cluster_cb(void *cb_arg, int bserrno) {
|
||
|
struct sync_context *ctx = cb_arg;
|
||
|
|
||
|
if (++ctx->pos < ctx->allocated_clusters) {
|
||
|
longhorn_snapshot_read_cluster(ctx);
|
||
|
} else {
|
||
|
/* done */
|
||
|
spdk_bdev_close(ctx->snapshot_desc);
|
||
|
spdk_lvol_close(ctx->lvol, lvol_close_cb, NULL);
|
||
|
free(ctx->table);
|
||
|
free(ctx);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void longhorn_snapshot_read_cluster_cb(struct spdk_bdev_io *bdev_io,
|
||
|
bool success,
|
||
|
void *cb_arg)
|
||
|
{
|
||
|
struct sync_context *ctx = cb_arg;
|
||
|
|
||
|
|
||
|
spdk_blob_io_write(ctx->lvol->blob, ctx->channel,
|
||
|
ctx->cluster, longhorn_get_cluster_offset(ctx),
|
||
|
ctx->io_units_per_cluster,
|
||
|
longhorn_snapshot_write_cluster_cb,
|
||
|
ctx);
|
||
|
|
||
|
}
|
||
|
|
||
|
static void longhorn_snapshot_read_cluster(struct sync_context *ctx) {
|
||
|
|
||
|
|
||
|
printf("reading %lu (cluster %u (%u)) (size = %u \n", ctx->table[ctx->pos] * ctx->cluster_size, ctx->table[ctx->pos], ctx->pos, ctx->cluster_size);
|
||
|
|
||
|
spdk_bdev_read(ctx->snapshot_desc, ctx->snapshot_channel,
|
||
|
ctx->cluster,
|
||
|
ctx->table[ctx->pos] * ctx->cluster_size,
|
||
|
ctx->cluster_size,
|
||
|
longhorn_snapshot_read_cluster_cb,
|
||
|
ctx);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
static void longhorn_snapshot_lvol_create_complete_cb(void *arg,
|
||
|
struct spdk_lvol *lvol,
|
||
|
int lvolerrno) {
|
||
|
struct sync_context *ctx = arg;
|
||
|
|
||
|
ctx->lvol = lvol;
|
||
|
|
||
|
ctx->pos = 0;
|
||
|
printf("lvol created\n");
|
||
|
|
||
|
longhorn_snapshot_read_cluster(ctx);
|
||
|
}
|
||
|
|
||
|
void snapshot_bdev_event_cb(enum spdk_bdev_event_type type,
|
||
|
struct spdk_bdev *bdev,
|
||
|
void *event_ctx)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void longhorn_snapshot_bdev_sync(const char *snapshot_bdev_name,
|
||
|
const char *name,
|
||
|
struct spdk_lvol_store *lvs,
|
||
|
uint64_t num_clusters,
|
||
|
uint64_t allocated_clusters,
|
||
|
uint32_t cluster_size,
|
||
|
uint32_t io_unit_size,
|
||
|
uint32_t *table)
|
||
|
{
|
||
|
struct sync_context *ctx;
|
||
|
|
||
|
ctx = calloc(1, sizeof(struct sync_context));
|
||
|
|
||
|
spdk_bdev_open_ext(snapshot_bdev_name, false, snapshot_bdev_event_cb,
|
||
|
ctx, &ctx->snapshot_desc);
|
||
|
|
||
|
ctx->snapshot_bdev = spdk_bdev_desc_get_bdev(ctx->snapshot_desc);
|
||
|
ctx->snapshot_channel = spdk_bdev_get_io_channel(ctx->snapshot_desc);
|
||
|
|
||
|
ctx->cluster = spdk_malloc(cluster_size, ALIGN_4K, NULL,
|
||
|
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
|
||
|
|
||
|
|
||
|
ctx->channel = spdk_bs_alloc_io_channel(lvs->blobstore);
|
||
|
|
||
|
ctx->num_clusters = num_clusters;
|
||
|
ctx->allocated_clusters = allocated_clusters;
|
||
|
ctx->cluster_size = cluster_size;
|
||
|
ctx->io_unit_size = io_unit_size;
|
||
|
ctx->table = table;
|
||
|
|
||
|
ctx->io_units_per_cluster = ctx->cluster_size / ctx->io_unit_size;
|
||
|
|
||
|
vbdev_lvol_create(lvs, name, ctx->num_clusters * ctx->cluster_size, true, LVOL_CLEAR_WITH_DEFAULT, longhorn_snapshot_lvol_create_complete_cb, ctx);
|
||
|
}
|
||
|
|
||
|
|