// SPDX-License-Identifier: MIT or GPL-2.0-only #include #include "ublksrv_tgt.h" static int null_init_tgt(struct ublksrv_dev *dev, int type, int argc, char *argv[]) { struct ublksrv_tgt_info *tgt = &dev->tgt; const struct ublksrv_ctrl_dev_info *info = ublksrv_ctrl_get_dev_info(ublksrv_get_ctrl_dev(dev)); int jbuf_size; char *jbuf = ublksrv_tgt_return_json_buf(dev, &jbuf_size); struct ublksrv_tgt_base_json tgt_json = { .type = type, }; unsigned long long dev_size = 250UL * 1024 * 1024 * 1024; struct ublk_params p = { .types = UBLK_PARAM_TYPE_BASIC, .basic = { .logical_bs_shift = 9, .physical_bs_shift = 12, .io_opt_shift = 12, .io_min_shift = 9, .max_sectors = info->max_io_buf_bytes >> 9, .dev_sectors = dev_size >> 9, }, }; strcpy(tgt_json.name, "null"); if (type != UBLKSRV_TGT_TYPE_NULL) return -1; tgt_json.dev_size = tgt->dev_size = dev_size; tgt->tgt_ring_depth = info->queue_depth; tgt->nr_fds = 0; ublksrv_tgt_set_io_data_size(tgt); ublk_json_write_dev_info(dev, &jbuf, &jbuf_size); ublk_json_write_target_base(dev, &jbuf, &jbuf_size, &tgt_json); ublk_json_write_params(dev, &jbuf, &jbuf_size, &p); return 0; } static int null_recovery_tgt(struct ublksrv_dev *dev, int type) { const struct ublksrv_ctrl_dev *cdev = ublksrv_get_ctrl_dev(dev); const char *jbuf = ublksrv_ctrl_get_recovery_jbuf(cdev); const struct ublksrv_ctrl_dev_info *info = ublksrv_ctrl_get_dev_info(cdev); struct ublksrv_tgt_info *tgt = &dev->tgt; int ret; struct ublk_params p; ublk_assert(jbuf); ublk_assert(info->state == UBLK_S_DEV_QUIESCED); ublk_assert(type == UBLKSRV_TGT_TYPE_NULL); ret = ublksrv_json_read_params(&p, jbuf); if (ret) { ublk_err( "%s: read ublk params failed %d\n", __func__, ret); return ret; } ublksrv_tgt_set_io_data_size(tgt); tgt->dev_size = p.basic.dev_sectors << 9; tgt->tgt_ring_depth = info->queue_depth; tgt->nr_fds = 0; return 0; } static co_io_job __null_handle_io_async(const struct ublksrv_queue *q, const struct ublk_io_data *data, int tag) { ublksrv_complete_io(q, tag, data->iod->nr_sectors << 9); co_return; } static int null_handle_io_async(const struct ublksrv_queue *q, const struct ublk_io_data *data) { struct ublk_io_tgt *io = __ublk_get_io_tgt_data(data); io->co = __null_handle_io_async(q, data, data->tag); return 0; } struct ublksrv_tgt_type null_tgt_type = { .handle_io_async = null_handle_io_async, .init_tgt = null_init_tgt, .type = UBLKSRV_TGT_TYPE_NULL, .name = "null", .recovery_tgt = null_recovery_tgt, }; static void tgt_null_init() __attribute__((constructor)); static void tgt_null_init(void) { ublksrv_register_tgt_type(&null_tgt_type); }