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 if (info->flags & UBLK_F_UNPRIVILEGED_DEV)
37 return -1;
38
39 tgt_json.dev_size = tgt->dev_size = dev_size;
40 tgt->tgt_ring_depth = info->queue_depth;
41 tgt->nr_fds = 0;
42 ublksrv_tgt_set_io_data_size(tgt);
43
44 ublk_json_write_dev_info(dev, &jbuf, &jbuf_size);
45 ublk_json_write_target_base(dev, &jbuf, &jbuf_size, &tgt_json);
46 ublk_json_write_params(dev, &jbuf, &jbuf_size, &p);
47
48 return 0;
49 }
50
null_recovery_tgt(struct ublksrv_dev * dev,int type)51 static int null_recovery_tgt(struct ublksrv_dev *dev, int type)
52 {
53 const struct ublksrv_ctrl_dev *cdev = ublksrv_get_ctrl_dev(dev);
54 const char *jbuf = ublksrv_ctrl_get_recovery_jbuf(cdev);
55 const struct ublksrv_ctrl_dev_info *info =
56 ublksrv_ctrl_get_dev_info(cdev);
57 struct ublksrv_tgt_info *tgt = &dev->tgt;
58 int ret;
59 struct ublk_params p;
60
61 ublk_assert(jbuf);
62 ublk_assert(type == UBLKSRV_TGT_TYPE_NULL);
63
64 ret = ublksrv_json_read_params(&p, jbuf);
65 if (ret) {
66 ublk_err( "%s: read ublk params failed %d\n",
67 __func__, ret);
68 return ret;
69 }
70
71 ublksrv_tgt_set_io_data_size(tgt);
72 tgt->dev_size = p.basic.dev_sectors << 9;
73 tgt->tgt_ring_depth = info->queue_depth;
74 tgt->nr_fds = 0;
75 return 0;
76 }
77
__null_handle_io_async(const struct ublksrv_queue * q,const struct ublk_io_data * data,int tag)78 static co_io_job __null_handle_io_async(const struct ublksrv_queue *q,
79 const struct ublk_io_data *data, int tag)
80 {
81 ublksrv_complete_io(q, tag, data->iod->nr_sectors << 9);
82
83 co_return;
84 }
85
null_handle_io_async(const struct ublksrv_queue * q,const struct ublk_io_data * data)86 static int null_handle_io_async(const struct ublksrv_queue *q,
87 const struct ublk_io_data *data)
88 {
89 struct ublk_io_tgt *io = __ublk_get_io_tgt_data(data);
90
91 io->co = __null_handle_io_async(q, data, data->tag);
92
93 return 0;
94 }
95
96 struct ublksrv_tgt_type null_tgt_type = {
97 .handle_io_async = null_handle_io_async,
98 .init_tgt = null_init_tgt,
99 .type = UBLKSRV_TGT_TYPE_NULL,
100 .name = "null",
101 .recovery_tgt = null_recovery_tgt,
102 };
103
104 static void tgt_null_init() __attribute__((constructor));
105
tgt_null_init(void)106 static void tgt_null_init(void)
107 {
108 ublksrv_register_tgt_type(&null_tgt_type);
109 }
110
111