206 lines
4.7 KiB
C
206 lines
4.7 KiB
C
#include "spdk/rpc.h"
|
|
#include "spdk/bdev.h"
|
|
#include "spdk/util.h"
|
|
#include "spdk/string.h"
|
|
#include "spdk/log.h"
|
|
#include "spdk/env.h"
|
|
#include "spdk_internal/lvolstore.h"
|
|
#include "../lvol/vbdev_lvol.h"
|
|
#include "lib/blob/blobstore.h"
|
|
#include "bdev_longhorn_lvol.h"
|
|
|
|
#define ALIGN_4K 4096
|
|
|
|
struct spdk_lvol_store *
|
|
longhorn_get_lvol_store_by_name(const char *name)
|
|
{
|
|
struct spdk_lvol_store *lvs = NULL;
|
|
struct lvol_store_bdev *lvs_bdev = vbdev_lvol_store_first();
|
|
|
|
while (lvs_bdev != NULL) {
|
|
lvs = lvs_bdev->lvs;
|
|
printf("lvs->name = %s\n", lvs->name);
|
|
if (strncmp(lvs->name, name, sizeof(lvs->name)) == 0) {
|
|
return lvs;
|
|
}
|
|
lvs_bdev = vbdev_lvol_store_next(lvs_bdev);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
enum longhorn_lvol_state {
|
|
LVOL_SEND_NAME,
|
|
LVOL_SEND_HEADER,
|
|
LVOL_SEND_TABLE,
|
|
LVOL_SEND_CLUSTER
|
|
};
|
|
|
|
struct longhorn_lvol_context {
|
|
int fd;
|
|
bool *busy;
|
|
spdk_blob_id blob_id;
|
|
char name[256];
|
|
|
|
struct spdk_blob_store *bs;
|
|
struct spdk_blob *blob;
|
|
struct spdk_io_channel *channel;
|
|
uint32_t *table;
|
|
struct longhorn_lvol_header header;
|
|
|
|
uint64_t io_units_per_cluster;
|
|
|
|
uint8_t *cluster;
|
|
|
|
enum longhorn_lvol_state state;
|
|
|
|
size_t pos;
|
|
|
|
};
|
|
|
|
|
|
|
|
uint64_t longhorn_get_allocated_clusters(struct spdk_blob *blob) {
|
|
uint64_t allocated_clusters = 0;
|
|
uint64_t i = 0;
|
|
|
|
for (i = 0; i < blob->active.num_clusters; ++i) {
|
|
if (blob->active.clusters[i] != 0) {
|
|
++allocated_clusters;
|
|
}
|
|
}
|
|
|
|
return allocated_clusters;
|
|
}
|
|
|
|
void longhorn_export_allocated_clusters(struct spdk_blob *blob, uint32_t *table) {
|
|
uint64_t i = 0;
|
|
uint64_t pos = 0;
|
|
|
|
for (i = 0; i < blob->active.num_clusters; ++i) {
|
|
if (blob->active.clusters[i] != 0) {
|
|
table[pos++] = i;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
static uint64_t longhorn_get_cluster_offset(struct longhorn_lvol_context *ctx) {
|
|
uint64_t offset = ctx->table[ctx->pos++] * ctx->io_units_per_cluster;
|
|
|
|
return offset;
|
|
}
|
|
|
|
static void longhorn_cluster_read_cb(void *arg1, int bserrno) {
|
|
struct longhorn_lvol_context *ctx = arg1;
|
|
|
|
|
|
if (bserrno) {
|
|
return;
|
|
}
|
|
|
|
printf("writing cluster %u\n", ctx->table[ctx->pos]);
|
|
write(ctx->fd, ctx->cluster, ctx->header.cluster_size);
|
|
printf("wrote cluster %u\n", ctx->table[ctx->pos]);
|
|
|
|
if (ctx->pos < ctx->header.allocated_clusters) {
|
|
spdk_blob_io_read(ctx->blob, ctx->channel, ctx->cluster,
|
|
longhorn_get_cluster_offset(ctx),
|
|
ctx->io_units_per_cluster,
|
|
longhorn_cluster_read_cb,
|
|
ctx);
|
|
} else {
|
|
/* Complete */
|
|
//ctx->busy = 0;
|
|
}
|
|
}
|
|
|
|
static void async_write(void *ptr, size_t size,
|
|
struct longhorn_lvol_context *ctx,
|
|
void (*next)(struct longhorn_lvol_context *arg)
|
|
) {
|
|
|
|
|
|
}
|
|
|
|
static void longhorn_blob_header(void *arg) {
|
|
struct longhorn_lvol_context *ctx = arg;
|
|
}
|
|
|
|
|
|
|
|
|
|
static void longhorn_blob_opened(void *arg, struct spdk_blob *blob, int bserrno) {
|
|
struct longhorn_lvol_context *ctx = arg;
|
|
char *name;
|
|
size_t len;
|
|
|
|
ctx->blob = blob;
|
|
|
|
spdk_blob_get_xattr_value(blob, "name", &name, &len);
|
|
|
|
printf("name = %s\n", name);
|
|
|
|
strncpy(ctx->name, name, len);
|
|
|
|
write(ctx->fd, ctx->name, sizeof(ctx->name));
|
|
|
|
ctx->header.num_clusters = blob->active.num_clusters;
|
|
ctx->header.allocated_clusters = longhorn_get_allocated_clusters(blob);
|
|
ctx->header.cluster_size = ctx->bs->cluster_sz;
|
|
ctx->header.io_unit_size = ctx->bs->io_unit_size;
|
|
|
|
write(ctx->fd, &ctx->header, sizeof(ctx->header));
|
|
|
|
ctx->table = calloc(1, sizeof(uint32_t) * ctx->header.allocated_clusters);
|
|
longhorn_export_allocated_clusters(blob, ctx->table);
|
|
|
|
printf("writing table\n");
|
|
write(ctx->fd, ctx->table, sizeof(uint32_t) * ctx->header.allocated_clusters);
|
|
printf("wrote table\n");
|
|
|
|
|
|
ctx->cluster = spdk_malloc(ctx->header.cluster_size, ALIGN_4K, NULL,
|
|
SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
|
|
|
|
ctx->io_units_per_cluster = ctx->header.cluster_size / ctx->header.io_unit_size;
|
|
ctx->channel = spdk_bs_alloc_io_channel(ctx->bs);
|
|
|
|
if (ctx->pos < ctx->header.allocated_clusters) {
|
|
spdk_blob_io_read(ctx->blob, ctx->channel, ctx->cluster,
|
|
longhorn_get_cluster_offset(ctx),
|
|
ctx->io_units_per_cluster,
|
|
longhorn_cluster_read_cb,
|
|
ctx);
|
|
}
|
|
|
|
}
|
|
|
|
static void longhorn_lvol_handle_state(struct longhorn_lvol_context *ctx) {
|
|
switch (ctx->state) {
|
|
case LVOL_SEND_NAME:
|
|
break;
|
|
case LVOL_SEND_HEADER:
|
|
break;
|
|
case LVOL_SEND_TABLE:
|
|
break;
|
|
case LVOL_SEND_CLUSTER:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void longhorn_lvol_transmit(int fd, uint64_t blob_id, struct spdk_blob_store *bs, bool *busy) {
|
|
struct longhorn_lvol_context *ctx;
|
|
|
|
ctx = calloc(1, sizeof(struct longhorn_lvol_context));
|
|
|
|
ctx->fd = fd;
|
|
ctx->blob_id = (spdk_blob_id) blob_id;
|
|
ctx->bs = bs;
|
|
|
|
spdk_bs_open_blob(bs, ctx->blob_id, longhorn_blob_opened, ctx);
|
|
}
|
|
|
|
|