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