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"
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)
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;
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
}
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);
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
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;
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 {
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
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
/**
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;
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
}
907
exp->st_gid = gid;
908
}
909
886
- return fuse_getattr(exp, out);
910
+ return fuse_co_getattr(exp, out);
911
}
912
913
/**
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,
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;
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
}
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;
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;
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
}
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
}
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
}
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;
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
}
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) {
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
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
}
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);
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
/**
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
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;
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
}
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
}
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:
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:
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
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