@samitouri / QOSamiQemu / commits / fb9427cc94

fuse: Process requests in coroutines

Make fuse_process_request() a coroutine_fn (fuse_co_process_request()) and have read_from_fuse_fd() launch it inside of a newly created coroutine instead of running it synchronously. This way, we can process requests in parallel. These are the benchmark results, compared to (a) the original results with libfuse, and (b) the results after switching away from libfuse (i.e. before this patch): file: (vs. libfuse / vs. no libfuse) read: seq aio: 97.8k ±1.5k (-2% / -8%) rand aio: 95.8k ±3.4k (+90% / +98%) seq sync: 34.5k ±1.0k (-4% / -3%) rand sync: 9.9k ±0.1k (-1% / -1%) write: seq aio: 68.7k ±1.3k (-5% / -10%) rand aio: 68.9k ±1.1k (-2% / -10%) seq sync: 30.6k ±0.9k (±0% / -3%) rand sync: 30.6k ±0.6k (+1% / -1%) null: read: seq aio: 174.5k ±6.8k (+11% / +8%) rand aio: 170.9k ±5.7k (+8% / +3%) seq sync: 82.0k ±3.3k (+2% / +2%) rand sync: 78.0k ±4.0k (+1% / -1%) write: seq aio: 196.0k ±2.8k (+27% / +6%) rand aio: 191.2k ±7.9k (+24% / +2%) seq sync: 83.3k ±4.4k (+9% / +1%) rand sync: 79.5k ±4.4k (+9% / +1%) So there is not much difference, especially when compared to how it was with libfuse, except for the randread AIO case with an actual file. That improves greatly. Signed-off-by: Hanna Czenczek <hreitz@redhat.com> Message-ID: <20260309150856.26800-20-hreitz@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Hanna Czenczek committed Mar 9, 2026 at 16:08 UTC fb9427cc9497efe9783876899cf6ad4b1a317480
1 file changed +104 -72
block/export/fuse.c
+104 -72
@@ -27,6 +27,7 @@
27 #include "block/qapi.h"
28 #include "qapi/error.h"
29 #include "qapi/qapi-commands-block.h"
30 +#include "qemu/coroutine.h"
31 #include "qemu/error-report.h"
32 #include "qemu/main-loop.h"
33 #include "system/block-backend.h"
@@ -181,9 +182,9 @@ static int mount_fuse_export(FuseExport *exp, Error **errp);
182 static bool is_regular_file(const char *path, Error **errp);
183
184 static void read_from_fuse_fd(void *opaque);
184 -static void fuse_process_request(FuseExport *exp,
185 - const FuseRequestInHeader *in_hdr,
186 - const void *data_buffer);
185 +static void coroutine_fn
186 +fuse_co_process_request(FuseExport *exp, const FuseRequestInHeader *in_hdr,
187 + const void *data_buffer);
188 static int fuse_write_err(int fd, const struct fuse_in_header *in_hdr, int err);
189
190 static void fuse_inc_in_flight(FuseExport *exp)
@@ -518,9 +519,14 @@ static ssize_t req_op_hdr_len(const FuseRequestInHeader *in_hdr)
519 }
520
521 /**
521 - * Try to read and process a single request from the FUSE FD.
522 + * Try to read a single request from the FUSE FD.
523 + * Takes a FuseExport pointer in `opaque`.
524 + *
525 + * Assumes the export's in-flight counter has already been incremented.
526 + *
527 + * If a request is available, process it.
528 */
523 -static void read_from_fuse_fd(void *opaque)
529 +static void coroutine_fn co_read_from_fuse_fd(void *opaque)
530 {
531 FuseExport *exp = opaque;
532 int fuse_fd = exp->fuse_fd;
@@ -531,8 +537,6 @@ static void read_from_fuse_fd(void *opaque)
537 struct iovec iov[2];
538 ssize_t op_hdr_len;
539
534 - fuse_inc_in_flight(exp);
535 -
540 if (unlikely(qatomic_read(&exp->halted))) {
541 goto no_request;
542 }
@@ -601,13 +605,29 @@ static void read_from_fuse_fd(void *opaque)
605 release_write_data_buffer(exp, &data_buffer);
606 }
607
604 - fuse_process_request(exp, in_hdr, data_buffer);
608 + fuse_co_process_request(exp, in_hdr, data_buffer);
609
610 no_request:
611 release_write_data_buffer(exp, &data_buffer);
612 fuse_dec_in_flight(exp);
613 }
614
615 +/**
616 + * Try to read and process a single request from the FUSE FD.
617 + * (To be used as a handler for when the FUSE FD becomes readable.)
618 + * Takes a FuseExport pointer in `opaque`.
619 + */
620 +static void read_from_fuse_fd(void *opaque)
621 +{
622 + FuseExport *exp = opaque;
623 + Coroutine *co;
624 +
625 + co = qemu_coroutine_create(co_read_from_fuse_fd, exp);
626 + /* Decremented by co_read_from_fuse_fd() */
627 + fuse_inc_in_flight(exp);
628 + qemu_coroutine_enter(co);
629 +}
630 +
631 static void fuse_export_shutdown(BlockExport *blk_exp)
632 {
633 FuseExport *exp = container_of(blk_exp, FuseExport, common);
@@ -682,8 +702,9 @@ static bool is_regular_file(const char *path, Error **errp)
702 * Process FUSE INIT.
703 * Return the number of bytes written to *out on success, and -errno on error.
704 */
685 -static ssize_t fuse_init(FuseExport *exp, struct fuse_init_out *out,
686 - const struct fuse_init_in_compat *in)
705 +static ssize_t coroutine_fn GRAPH_RDLOCK
706 +fuse_co_init(FuseExport *exp, struct fuse_init_out *out,
707 + const struct fuse_init_in_compat *in)
708 {
709 const uint32_t supported_flags = FUSE_ASYNC_READ | FUSE_ASYNC_DIO;
710
@@ -738,7 +759,8 @@ static ssize_t fuse_init(FuseExport *exp, struct fuse_init_out *out,
759 /**
760 * Return some filesystem information, just to not break e.g. `df`.
761 */
741 -static ssize_t fuse_statfs(FuseExport *exp, struct fuse_statfs_out *out)
762 +static ssize_t coroutine_fn GRAPH_RDLOCK
763 +fuse_co_statfs(FuseExport *exp, struct fuse_statfs_out *out)
764 {
765 BlockDriverState *root_bs;
766 uint32_t opt_transfer = 512;
@@ -766,17 +788,18 @@ static ssize_t fuse_statfs(FuseExport *exp, struct fuse_statfs_out *out)
788 * Let clients get file attributes (i.e., stat() the file).
789 * Return the number of bytes written to *out on success, and -errno on error.
790 */
769 -static ssize_t fuse_getattr(FuseExport *exp, struct fuse_attr_out *out)
791 +static ssize_t coroutine_fn GRAPH_RDLOCK
792 +fuse_co_getattr(FuseExport *exp, struct fuse_attr_out *out)
793 {
794 int64_t length, allocated_blocks;
795 time_t now = time(NULL);
796
774 - length = blk_getlength(exp->common.blk);
797 + length = blk_co_getlength(exp->common.blk);
798 if (length < 0) {
799 return length;
800 }
801
779 - allocated_blocks = bdrv_get_allocated_file_size(blk_bs(exp->common.blk));
802 + allocated_blocks = bdrv_co_get_allocated_file_size(blk_bs(exp->common.blk));
803 if (allocated_blocks <= 0) {
804 allocated_blocks = DIV_ROUND_UP(length, 512);
805 } else {
@@ -803,8 +826,9 @@ static ssize_t fuse_getattr(FuseExport *exp, struct fuse_attr_out *out)
826 return sizeof(*out);
827 }
828
806 -static int fuse_do_truncate(const FuseExport *exp, int64_t size,
807 - bool req_zero_write, PreallocMode prealloc)
829 +static int coroutine_fn GRAPH_RDLOCK
830 +fuse_co_do_truncate(const FuseExport *exp, int64_t size, bool req_zero_write,
831 + PreallocMode prealloc)
832 {
833 BdrvRequestFlags truncate_flags = 0;
834
@@ -812,8 +836,8 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
836 truncate_flags |= BDRV_REQ_ZERO_WRITE;
837 }
838
815 - return blk_truncate(exp->common.blk, size, true, prealloc,
816 - truncate_flags, NULL);
839 + return blk_co_truncate(exp->common.blk, size, true, prealloc,
840 + truncate_flags, NULL);
841 }
842
843 /**
@@ -825,9 +849,9 @@ static int fuse_do_truncate(const FuseExport *exp, int64_t size,
849 * they cannot be given non-owner access.
850 * Return the number of bytes written to *out on success, and -errno on error.
851 */
828 -static ssize_t fuse_setattr(FuseExport *exp, struct fuse_attr_out *out,
829 - uint32_t to_set, uint64_t size, uint32_t mode,
830 - uint32_t uid, uint32_t gid)
852 +static ssize_t coroutine_fn GRAPH_RDLOCK
853 +fuse_co_setattr(FuseExport *exp, struct fuse_attr_out *out, uint32_t to_set,
854 + uint64_t size, uint32_t mode, uint32_t uid, uint32_t gid)
855 {
856 int supported_attrs;
857 int ret;
@@ -864,7 +888,7 @@ static ssize_t fuse_setattr(FuseExport *exp, struct fuse_attr_out *out,
888 return -EACCES;
889 }
890
867 - ret = fuse_do_truncate(exp, size, true, PREALLOC_MODE_OFF);
891 + ret = fuse_co_do_truncate(exp, size, true, PREALLOC_MODE_OFF);
892 if (ret < 0) {
893 return ret;
894 }
@@ -883,7 +907,7 @@ static ssize_t fuse_setattr(FuseExport *exp, struct fuse_attr_out *out,
907 exp->st_gid = gid;
908 }
909
886 - return fuse_getattr(exp, out);
910 + return fuse_co_getattr(exp, out);
911 }
912
913 /**
@@ -891,7 +915,8 @@ static ssize_t fuse_setattr(FuseExport *exp, struct fuse_attr_out *out,
915 * just acknowledge the request.
916 * Return the number of bytes written to *out on success, and -errno on error.
917 */
894 -static ssize_t fuse_open(FuseExport *exp, struct fuse_open_out *out)
918 +static ssize_t coroutine_fn GRAPH_RDLOCK
919 +fuse_co_open(FuseExport *exp, struct fuse_open_out *out)
920 {
921 *out = (struct fuse_open_out) {
922 .open_flags = FOPEN_DIRECT_IO | FOPEN_PARALLEL_DIRECT_WRITES,
@@ -906,8 +931,8 @@ static ssize_t fuse_open(FuseExport *exp, struct fuse_open_out *out)
931 * Note: If the returned size is 0, *bufptr will be set to NULL.
932 * After use, *bufptr must be freed via qemu_vfree().
933 */
909 -static ssize_t fuse_read(FuseExport *exp, void **bufptr,
910 - uint64_t offset, uint32_t size)
934 +static ssize_t coroutine_fn GRAPH_RDLOCK
935 +fuse_co_read(FuseExport *exp, void **bufptr, uint64_t offset, uint32_t size)
936 {
937 int64_t blk_len;
938 void *buf;
@@ -922,7 +947,7 @@ static ssize_t fuse_read(FuseExport *exp, void **bufptr,
947 * Clients will expect short reads at EOF, so we have to limit
948 * offset+size to the image length.
949 */
925 - blk_len = blk_getlength(exp->common.blk);
950 + blk_len = blk_co_getlength(exp->common.blk);
951 if (blk_len < 0) {
952 return blk_len;
953 }
@@ -942,7 +967,7 @@ static ssize_t fuse_read(FuseExport *exp, void **bufptr,
967 return -ENOMEM;
968 }
969
945 - ret = blk_pread(exp->common.blk, offset, size, buf, 0);
970 + ret = blk_co_pread(exp->common.blk, offset, size, buf, 0);
971 if (ret < 0) {
972 qemu_vfree(buf);
973 return ret;
@@ -956,8 +981,9 @@ static ssize_t fuse_read(FuseExport *exp, void **bufptr,
981 * Handle client writes to the exported image. @buf has the data to be written.
982 * Return the number of bytes written to *out on success, and -errno on error.
983 */
959 -static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out,
960 - uint64_t offset, uint32_t size, const void *buf)
984 +static ssize_t coroutine_fn GRAPH_RDLOCK
985 +fuse_co_write(FuseExport *exp, struct fuse_write_out *out,
986 + uint64_t offset, uint32_t size, const void *buf)
987 {
988 int64_t blk_len;
989 int ret;
@@ -976,7 +1002,7 @@ static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out,
1002 * Clients will expect short writes at EOF, so we have to limit
1003 * offset+size to the image length.
1004 */
979 - blk_len = blk_getlength(exp->common.blk);
1005 + blk_len = blk_co_getlength(exp->common.blk);
1006 if (blk_len < 0) {
1007 return blk_len;
1008 }
@@ -992,7 +1018,8 @@ static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out,
1018 return -EINVAL;
1019 } else if (offset + size > blk_len) {
1020 if (exp->growable) {
995 - ret = fuse_do_truncate(exp, offset + size, true, PREALLOC_MODE_OFF);
1021 + ret = fuse_co_do_truncate(exp, offset + size, true,
1022 + PREALLOC_MODE_OFF);
1023 if (ret < 0) {
1024 return ret;
1025 }
@@ -1001,7 +1028,7 @@ static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out,
1028 }
1029 }
1030
1004 - ret = blk_pwrite(exp->common.blk, offset, size, buf, 0);
1031 + ret = blk_co_pwrite(exp->common.blk, offset, size, buf, 0);
1032 if (ret < 0) {
1033 return ret;
1034 }
@@ -1016,8 +1043,9 @@ static ssize_t fuse_write(FuseExport *exp, struct fuse_write_out *out,
1043 * Let clients perform various fallocate() operations.
1044 * Return 0 on success (no 'out' object), and -errno on error.
1045 */
1019 -static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1020 - uint32_t mode)
1046 +static ssize_t coroutine_fn GRAPH_RDLOCK
1047 +fuse_co_fallocate(FuseExport *exp,
1048 + uint64_t offset, uint64_t length, uint32_t mode)
1049 {
1050 int64_t blk_len;
1051 int ret;
@@ -1026,7 +1054,7 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1054 return -EACCES;
1055 }
1056
1029 - blk_len = blk_getlength(exp->common.blk);
1057 + blk_len = blk_co_getlength(exp->common.blk);
1058 if (blk_len < 0) {
1059 return blk_len;
1060 }
@@ -1045,14 +1073,14 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1073
1074 if (offset > blk_len) {
1075 /* No preallocation needed here */
1048 - ret = fuse_do_truncate(exp, offset, true, PREALLOC_MODE_OFF);
1076 + ret = fuse_co_do_truncate(exp, offset, true, PREALLOC_MODE_OFF);
1077 if (ret < 0) {
1078 return ret;
1079 }
1080 }
1081
1054 - ret = fuse_do_truncate(exp, offset + length, true,
1055 - PREALLOC_MODE_FALLOC);
1082 + ret = fuse_co_do_truncate(exp, offset + length, true,
1083 + PREALLOC_MODE_FALLOC);
1084 }
1085 #ifdef CONFIG_FALLOCATE_PUNCH_HOLE
1086 else if (mode & FALLOC_FL_PUNCH_HOLE) {
@@ -1063,8 +1091,9 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1091 do {
1092 int size = MIN(length, BDRV_REQUEST_MAX_BYTES);
1093
1066 - ret = blk_pwrite_zeroes(exp->common.blk, offset, size,
1067 - BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK);
1094 + ret = blk_co_pwrite_zeroes(exp->common.blk, offset, size,
1095 + BDRV_REQ_MAY_UNMAP |
1096 + BDRV_REQ_NO_FALLBACK);
1097 if (ret == -ENOTSUP) {
1098 /*
1099 * fallocate() specifies to return EOPNOTSUPP for unsupported
@@ -1082,8 +1111,8 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1111 else if (mode & FALLOC_FL_ZERO_RANGE) {
1112 if (!(mode & FALLOC_FL_KEEP_SIZE) && offset + length > blk_len) {
1113 /* No need for zeroes, we are going to write them ourselves */
1085 - ret = fuse_do_truncate(exp, offset + length, false,
1086 - PREALLOC_MODE_OFF);
1114 + ret = fuse_co_do_truncate(exp, offset + length, false,
1115 + PREALLOC_MODE_OFF);
1116 if (ret < 0) {
1117 return ret;
1118 }
@@ -1092,8 +1121,8 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1121 do {
1122 int size = MIN(length, BDRV_REQUEST_MAX_BYTES);
1123
1095 - ret = blk_pwrite_zeroes(exp->common.blk,
1096 - offset, size, 0);
1124 + ret = blk_co_pwrite_zeroes(exp->common.blk,
1125 + offset, size, 0);
1126 offset += size;
1127 length -= size;
1128 } while (ret == 0 && length > 0);
@@ -1110,9 +1139,9 @@ static ssize_t fuse_fallocate(FuseExport *exp, uint64_t offset, uint64_t length,
1139 * Let clients fsync the exported image.
1140 * Return 0 on success (no 'out' object), and -errno on error.
1141 */
1113 -static ssize_t fuse_fsync(FuseExport *exp)
1142 +static ssize_t coroutine_fn GRAPH_RDLOCK fuse_co_fsync(FuseExport *exp)
1143 {
1115 - return blk_flush(exp->common.blk);
1144 + return blk_co_flush(exp->common.blk);
1145 }
1146
1147 /**
@@ -1120,9 +1149,9 @@ static ssize_t fuse_fsync(FuseExport *exp)
1149 * notes this to be a way to return last-minute errors.)
1150 * Return 0 on success (no 'out' object), and -errno on error.
1151 */
1123 -static ssize_t fuse_flush(FuseExport *exp)
1152 +static ssize_t coroutine_fn GRAPH_RDLOCK fuse_co_flush(FuseExport *exp)
1153 {
1125 - return blk_flush(exp->common.blk);
1154 + return blk_co_flush(exp->common.blk);
1155 }
1156
1157 #ifdef CONFIG_FUSE_LSEEK
@@ -1130,8 +1159,9 @@ static ssize_t fuse_flush(FuseExport *exp)
1159 * Let clients inquire allocation status.
1160 * Return the number of bytes written to *out on success, and -errno on error.
1161 */
1133 -static ssize_t fuse_lseek(FuseExport *exp, struct fuse_lseek_out *out,
1134 - uint64_t offset, uint32_t whence)
1162 +static ssize_t coroutine_fn GRAPH_RDLOCK
1163 +fuse_co_lseek(FuseExport *exp, struct fuse_lseek_out *out,
1164 + uint64_t offset, uint32_t whence)
1165 {
1166 if (whence != SEEK_HOLE && whence != SEEK_DATA) {
1167 return -EINVAL;
@@ -1141,8 +1171,8 @@ static ssize_t fuse_lseek(FuseExport *exp, struct fuse_lseek_out *out,
1171 int64_t pnum;
1172 int ret;
1173
1144 - ret = bdrv_block_status_above(blk_bs(exp->common.blk), NULL,
1145 - offset, INT64_MAX, &pnum, NULL, NULL);
1174 + ret = bdrv_co_block_status_above(blk_bs(exp->common.blk), NULL,
1175 + offset, INT64_MAX, &pnum, NULL, NULL);
1176 if (ret < 0) {
1177 return ret;
1178 }
@@ -1159,7 +1189,7 @@ static ssize_t fuse_lseek(FuseExport *exp, struct fuse_lseek_out *out,
1189 * and @blk_len (the client-visible EOF).
1190 */
1191
1162 - blk_len = blk_getlength(exp->common.blk);
1192 + blk_len = blk_co_getlength(exp->common.blk);
1193 if (blk_len < 0) {
1194 return blk_len;
1195 }
@@ -1303,18 +1333,20 @@ static int fuse_write_buf_response(int fd,
1333 /**
1334 * Process a FUSE request, incl. writing the response.
1335 */
1306 -static void fuse_process_request(FuseExport *exp,
1307 - const FuseRequestInHeader *in_hdr,
1308 - const void *data_buffer)
1336 +static void coroutine_fn
1337 +fuse_co_process_request(FuseExport *exp, const FuseRequestInHeader *in_hdr,
1338 + const void *data_buffer)
1339 {
1340 FuseRequestOutHeader out_hdr;
1341 /* For read requests: Data to be returned */
1342 void *out_data_buffer = NULL;
1343 ssize_t ret;
1344
1345 + GRAPH_RDLOCK_GUARD();
1346 +
1347 switch (in_hdr->common.opcode) {
1348 case FUSE_INIT:
1317 - ret = fuse_init(exp, &out_hdr.init, &in_hdr->init);
1349 + ret = fuse_co_init(exp, &out_hdr.init, &in_hdr->init);
1350 break;
1351
1352 case FUSE_DESTROY:
@@ -1322,11 +1354,11 @@ static void fuse_process_request(FuseExport *exp,
1354 break;
1355
1356 case FUSE_STATFS:
1325 - ret = fuse_statfs(exp, &out_hdr.statfs);
1357 + ret = fuse_co_statfs(exp, &out_hdr.statfs);
1358 break;
1359
1360 case FUSE_OPEN:
1329 - ret = fuse_open(exp, &out_hdr.open);
1361 + ret = fuse_co_open(exp, &out_hdr.open);
1362 break;
1363
1364 case FUSE_RELEASE:
@@ -1343,19 +1375,19 @@ static void fuse_process_request(FuseExport *exp,
1375 return;
1376
1377 case FUSE_GETATTR:
1346 - ret = fuse_getattr(exp, &out_hdr.attr);
1378 + ret = fuse_co_getattr(exp, &out_hdr.attr);
1379 break;
1380
1381 case FUSE_SETATTR: {
1382 const struct fuse_setattr_in *in = &in_hdr->setattr;
1351 - ret = fuse_setattr(exp, &out_hdr.attr,
1352 - in->valid, in->size, in->mode, in->uid, in->gid);
1383 + ret = fuse_co_setattr(exp, &out_hdr.attr,
1384 + in->valid, in->size, in->mode, in->uid, in->gid);
1385 break;
1386 }
1387
1388 case FUSE_READ: {
1389 const struct fuse_read_in *in = &in_hdr->read;
1358 - ret = fuse_read(exp, &out_data_buffer, in->offset, in->size);
1390 + ret = fuse_co_read(exp, &out_data_buffer, in->offset, in->size);
1391 break;
1392 }
1393
@@ -1373,36 +1405,36 @@ static void fuse_process_request(FuseExport *exp,
1405 }
1406
1407 /*
1376 - * read_from_fuse_fd() has checked that in_hdr->len matches the number
1377 - * of bytes read, which cannot exceed the max_write value we set
1408 + * co_read_from_fuse_fd() has checked that in_hdr->len matches the
1409 + * number of bytes read, which cannot exceed the max_write value we set
1410 * (FUSE_MAX_WRITE_BYTES). So we know that FUSE_MAX_WRITE_BYTES >=
1411 * in_hdr->len >= in->size + X, so this assertion must hold.
1412 */
1413 assert(in->size <= FUSE_MAX_WRITE_BYTES);
1414
1383 - ret = fuse_write(exp, &out_hdr.write,
1384 - in->offset, in->size, data_buffer);
1415 + ret = fuse_co_write(exp, &out_hdr.write,
1416 + in->offset, in->size, data_buffer);
1417 break;
1418 }
1419
1420 case FUSE_FALLOCATE: {
1421 const struct fuse_fallocate_in *in = &in_hdr->fallocate;
1390 - ret = fuse_fallocate(exp, in->offset, in->length, in->mode);
1422 + ret = fuse_co_fallocate(exp, in->offset, in->length, in->mode);
1423 break;
1424 }
1425
1426 case FUSE_FSYNC:
1395 - ret = fuse_fsync(exp);
1427 + ret = fuse_co_fsync(exp);
1428 break;
1429
1430 case FUSE_FLUSH:
1399 - ret = fuse_flush(exp);
1431 + ret = fuse_co_flush(exp);
1432 break;
1433
1434 #ifdef CONFIG_FUSE_LSEEK
1435 case FUSE_LSEEK: {
1436 const struct fuse_lseek_in *in = &in_hdr->lseek;
1405 - ret = fuse_lseek(exp, &out_hdr.lseek, in->offset, in->whence);
1437 + ret = fuse_co_lseek(exp, &out_hdr.lseek, in->offset, in->whence);
1438 break;
1439 }
1440 #endif