xref: /spdk/lib/fsdev/fsdev_io.c (revision b69e3ff279affbf4cbc4a09fa1f9c6c2b72397ff)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  */
4 
5 #include "spdk/stdinc.h"
6 #include "spdk/fsdev.h"
7 #include "spdk/fsdev_module.h"
8 #include "fsdev_internal.h"
9 
10 #define CALL_USR_CLB(_fsdev_io, ch, type, ...) \
11 	do { \
12 		type *usr_cb_fn = _fsdev_io->internal.usr_cb_fn; \
13 		usr_cb_fn(_fsdev_io->internal.usr_cb_arg, ch, _fsdev_io->internal.status, ## __VA_ARGS__); \
14 	} while (0)
15 
16 static struct spdk_fsdev_io *
17 fsdev_io_get_and_fill(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
18 		      void *usr_cb_fn, void *usr_cb_arg, spdk_fsdev_io_completion_cb cb_fn, void *cb_arg,
19 		      enum spdk_fsdev_io_type type)
20 {
21 	struct spdk_fsdev_io *fsdev_io;
22 	struct spdk_fsdev_channel *channel = __io_ch_to_fsdev_ch(ch);
23 
24 	fsdev_io = fsdev_channel_get_io(channel);
25 	if (!fsdev_io) {
26 		return NULL;
27 	}
28 
29 	fsdev_io->fsdev = spdk_fsdev_desc_get_fsdev(desc);
30 	fsdev_io->internal.ch = channel;
31 	fsdev_io->internal.desc = desc;
32 	fsdev_io->internal.type = type;
33 	fsdev_io->internal.unique = unique;
34 	fsdev_io->internal.usr_cb_fn = usr_cb_fn;
35 	fsdev_io->internal.usr_cb_arg = usr_cb_arg;
36 	fsdev_io->internal.cb_arg = cb_arg;
37 	fsdev_io->internal.cb_fn = cb_fn;
38 	fsdev_io->internal.status = -ENOSYS;
39 	fsdev_io->internal.in_submit_request = false;
40 
41 	return fsdev_io;
42 }
43 
44 static inline void
45 fsdev_io_free(struct spdk_fsdev_io *fsdev_io)
46 {
47 	spdk_fsdev_free_io(fsdev_io);
48 }
49 
50 static void
51 _spdk_fsdev_lookup_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
52 {
53 	struct spdk_io_channel *ch = cb_arg;
54 
55 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_lookup_cpl_cb, fsdev_io->u_out.lookup.fobject,
56 		     &fsdev_io->u_out.lookup.attr);
57 
58 	free(fsdev_io->u_in.lookup.name);
59 	fsdev_io_free(fsdev_io);
60 }
61 
62 int
63 spdk_fsdev_lookup(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
64 		  struct spdk_fsdev_file_object *parent_fobject, const char *name,
65 		  spdk_fsdev_lookup_cpl_cb cb_fn, void *cb_arg)
66 {
67 	struct spdk_fsdev_io *fsdev_io;
68 
69 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_lookup_cb, ch,
70 					 SPDK_FSDEV_IO_LOOKUP);
71 	if (!fsdev_io) {
72 		return -ENOBUFS;
73 	}
74 
75 	fsdev_io->u_in.lookup.name = strdup(name);
76 	if (!fsdev_io->u_in.lookup.name) {
77 		fsdev_io_free(fsdev_io);
78 		return -ENOMEM;
79 	}
80 
81 	fsdev_io->u_in.lookup.parent_fobject = parent_fobject;
82 
83 	fsdev_io_submit(fsdev_io);
84 	return 0;
85 }
86 
87 static void
88 _spdk_fsdev_forget_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
89 {
90 	struct spdk_io_channel *ch = cb_arg;
91 
92 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_forget_cpl_cb);
93 
94 	fsdev_io_free(fsdev_io);
95 }
96 
97 int
98 spdk_fsdev_forget(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
99 		  struct spdk_fsdev_file_object *fobject, uint64_t nlookup,
100 		  spdk_fsdev_forget_cpl_cb cb_fn, void *cb_arg)
101 {
102 	struct spdk_fsdev_io *fsdev_io;
103 
104 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_forget_cb, ch,
105 					 SPDK_FSDEV_IO_FORGET);
106 	if (!fsdev_io) {
107 		return -ENOBUFS;
108 	}
109 
110 	fsdev_io->u_in.forget.fobject = fobject;
111 	fsdev_io->u_in.forget.nlookup = nlookup;
112 
113 	fsdev_io_submit(fsdev_io);
114 	return 0;
115 }
116 
117 static void
118 _spdk_fsdev_getattr_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
119 {
120 	struct spdk_io_channel *ch = cb_arg;
121 
122 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_getattr_cpl_cb, &fsdev_io->u_out.getattr.attr);
123 
124 	fsdev_io_free(fsdev_io);
125 }
126 
127 int
128 spdk_fsdev_getattr(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
129 		   struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
130 		   spdk_fsdev_getattr_cpl_cb cb_fn, void *cb_arg)
131 {
132 	struct spdk_fsdev_io *fsdev_io;
133 
134 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_getattr_cb, ch,
135 					 SPDK_FSDEV_IO_GETATTR);
136 	if (!fsdev_io) {
137 		return -ENOBUFS;
138 	}
139 
140 	fsdev_io->u_in.getattr.fobject = fobject;
141 	fsdev_io->u_in.getattr.fhandle = fhandle;
142 
143 	fsdev_io_submit(fsdev_io);
144 	return 0;
145 }
146 
147 static void
148 _spdk_fsdev_setattr_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
149 {
150 	struct spdk_io_channel *ch = cb_arg;
151 
152 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_setattr_cpl_cb, &fsdev_io->u_out.setattr.attr);
153 
154 	fsdev_io_free(fsdev_io);
155 }
156 
157 int
158 spdk_fsdev_setattr(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
159 		   struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
160 		   const struct spdk_fsdev_file_attr *attr, uint32_t to_set,
161 		   spdk_fsdev_setattr_cpl_cb cb_fn, void *cb_arg)
162 {
163 	struct spdk_fsdev_io *fsdev_io;
164 
165 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_setattr_cb, ch,
166 					 SPDK_FSDEV_IO_SETATTR);
167 	if (!fsdev_io) {
168 		return -ENOBUFS;
169 	}
170 
171 	fsdev_io->u_in.setattr.fobject = fobject;
172 	fsdev_io->u_in.setattr.fhandle = fhandle;
173 	fsdev_io->u_in.setattr.attr = *attr;
174 	fsdev_io->u_in.setattr.to_set = to_set;
175 
176 	fsdev_io_submit(fsdev_io);
177 	return 0;
178 }
179 
180 static void
181 _spdk_fsdev_readlink_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
182 {
183 	struct spdk_io_channel *ch = cb_arg;
184 
185 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_readlink_cpl_cb, fsdev_io->u_out.readlink.linkname);
186 
187 	free(fsdev_io->u_out.readlink.linkname);
188 	fsdev_io_free(fsdev_io);
189 }
190 
191 int
192 spdk_fsdev_readlink(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
193 		    struct spdk_fsdev_file_object *fobject, spdk_fsdev_readlink_cpl_cb cb_fn, void *cb_arg)
194 {
195 	struct spdk_fsdev_io *fsdev_io;
196 
197 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_readlink_cb, ch,
198 					 SPDK_FSDEV_IO_READLINK);
199 	if (!fsdev_io) {
200 		return -ENOBUFS;
201 	}
202 
203 	fsdev_io->u_in.readlink.fobject = fobject;
204 	fsdev_io->u_out.readlink.linkname = NULL;
205 
206 	fsdev_io_submit(fsdev_io);
207 	return 0;
208 }
209 
210 static void
211 _spdk_fsdev_symlink_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
212 {
213 	struct spdk_io_channel *ch = cb_arg;
214 
215 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_symlink_cpl_cb, fsdev_io->u_out.symlink.fobject,
216 		     &fsdev_io->u_out.symlink.attr);
217 
218 	free(fsdev_io->u_in.symlink.target);
219 	free(fsdev_io->u_in.symlink.linkpath);
220 
221 	fsdev_io_free(fsdev_io);
222 }
223 
224 int
225 spdk_fsdev_symlink(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
226 		   struct spdk_fsdev_file_object *parent_fobject, const char *target, const char *linkpath,
227 		   uid_t euid, gid_t egid, spdk_fsdev_symlink_cpl_cb cb_fn, void *cb_arg)
228 {
229 	struct spdk_fsdev_io *fsdev_io;
230 
231 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_symlink_cb, ch,
232 					 SPDK_FSDEV_IO_SYMLINK);
233 	if (!fsdev_io) {
234 		return -ENOBUFS;
235 	}
236 
237 	fsdev_io->u_in.symlink.target = strdup(target);
238 	if (!fsdev_io) {
239 		fsdev_io_free(fsdev_io);
240 		return -ENOMEM;
241 	}
242 
243 	fsdev_io->u_in.symlink.linkpath = strdup(linkpath);
244 	if (!fsdev_io) {
245 		fsdev_io_free(fsdev_io);
246 		free(fsdev_io->u_in.symlink.target);
247 		return -ENOMEM;
248 	}
249 
250 	fsdev_io->u_in.symlink.parent_fobject = parent_fobject;
251 	fsdev_io->u_in.symlink.euid = euid;
252 	fsdev_io->u_in.symlink.egid = egid;
253 
254 	fsdev_io_submit(fsdev_io);
255 	return 0;
256 }
257 
258 static void
259 _spdk_fsdev_mknod_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
260 {
261 	struct spdk_io_channel *ch = cb_arg;
262 
263 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_mknod_cpl_cb, fsdev_io->u_out.mknod.fobject,
264 		     &fsdev_io->u_out.mknod.attr);
265 
266 	free(fsdev_io->u_in.mknod.name);
267 
268 	fsdev_io_free(fsdev_io);
269 }
270 
271 int
272 spdk_fsdev_mknod(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
273 		 struct spdk_fsdev_file_object *parent_fobject, const char *name, mode_t mode, dev_t rdev,
274 		 uid_t euid, gid_t egid, spdk_fsdev_mknod_cpl_cb cb_fn, void *cb_arg)
275 {
276 	struct spdk_fsdev_io *fsdev_io;
277 
278 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_mknod_cb, ch,
279 					 SPDK_FSDEV_IO_MKNOD);
280 	if (!fsdev_io) {
281 		return -ENOBUFS;
282 	}
283 
284 	fsdev_io->u_in.mknod.name = strdup(name);
285 	if (!fsdev_io->u_in.mknod.name) {
286 		fsdev_io_free(fsdev_io);
287 		return -ENOMEM;
288 	}
289 
290 	fsdev_io->u_in.mknod.parent_fobject = parent_fobject;
291 	fsdev_io->u_in.mknod.mode = mode;
292 	fsdev_io->u_in.mknod.rdev = rdev;
293 	fsdev_io->u_in.mknod.euid = euid;
294 	fsdev_io->u_in.mknod.egid = egid;
295 
296 	fsdev_io_submit(fsdev_io);
297 	return 0;
298 }
299 
300 static void
301 _spdk_fsdev_mkdir_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
302 {
303 	struct spdk_io_channel *ch = cb_arg;
304 
305 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_mkdir_cpl_cb, fsdev_io->u_out.mkdir.fobject,
306 		     &fsdev_io->u_out.mkdir.attr);
307 
308 	free(fsdev_io->u_in.mkdir.name);
309 
310 	fsdev_io_free(fsdev_io);
311 }
312 
313 int
314 spdk_fsdev_mkdir(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
315 		 struct spdk_fsdev_file_object *parent_fobject, const char *name, mode_t mode,
316 		 uid_t euid, gid_t egid, spdk_fsdev_mkdir_cpl_cb cb_fn, void *cb_arg)
317 {
318 	struct spdk_fsdev_io *fsdev_io;
319 
320 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_mkdir_cb, ch,
321 					 SPDK_FSDEV_IO_MKDIR);
322 	if (!fsdev_io) {
323 		return -ENOBUFS;
324 	}
325 
326 	fsdev_io->u_in.mkdir.name = strdup(name);
327 	if (!fsdev_io->u_in.mkdir.name) {
328 		fsdev_io_free(fsdev_io);
329 		return -ENOMEM;
330 	}
331 
332 	fsdev_io->u_in.mkdir.parent_fobject = parent_fobject;
333 	fsdev_io->u_in.mkdir.mode = mode;
334 	fsdev_io->u_in.mkdir.euid = euid;
335 	fsdev_io->u_in.mkdir.egid = egid;
336 
337 	fsdev_io_submit(fsdev_io);
338 	return 0;
339 }
340 
341 static void
342 _spdk_fsdev_unlink_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
343 {
344 	struct spdk_io_channel *ch = cb_arg;
345 
346 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_unlink_cpl_cb);
347 
348 	free(fsdev_io->u_in.unlink.name);
349 
350 	fsdev_io_free(fsdev_io);
351 }
352 
353 int
354 spdk_fsdev_unlink(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
355 		  struct spdk_fsdev_file_object *parent_fobject, const char *name,
356 		  spdk_fsdev_unlink_cpl_cb cb_fn, void *cb_arg)
357 {
358 	struct spdk_fsdev_io *fsdev_io;
359 
360 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_unlink_cb, ch,
361 					 SPDK_FSDEV_IO_UNLINK);
362 	if (!fsdev_io) {
363 		return -ENOBUFS;
364 	}
365 
366 	fsdev_io->u_in.unlink.name = strdup(name);
367 	if (!fsdev_io->u_in.unlink.name) {
368 		fsdev_io_free(fsdev_io);
369 		return -ENOMEM;
370 	}
371 
372 	fsdev_io->u_in.unlink.parent_fobject = parent_fobject;
373 
374 	fsdev_io_submit(fsdev_io);
375 	return 0;
376 }
377 
378 static void
379 _spdk_fsdev_rmdir_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
380 {
381 	struct spdk_io_channel *ch = cb_arg;
382 
383 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_rmdir_cpl_cb);
384 
385 	free(fsdev_io->u_in.rmdir.name);
386 
387 	fsdev_io_free(fsdev_io);
388 }
389 
390 int
391 spdk_fsdev_rmdir(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
392 		 struct spdk_fsdev_file_object *parent_fobject, const char *name,
393 		 spdk_fsdev_rmdir_cpl_cb cb_fn, void *cb_arg)
394 {
395 	struct spdk_fsdev_io *fsdev_io;
396 
397 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_rmdir_cb, ch,
398 					 SPDK_FSDEV_IO_RMDIR);
399 	if (!fsdev_io) {
400 		return -ENOBUFS;
401 	}
402 
403 	fsdev_io->u_in.rmdir.name = strdup(name);
404 	if (!fsdev_io->u_in.rmdir.name) {
405 		fsdev_io_free(fsdev_io);
406 		return -ENOMEM;
407 	}
408 
409 	fsdev_io->u_in.rmdir.parent_fobject = parent_fobject;
410 
411 	fsdev_io_submit(fsdev_io);
412 	return 0;
413 }
414 
415 static void
416 _spdk_fsdev_rename_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
417 {
418 	struct spdk_io_channel *ch = cb_arg;
419 
420 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_rename_cpl_cb);
421 
422 	free(fsdev_io->u_in.rename.name);
423 	free(fsdev_io->u_in.rename.new_name);
424 
425 	fsdev_io_free(fsdev_io);
426 }
427 
428 int
429 spdk_fsdev_rename(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
430 		  struct spdk_fsdev_file_object *parent_fobject, const char *name,
431 		  struct spdk_fsdev_file_object *new_parent_fobject, const char *new_name,
432 		  uint32_t flags, spdk_fsdev_rename_cpl_cb cb_fn, void *cb_arg)
433 {
434 	struct spdk_fsdev_io *fsdev_io;
435 
436 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_rename_cb, ch,
437 					 SPDK_FSDEV_IO_RENAME);
438 	if (!fsdev_io) {
439 		return -ENOBUFS;
440 	}
441 
442 	fsdev_io->u_in.rename.name = strdup(name);
443 	if (!fsdev_io->u_in.rename.name) {
444 		fsdev_io_free(fsdev_io);
445 		return -ENOMEM;
446 	}
447 
448 	fsdev_io->u_in.rename.new_name = strdup(new_name);
449 	if (!fsdev_io->u_in.rename.new_name) {
450 		free(fsdev_io->u_in.rename.name);
451 		fsdev_io_free(fsdev_io);
452 		return -ENOMEM;
453 	}
454 
455 	fsdev_io->u_in.rename.parent_fobject = parent_fobject;
456 	fsdev_io->u_in.rename.new_parent_fobject = new_parent_fobject;
457 	fsdev_io->u_in.rename.flags = flags;
458 
459 	fsdev_io_submit(fsdev_io);
460 	return 0;
461 }
462 
463 static void
464 _spdk_fsdev_link_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
465 {
466 	struct spdk_io_channel *ch = cb_arg;
467 
468 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_link_cpl_cb, fsdev_io->u_out.link.fobject,
469 		     &fsdev_io->u_out.link.attr);
470 
471 	free(fsdev_io->u_in.link.name);
472 
473 	fsdev_io_free(fsdev_io);
474 }
475 
476 int
477 spdk_fsdev_link(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
478 		struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_object *new_parent_fobject,
479 		const char *name, spdk_fsdev_link_cpl_cb cb_fn, void *cb_arg)
480 {
481 	struct spdk_fsdev_io *fsdev_io;
482 
483 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_link_cb, ch,
484 					 SPDK_FSDEV_IO_LINK);
485 	if (!fsdev_io) {
486 		return -ENOBUFS;
487 	}
488 
489 	fsdev_io->u_in.link.name = strdup(name);
490 	if (!fsdev_io->u_in.link.name) {
491 		fsdev_io_free(fsdev_io);
492 		return -ENOMEM;
493 	}
494 
495 	fsdev_io->u_in.link.fobject = fobject;
496 	fsdev_io->u_in.link.new_parent_fobject = new_parent_fobject;
497 
498 	fsdev_io_submit(fsdev_io);
499 	return 0;
500 }
501 
502 static void
503 _spdk_fsdev_fopen_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
504 {
505 	struct spdk_io_channel *ch = cb_arg;
506 
507 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_fopen_cpl_cb, fsdev_io->u_out.open.fhandle);
508 
509 	fsdev_io_free(fsdev_io);
510 }
511 
512 int
513 spdk_fsdev_fopen(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
514 		 struct spdk_fsdev_file_object *fobject, uint32_t flags,
515 		 spdk_fsdev_fopen_cpl_cb cb_fn, void *cb_arg)
516 {
517 	struct spdk_fsdev_io *fsdev_io;
518 
519 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_fopen_cb, ch,
520 					 SPDK_FSDEV_IO_OPEN);
521 	if (!fsdev_io) {
522 		return -ENOBUFS;
523 	}
524 
525 	fsdev_io->u_in.open.fobject = fobject;
526 	fsdev_io->u_in.open.flags = flags;
527 
528 	fsdev_io_submit(fsdev_io);
529 	return 0;
530 }
531 
532 static void
533 _spdk_fsdev_read_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
534 {
535 	struct spdk_io_channel *ch = cb_arg;
536 
537 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_read_cpl_cb, fsdev_io->u_out.read.data_size);
538 
539 	fsdev_io_free(fsdev_io);
540 }
541 
542 int
543 spdk_fsdev_read(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
544 		struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
545 		size_t size, uint64_t offs, uint32_t flags,
546 		struct iovec *iov, uint32_t iovcnt, struct spdk_fsdev_io_opts *opts,
547 		spdk_fsdev_read_cpl_cb cb_fn, void *cb_arg)
548 {
549 	struct spdk_fsdev_io *fsdev_io;
550 
551 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_read_cb, ch,
552 					 SPDK_FSDEV_IO_READ);
553 	if (!fsdev_io) {
554 		return -ENOBUFS;
555 	}
556 
557 	fsdev_io->u_in.read.fobject = fobject;
558 	fsdev_io->u_in.read.fhandle = fhandle;
559 	fsdev_io->u_in.read.size = size;
560 	fsdev_io->u_in.read.offs = offs;
561 	fsdev_io->u_in.read.flags = flags;
562 	fsdev_io->u_in.read.iov = iov;
563 	fsdev_io->u_in.read.iovcnt = iovcnt;
564 	fsdev_io->u_in.read.opts = opts;
565 
566 	fsdev_io_submit(fsdev_io);
567 	return 0;
568 }
569 
570 static void
571 _spdk_fsdev_write_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
572 {
573 	struct spdk_io_channel *ch = cb_arg;
574 
575 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_write_cpl_cb, fsdev_io->u_out.write.data_size);
576 
577 	fsdev_io_free(fsdev_io);
578 }
579 
580 int
581 spdk_fsdev_write(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
582 		 struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
583 		 size_t size, uint64_t offs, uint64_t flags,
584 		 const struct iovec *iov, uint32_t iovcnt, struct spdk_fsdev_io_opts *opts,
585 		 spdk_fsdev_write_cpl_cb cb_fn, void *cb_arg)
586 {
587 	struct spdk_fsdev_io *fsdev_io;
588 
589 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_write_cb, ch,
590 					 SPDK_FSDEV_IO_WRITE);
591 	if (!fsdev_io) {
592 		return -ENOBUFS;
593 	}
594 
595 	fsdev_io->u_in.write.fobject = fobject;
596 	fsdev_io->u_in.write.fhandle = fhandle;
597 	fsdev_io->u_in.write.size = size;
598 	fsdev_io->u_in.write.offs = offs;
599 	fsdev_io->u_in.write.flags = flags;
600 	fsdev_io->u_in.write.iov = iov;
601 	fsdev_io->u_in.write.iovcnt = iovcnt;
602 	fsdev_io->u_in.write.opts = opts;
603 
604 	fsdev_io_submit(fsdev_io);
605 	return 0;
606 }
607 
608 static void
609 _spdk_fsdev_statfs_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
610 {
611 	struct spdk_io_channel *ch = cb_arg;
612 
613 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_statfs_cpl_cb, &fsdev_io->u_out.statfs.statfs);
614 
615 	fsdev_io_free(fsdev_io);
616 }
617 
618 int
619 spdk_fsdev_statfs(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
620 		  struct spdk_fsdev_file_object *fobject, spdk_fsdev_statfs_cpl_cb cb_fn, void *cb_arg)
621 {
622 	struct spdk_fsdev_io *fsdev_io;
623 
624 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_statfs_cb, ch,
625 					 SPDK_FSDEV_IO_STATFS);
626 	if (!fsdev_io) {
627 		return -ENOBUFS;
628 	}
629 
630 	fsdev_io->u_in.statfs.fobject = fobject;
631 
632 	fsdev_io_submit(fsdev_io);
633 	return 0;
634 }
635 
636 static void
637 _spdk_fsdev_release_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
638 {
639 	struct spdk_io_channel *ch = cb_arg;
640 
641 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_release_cpl_cb);
642 
643 	fsdev_io_free(fsdev_io);
644 }
645 
646 int
647 spdk_fsdev_release(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
648 		   struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
649 		   spdk_fsdev_release_cpl_cb cb_fn, void *cb_arg)
650 {
651 	struct spdk_fsdev_io *fsdev_io;
652 
653 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_release_cb, ch,
654 					 SPDK_FSDEV_IO_RELEASE);
655 	if (!fsdev_io) {
656 		return -ENOBUFS;
657 	}
658 
659 	fsdev_io->u_in.release.fobject = fobject;
660 	fsdev_io->u_in.release.fhandle = fhandle;
661 
662 	fsdev_io_submit(fsdev_io);
663 	return 0;
664 }
665 
666 static void
667 _spdk_fsdev_fsync_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
668 {
669 	struct spdk_io_channel *ch = cb_arg;
670 
671 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_fsync_cpl_cb);
672 
673 	fsdev_io_free(fsdev_io);
674 }
675 
676 int
677 spdk_fsdev_fsync(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
678 		 struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle, bool datasync,
679 		 spdk_fsdev_fsync_cpl_cb cb_fn, void *cb_arg)
680 {
681 	struct spdk_fsdev_io *fsdev_io;
682 
683 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_fsync_cb, ch,
684 					 SPDK_FSDEV_IO_FSYNC);
685 	if (!fsdev_io) {
686 		return -ENOBUFS;
687 	}
688 
689 	fsdev_io->u_in.fsync.fobject = fobject;
690 	fsdev_io->u_in.fsync.fhandle = fhandle;
691 	fsdev_io->u_in.fsync.datasync = datasync;
692 
693 	fsdev_io_submit(fsdev_io);
694 	return 0;
695 }
696 
697 static void
698 _spdk_fsdev_setxattr_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
699 {
700 	struct spdk_io_channel *ch = cb_arg;
701 
702 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_setxattr_cpl_cb);
703 
704 	free(fsdev_io->u_in.setxattr.value);
705 	free(fsdev_io->u_in.setxattr.name);
706 
707 	fsdev_io_free(fsdev_io);
708 }
709 
710 int
711 spdk_fsdev_setxattr(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
712 		    struct spdk_fsdev_file_object *fobject, const char *name, const char *value, size_t size,
713 		    uint32_t flags, spdk_fsdev_setxattr_cpl_cb cb_fn, void *cb_arg)
714 {
715 	struct spdk_fsdev_io *fsdev_io;
716 
717 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_setxattr_cb, ch,
718 					 SPDK_FSDEV_IO_SETXATTR);
719 	if (!fsdev_io) {
720 		return -ENOBUFS;
721 	}
722 
723 	fsdev_io->u_in.setxattr.name = strdup(name);
724 	if (!fsdev_io->u_in.setxattr.name) {
725 		fsdev_io_free(fsdev_io);
726 		return -ENOMEM;
727 	}
728 
729 	fsdev_io->u_in.setxattr.value = malloc(size);
730 	if (!fsdev_io->u_in.setxattr.value) {
731 		free(fsdev_io->u_in.setxattr.name);
732 		fsdev_io_free(fsdev_io);
733 		return -ENOMEM;
734 	}
735 
736 	memcpy(fsdev_io->u_in.setxattr.value, value, size);
737 	fsdev_io->u_in.setxattr.fobject = fobject;
738 	fsdev_io->u_in.setxattr.size = size;
739 	fsdev_io->u_in.setxattr.flags = flags;
740 
741 	fsdev_io_submit(fsdev_io);
742 	return 0;
743 }
744 
745 static void
746 _spdk_fsdev_getxattr_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
747 {
748 	struct spdk_io_channel *ch = cb_arg;
749 
750 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_getxattr_cpl_cb, fsdev_io->u_out.getxattr.value_size);
751 
752 	free(fsdev_io->u_in.getxattr.name);
753 
754 	fsdev_io_free(fsdev_io);
755 }
756 
757 int
758 spdk_fsdev_getxattr(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
759 		    struct spdk_fsdev_file_object *fobject, const char *name, void *buffer, size_t size,
760 		    spdk_fsdev_getxattr_cpl_cb cb_fn, void *cb_arg)
761 {
762 	struct spdk_fsdev_io *fsdev_io;
763 
764 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_getxattr_cb, ch,
765 					 SPDK_FSDEV_IO_GETXATTR);
766 	if (!fsdev_io) {
767 		return -ENOBUFS;
768 	}
769 
770 	fsdev_io->u_in.getxattr.name = strdup(name);
771 	if (!fsdev_io->u_in.getxattr.name) {
772 		fsdev_io_free(fsdev_io);
773 		return -ENOMEM;
774 	}
775 
776 	fsdev_io->u_in.getxattr.fobject = fobject;
777 	fsdev_io->u_in.getxattr.buffer = buffer;
778 	fsdev_io->u_in.getxattr.size = size;
779 
780 	fsdev_io_submit(fsdev_io);
781 	return 0;
782 }
783 
784 static void
785 _spdk_fsdev_listxattr_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
786 {
787 	struct spdk_io_channel *ch = cb_arg;
788 
789 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_listxattr_cpl_cb, fsdev_io->u_out.listxattr.data_size,
790 		     fsdev_io->u_out.listxattr.size_only);
791 
792 	fsdev_io_free(fsdev_io);
793 }
794 
795 int
796 spdk_fsdev_listxattr(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
797 		     struct spdk_fsdev_file_object *fobject, char *buffer, size_t size,
798 		     spdk_fsdev_listxattr_cpl_cb cb_fn, void *cb_arg)
799 {
800 	struct spdk_fsdev_io *fsdev_io;
801 
802 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_listxattr_cb, ch,
803 					 SPDK_FSDEV_IO_LISTXATTR);
804 	if (!fsdev_io) {
805 		return -ENOBUFS;
806 	}
807 
808 	fsdev_io->u_in.listxattr.fobject = fobject;
809 	fsdev_io->u_in.listxattr.buffer = buffer;
810 	fsdev_io->u_in.listxattr.size = size;
811 
812 	fsdev_io_submit(fsdev_io);
813 	return 0;
814 }
815 
816 static void
817 _spdk_fsdev_removexattr_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
818 {
819 	struct spdk_io_channel *ch = cb_arg;
820 
821 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_removexattr_cpl_cb);
822 
823 	free(fsdev_io->u_in.removexattr.name);
824 
825 	fsdev_io_free(fsdev_io);
826 }
827 
828 int
829 spdk_fsdev_removexattr(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
830 		       struct spdk_fsdev_file_object *fobject, const char *name,
831 		       spdk_fsdev_removexattr_cpl_cb cb_fn, void *cb_arg)
832 {
833 	struct spdk_fsdev_io *fsdev_io;
834 
835 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_removexattr_cb, ch,
836 					 SPDK_FSDEV_IO_REMOVEXATTR);
837 	if (!fsdev_io) {
838 		return -ENOBUFS;
839 	}
840 
841 	fsdev_io->u_in.removexattr.name = strdup(name);
842 	if (!fsdev_io->u_in.removexattr.name) {
843 		fsdev_io_free(fsdev_io);
844 		return -ENOMEM;
845 	}
846 
847 	fsdev_io->u_in.removexattr.fobject = fobject;
848 
849 	fsdev_io_submit(fsdev_io);
850 	return 0;
851 }
852 
853 static void
854 _spdk_fsdev_flush_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
855 {
856 	struct spdk_io_channel *ch = cb_arg;
857 
858 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_flush_cpl_cb);
859 
860 	fsdev_io_free(fsdev_io);
861 }
862 
863 int
864 spdk_fsdev_flush(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
865 		 struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
866 		 spdk_fsdev_flush_cpl_cb cb_fn, void *cb_arg)
867 {
868 	struct spdk_fsdev_io *fsdev_io;
869 
870 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_flush_cb, ch,
871 					 SPDK_FSDEV_IO_FLUSH);
872 	if (!fsdev_io) {
873 		return -ENOBUFS;
874 	}
875 
876 	fsdev_io->u_in.flush.fobject = fobject;
877 	fsdev_io->u_in.flush.fhandle = fhandle;
878 
879 	fsdev_io_submit(fsdev_io);
880 	return 0;
881 }
882 
883 static void
884 _spdk_fsdev_opendir_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
885 {
886 	struct spdk_io_channel *ch = cb_arg;
887 
888 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_opendir_cpl_cb, fsdev_io->u_out.opendir.fhandle);
889 
890 	fsdev_io_free(fsdev_io);
891 }
892 
893 int
894 spdk_fsdev_opendir(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
895 		   struct spdk_fsdev_file_object *fobject, uint32_t flags,
896 		   spdk_fsdev_opendir_cpl_cb cb_fn, void *cb_arg)
897 {
898 	struct spdk_fsdev_io *fsdev_io;
899 
900 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_opendir_cb, ch,
901 					 SPDK_FSDEV_IO_OPENDIR);
902 	if (!fsdev_io) {
903 		return -ENOBUFS;
904 	}
905 
906 	fsdev_io->u_in.opendir.fobject = fobject;
907 	fsdev_io->u_in.opendir.flags = flags;
908 
909 	fsdev_io_submit(fsdev_io);
910 	return 0;
911 }
912 
913 static int
914 _spdk_fsdev_readdir_entry_clb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
915 {
916 	spdk_fsdev_readdir_entry_cb *usr_entry_cb_fn = fsdev_io->u_in.readdir.usr_entry_cb_fn;
917 	struct spdk_io_channel *ch = cb_arg;
918 
919 	return usr_entry_cb_fn(fsdev_io->internal.usr_cb_arg, ch, fsdev_io->u_out.readdir.name,
920 			       fsdev_io->u_out.readdir.fobject, &fsdev_io->u_out.readdir.attr, fsdev_io->u_out.readdir.offset);
921 }
922 
923 static void
924 _spdk_fsdev_readdir_emum_clb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
925 {
926 	struct spdk_io_channel *ch = cb_arg;
927 
928 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_readdir_cpl_cb);
929 
930 	fsdev_io_free(fsdev_io);
931 }
932 
933 int
934 spdk_fsdev_readdir(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
935 		   struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle, uint64_t offset,
936 		   spdk_fsdev_readdir_entry_cb entry_cb_fn, spdk_fsdev_readdir_cpl_cb cpl_cb_fn, void *cb_arg)
937 {
938 	struct spdk_fsdev_io *fsdev_io;
939 
940 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cpl_cb_fn, cb_arg,
941 					 _spdk_fsdev_readdir_emum_clb, ch, SPDK_FSDEV_IO_READDIR);
942 	if (!fsdev_io) {
943 		return -ENOBUFS;
944 	}
945 
946 	fsdev_io->u_in.readdir.fobject = fobject;
947 	fsdev_io->u_in.readdir.fhandle = fhandle;
948 	fsdev_io->u_in.readdir.offset = offset;
949 	fsdev_io->u_in.readdir.entry_cb_fn = _spdk_fsdev_readdir_entry_clb;
950 	fsdev_io->u_in.readdir.usr_entry_cb_fn = entry_cb_fn;
951 
952 	fsdev_io_submit(fsdev_io);
953 	return 0;
954 }
955 
956 static void
957 _spdk_fsdev_releasedir_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
958 {
959 	struct spdk_io_channel *ch = cb_arg;
960 
961 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_releasedir_cpl_cb);
962 
963 	fsdev_io_free(fsdev_io);
964 }
965 
966 int
967 spdk_fsdev_releasedir(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
968 		      struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
969 		      spdk_fsdev_releasedir_cpl_cb cb_fn, void *cb_arg)
970 {
971 	struct spdk_fsdev_io *fsdev_io;
972 
973 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_releasedir_cb, ch,
974 					 SPDK_FSDEV_IO_RELEASEDIR);
975 	if (!fsdev_io) {
976 		return -ENOBUFS;
977 	}
978 
979 	fsdev_io->u_in.releasedir.fobject = fobject;
980 	fsdev_io->u_in.releasedir.fhandle = fhandle;
981 
982 	fsdev_io_submit(fsdev_io);
983 	return 0;
984 }
985 
986 static void
987 _spdk_fsdev_fsyncdir_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
988 {
989 	struct spdk_io_channel *ch = cb_arg;
990 
991 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_fsyncdir_cpl_cb);
992 
993 	fsdev_io_free(fsdev_io);
994 }
995 
996 int
997 spdk_fsdev_fsyncdir(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
998 		    struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle, bool datasync,
999 		    spdk_fsdev_fsyncdir_cpl_cb cb_fn, void *cb_arg)
1000 {
1001 	struct spdk_fsdev_io *fsdev_io;
1002 
1003 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_fsyncdir_cb, ch,
1004 					 SPDK_FSDEV_IO_FSYNCDIR);
1005 	if (!fsdev_io) {
1006 		return -ENOBUFS;
1007 	}
1008 
1009 	fsdev_io->u_in.fsyncdir.fobject = fobject;
1010 	fsdev_io->u_in.fsyncdir.fhandle = fhandle;
1011 	fsdev_io->u_in.fsyncdir.datasync = datasync;
1012 
1013 	fsdev_io_submit(fsdev_io);
1014 	return 0;
1015 }
1016 
1017 static void
1018 _spdk_fsdev_flock_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
1019 {
1020 	struct spdk_io_channel *ch = cb_arg;
1021 
1022 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_flock_cpl_cb);
1023 
1024 	fsdev_io_free(fsdev_io);
1025 }
1026 
1027 int
1028 spdk_fsdev_flock(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
1029 		 struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle, int operation,
1030 		 spdk_fsdev_flock_cpl_cb cb_fn, void *cb_arg)
1031 {
1032 	struct spdk_fsdev_io *fsdev_io;
1033 
1034 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_flock_cb, ch,
1035 					 SPDK_FSDEV_IO_FLOCK);
1036 	if (!fsdev_io) {
1037 		return -ENOBUFS;
1038 	}
1039 
1040 	fsdev_io->u_in.flock.fobject = fobject;
1041 	fsdev_io->u_in.flock.fhandle = fhandle;
1042 	fsdev_io->u_in.flock.operation = operation;
1043 
1044 	fsdev_io_submit(fsdev_io);
1045 	return 0;
1046 }
1047 
1048 static void
1049 _spdk_fsdev_create_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
1050 {
1051 	struct spdk_io_channel *ch = cb_arg;
1052 
1053 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_create_cpl_cb, fsdev_io->u_out.create.fobject,
1054 		     &fsdev_io->u_out.create.attr, fsdev_io->u_out.create.fhandle);
1055 
1056 	free(fsdev_io->u_in.create.name);
1057 
1058 	fsdev_io_free(fsdev_io);
1059 }
1060 
1061 int
1062 spdk_fsdev_create(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
1063 		  struct spdk_fsdev_file_object *parent_fobject, const char *name, mode_t mode, uint32_t flags,
1064 		  mode_t umask, uid_t euid, gid_t egid, spdk_fsdev_create_cpl_cb cb_fn, void *cb_arg)
1065 {
1066 	struct spdk_fsdev_io *fsdev_io;
1067 
1068 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_create_cb, ch,
1069 					 SPDK_FSDEV_IO_CREATE);
1070 	if (!fsdev_io) {
1071 		return -ENOBUFS;
1072 	}
1073 
1074 	fsdev_io->u_in.create.name = strdup(name);
1075 	if (!fsdev_io->u_in.create.name) {
1076 		fsdev_io_free(fsdev_io);
1077 		return -ENOMEM;
1078 	}
1079 
1080 	fsdev_io->u_in.create.parent_fobject = parent_fobject;
1081 	fsdev_io->u_in.create.mode = mode;
1082 	fsdev_io->u_in.create.flags = flags;
1083 	fsdev_io->u_in.create.umask = umask;
1084 	fsdev_io->u_in.create.euid = euid;
1085 	fsdev_io->u_in.create.egid = egid;
1086 
1087 	fsdev_io_submit(fsdev_io);
1088 	return 0;
1089 }
1090 
1091 static void
1092 _spdk_fsdev_interrupt_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
1093 {
1094 	struct spdk_io_channel *ch = cb_arg;
1095 
1096 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_abort_cpl_cb);
1097 
1098 	fsdev_io_free(fsdev_io);
1099 }
1100 
1101 int
1102 spdk_fsdev_abort(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch,
1103 		 uint64_t unique_to_abort, spdk_fsdev_abort_cpl_cb cb_fn, void *cb_arg)
1104 {
1105 	struct spdk_fsdev_io *fsdev_io;
1106 
1107 	fsdev_io = fsdev_io_get_and_fill(desc, ch, 0, cb_fn, cb_arg, _spdk_fsdev_interrupt_cb, ch,
1108 					 SPDK_FSDEV_IO_ABORT);
1109 	if (!fsdev_io) {
1110 		return -ENOBUFS;
1111 	}
1112 
1113 	fsdev_io->u_in.abort.unique_to_abort = unique_to_abort;
1114 
1115 	fsdev_io_submit(fsdev_io);
1116 	return 0;
1117 }
1118 
1119 static void
1120 _spdk_fsdev_fallocate_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
1121 {
1122 	struct spdk_io_channel *ch = cb_arg;
1123 
1124 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_fallocate_cpl_cb);
1125 
1126 	fsdev_io_free(fsdev_io);
1127 }
1128 
1129 int
1130 spdk_fsdev_fallocate(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch, uint64_t unique,
1131 		     struct spdk_fsdev_file_object *fobject, struct spdk_fsdev_file_handle *fhandle,
1132 		     int mode, off_t offset, off_t length,
1133 		     spdk_fsdev_fallocate_cpl_cb cb_fn, void *cb_arg)
1134 {
1135 	struct spdk_fsdev_io *fsdev_io;
1136 
1137 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_fallocate_cb, ch,
1138 					 SPDK_FSDEV_IO_FALLOCATE);
1139 	if (!fsdev_io) {
1140 		return -ENOBUFS;
1141 	}
1142 
1143 	fsdev_io->u_in.fallocate.fobject = fobject;
1144 	fsdev_io->u_in.fallocate.fhandle = fhandle;
1145 	fsdev_io->u_in.fallocate.mode = mode;
1146 	fsdev_io->u_in.fallocate.offset = offset;
1147 	fsdev_io->u_in.fallocate.length = length;
1148 
1149 	fsdev_io_submit(fsdev_io);
1150 	return 0;
1151 }
1152 
1153 static void
1154 _spdk_fsdev_copy_file_range_cb(struct spdk_fsdev_io *fsdev_io, void *cb_arg)
1155 {
1156 	struct spdk_io_channel *ch = cb_arg;
1157 
1158 	CALL_USR_CLB(fsdev_io, ch, spdk_fsdev_copy_file_range_cpl_cb,
1159 		     fsdev_io->u_out.copy_file_range.data_size);
1160 
1161 	fsdev_io_free(fsdev_io);
1162 }
1163 
1164 int
1165 spdk_fsdev_copy_file_range(struct spdk_fsdev_desc *desc, struct spdk_io_channel *ch,
1166 			   uint64_t unique,
1167 			   struct spdk_fsdev_file_object *fobject_in, struct spdk_fsdev_file_handle *fhandle_in, off_t off_in,
1168 			   struct spdk_fsdev_file_object *fobject_out, struct spdk_fsdev_file_handle *fhandle_out,
1169 			   off_t off_out, size_t len, uint32_t flags,
1170 			   spdk_fsdev_copy_file_range_cpl_cb cb_fn, void *cb_arg)
1171 {
1172 	struct spdk_fsdev_io *fsdev_io;
1173 
1174 	fsdev_io = fsdev_io_get_and_fill(desc, ch, unique, cb_fn, cb_arg, _spdk_fsdev_copy_file_range_cb,
1175 					 ch,
1176 					 SPDK_FSDEV_IO_COPY_FILE_RANGE);
1177 	if (!fsdev_io) {
1178 		return -ENOBUFS;
1179 	}
1180 
1181 	fsdev_io->u_in.copy_file_range.fobject_in = fobject_in;
1182 	fsdev_io->u_in.copy_file_range.fhandle_in = fhandle_in;
1183 	fsdev_io->u_in.copy_file_range.off_in = off_in;
1184 	fsdev_io->u_in.copy_file_range.fobject_out = fobject_out;
1185 	fsdev_io->u_in.copy_file_range.fhandle_out = fhandle_out;
1186 	fsdev_io->u_in.copy_file_range.off_out = off_out;
1187 	fsdev_io->u_in.copy_file_range.len = len;
1188 	fsdev_io->u_in.copy_file_range.flags = flags;
1189 
1190 	fsdev_io_submit(fsdev_io);
1191 	return 0;
1192 }
1193