4 * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
5 * Copyright (c) Intel Corporation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * * Neither the name of Intel Corporation nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Block Device Module Interface
39 #ifndef SPDK_INTERNAL_BDEV_H
40 #define SPDK_INTERNAL_BDEV_H
44 #include <stddef.h> /* for offsetof */
45 #include <sys/uio.h> /* for struct iovec */
48 #include "spdk/bdev.h"
49 #include "spdk/event.h"
50 #include "spdk/queue.h"
51 #include "spdk/scsi_spec.h"
53 /** \page block_backend_modules Block Device Backend Modules
55 To implement a backend block device driver, a number of functions
56 dictated by struct spdk_bdev_fn_table must be provided.
58 The module should register itself using SPDK_BDEV_MODULE_REGISTER or
59 SPDK_VBDEV_MODULE_REGISTER to define the parameters for the module.
61 Use SPDK_BDEV_MODULE_REGISTER for all block backends that are real disks.
62 Any virtual backends such as RAID, partitioning, etc. should use
63 SPDK_VBDEV_MODULE_REGISTER.
67 In the module initialization code, the config file sections can be parsed to
68 acquire custom configuration parameters. For example, if the config file has
69 a section such as below:
75 The value can be extracted as the example below:
77 struct spdk_conf_section *sp = spdk_conf_find_section(NULL, "MyBe");
78 int my_param = spdk_conf_section_get_intval(sp, "MyParam");
81 The backend initialization routine also need to create "disks". A virtual
82 representation of each LUN must be constructed. Mainly a struct spdk_bdev
83 must be passed to the bdev database via spdk_bdev_register().
87 /** Block device module */
88 struct spdk_bdev_module_if
{
90 * Initialization function for the module. Called by the spdk
91 * application during startup.
93 * Modules are required to define this function.
95 int (*module_init
)(void);
98 * Finish function for the module. Called by the spdk application
99 * before the spdk application exits to perform any necessary cleanup.
101 * Modules are not required to define this function.
103 void (*module_fini
)(void);
106 * Function called to return a text string representing the
107 * module's configuration options for inclusion in a configuration file.
109 void (*config_text
)(FILE *fp
);
111 /** Name for the modules being defined. */
112 const char *module_name
;
115 * Returns the allocation size required for the backend for uses such as local
116 * command structs, local SGL, iovecs, or other user context.
118 int (*get_ctx_size
)(void);
120 TAILQ_ENTRY(spdk_bdev_module_if
) tailq
;
124 * Function table for a block device backend.
126 * The backend block device function table provides a set of APIs to allow
127 * communication with a backend. The main commands are read/write API
128 * calls for I/O via submit_request.
130 struct spdk_bdev_fn_table
{
131 /** Destroy the backend block device object */
132 int (*destruct
)(void *ctx
);
134 /** Process the IO. */
135 void (*submit_request
)(struct spdk_bdev_io
*);
137 /** Check if the block device supports a specific I/O type. */
138 bool (*io_type_supported
)(void *ctx
, enum spdk_bdev_io_type
);
140 /** Get an I/O channel for the specific bdev for the calling thread. */
141 struct spdk_io_channel
*(*get_io_channel
)(void *ctx
, uint32_t priority
);
144 * Output driver-specific configuration to a JSON stream. Optional - may be NULL.
146 * The JSON write context will be initialized with an open object, so the bdev
147 * driver should write a name (based on the driver name) followed by a JSON value
148 * (most likely another nested object).
150 int (*dump_config_json
)(void *ctx
, struct spdk_json_write_ctx
*w
);
153 void spdk_bdev_register(struct spdk_bdev
*bdev
);
154 void spdk_bdev_io_get_rbuf(struct spdk_bdev_io
*bdev_io
, spdk_bdev_io_get_rbuf_cb cb
);
155 struct spdk_bdev_io
*spdk_bdev_get_io(void);
156 struct spdk_bdev_io
*spdk_bdev_get_child_io(struct spdk_bdev_io
*parent
,
157 struct spdk_bdev
*bdev
,
158 spdk_bdev_io_completion_cb cb
,
160 void spdk_bdev_io_resubmit(struct spdk_bdev_io
*bdev_io
, struct spdk_bdev
*new_bdev
);
161 void spdk_bdev_io_complete(struct spdk_bdev_io
*bdev_io
,
162 enum spdk_bdev_io_status status
);
165 * Complete a bdev_io with an NVMe status code.
167 * \param bdev_io I/O to complete.
168 * \param sct NVMe Status Code Type.
169 * \param sc NVMe Status Code.
171 void spdk_bdev_io_complete_nvme_status(struct spdk_bdev_io
*bdev_io
, int sct
, int sc
);
173 void spdk_bdev_module_list_add(struct spdk_bdev_module_if
*bdev_module
);
174 void spdk_vbdev_module_list_add(struct spdk_bdev_module_if
*vbdev_module
);
176 static inline struct spdk_bdev_io
*
177 spdk_bdev_io_from_ctx(void *ctx
)
179 return (struct spdk_bdev_io
*)
180 ((uintptr_t)ctx
- offsetof(struct spdk_bdev_io
, driver_ctx
));
183 #define SPDK_BDEV_MODULE_REGISTER(init_fn, fini_fn, config_fn, ctx_size_fn) \
184 static struct spdk_bdev_module_if init_fn ## _if = { \
185 .module_init = init_fn, \
186 .module_fini = fini_fn, \
187 .config_text = config_fn, \
188 .get_ctx_size = ctx_size_fn, \
190 __attribute__((constructor)) static void init_fn ## _init(void) \
192 spdk_bdev_module_list_add(&init_fn ## _if); \
195 #define SPDK_VBDEV_MODULE_REGISTER(init_fn, fini_fn, config_fn, ctx_size_fn) \
196 static struct spdk_bdev_module_if init_fn ## _if = { \
197 .module_init = init_fn, \
198 .module_fini = fini_fn, \
199 .config_text = config_fn, \
200 .get_ctx_size = ctx_size_fn, \
202 __attribute__((constructor)) static void init_fn ## _init(void) \
204 spdk_vbdev_module_list_add(&init_fn ## _if); \
207 #endif /* SPDK_INTERNAL_BDEV_H */