1 // SPDX-License-Identifier: MIT or GPL-2.0-only
2
3 #include <config.h>
4
5 #include "ublksrv_tgt.h"
6
null_init_tgt(struct ublksrv_dev * dev,int type,int argc,char * argv[])7 static int null_init_tgt(struct ublksrv_dev *dev, int type, int argc,
8 char *argv[])
9 {
10 struct ublksrv_tgt_info *tgt = &dev->tgt;
11 const struct ublksrv_ctrl_dev_info *info =
12 ublksrv_ctrl_get_dev_info(ublksrv_get_ctrl_dev(dev));
13 int jbuf_size;
14 char *jbuf = ublksrv_tgt_return_json_buf(dev, &jbuf_size);
15 struct ublksrv_tgt_base_json tgt_json = {
16 .type = type,
17 };
18 unsigned long long dev_size = 250UL * 1024 * 1024 * 1024;
19 struct ublk_params p = {
20 .types = UBLK_PARAM_TYPE_BASIC,
21 .basic = {
22 .logical_bs_shift = 9,
23 .physical_bs_shift = 12,
24 .io_opt_shift = 12,
25 .io_min_shift = 9,
26 .max_sectors = info->max_io_buf_bytes >> 9,
27 .dev_sectors = dev_size >> 9,
28 },
29 };
30
31 strcpy(tgt_json.name, "null");
32
33 if (type != UBLKSRV_TGT_TYPE_NULL)
34 return -1;
35
36 tgt_json.dev_size = tgt->dev_size = dev_size;
37 tgt->tgt_ring_depth = info->queue_depth;
38 tgt->nr_fds = 0;
39 ublksrv_tgt_set_io_data_size(tgt);
40
41 ublk_json_write_dev_info(dev, &jbuf, &jbuf_size);
42 ublk_json_write_target_base(dev, &jbuf, &jbuf_size, &tgt_json);
43 ublk_json_write_params(dev, &jbuf, &jbuf_size, &p);
44
45 return 0;
46 }
47
null_recovery_tgt(struct ublksrv_dev * dev,int type)48 static int null_recovery_tgt(struct ublksrv_dev *dev, int type)
49 {
50 const struct ublksrv_ctrl_dev *cdev = ublksrv_get_ctrl_dev(dev);
51 const char *jbuf = ublksrv_ctrl_get_recovery_jbuf(cdev);
52 const struct ublksrv_ctrl_dev_info *info =
53 ublksrv_ctrl_get_dev_info(cdev);
54 struct ublksrv_tgt_info *tgt = &dev->tgt;
55 int ret;
56 struct ublk_params p;
57
58 ublk_assert(jbuf);
59 ublk_assert(info->state == UBLK_S_DEV_QUIESCED);
60 ublk_assert(type == UBLKSRV_TGT_TYPE_NULL);
61
62 ret = ublksrv_json_read_params(&p, jbuf);
63 if (ret) {
64 ublk_err( "%s: read ublk params failed %d\n",
65 __func__, ret);
66 return ret;
67 }
68
69 ublksrv_tgt_set_io_data_size(tgt);
70 tgt->dev_size = p.basic.dev_sectors << 9;
71 tgt->tgt_ring_depth = info->queue_depth;
72 tgt->nr_fds = 0;
73 return 0;
74 }
75
__null_handle_io_async(const struct ublksrv_queue * q,const struct ublk_io_data * data,int tag)76 static co_io_job __null_handle_io_async(const struct ublksrv_queue *q,
77 const struct ublk_io_data *data, int tag)
78 {
79 ublksrv_complete_io(q, tag, data->iod->nr_sectors << 9);
80
81 co_return;
82 }
83
null_handle_io_async(const struct ublksrv_queue * q,const struct ublk_io_data * data)84 static int null_handle_io_async(const struct ublksrv_queue *q,
85 const struct ublk_io_data *data)
86 {
87 struct ublk_io_tgt *io = __ublk_get_io_tgt_data(data);
88
89 io->co = __null_handle_io_async(q, data, data->tag);
90
91 return 0;
92 }
93
94 struct ublksrv_tgt_type null_tgt_type = {
95 .handle_io_async = null_handle_io_async,
96 .init_tgt = null_init_tgt,
97 .type = UBLKSRV_TGT_TYPE_NULL,
98 .name = "null",
99 .recovery_tgt = null_recovery_tgt,
100 };
101
102 static void tgt_null_init() __attribute__((constructor));
103
tgt_null_init(void)104 static void tgt_null_init(void)
105 {
106 ublksrv_register_tgt_type(&null_tgt_type);
107 }
108
109