Spdk/lib/blob/zeroes.c
Evgeniy Kochetov 9e843fdbd1 blob: Add translate_lba operation
New `translate_lba` operation allows to translate blob lba to lba on
the underlying bdev. It recurses down the whole chain of bs_dev's. The
operation may fail to do the translation when blob lba is not backed
by the real bdev. For example, when we eventually hit zeroes device in
the chain.

This operation is used in the next commit to get source LBA for copy
operation.

Signed-off-by: Evgeniy Kochetov <evgeniik@nvidia.com>
Change-Id: I89c2d03d1982d66b9137a3a3653a98c361984fab
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14528
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com>
2022-12-08 12:54:54 +00:00

156 lines
3.9 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (C) 2018 Intel Corporation.
* All rights reserved.
* Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*/
#include "spdk/stdinc.h"
#include "spdk/blob.h"
#include "spdk/dma.h"
#include "blobstore.h"
static void
zeroes_destroy(struct spdk_bs_dev *bs_dev)
{
return;
}
static void
zeroes_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
{
memset(payload, 0, dev->blocklen * lba_count);
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
}
static void
zeroes_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args)
{
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
assert(false);
}
static void
zeroes_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt,
uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
{
int i;
for (i = 0; i < iovcnt; i++) {
memset(iov[i].iov_base, 0, iov[i].iov_len);
}
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
}
static void
zeroes_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args)
{
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
assert(false);
}
static void
_read_memory_domain_memzero_done(void *ctx, int rc)
{
struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)ctx;
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc);
}
static void
zeroes_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt,
uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args,
struct spdk_blob_ext_io_opts *ext_io_opts)
{
int i, rc;
if (ext_io_opts->memory_domain) {
rc = spdk_memory_domain_memzero(ext_io_opts->memory_domain, ext_io_opts->memory_domain_ctx, iov,
iovcnt, _read_memory_domain_memzero_done, cb_args);
if (rc) {
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc);
}
return;
}
for (i = 0; i < iovcnt; i++) {
memset(iov[i].iov_base, 0, iov[i].iov_len);
}
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
}
static void
zeroes_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
struct iovec *iov, int iovcnt,
uint64_t lba, uint32_t lba_count,
struct spdk_bs_dev_cb_args *cb_args,
struct spdk_blob_ext_io_opts *ext_io_opts)
{
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
assert(false);
}
static void
zeroes_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
uint64_t lba, uint64_t lba_count,
struct spdk_bs_dev_cb_args *cb_args)
{
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
assert(false);
}
static void
zeroes_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
uint64_t lba, uint64_t lba_count,
struct spdk_bs_dev_cb_args *cb_args)
{
cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
assert(false);
}
static bool
zeroes_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
{
return true;
}
static bool
zeroes_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba)
{
return false;
}
static struct spdk_bs_dev g_zeroes_bs_dev = {
.blockcnt = UINT64_MAX,
.blocklen = 512,
.create_channel = NULL,
.destroy_channel = NULL,
.destroy = zeroes_destroy,
.read = zeroes_read,
.write = zeroes_write,
.readv = zeroes_readv,
.writev = zeroes_writev,
.readv_ext = zeroes_readv_ext,
.writev_ext = zeroes_writev_ext,
.write_zeroes = zeroes_write_zeroes,
.unmap = zeroes_unmap,
.is_zeroes = zeroes_is_zeroes,
.translate_lba = zeroes_translate_lba,
};
struct spdk_bs_dev *
bs_create_zeroes_dev(void)
{
return &g_zeroes_bs_dev;
}