4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include "bdev_ocssd.h"
38 struct nvme_bdev_ctrlrs g_nvme_bdev_ctrlrs
= TAILQ_HEAD_INITIALIZER(g_nvme_bdev_ctrlrs
);
39 pthread_mutex_t g_bdev_nvme_mutex
= PTHREAD_MUTEX_INITIALIZER
;
40 bool g_bdev_nvme_module_finish
;
42 struct nvme_bdev_ctrlr
*
43 nvme_bdev_ctrlr_get(const struct spdk_nvme_transport_id
*trid
)
45 struct nvme_bdev_ctrlr
*nvme_bdev_ctrlr
;
47 TAILQ_FOREACH(nvme_bdev_ctrlr
, &g_nvme_bdev_ctrlrs
, tailq
) {
48 if (spdk_nvme_transport_id_compare(trid
, nvme_bdev_ctrlr
->trid
) == 0) {
49 return nvme_bdev_ctrlr
;
56 struct nvme_bdev_ctrlr
*
57 nvme_bdev_ctrlr_get_by_name(const char *name
)
59 struct nvme_bdev_ctrlr
*nvme_bdev_ctrlr
;
65 TAILQ_FOREACH(nvme_bdev_ctrlr
, &g_nvme_bdev_ctrlrs
, tailq
) {
66 if (strcmp(name
, nvme_bdev_ctrlr
->name
) == 0) {
67 return nvme_bdev_ctrlr
;
74 struct nvme_bdev_ctrlr
*
75 nvme_bdev_first_ctrlr(void)
77 return TAILQ_FIRST(&g_nvme_bdev_ctrlrs
);
80 struct nvme_bdev_ctrlr
*
81 nvme_bdev_next_ctrlr(struct nvme_bdev_ctrlr
*prev
)
83 return TAILQ_NEXT(prev
, tailq
);
87 nvme_bdev_dump_trid_json(struct spdk_nvme_transport_id
*trid
, struct spdk_json_write_ctx
*w
)
89 const char *trtype_str
;
90 const char *adrfam_str
;
92 trtype_str
= spdk_nvme_transport_id_trtype_str(trid
->trtype
);
94 spdk_json_write_named_string(w
, "trtype", trtype_str
);
97 adrfam_str
= spdk_nvme_transport_id_adrfam_str(trid
->adrfam
);
99 spdk_json_write_named_string(w
, "adrfam", adrfam_str
);
102 if (trid
->traddr
[0] != '\0') {
103 spdk_json_write_named_string(w
, "traddr", trid
->traddr
);
106 if (trid
->trsvcid
[0] != '\0') {
107 spdk_json_write_named_string(w
, "trsvcid", trid
->trsvcid
);
110 if (trid
->subnqn
[0] != '\0') {
111 spdk_json_write_named_string(w
, "subnqn", trid
->subnqn
);
116 nvme_bdev_unregister_cb(void *io_device
)
118 struct nvme_bdev_ctrlr
*nvme_bdev_ctrlr
= io_device
;
121 pthread_mutex_lock(&g_bdev_nvme_mutex
);
122 TAILQ_REMOVE(&g_nvme_bdev_ctrlrs
, nvme_bdev_ctrlr
, tailq
);
123 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
124 spdk_nvme_detach(nvme_bdev_ctrlr
->ctrlr
);
125 spdk_poller_unregister(&nvme_bdev_ctrlr
->adminq_timer_poller
);
126 free(nvme_bdev_ctrlr
->name
);
127 for (i
= 0; i
< nvme_bdev_ctrlr
->num_ns
; i
++) {
128 free(nvme_bdev_ctrlr
->namespaces
[i
]);
130 free(nvme_bdev_ctrlr
->namespaces
);
131 free(nvme_bdev_ctrlr
->trid
);
132 free(nvme_bdev_ctrlr
);
134 pthread_mutex_lock(&g_bdev_nvme_mutex
);
135 if (g_bdev_nvme_module_finish
&& TAILQ_EMPTY(&g_nvme_bdev_ctrlrs
)) {
136 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
137 spdk_io_device_unregister(&g_nvme_bdev_ctrlrs
, NULL
);
138 spdk_bdev_module_finish_done();
142 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
146 nvme_bdev_ctrlr_destruct(struct nvme_bdev_ctrlr
*nvme_bdev_ctrlr
)
148 assert(nvme_bdev_ctrlr
->destruct
);
149 pthread_mutex_lock(&g_bdev_nvme_mutex
);
151 /* If we have already registered a poller, let that one take care of it. */
152 if (nvme_bdev_ctrlr
->destruct_poller
!= NULL
) {
153 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
154 return SPDK_POLLER_IDLE
;
157 if (nvme_bdev_ctrlr
->resetting
) {
158 nvme_bdev_ctrlr
->destruct_poller
=
159 SPDK_POLLER_REGISTER((spdk_poller_fn
)nvme_bdev_ctrlr_destruct
, nvme_bdev_ctrlr
, 1000);
160 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
161 return SPDK_POLLER_BUSY
;
163 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
165 spdk_poller_unregister(&nvme_bdev_ctrlr
->destruct_poller
);
166 if (nvme_bdev_ctrlr
->opal_dev
) {
167 spdk_opal_dev_destruct(nvme_bdev_ctrlr
->opal_dev
);
168 nvme_bdev_ctrlr
->opal_dev
= NULL
;
171 if (nvme_bdev_ctrlr
->ocssd_ctrlr
) {
172 bdev_ocssd_fini_ctrlr(nvme_bdev_ctrlr
);
175 spdk_io_device_unregister(nvme_bdev_ctrlr
, nvme_bdev_unregister_cb
);
176 return SPDK_POLLER_BUSY
;
180 nvme_bdev_attach_bdev_to_ns(struct nvme_bdev_ns
*nvme_ns
, struct nvme_bdev
*nvme_disk
)
182 nvme_ns
->ctrlr
->ref
++;
184 TAILQ_INSERT_TAIL(&nvme_ns
->bdevs
, nvme_disk
, tailq
);
188 nvme_bdev_detach_bdev_from_ns(struct nvme_bdev
*nvme_disk
)
190 struct nvme_bdev_ctrlr
*ctrlr
= nvme_disk
->nvme_ns
->ctrlr
;
192 pthread_mutex_lock(&g_bdev_nvme_mutex
);
195 TAILQ_REMOVE(&nvme_disk
->nvme_ns
->bdevs
, nvme_disk
, tailq
);
197 if (ctrlr
->ref
== 0 && ctrlr
->destruct
) {
198 pthread_mutex_unlock(&g_bdev_nvme_mutex
);
199 nvme_bdev_ctrlr_destruct(ctrlr
);
203 pthread_mutex_unlock(&g_bdev_nvme_mutex
);