xref: /spdk/lib/blob/zeroes.c (revision d3594f8437a2e8db487ac15c32650088d7c783e0)
1488570ebSJim Harris /*   SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse  *   Copyright (C) 2018 Intel Corporation.
38970f868SBen Walker  *   All rights reserved.
4ba8f1a9eSAlexey Marchuk  *   Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
58970f868SBen Walker  */
68970f868SBen Walker 
78970f868SBen Walker #include "spdk/stdinc.h"
88970f868SBen Walker #include "spdk/blob.h"
9ba8f1a9eSAlexey Marchuk #include "spdk/dma.h"
108970f868SBen Walker 
118970f868SBen Walker #include "blobstore.h"
128970f868SBen Walker 
138970f868SBen Walker static void
148970f868SBen Walker zeroes_destroy(struct spdk_bs_dev *bs_dev)
158970f868SBen Walker {
168970f868SBen Walker 	return;
178970f868SBen Walker }
188970f868SBen Walker 
198970f868SBen Walker static void
208970f868SBen Walker zeroes_read(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
218970f868SBen Walker 	    uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
228970f868SBen Walker {
238970f868SBen Walker 	memset(payload, 0, dev->blocklen * lba_count);
248970f868SBen Walker 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
258970f868SBen Walker }
268970f868SBen Walker 
278970f868SBen Walker static void
288970f868SBen Walker zeroes_write(struct spdk_bs_dev *dev, struct spdk_io_channel *channel, void *payload,
298970f868SBen Walker 	     uint64_t lba, uint32_t lba_count,
308970f868SBen Walker 	     struct spdk_bs_dev_cb_args *cb_args)
318970f868SBen Walker {
328970f868SBen Walker 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
338970f868SBen Walker 	assert(false);
348970f868SBen Walker }
358970f868SBen Walker 
368970f868SBen Walker static void
378970f868SBen Walker zeroes_readv(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
388970f868SBen Walker 	     struct iovec *iov, int iovcnt,
398970f868SBen Walker 	     uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args)
408970f868SBen Walker {
418970f868SBen Walker 	int i;
428970f868SBen Walker 
438970f868SBen Walker 	for (i = 0; i < iovcnt; i++) {
448970f868SBen Walker 		memset(iov[i].iov_base, 0, iov[i].iov_len);
458970f868SBen Walker 	}
468970f868SBen Walker 
478970f868SBen Walker 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
488970f868SBen Walker }
498970f868SBen Walker 
508970f868SBen Walker static void
518970f868SBen Walker zeroes_writev(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
528970f868SBen Walker 	      struct iovec *iov, int iovcnt,
538970f868SBen Walker 	      uint64_t lba, uint32_t lba_count,
548970f868SBen Walker 	      struct spdk_bs_dev_cb_args *cb_args)
558970f868SBen Walker {
568970f868SBen Walker 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
578970f868SBen Walker 	assert(false);
588970f868SBen Walker }
598970f868SBen Walker 
608970f868SBen Walker static void
61ba8f1a9eSAlexey Marchuk _read_memory_domain_memzero_done(void *ctx, int rc)
62ba8f1a9eSAlexey Marchuk {
63ba8f1a9eSAlexey Marchuk 	struct spdk_bs_dev_cb_args *cb_args = (struct spdk_bs_dev_cb_args *)ctx;
64ba8f1a9eSAlexey Marchuk 
65ba8f1a9eSAlexey Marchuk 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc);
66ba8f1a9eSAlexey Marchuk }
67ba8f1a9eSAlexey Marchuk 
68ba8f1a9eSAlexey Marchuk static void
69ba8f1a9eSAlexey Marchuk zeroes_readv_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
70ba8f1a9eSAlexey Marchuk 		 struct iovec *iov, int iovcnt,
71ba8f1a9eSAlexey Marchuk 		 uint64_t lba, uint32_t lba_count, struct spdk_bs_dev_cb_args *cb_args,
72ba8f1a9eSAlexey Marchuk 		 struct spdk_blob_ext_io_opts *ext_io_opts)
73ba8f1a9eSAlexey Marchuk {
74ba8f1a9eSAlexey Marchuk 	int i, rc;
75ba8f1a9eSAlexey Marchuk 
76ba8f1a9eSAlexey Marchuk 	if (ext_io_opts->memory_domain) {
77ba8f1a9eSAlexey Marchuk 		rc = spdk_memory_domain_memzero(ext_io_opts->memory_domain, ext_io_opts->memory_domain_ctx, iov,
78ba8f1a9eSAlexey Marchuk 						iovcnt, _read_memory_domain_memzero_done, cb_args);
79ba8f1a9eSAlexey Marchuk 		if (rc) {
80ba8f1a9eSAlexey Marchuk 			cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, rc);
81ba8f1a9eSAlexey Marchuk 		}
82ba8f1a9eSAlexey Marchuk 		return;
83ba8f1a9eSAlexey Marchuk 	}
84ba8f1a9eSAlexey Marchuk 
85ba8f1a9eSAlexey Marchuk 	for (i = 0; i < iovcnt; i++) {
86ba8f1a9eSAlexey Marchuk 		memset(iov[i].iov_base, 0, iov[i].iov_len);
87ba8f1a9eSAlexey Marchuk 	}
88ba8f1a9eSAlexey Marchuk 
89ba8f1a9eSAlexey Marchuk 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, 0);
90ba8f1a9eSAlexey Marchuk }
91ba8f1a9eSAlexey Marchuk 
92ba8f1a9eSAlexey Marchuk static void
93ba8f1a9eSAlexey Marchuk zeroes_writev_ext(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
94ba8f1a9eSAlexey Marchuk 		  struct iovec *iov, int iovcnt,
95ba8f1a9eSAlexey Marchuk 		  uint64_t lba, uint32_t lba_count,
96ba8f1a9eSAlexey Marchuk 		  struct spdk_bs_dev_cb_args *cb_args,
97ba8f1a9eSAlexey Marchuk 		  struct spdk_blob_ext_io_opts *ext_io_opts)
98ba8f1a9eSAlexey Marchuk {
99ba8f1a9eSAlexey Marchuk 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
100ba8f1a9eSAlexey Marchuk 	assert(false);
101ba8f1a9eSAlexey Marchuk }
102ba8f1a9eSAlexey Marchuk 
103ba8f1a9eSAlexey Marchuk static void
1048970f868SBen Walker zeroes_write_zeroes(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
105f01146aeSJim Harris 		    uint64_t lba, uint64_t lba_count,
1068970f868SBen Walker 		    struct spdk_bs_dev_cb_args *cb_args)
1078970f868SBen Walker {
108a8c32ed5SChangpeng Liu 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
109a8c32ed5SChangpeng Liu 	assert(false);
1108970f868SBen Walker }
1118970f868SBen Walker 
1128970f868SBen Walker static void
1138970f868SBen Walker zeroes_unmap(struct spdk_bs_dev *dev, struct spdk_io_channel *channel,
114f01146aeSJim Harris 	     uint64_t lba, uint64_t lba_count,
1158970f868SBen Walker 	     struct spdk_bs_dev_cb_args *cb_args)
1168970f868SBen Walker {
117a8c32ed5SChangpeng Liu 	cb_args->cb_fn(cb_args->channel, cb_args->cb_arg, -EPERM);
118a8c32ed5SChangpeng Liu 	assert(false);
1198970f868SBen Walker }
1208970f868SBen Walker 
1212e7a7fe5SEvgeniy Kochetov static bool
1222e7a7fe5SEvgeniy Kochetov zeroes_is_zeroes(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
1232e7a7fe5SEvgeniy Kochetov {
1242e7a7fe5SEvgeniy Kochetov 	return true;
1252e7a7fe5SEvgeniy Kochetov }
1262e7a7fe5SEvgeniy Kochetov 
1279e843fdbSEvgeniy Kochetov static bool
12800311abcSDiwakar Sharma zeroes_is_range_valid(struct spdk_bs_dev *dev, uint64_t lba, uint64_t lba_count)
12900311abcSDiwakar Sharma {
13000311abcSDiwakar Sharma 	return true;
13100311abcSDiwakar Sharma }
13200311abcSDiwakar Sharma 
13300311abcSDiwakar Sharma static bool
1349e843fdbSEvgeniy Kochetov zeroes_translate_lba(struct spdk_bs_dev *dev, uint64_t lba, uint64_t *base_lba)
1359e843fdbSEvgeniy Kochetov {
1369e843fdbSEvgeniy Kochetov 	return false;
1379e843fdbSEvgeniy Kochetov }
1389e843fdbSEvgeniy Kochetov 
1398970f868SBen Walker static struct spdk_bs_dev g_zeroes_bs_dev = {
1408970f868SBen Walker 	.blockcnt = UINT64_MAX,
1416609b776SPiotr Pelplinski 	.blocklen = 512,
1428970f868SBen Walker 	.create_channel = NULL,
1438970f868SBen Walker 	.destroy_channel = NULL,
1448970f868SBen Walker 	.destroy = zeroes_destroy,
1458970f868SBen Walker 	.read = zeroes_read,
1468970f868SBen Walker 	.write = zeroes_write,
1478970f868SBen Walker 	.readv = zeroes_readv,
1488970f868SBen Walker 	.writev = zeroes_writev,
149ba8f1a9eSAlexey Marchuk 	.readv_ext = zeroes_readv_ext,
150ba8f1a9eSAlexey Marchuk 	.writev_ext = zeroes_writev_ext,
1518970f868SBen Walker 	.write_zeroes = zeroes_write_zeroes,
1528970f868SBen Walker 	.unmap = zeroes_unmap,
1532e7a7fe5SEvgeniy Kochetov 	.is_zeroes = zeroes_is_zeroes,
15400311abcSDiwakar Sharma 	.is_range_valid = zeroes_is_range_valid,
1559e843fdbSEvgeniy Kochetov 	.translate_lba = zeroes_translate_lba,
1568970f868SBen Walker };
1578970f868SBen Walker 
1588970f868SBen Walker struct spdk_bs_dev *
159ad7fdd12SSeth Howell bs_create_zeroes_dev(void)
1608970f868SBen Walker {
1618970f868SBen Walker 	return &g_zeroes_bs_dev;
1628970f868SBen Walker }
163*d3594f84Sxupeng-mingtu 
164*d3594f84Sxupeng-mingtu bool
165*d3594f84Sxupeng-mingtu blob_backed_with_zeroes_dev(struct spdk_blob *blob)
166*d3594f84Sxupeng-mingtu {
167*d3594f84Sxupeng-mingtu 	return blob != NULL && blob->back_bs_dev == &g_zeroes_bs_dev;
168*d3594f84Sxupeng-mingtu }
169