xref: /spdk/lib/nvme/nvme_cuse.c (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2019 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #define FUSE_USE_VERSION 31
7 
8 #include <fuse3/cuse_lowlevel.h>
9 
10 #include <linux/nvme_ioctl.h>
11 #include <linux/fs.h>
12 
13 #include "nvme_internal.h"
14 #include "nvme_io_msg.h"
15 #include "nvme_cuse.h"
16 
17 struct cuse_device {
18 	char				dev_name[128];
19 	uint32_t			index;
20 	int				claim_fd;
21 	char				lock_name[64];
22 
23 	struct spdk_nvme_ctrlr		*ctrlr;		/**< NVMe controller */
24 	uint32_t			nsid;		/**< NVMe name space id, or 0 */
25 
26 	pthread_t			tid;
27 	struct fuse_session		*session;
28 
29 	struct cuse_device		*ctrlr_device;
30 	TAILQ_HEAD(, cuse_device)	ns_devices;
31 
32 	TAILQ_ENTRY(cuse_device)	tailq;
33 };
34 
35 static pthread_mutex_t g_cuse_mtx = PTHREAD_MUTEX_INITIALIZER;
36 static TAILQ_HEAD(, cuse_device) g_ctrlr_ctx_head = TAILQ_HEAD_INITIALIZER(g_ctrlr_ctx_head);
37 static struct spdk_bit_array *g_ctrlr_started;
38 
39 struct cuse_io_ctx {
40 	struct spdk_nvme_cmd		nvme_cmd;
41 	enum spdk_nvme_data_transfer	data_transfer;
42 
43 	uint64_t			lba;
44 	uint32_t			lba_count;
45 	uint16_t			apptag;
46 	uint16_t			appmask;
47 
48 	void				*data;
49 	void				*metadata;
50 
51 	int				data_len;
52 	int				metadata_len;
53 
54 	fuse_req_t			req;
55 };
56 
57 static void
58 cuse_io_ctx_free(struct cuse_io_ctx *ctx)
59 {
60 	spdk_free(ctx->data);
61 	spdk_free(ctx->metadata);
62 	free(ctx);
63 }
64 
65 #define FUSE_REPLY_CHECK_BUFFER(req, arg, out_bufsz, val)		\
66 	if (out_bufsz == 0) {						\
67 		struct iovec out_iov;					\
68 		out_iov.iov_base = (void *)arg;				\
69 		out_iov.iov_len = sizeof(val);				\
70 		fuse_reply_ioctl_retry(req, NULL, 0, &out_iov, 1);	\
71 		return;							\
72 	}
73 
74 #define FUSE_MAX_SIZE 128*1024
75 
76 static bool
77 fuse_check_req_size(fuse_req_t req, struct iovec iov[], int iovcnt)
78 {
79 	int total_iov_len = 0;
80 	for (int i = 0; i < iovcnt; i++) {
81 		total_iov_len += iov[i].iov_len;
82 		if (total_iov_len > FUSE_MAX_SIZE) {
83 			fuse_reply_err(req, ENOMEM);
84 			SPDK_ERRLOG("FUSE request cannot be larger that %d\n", FUSE_MAX_SIZE);
85 			return false;
86 		}
87 	}
88 	return true;
89 }
90 
91 static void
92 cuse_nvme_passthru_cmd_cb(void *arg, const struct spdk_nvme_cpl *cpl)
93 {
94 	struct cuse_io_ctx *ctx = arg;
95 	struct iovec out_iov[3];
96 	struct spdk_nvme_cpl _cpl;
97 	int out_iovcnt = 0;
98 	uint16_t status_field = cpl->status_raw >> 1; /* Drop out phase bit */
99 
100 	memcpy(&_cpl, cpl, sizeof(struct spdk_nvme_cpl));
101 	out_iov[out_iovcnt].iov_base = &_cpl.cdw0;
102 	out_iov[out_iovcnt].iov_len = sizeof(_cpl.cdw0);
103 	out_iovcnt += 1;
104 
105 	if (ctx->data_transfer == SPDK_NVME_DATA_CONTROLLER_TO_HOST) {
106 		if (ctx->data_len > 0) {
107 			out_iov[out_iovcnt].iov_base = ctx->data;
108 			out_iov[out_iovcnt].iov_len = ctx->data_len;
109 			out_iovcnt += 1;
110 		}
111 		if (ctx->metadata_len > 0) {
112 			out_iov[out_iovcnt].iov_base = ctx->metadata;
113 			out_iov[out_iovcnt].iov_len = ctx->metadata_len;
114 			out_iovcnt += 1;
115 		}
116 	}
117 
118 	fuse_reply_ioctl_iov(ctx->req, status_field, out_iov, out_iovcnt);
119 	cuse_io_ctx_free(ctx);
120 }
121 
122 static void
123 cuse_nvme_passthru_cmd_execute(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, void *arg)
124 {
125 	int rc;
126 	struct cuse_io_ctx *ctx = arg;
127 
128 	if (nsid != 0) {
129 		rc = spdk_nvme_ctrlr_cmd_io_raw_with_md(ctrlr, ctrlr->external_io_msgs_qpair, &ctx->nvme_cmd,
130 							ctx->data,
131 							ctx->data_len, ctx->metadata, cuse_nvme_passthru_cmd_cb, (void *)ctx);
132 	} else {
133 		rc = spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &ctx->nvme_cmd, ctx->data, ctx->data_len,
134 						   cuse_nvme_passthru_cmd_cb, (void *)ctx);
135 	}
136 	if (rc < 0) {
137 		fuse_reply_err(ctx->req, EINVAL);
138 		cuse_io_ctx_free(ctx);
139 	}
140 }
141 
142 static void
143 cuse_nvme_passthru_cmd_send(fuse_req_t req, struct nvme_passthru_cmd *passthru_cmd,
144 			    const void *data, const void *metadata, int cmd)
145 {
146 	struct cuse_io_ctx *ctx;
147 	struct cuse_device *cuse_device = fuse_req_userdata(req);
148 	int rv;
149 
150 	ctx = (struct cuse_io_ctx *)calloc(1, sizeof(struct cuse_io_ctx));
151 	if (!ctx) {
152 		SPDK_ERRLOG("Cannot allocate memory for cuse_io_ctx\n");
153 		fuse_reply_err(req, ENOMEM);
154 		return;
155 	}
156 
157 	ctx->req = req;
158 	ctx->data_transfer = spdk_nvme_opc_get_data_transfer(passthru_cmd->opcode);
159 
160 	memset(&ctx->nvme_cmd, 0, sizeof(ctx->nvme_cmd));
161 	ctx->nvme_cmd.opc = passthru_cmd->opcode;
162 	ctx->nvme_cmd.nsid = passthru_cmd->nsid;
163 	ctx->nvme_cmd.cdw10 = passthru_cmd->cdw10;
164 	ctx->nvme_cmd.cdw11 = passthru_cmd->cdw11;
165 	ctx->nvme_cmd.cdw12 = passthru_cmd->cdw12;
166 	ctx->nvme_cmd.cdw13 = passthru_cmd->cdw13;
167 	ctx->nvme_cmd.cdw14 = passthru_cmd->cdw14;
168 	ctx->nvme_cmd.cdw15 = passthru_cmd->cdw15;
169 
170 	ctx->data_len = passthru_cmd->data_len;
171 	ctx->metadata_len = passthru_cmd->metadata_len;
172 
173 	if (ctx->data_len > 0) {
174 		ctx->data = spdk_malloc(ctx->data_len, 4096, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
175 		if (!ctx->data) {
176 			SPDK_ERRLOG("Cannot allocate memory for data\n");
177 			fuse_reply_err(req, ENOMEM);
178 			free(ctx);
179 			return;
180 		}
181 		if (data != NULL) {
182 			memcpy(ctx->data, data, ctx->data_len);
183 		}
184 	}
185 
186 	if (ctx->metadata_len > 0) {
187 		ctx->metadata = spdk_malloc(ctx->metadata_len, 4096, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
188 		if (!ctx->metadata) {
189 			SPDK_ERRLOG("Cannot allocate memory for metadata\n");
190 			fuse_reply_err(req, ENOMEM);
191 			cuse_io_ctx_free(ctx);
192 			return;
193 		}
194 		if (metadata != NULL) {
195 			memcpy(ctx->metadata, metadata, ctx->metadata_len);
196 		}
197 	}
198 
199 	if ((unsigned int)cmd != NVME_IOCTL_ADMIN_CMD) {
200 		/* Send NS for IO IOCTLs */
201 		rv = nvme_io_msg_send(cuse_device->ctrlr, passthru_cmd->nsid, cuse_nvme_passthru_cmd_execute, ctx);
202 	} else {
203 		/* NS == 0 for Admin IOCTLs */
204 		rv = nvme_io_msg_send(cuse_device->ctrlr, 0, cuse_nvme_passthru_cmd_execute, ctx);
205 	}
206 	if (rv) {
207 		SPDK_ERRLOG("Cannot send io msg to the controller\n");
208 		fuse_reply_err(req, -rv);
209 		cuse_io_ctx_free(ctx);
210 		return;
211 	}
212 }
213 
214 static void
215 cuse_nvme_passthru_cmd(fuse_req_t req, int cmd, void *arg,
216 		       struct fuse_file_info *fi, unsigned flags,
217 		       const void *in_buf, size_t in_bufsz, size_t out_bufsz)
218 {
219 	struct nvme_passthru_cmd *passthru_cmd;
220 	struct iovec in_iov[3], out_iov[3];
221 	int in_iovcnt = 0, out_iovcnt = 0;
222 	const void *dptr = NULL, *mdptr = NULL;
223 	enum spdk_nvme_data_transfer data_transfer;
224 
225 	in_iov[in_iovcnt].iov_base = (void *)arg;
226 	in_iov[in_iovcnt].iov_len = sizeof(*passthru_cmd);
227 	in_iovcnt += 1;
228 	if (in_bufsz == 0) {
229 		fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, NULL, out_iovcnt);
230 		return;
231 	}
232 
233 	passthru_cmd = (struct nvme_passthru_cmd *)in_buf;
234 	data_transfer = spdk_nvme_opc_get_data_transfer(passthru_cmd->opcode);
235 
236 	if (data_transfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER) {
237 		/* Make data pointer accessible (RO) */
238 		if (passthru_cmd->addr != 0) {
239 			in_iov[in_iovcnt].iov_base = (void *)passthru_cmd->addr;
240 			in_iov[in_iovcnt].iov_len = passthru_cmd->data_len;
241 			in_iovcnt += 1;
242 		}
243 		/* Make metadata pointer accessible (RO) */
244 		if (passthru_cmd->metadata != 0) {
245 			in_iov[in_iovcnt].iov_base = (void *)passthru_cmd->metadata;
246 			in_iov[in_iovcnt].iov_len = passthru_cmd->metadata_len;
247 			in_iovcnt += 1;
248 		}
249 	}
250 
251 	if (!fuse_check_req_size(req, in_iov, in_iovcnt)) {
252 		return;
253 	}
254 	/* Always make result field writeable regardless of data transfer bits */
255 	out_iov[out_iovcnt].iov_base = &((struct nvme_passthru_cmd *)arg)->result;
256 	out_iov[out_iovcnt].iov_len = sizeof(uint32_t);
257 	out_iovcnt += 1;
258 
259 	if (data_transfer == SPDK_NVME_DATA_CONTROLLER_TO_HOST) {
260 		/* Make data pointer accessible (WO) */
261 		if (passthru_cmd->data_len > 0) {
262 			out_iov[out_iovcnt].iov_base = (void *)passthru_cmd->addr;
263 			out_iov[out_iovcnt].iov_len = passthru_cmd->data_len;
264 			out_iovcnt += 1;
265 		}
266 		/* Make metadata pointer accessible (WO) */
267 		if (passthru_cmd->metadata_len > 0) {
268 			out_iov[out_iovcnt].iov_base = (void *)passthru_cmd->metadata;
269 			out_iov[out_iovcnt].iov_len = passthru_cmd->metadata_len;
270 			out_iovcnt += 1;
271 		}
272 	}
273 
274 	if (!fuse_check_req_size(req, out_iov, out_iovcnt)) {
275 		return;
276 	}
277 
278 	if (out_bufsz == 0) {
279 		fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
280 		return;
281 	}
282 
283 	if (data_transfer == SPDK_NVME_DATA_BIDIRECTIONAL) {
284 		fuse_reply_err(req, EINVAL);
285 		return;
286 	}
287 
288 	if (data_transfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER) {
289 		dptr = (passthru_cmd->addr == 0) ? NULL : in_buf + sizeof(*passthru_cmd);
290 		mdptr = (passthru_cmd->metadata == 0) ? NULL : in_buf + sizeof(*passthru_cmd) +
291 			passthru_cmd->data_len;
292 	}
293 
294 	cuse_nvme_passthru_cmd_send(req, passthru_cmd, dptr, mdptr, cmd);
295 }
296 
297 static void
298 cuse_nvme_reset_execute(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, void *arg)
299 {
300 	int rc;
301 	fuse_req_t req = arg;
302 
303 	rc = spdk_nvme_ctrlr_reset(ctrlr);
304 	if (rc) {
305 		fuse_reply_err(req, rc);
306 		return;
307 	}
308 
309 	fuse_reply_ioctl_iov(req, 0, NULL, 0);
310 }
311 
312 static void
313 cuse_nvme_subsys_reset_execute(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, void *arg)
314 {
315 	int rc;
316 	fuse_req_t req = arg;
317 
318 	rc = spdk_nvme_ctrlr_reset_subsystem(ctrlr);
319 	if (rc) {
320 		fuse_reply_err(req, rc);
321 		return;
322 	}
323 
324 	fuse_reply_ioctl_iov(req, 0, NULL, 0);
325 }
326 
327 static void
328 cuse_nvme_reset(fuse_req_t req, int cmd, void *arg,
329 		struct fuse_file_info *fi, unsigned flags,
330 		const void *in_buf, size_t in_bufsz, size_t out_bufsz)
331 {
332 	int rv;
333 	struct cuse_device *cuse_device = fuse_req_userdata(req);
334 
335 	if (cuse_device->nsid) {
336 		SPDK_ERRLOG("Namespace reset not supported\n");
337 		fuse_reply_err(req, EINVAL);
338 		return;
339 	}
340 
341 	if (cmd == NVME_IOCTL_SUBSYS_RESET) {
342 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_SUBSYS_RESET\n");
343 		rv = nvme_io_msg_send(cuse_device->ctrlr, cuse_device->nsid, cuse_nvme_subsys_reset_execute,
344 				      (void *)req);
345 	} else {
346 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_RESET\n");
347 		rv = nvme_io_msg_send(cuse_device->ctrlr, cuse_device->nsid, cuse_nvme_reset_execute, (void *)req);
348 	}
349 	if (rv) {
350 		SPDK_ERRLOG("Cannot send reset\n");
351 		fuse_reply_err(req, EINVAL);
352 	}
353 }
354 
355 static void
356 cuse_nvme_rescan_execute(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, void *arg)
357 {
358 	fuse_req_t req = arg;
359 
360 	nvme_ctrlr_update_namespaces(ctrlr);
361 	fuse_reply_ioctl_iov(req, 0, NULL, 0);
362 }
363 
364 static void
365 cuse_nvme_rescan(fuse_req_t req, int cmd, void *arg,
366 		 struct fuse_file_info *fi, unsigned flags,
367 		 const void *in_buf, size_t in_bufsz, size_t out_bufsz)
368 {
369 	int rv;
370 	struct cuse_device *cuse_device = fuse_req_userdata(req);
371 
372 	if (cuse_device->nsid) {
373 		SPDK_ERRLOG("Namespace rescan not supported\n");
374 		fuse_reply_err(req, EINVAL);
375 		return;
376 	}
377 
378 	rv = nvme_io_msg_send(cuse_device->ctrlr, cuse_device->nsid, cuse_nvme_rescan_execute, (void *)req);
379 	if (rv) {
380 		SPDK_ERRLOG("Cannot send rescan\n");
381 		fuse_reply_err(req, EINVAL);
382 	}
383 }
384 
385 /*****************************************************************************
386  * Namespace IO requests
387  */
388 
389 static void
390 cuse_nvme_submit_io_write_done(void *ref, const struct spdk_nvme_cpl *cpl)
391 {
392 	struct cuse_io_ctx *ctx = (struct cuse_io_ctx *)ref;
393 	uint16_t status_field = cpl->status_raw >> 1; /* Drop out phase bit */
394 
395 	fuse_reply_ioctl_iov(ctx->req, status_field, NULL, 0);
396 
397 	cuse_io_ctx_free(ctx);
398 }
399 
400 static void
401 cuse_nvme_submit_io_write_cb(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, void *arg)
402 {
403 	int rc;
404 	struct cuse_io_ctx *ctx = arg;
405 	struct spdk_nvme_ns *ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
406 
407 	rc = spdk_nvme_ns_cmd_write_with_md(ns, ctrlr->external_io_msgs_qpair, ctx->data, ctx->metadata,
408 					    ctx->lba, /* LBA start */
409 					    ctx->lba_count, /* number of LBAs */
410 					    cuse_nvme_submit_io_write_done, ctx, 0,
411 					    ctx->appmask, ctx->apptag);
412 
413 	if (rc != 0) {
414 		SPDK_ERRLOG("write failed: rc = %d\n", rc);
415 		fuse_reply_err(ctx->req, rc);
416 		cuse_io_ctx_free(ctx);
417 		return;
418 	}
419 }
420 
421 static void
422 cuse_nvme_submit_io_write(struct cuse_device *cuse_device, fuse_req_t req, int cmd, void *arg,
423 			  struct fuse_file_info *fi, unsigned flags, uint32_t block_size, uint32_t md_size,
424 			  const void *in_buf, size_t in_bufsz, size_t out_bufsz)
425 {
426 	const struct nvme_user_io *user_io = in_buf;
427 	struct cuse_io_ctx *ctx;
428 	int rc;
429 
430 	ctx = (struct cuse_io_ctx *)calloc(1, sizeof(struct cuse_io_ctx));
431 	if (!ctx) {
432 		SPDK_ERRLOG("Cannot allocate memory for context\n");
433 		fuse_reply_err(req, ENOMEM);
434 		return;
435 	}
436 
437 	ctx->req = req;
438 	ctx->lba = user_io->slba;
439 	ctx->lba_count = user_io->nblocks + 1;
440 	ctx->data_len = ctx->lba_count * block_size;
441 
442 	ctx->data = spdk_zmalloc(ctx->data_len, 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY,
443 				 SPDK_MALLOC_DMA);
444 	if (ctx->data == NULL) {
445 		SPDK_ERRLOG("Write buffer allocation failed\n");
446 		fuse_reply_err(ctx->req, ENOMEM);
447 		free(ctx);
448 		return;
449 	}
450 
451 	memcpy(ctx->data, in_buf + sizeof(*user_io), ctx->data_len);
452 
453 	if (user_io->metadata) {
454 		ctx->apptag = user_io->apptag;
455 		ctx->appmask = user_io->appmask;
456 		ctx->metadata_len = md_size * ctx->lba_count;
457 		ctx->metadata = spdk_zmalloc(ctx->metadata_len, 4096, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
458 
459 		if (ctx->metadata == NULL) {
460 			SPDK_ERRLOG("Cannot allocate memory for metadata\n");
461 			if (ctx->metadata_len == 0) {
462 				SPDK_ERRLOG("Device format does not support metadata\n");
463 			}
464 			fuse_reply_err(req, ENOMEM);
465 			cuse_io_ctx_free(ctx);
466 			return;
467 		}
468 
469 		memcpy(ctx->metadata, in_buf + sizeof(*user_io) + ctx->data_len, ctx->metadata_len);
470 	}
471 
472 	rc = nvme_io_msg_send(cuse_device->ctrlr, cuse_device->nsid, cuse_nvme_submit_io_write_cb,
473 			      ctx);
474 	if (rc < 0) {
475 		SPDK_ERRLOG("Cannot send write io\n");
476 		fuse_reply_err(ctx->req, rc);
477 		cuse_io_ctx_free(ctx);
478 	}
479 }
480 
481 static void
482 cuse_nvme_submit_io_read_done(void *ref, const struct spdk_nvme_cpl *cpl)
483 {
484 	struct cuse_io_ctx *ctx = (struct cuse_io_ctx *)ref;
485 	struct iovec iov[2];
486 	int iovcnt = 0;
487 	uint16_t status_field = cpl->status_raw >> 1; /* Drop out phase bit */
488 
489 	iov[iovcnt].iov_base = ctx->data;
490 	iov[iovcnt].iov_len = ctx->data_len;
491 	iovcnt += 1;
492 
493 	if (ctx->metadata) {
494 		iov[iovcnt].iov_base = ctx->metadata;
495 		iov[iovcnt].iov_len = ctx->metadata_len;
496 		iovcnt += 1;
497 	}
498 
499 	fuse_reply_ioctl_iov(ctx->req, status_field, iov, iovcnt);
500 
501 	cuse_io_ctx_free(ctx);
502 }
503 
504 static void
505 cuse_nvme_submit_io_read_cb(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, void *arg)
506 {
507 	int rc;
508 	struct cuse_io_ctx *ctx = arg;
509 	struct spdk_nvme_ns *ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
510 
511 	rc = spdk_nvme_ns_cmd_read_with_md(ns, ctrlr->external_io_msgs_qpair, ctx->data, ctx->metadata,
512 					   ctx->lba, /* LBA start */
513 					   ctx->lba_count, /* number of LBAs */
514 					   cuse_nvme_submit_io_read_done, ctx, 0,
515 					   ctx->appmask, ctx->apptag);
516 
517 	if (rc != 0) {
518 		SPDK_ERRLOG("read failed: rc = %d\n", rc);
519 		fuse_reply_err(ctx->req, rc);
520 		cuse_io_ctx_free(ctx);
521 		return;
522 	}
523 }
524 
525 static void
526 cuse_nvme_submit_io_read(struct cuse_device *cuse_device, fuse_req_t req, int cmd, void *arg,
527 			 struct fuse_file_info *fi, unsigned flags, uint32_t block_size, uint32_t md_size,
528 			 const void *in_buf, size_t in_bufsz, size_t out_bufsz)
529 {
530 	int rc;
531 	struct cuse_io_ctx *ctx;
532 	const struct nvme_user_io *user_io = in_buf;
533 
534 	ctx = (struct cuse_io_ctx *)calloc(1, sizeof(struct cuse_io_ctx));
535 	if (!ctx) {
536 		SPDK_ERRLOG("Cannot allocate memory for context\n");
537 		fuse_reply_err(req, ENOMEM);
538 		return;
539 	}
540 
541 	ctx->req = req;
542 	ctx->lba = user_io->slba;
543 	ctx->lba_count = user_io->nblocks + 1;
544 
545 	ctx->data_len = ctx->lba_count * block_size;
546 	ctx->data = spdk_zmalloc(ctx->data_len, 0x1000, NULL, SPDK_ENV_SOCKET_ID_ANY,
547 				 SPDK_MALLOC_DMA);
548 	if (ctx->data == NULL) {
549 		SPDK_ERRLOG("Read buffer allocation failed\n");
550 		fuse_reply_err(ctx->req, ENOMEM);
551 		free(ctx);
552 		return;
553 	}
554 
555 	if (user_io->metadata) {
556 		ctx->apptag = user_io->apptag;
557 		ctx->appmask = user_io->appmask;
558 		ctx->metadata_len = md_size * ctx->lba_count;
559 		ctx->metadata = spdk_zmalloc(ctx->metadata_len, 4096, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
560 
561 		if (ctx->metadata == NULL) {
562 			SPDK_ERRLOG("Cannot allocate memory for metadata\n");
563 			if (ctx->metadata_len == 0) {
564 				SPDK_ERRLOG("Device format does not support metadata\n");
565 			}
566 			fuse_reply_err(req, ENOMEM);
567 			cuse_io_ctx_free(ctx);
568 			return;
569 		}
570 	}
571 
572 	rc = nvme_io_msg_send(cuse_device->ctrlr, cuse_device->nsid, cuse_nvme_submit_io_read_cb, ctx);
573 	if (rc < 0) {
574 		SPDK_ERRLOG("Cannot send read io\n");
575 		fuse_reply_err(ctx->req, rc);
576 		cuse_io_ctx_free(ctx);
577 	}
578 }
579 
580 
581 static void
582 cuse_nvme_submit_io(fuse_req_t req, int cmd, void *arg,
583 		    struct fuse_file_info *fi, unsigned flags,
584 		    const void *in_buf, size_t in_bufsz, size_t out_bufsz)
585 {
586 	const struct nvme_user_io *user_io;
587 	struct iovec in_iov[3], out_iov[2];
588 	int in_iovcnt = 0, out_iovcnt = 0;
589 	struct cuse_device *cuse_device = fuse_req_userdata(req);
590 	struct spdk_nvme_ns *ns;
591 	uint32_t block_size;
592 	uint32_t md_size;
593 
594 	in_iov[in_iovcnt].iov_base = (void *)arg;
595 	in_iov[in_iovcnt].iov_len = sizeof(*user_io);
596 	in_iovcnt += 1;
597 	if (in_bufsz == 0) {
598 		fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, NULL, 0);
599 		return;
600 	}
601 
602 	user_io = in_buf;
603 
604 	ns = spdk_nvme_ctrlr_get_ns(cuse_device->ctrlr, cuse_device->nsid);
605 	block_size = spdk_nvme_ns_get_sector_size(ns);
606 	md_size = spdk_nvme_ns_get_md_size(ns);
607 
608 	switch (user_io->opcode) {
609 	case SPDK_NVME_OPC_READ:
610 		out_iov[out_iovcnt].iov_base = (void *)user_io->addr;
611 		out_iov[out_iovcnt].iov_len = (user_io->nblocks + 1) * block_size;
612 		out_iovcnt += 1;
613 		if (user_io->metadata != 0) {
614 			out_iov[out_iovcnt].iov_base = (void *)user_io->metadata;
615 			out_iov[out_iovcnt].iov_len = (user_io->nblocks + 1) * md_size;
616 			out_iovcnt += 1;
617 		}
618 		if (!fuse_check_req_size(req, out_iov, out_iovcnt)) {
619 			return;
620 		}
621 		if (out_bufsz == 0) {
622 			fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, out_iov, out_iovcnt);
623 			return;
624 		}
625 
626 		cuse_nvme_submit_io_read(cuse_device, req, cmd, arg, fi, flags,
627 					 block_size, md_size, in_buf, in_bufsz, out_bufsz);
628 		break;
629 	case SPDK_NVME_OPC_WRITE:
630 		in_iov[in_iovcnt].iov_base = (void *)user_io->addr;
631 		in_iov[in_iovcnt].iov_len = (user_io->nblocks + 1) * block_size;
632 		in_iovcnt += 1;
633 		if (user_io->metadata != 0) {
634 			in_iov[in_iovcnt].iov_base = (void *)user_io->metadata;
635 			in_iov[in_iovcnt].iov_len = (user_io->nblocks + 1) * md_size;
636 			in_iovcnt += 1;
637 		}
638 		if (!fuse_check_req_size(req, in_iov, in_iovcnt)) {
639 			return;
640 		}
641 		if (in_bufsz == sizeof(*user_io)) {
642 			fuse_reply_ioctl_retry(req, in_iov, in_iovcnt, NULL, out_iovcnt);
643 			return;
644 		}
645 
646 		cuse_nvme_submit_io_write(cuse_device, req, cmd, arg, fi, flags,
647 					  block_size, md_size, in_buf, in_bufsz, out_bufsz);
648 		break;
649 	default:
650 		SPDK_ERRLOG("SUBMIT_IO: opc:%d not valid\n", user_io->opcode);
651 		fuse_reply_err(req, EINVAL);
652 		return;
653 	}
654 
655 }
656 
657 /*****************************************************************************
658  * Other namespace IOCTLs
659  */
660 static void
661 cuse_blkgetsize64(fuse_req_t req, int cmd, void *arg,
662 		  struct fuse_file_info *fi, unsigned flags,
663 		  const void *in_buf, size_t in_bufsz, size_t out_bufsz)
664 {
665 	uint64_t size;
666 	struct spdk_nvme_ns *ns;
667 	struct cuse_device *cuse_device = fuse_req_userdata(req);
668 
669 	FUSE_REPLY_CHECK_BUFFER(req, arg, out_bufsz, size);
670 
671 	ns = spdk_nvme_ctrlr_get_ns(cuse_device->ctrlr, cuse_device->nsid);
672 	size = spdk_nvme_ns_get_num_sectors(ns);
673 	fuse_reply_ioctl(req, 0, &size, sizeof(size));
674 }
675 
676 static void
677 cuse_blkpbszget(fuse_req_t req, int cmd, void *arg,
678 		struct fuse_file_info *fi, unsigned flags,
679 		const void *in_buf, size_t in_bufsz, size_t out_bufsz)
680 {
681 	int pbsz;
682 	struct spdk_nvme_ns *ns;
683 	struct cuse_device *cuse_device = fuse_req_userdata(req);
684 
685 	FUSE_REPLY_CHECK_BUFFER(req, arg, out_bufsz, pbsz);
686 
687 	ns = spdk_nvme_ctrlr_get_ns(cuse_device->ctrlr, cuse_device->nsid);
688 	pbsz = spdk_nvme_ns_get_sector_size(ns);
689 	fuse_reply_ioctl(req, 0, &pbsz, sizeof(pbsz));
690 }
691 
692 static void
693 cuse_blkgetsize(fuse_req_t req, int cmd, void *arg,
694 		struct fuse_file_info *fi, unsigned flags,
695 		const void *in_buf, size_t in_bufsz, size_t out_bufsz)
696 {
697 	long size;
698 	struct spdk_nvme_ns *ns;
699 	struct cuse_device *cuse_device = fuse_req_userdata(req);
700 
701 	FUSE_REPLY_CHECK_BUFFER(req, arg, out_bufsz, size);
702 
703 	ns = spdk_nvme_ctrlr_get_ns(cuse_device->ctrlr, cuse_device->nsid);
704 
705 	/* return size in 512 bytes blocks */
706 	size = spdk_nvme_ns_get_num_sectors(ns) * 512 / spdk_nvme_ns_get_sector_size(ns);
707 	fuse_reply_ioctl(req, 0, &size, sizeof(size));
708 }
709 
710 static void
711 cuse_blkgetsectorsize(fuse_req_t req, int cmd, void *arg,
712 		      struct fuse_file_info *fi, unsigned flags,
713 		      const void *in_buf, size_t in_bufsz, size_t out_bufsz)
714 {
715 	int ssize;
716 	struct spdk_nvme_ns *ns;
717 	struct cuse_device *cuse_device = fuse_req_userdata(req);
718 
719 	FUSE_REPLY_CHECK_BUFFER(req, arg, out_bufsz, ssize);
720 
721 	ns = spdk_nvme_ctrlr_get_ns(cuse_device->ctrlr, cuse_device->nsid);
722 	ssize = spdk_nvme_ns_get_sector_size(ns);
723 	fuse_reply_ioctl(req, 0, &ssize, sizeof(ssize));
724 }
725 
726 static void
727 cuse_getid(fuse_req_t req, int cmd, void *arg,
728 	   struct fuse_file_info *fi, unsigned flags,
729 	   const void *in_buf, size_t in_bufsz, size_t out_bufsz)
730 {
731 	struct cuse_device *cuse_device = fuse_req_userdata(req);
732 
733 	fuse_reply_ioctl(req, cuse_device->nsid, NULL, 0);
734 }
735 
736 static void
737 cuse_ctrlr_ioctl(fuse_req_t req, int cmd, void *arg,
738 		 struct fuse_file_info *fi, unsigned flags,
739 		 const void *in_buf, size_t in_bufsz, size_t out_bufsz)
740 {
741 	if (flags & FUSE_IOCTL_COMPAT) {
742 		fuse_reply_err(req, ENOSYS);
743 		return;
744 	}
745 
746 	switch ((unsigned int)cmd) {
747 	case NVME_IOCTL_ADMIN_CMD:
748 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_ADMIN_CMD\n");
749 		cuse_nvme_passthru_cmd(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
750 		break;
751 
752 	case NVME_IOCTL_RESET:
753 	case NVME_IOCTL_SUBSYS_RESET:
754 		cuse_nvme_reset(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
755 		break;
756 
757 	case NVME_IOCTL_RESCAN:
758 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_RESCAN\n");
759 		cuse_nvme_rescan(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
760 		break;
761 
762 	default:
763 		SPDK_ERRLOG("Unsupported IOCTL 0x%X.\n", cmd);
764 		fuse_reply_err(req, ENOTTY);
765 	}
766 }
767 
768 static void
769 cuse_ns_ioctl(fuse_req_t req, int cmd, void *arg,
770 	      struct fuse_file_info *fi, unsigned flags,
771 	      const void *in_buf, size_t in_bufsz, size_t out_bufsz)
772 {
773 	if (flags & FUSE_IOCTL_COMPAT) {
774 		fuse_reply_err(req, ENOSYS);
775 		return;
776 	}
777 
778 	switch ((unsigned int)cmd) {
779 	case NVME_IOCTL_ADMIN_CMD:
780 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_ADMIN_CMD\n");
781 		cuse_nvme_passthru_cmd(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
782 		break;
783 
784 	case NVME_IOCTL_SUBMIT_IO:
785 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_SUBMIT_IO\n");
786 		cuse_nvme_submit_io(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
787 		break;
788 
789 	case NVME_IOCTL_IO_CMD:
790 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_IO_CMD\n");
791 		cuse_nvme_passthru_cmd(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
792 		break;
793 
794 	case NVME_IOCTL_ID:
795 		SPDK_DEBUGLOG(nvme_cuse, "NVME_IOCTL_ID\n");
796 		cuse_getid(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
797 		break;
798 
799 	case BLKPBSZGET:
800 		SPDK_DEBUGLOG(nvme_cuse, "BLKPBSZGET\n");
801 		cuse_blkpbszget(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
802 		break;
803 
804 	case BLKSSZGET:
805 		SPDK_DEBUGLOG(nvme_cuse, "BLKSSZGET\n");
806 		cuse_blkgetsectorsize(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
807 		break;
808 
809 	case BLKGETSIZE:
810 		SPDK_DEBUGLOG(nvme_cuse, "BLKGETSIZE\n");
811 		/* Returns the device size as a number of 512-byte blocks (returns pointer to long) */
812 		cuse_blkgetsize(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
813 		break;
814 
815 	case BLKGETSIZE64:
816 		SPDK_DEBUGLOG(nvme_cuse, "BLKGETSIZE64\n");
817 		/* Returns the device size in sectors (returns pointer to uint64_t) */
818 		cuse_blkgetsize64(req, cmd, arg, fi, flags, in_buf, in_bufsz, out_bufsz);
819 		break;
820 
821 	default:
822 		SPDK_ERRLOG("Unsupported IOCTL 0x%X.\n", cmd);
823 		fuse_reply_err(req, ENOTTY);
824 	}
825 }
826 
827 /*****************************************************************************
828  * CUSE threads initialization.
829  */
830 
831 static void
832 cuse_open(fuse_req_t req, struct fuse_file_info *fi)
833 {
834 	fuse_reply_open(req, fi);
835 }
836 
837 static const struct cuse_lowlevel_ops cuse_ctrlr_clop = {
838 	.open		= cuse_open,
839 	.ioctl		= cuse_ctrlr_ioctl,
840 };
841 
842 static const struct cuse_lowlevel_ops cuse_ns_clop = {
843 	.open		= cuse_open,
844 	.ioctl		= cuse_ns_ioctl,
845 };
846 
847 static int
848 cuse_session_create(struct cuse_device *cuse_device)
849 {
850 	char *cuse_argv[] = { "cuse", "-f" };
851 	int multithreaded;
852 	int cuse_argc = SPDK_COUNTOF(cuse_argv);
853 	struct cuse_info ci;
854 	char devname_arg[128 + 8];
855 	const char *dev_info_argv[] = { devname_arg };
856 
857 	snprintf(devname_arg, sizeof(devname_arg), "DEVNAME=%s", cuse_device->dev_name);
858 
859 	memset(&ci, 0, sizeof(ci));
860 	ci.dev_info_argc = 1;
861 	ci.dev_info_argv = dev_info_argv;
862 	ci.flags = CUSE_UNRESTRICTED_IOCTL;
863 
864 	if (cuse_device->nsid) {
865 		cuse_device->session = cuse_lowlevel_setup(cuse_argc, cuse_argv, &ci, &cuse_ns_clop,
866 				       &multithreaded, cuse_device);
867 	} else {
868 		cuse_device->session = cuse_lowlevel_setup(cuse_argc, cuse_argv, &ci, &cuse_ctrlr_clop,
869 				       &multithreaded, cuse_device);
870 	}
871 
872 	if (!cuse_device->session) {
873 		SPDK_ERRLOG("Cannot create cuse session\n");
874 		return -1;
875 	}
876 	SPDK_NOTICELOG("fuse session for device %s created\n", cuse_device->dev_name);
877 	return 0;
878 }
879 
880 static void *
881 cuse_thread(void *arg)
882 {
883 	struct cuse_device *cuse_device = arg;
884 	int rc;
885 	struct fuse_buf buf = { .mem = NULL };
886 	struct pollfd fds;
887 	int timeout_msecs = 500;
888 
889 	spdk_unaffinitize_thread();
890 
891 	/* Receive and process fuse requests */
892 	fds.fd = fuse_session_fd(cuse_device->session);
893 	fds.events = POLLIN;
894 	while (!fuse_session_exited(cuse_device->session)) {
895 		rc = poll(&fds, 1, timeout_msecs);
896 		if (rc <= 0) {
897 			continue;
898 		}
899 		rc = fuse_session_receive_buf(cuse_device->session, &buf);
900 		if (rc > 0) {
901 			fuse_session_process_buf(cuse_device->session, &buf);
902 		}
903 	}
904 	free(buf.mem);
905 	fuse_session_reset(cuse_device->session);
906 	pthread_exit(NULL);
907 }
908 
909 static struct cuse_device *nvme_cuse_get_cuse_ns_device(struct spdk_nvme_ctrlr *ctrlr,
910 		uint32_t nsid);
911 
912 /*****************************************************************************
913  * CUSE devices management
914  */
915 
916 static int
917 cuse_nvme_ns_start(struct cuse_device *ctrlr_device, uint32_t nsid)
918 {
919 	struct cuse_device *ns_device;
920 	int rv;
921 
922 	ns_device = nvme_cuse_get_cuse_ns_device(ctrlr_device->ctrlr, nsid);
923 	if (ns_device != NULL) {
924 		return 0;
925 	}
926 
927 	ns_device = calloc(1, sizeof(struct cuse_device));
928 	if (ns_device == NULL) {
929 		return -ENOMEM;
930 	}
931 
932 	ns_device->ctrlr = ctrlr_device->ctrlr;
933 	ns_device->ctrlr_device = ctrlr_device;
934 	ns_device->nsid = nsid;
935 	rv = snprintf(ns_device->dev_name, sizeof(ns_device->dev_name), "%sn%d",
936 		      ctrlr_device->dev_name, ns_device->nsid);
937 	if (rv < 0) {
938 		SPDK_ERRLOG("Device name too long.\n");
939 		free(ns_device);
940 		return -ENAMETOOLONG;
941 	}
942 	rv = cuse_session_create(ns_device);
943 	if (rv != 0) {
944 		free(ns_device);
945 		return rv;
946 	}
947 	rv = pthread_create(&ns_device->tid, NULL, cuse_thread, ns_device);
948 	if (rv != 0) {
949 		SPDK_ERRLOG("pthread_create failed\n");
950 		free(ns_device);
951 		return -rv;
952 	}
953 	TAILQ_INSERT_TAIL(&ctrlr_device->ns_devices, ns_device, tailq);
954 
955 	return 0;
956 }
957 
958 static void
959 cuse_nvme_ns_stop(struct cuse_device *ctrlr_device, struct cuse_device *ns_device)
960 {
961 	if (ns_device->session != NULL) {
962 		fuse_session_exit(ns_device->session);
963 	}
964 	pthread_join(ns_device->tid, NULL);
965 	TAILQ_REMOVE(&ctrlr_device->ns_devices, ns_device, tailq);
966 	if (ns_device->session != NULL) {
967 		cuse_lowlevel_teardown(ns_device->session);
968 	}
969 	free(ns_device);
970 }
971 
972 static int
973 nvme_cuse_claim(struct cuse_device *ctrlr_device, uint32_t index)
974 {
975 	int dev_fd;
976 	int pid;
977 	void *dev_map;
978 	struct flock cusedev_lock = {
979 		.l_type = F_WRLCK,
980 		.l_whence = SEEK_SET,
981 		.l_start = 0,
982 		.l_len = 0,
983 	};
984 
985 	snprintf(ctrlr_device->lock_name, sizeof(ctrlr_device->lock_name),
986 		 "/var/tmp/spdk_nvme_cuse_lock_%" PRIu32, index);
987 
988 	dev_fd = open(ctrlr_device->lock_name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
989 	if (dev_fd == -1) {
990 		SPDK_ERRLOG("could not open %s\n", ctrlr_device->lock_name);
991 		return -errno;
992 	}
993 
994 	if (ftruncate(dev_fd, sizeof(int)) != 0) {
995 		SPDK_ERRLOG("could not truncate %s\n", ctrlr_device->lock_name);
996 		close(dev_fd);
997 		return -errno;
998 	}
999 
1000 	dev_map = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
1001 		       MAP_SHARED, dev_fd, 0);
1002 	if (dev_map == MAP_FAILED) {
1003 		SPDK_ERRLOG("could not mmap dev %s (%d)\n", ctrlr_device->lock_name, errno);
1004 		close(dev_fd);
1005 		return -errno;
1006 	}
1007 
1008 	if (fcntl(dev_fd, F_SETLK, &cusedev_lock) != 0) {
1009 		pid = *(int *)dev_map;
1010 		SPDK_ERRLOG("Cannot create lock on device %s, probably"
1011 			    " process %d has claimed it\n", ctrlr_device->lock_name, pid);
1012 		munmap(dev_map, sizeof(int));
1013 		close(dev_fd);
1014 		/* F_SETLK returns unspecified errnos, normalize them */
1015 		return -EACCES;
1016 	}
1017 
1018 	*(int *)dev_map = (int)getpid();
1019 	munmap(dev_map, sizeof(int));
1020 	ctrlr_device->claim_fd = dev_fd;
1021 	ctrlr_device->index = index;
1022 	/* Keep dev_fd open to maintain the lock. */
1023 	return 0;
1024 }
1025 
1026 static void
1027 nvme_cuse_unclaim(struct cuse_device *ctrlr_device)
1028 {
1029 	close(ctrlr_device->claim_fd);
1030 	ctrlr_device->claim_fd = -1;
1031 	unlink(ctrlr_device->lock_name);
1032 }
1033 
1034 static void
1035 cuse_nvme_ctrlr_stop(struct cuse_device *ctrlr_device)
1036 {
1037 	struct cuse_device *ns_device, *tmp;
1038 
1039 	TAILQ_FOREACH_SAFE(ns_device, &ctrlr_device->ns_devices, tailq, tmp) {
1040 		cuse_nvme_ns_stop(ctrlr_device, ns_device);
1041 	}
1042 
1043 	assert(TAILQ_EMPTY(&ctrlr_device->ns_devices));
1044 
1045 	fuse_session_exit(ctrlr_device->session);
1046 	pthread_join(ctrlr_device->tid, NULL);
1047 	TAILQ_REMOVE(&g_ctrlr_ctx_head, ctrlr_device, tailq);
1048 	spdk_bit_array_clear(g_ctrlr_started, ctrlr_device->index);
1049 	if (spdk_bit_array_count_set(g_ctrlr_started) == 0) {
1050 		spdk_bit_array_free(&g_ctrlr_started);
1051 	}
1052 	nvme_cuse_unclaim(ctrlr_device);
1053 	if (ctrlr_device->session != NULL) {
1054 		cuse_lowlevel_teardown(ctrlr_device->session);
1055 	}
1056 	free(ctrlr_device);
1057 }
1058 
1059 static int
1060 cuse_nvme_ctrlr_update_namespaces(struct cuse_device *ctrlr_device)
1061 {
1062 	struct cuse_device *ns_device, *tmp;
1063 	uint32_t nsid;
1064 
1065 	/* Remove namespaces that have disappeared */
1066 	TAILQ_FOREACH_SAFE(ns_device, &ctrlr_device->ns_devices, tailq, tmp) {
1067 		if (!spdk_nvme_ctrlr_is_active_ns(ctrlr_device->ctrlr, ns_device->nsid)) {
1068 			cuse_nvme_ns_stop(ctrlr_device, ns_device);
1069 		}
1070 	}
1071 
1072 	/* Add new namespaces */
1073 	nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr_device->ctrlr);
1074 	while (nsid != 0) {
1075 		if (cuse_nvme_ns_start(ctrlr_device, nsid) < 0) {
1076 			SPDK_ERRLOG("Cannot start CUSE namespace device.");
1077 			return -1;
1078 		}
1079 
1080 		nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr_device->ctrlr, nsid);
1081 	}
1082 
1083 	return 0;
1084 }
1085 
1086 static int
1087 nvme_cuse_start(struct spdk_nvme_ctrlr *ctrlr)
1088 {
1089 	int rv = 0;
1090 	struct cuse_device *ctrlr_device;
1091 
1092 	SPDK_NOTICELOG("Creating cuse device for controller\n");
1093 
1094 	if (g_ctrlr_started == NULL) {
1095 		g_ctrlr_started = spdk_bit_array_create(128);
1096 		if (g_ctrlr_started == NULL) {
1097 			SPDK_ERRLOG("Cannot create bit array\n");
1098 			return -ENOMEM;
1099 		}
1100 	}
1101 
1102 	ctrlr_device = (struct cuse_device *)calloc(1, sizeof(struct cuse_device));
1103 	if (!ctrlr_device) {
1104 		SPDK_ERRLOG("Cannot allocate memory for ctrlr_device.");
1105 		rv = -ENOMEM;
1106 		goto free_device;
1107 	}
1108 
1109 	ctrlr_device->ctrlr = ctrlr;
1110 
1111 	/* Check if device already exists, if not increment index until success */
1112 	ctrlr_device->index = 0;
1113 	while (1) {
1114 		ctrlr_device->index = spdk_bit_array_find_first_clear(g_ctrlr_started, ctrlr_device->index);
1115 		if (ctrlr_device->index == UINT32_MAX) {
1116 			SPDK_ERRLOG("Too many registered controllers\n");
1117 			goto free_device;
1118 		}
1119 
1120 		if (nvme_cuse_claim(ctrlr_device, ctrlr_device->index) == 0) {
1121 			break;
1122 		}
1123 		ctrlr_device->index++;
1124 	}
1125 	spdk_bit_array_set(g_ctrlr_started, ctrlr_device->index);
1126 	snprintf(ctrlr_device->dev_name, sizeof(ctrlr_device->dev_name), "spdk/nvme%d",
1127 		 ctrlr_device->index);
1128 
1129 	rv = cuse_session_create(ctrlr_device);
1130 	if (rv != 0) {
1131 		goto clear_and_free;
1132 	}
1133 
1134 	rv = pthread_create(&ctrlr_device->tid, NULL, cuse_thread, ctrlr_device);
1135 	if (rv != 0) {
1136 		SPDK_ERRLOG("pthread_create failed\n");
1137 		rv = -rv;
1138 		goto clear_and_free;
1139 	}
1140 
1141 	TAILQ_INSERT_TAIL(&g_ctrlr_ctx_head, ctrlr_device, tailq);
1142 
1143 	TAILQ_INIT(&ctrlr_device->ns_devices);
1144 
1145 	/* Start all active namespaces */
1146 	if (cuse_nvme_ctrlr_update_namespaces(ctrlr_device) < 0) {
1147 		SPDK_ERRLOG("Cannot start CUSE namespace devices.");
1148 		cuse_nvme_ctrlr_stop(ctrlr_device);
1149 		rv = -1;
1150 		goto clear_and_free;
1151 	}
1152 
1153 	return 0;
1154 
1155 clear_and_free:
1156 	spdk_bit_array_clear(g_ctrlr_started, ctrlr_device->index);
1157 free_device:
1158 	free(ctrlr_device);
1159 	if (spdk_bit_array_count_set(g_ctrlr_started) == 0) {
1160 		spdk_bit_array_free(&g_ctrlr_started);
1161 	}
1162 	return rv;
1163 }
1164 
1165 static struct cuse_device *
1166 nvme_cuse_get_cuse_ctrlr_device(struct spdk_nvme_ctrlr *ctrlr)
1167 {
1168 	struct cuse_device *ctrlr_device = NULL;
1169 
1170 	TAILQ_FOREACH(ctrlr_device, &g_ctrlr_ctx_head, tailq) {
1171 		if (ctrlr_device->ctrlr == ctrlr) {
1172 			break;
1173 		}
1174 	}
1175 
1176 	return ctrlr_device;
1177 }
1178 
1179 static struct cuse_device *
1180 nvme_cuse_get_cuse_ns_device(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid)
1181 {
1182 	struct cuse_device *ctrlr_device = NULL;
1183 	struct cuse_device *ns_device;
1184 
1185 	ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
1186 	if (!ctrlr_device) {
1187 		return NULL;
1188 	}
1189 
1190 	TAILQ_FOREACH(ns_device, &ctrlr_device->ns_devices, tailq) {
1191 		if (ns_device->nsid == nsid) {
1192 			return ns_device;
1193 		}
1194 	}
1195 
1196 	return NULL;
1197 }
1198 
1199 static void
1200 nvme_cuse_stop(struct spdk_nvme_ctrlr *ctrlr)
1201 {
1202 	struct cuse_device *ctrlr_device;
1203 
1204 	pthread_mutex_lock(&g_cuse_mtx);
1205 
1206 	ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
1207 	if (!ctrlr_device) {
1208 		SPDK_ERRLOG("Cannot find associated CUSE device\n");
1209 		pthread_mutex_unlock(&g_cuse_mtx);
1210 		return;
1211 	}
1212 
1213 	cuse_nvme_ctrlr_stop(ctrlr_device);
1214 
1215 	pthread_mutex_unlock(&g_cuse_mtx);
1216 }
1217 
1218 static void
1219 nvme_cuse_update(struct spdk_nvme_ctrlr *ctrlr)
1220 {
1221 	struct cuse_device *ctrlr_device;
1222 
1223 	pthread_mutex_lock(&g_cuse_mtx);
1224 
1225 	ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
1226 	if (!ctrlr_device) {
1227 		pthread_mutex_unlock(&g_cuse_mtx);
1228 		return;
1229 	}
1230 
1231 	cuse_nvme_ctrlr_update_namespaces(ctrlr_device);
1232 
1233 	pthread_mutex_unlock(&g_cuse_mtx);
1234 }
1235 
1236 static struct nvme_io_msg_producer cuse_nvme_io_msg_producer = {
1237 	.name = "cuse",
1238 	.stop = nvme_cuse_stop,
1239 	.update = nvme_cuse_update,
1240 };
1241 
1242 int
1243 spdk_nvme_cuse_register(struct spdk_nvme_ctrlr *ctrlr)
1244 {
1245 	int rc;
1246 
1247 	rc = nvme_io_msg_ctrlr_register(ctrlr, &cuse_nvme_io_msg_producer);
1248 	if (rc) {
1249 		return rc;
1250 	}
1251 
1252 	pthread_mutex_lock(&g_cuse_mtx);
1253 
1254 	rc = nvme_cuse_start(ctrlr);
1255 	if (rc) {
1256 		nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer);
1257 	}
1258 
1259 	pthread_mutex_unlock(&g_cuse_mtx);
1260 
1261 	return rc;
1262 }
1263 
1264 int
1265 spdk_nvme_cuse_unregister(struct spdk_nvme_ctrlr *ctrlr)
1266 {
1267 	struct cuse_device *ctrlr_device;
1268 
1269 	pthread_mutex_lock(&g_cuse_mtx);
1270 
1271 	ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
1272 	if (!ctrlr_device) {
1273 		SPDK_ERRLOG("Cannot find associated CUSE device\n");
1274 		pthread_mutex_unlock(&g_cuse_mtx);
1275 		return -ENODEV;
1276 	}
1277 
1278 	cuse_nvme_ctrlr_stop(ctrlr_device);
1279 
1280 	pthread_mutex_unlock(&g_cuse_mtx);
1281 
1282 	nvme_io_msg_ctrlr_unregister(ctrlr, &cuse_nvme_io_msg_producer);
1283 
1284 	return 0;
1285 }
1286 
1287 void
1288 spdk_nvme_cuse_update_namespaces(struct spdk_nvme_ctrlr *ctrlr)
1289 {
1290 	nvme_cuse_update(ctrlr);
1291 }
1292 
1293 int
1294 spdk_nvme_cuse_get_ctrlr_name(struct spdk_nvme_ctrlr *ctrlr, char *name, size_t *size)
1295 {
1296 	struct cuse_device *ctrlr_device;
1297 	size_t req_len;
1298 
1299 	pthread_mutex_lock(&g_cuse_mtx);
1300 
1301 	ctrlr_device = nvme_cuse_get_cuse_ctrlr_device(ctrlr);
1302 	if (!ctrlr_device) {
1303 		pthread_mutex_unlock(&g_cuse_mtx);
1304 		return -ENODEV;
1305 	}
1306 
1307 	req_len = strnlen(ctrlr_device->dev_name, sizeof(ctrlr_device->dev_name));
1308 	if (*size < req_len) {
1309 		*size = req_len;
1310 		pthread_mutex_unlock(&g_cuse_mtx);
1311 		return -ENOSPC;
1312 	}
1313 	snprintf(name, req_len + 1, "%s", ctrlr_device->dev_name);
1314 
1315 	pthread_mutex_unlock(&g_cuse_mtx);
1316 
1317 	return 0;
1318 }
1319 
1320 int
1321 spdk_nvme_cuse_get_ns_name(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, char *name, size_t *size)
1322 {
1323 	struct cuse_device *ns_device;
1324 	size_t req_len;
1325 
1326 	pthread_mutex_lock(&g_cuse_mtx);
1327 
1328 	ns_device = nvme_cuse_get_cuse_ns_device(ctrlr, nsid);
1329 	if (!ns_device) {
1330 		pthread_mutex_unlock(&g_cuse_mtx);
1331 		return -ENODEV;
1332 	}
1333 
1334 	req_len = strnlen(ns_device->dev_name, sizeof(ns_device->dev_name));
1335 	if (*size < req_len) {
1336 		*size = req_len;
1337 		pthread_mutex_unlock(&g_cuse_mtx);
1338 		return -ENOSPC;
1339 	}
1340 	snprintf(name, req_len + 1, "%s", ns_device->dev_name);
1341 
1342 	pthread_mutex_unlock(&g_cuse_mtx);
1343 
1344 	return 0;
1345 }
1346 
1347 SPDK_LOG_REGISTER_COMPONENT(nvme_cuse)
1348