Revision ff06030f hw/9pfs/virtio-9p.c
b/hw/9pfs/virtio-9p.c | ||
---|---|---|
19 | 19 |
#include "fsdev/qemu-fsdev.h" |
20 | 20 |
#include "virtio-9p-debug.h" |
21 | 21 |
#include "virtio-9p-xattr.h" |
22 |
#include "virtio-9p-coth.h" |
|
22 | 23 |
|
23 | 24 |
int debug_9p_pdu; |
24 | 25 |
|
... | ... | |
1191 | 1192 |
v9fs_string_free(&str); |
1192 | 1193 |
} |
1193 | 1194 |
|
1194 |
static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
|
|
1195 |
static void v9fs_version(void *opaque)
|
|
1195 | 1196 |
{ |
1197 |
V9fsPDU *pdu = opaque; |
|
1198 |
V9fsState *s = pdu->s; |
|
1196 | 1199 |
V9fsString version; |
1197 | 1200 |
size_t offset = 7; |
1198 | 1201 |
|
... | ... | |
1210 | 1213 |
complete_pdu(s, pdu, offset); |
1211 | 1214 |
|
1212 | 1215 |
v9fs_string_free(&version); |
1216 |
return; |
|
1213 | 1217 |
} |
1214 | 1218 |
|
1215 |
static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
|
|
1219 |
static void v9fs_attach(void *opaque)
|
|
1216 | 1220 |
{ |
1221 |
V9fsPDU *pdu = opaque; |
|
1222 |
V9fsState *s = pdu->s; |
|
1217 | 1223 |
int32_t fid, afid, n_uname; |
1218 | 1224 |
V9fsString uname, aname; |
1219 | 1225 |
V9fsFidState *fidp; |
... | ... | |
1268 | 1274 |
qemu_free(vs); |
1269 | 1275 |
} |
1270 | 1276 |
|
1271 |
static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
|
|
1277 |
static void v9fs_stat(void *opaque)
|
|
1272 | 1278 |
{ |
1279 |
V9fsPDU *pdu = opaque; |
|
1280 |
V9fsState *s = pdu->s; |
|
1273 | 1281 |
int32_t fid; |
1274 | 1282 |
V9fsStatState *vs; |
1275 | 1283 |
ssize_t err = 0; |
... | ... | |
1315 | 1323 |
qemu_free(vs); |
1316 | 1324 |
} |
1317 | 1325 |
|
1318 |
static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
|
|
1326 |
static void v9fs_getattr(void *opaque)
|
|
1319 | 1327 |
{ |
1328 |
V9fsPDU *pdu = opaque; |
|
1329 |
V9fsState *s = pdu->s; |
|
1320 | 1330 |
int32_t fid; |
1321 | 1331 |
V9fsStatStateDotl *vs; |
1322 | 1332 |
ssize_t err = 0; |
... | ... | |
1464 | 1474 |
qemu_free(vs); |
1465 | 1475 |
} |
1466 | 1476 |
|
1467 |
static void v9fs_setattr(V9fsState *s, V9fsPDU *pdu)
|
|
1477 |
static void v9fs_setattr(void *opaque)
|
|
1468 | 1478 |
{ |
1479 |
V9fsPDU *pdu = opaque; |
|
1480 |
V9fsState *s = pdu->s; |
|
1469 | 1481 |
int32_t fid; |
1470 | 1482 |
V9fsSetattrState *vs; |
1471 | 1483 |
int err = 0; |
... | ... | |
1578 | 1590 |
v9fs_walk_complete(s, vs, err); |
1579 | 1591 |
} |
1580 | 1592 |
|
1581 |
static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
|
|
1593 |
static void v9fs_walk(void *opaque)
|
|
1582 | 1594 |
{ |
1595 |
V9fsPDU *pdu = opaque; |
|
1596 |
V9fsState *s = pdu->s; |
|
1583 | 1597 |
int32_t fid, newfid; |
1584 | 1598 |
V9fsWalkState *vs; |
1585 | 1599 |
int err = 0; |
... | ... | |
1750 | 1764 |
qemu_free(vs); |
1751 | 1765 |
} |
1752 | 1766 |
|
1753 |
static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
|
|
1767 |
static void v9fs_open(void *opaque)
|
|
1754 | 1768 |
{ |
1769 |
V9fsPDU *pdu = opaque; |
|
1770 |
V9fsState *s = pdu->s; |
|
1755 | 1771 |
int32_t fid; |
1756 | 1772 |
V9fsOpenState *vs; |
1757 | 1773 |
ssize_t err = 0; |
... | ... | |
1835 | 1851 |
v9fs_post_lcreate(s, vs, err); |
1836 | 1852 |
} |
1837 | 1853 |
|
1838 |
static void v9fs_lcreate(V9fsState *s, V9fsPDU *pdu)
|
|
1854 |
static void v9fs_lcreate(void *opaque)
|
|
1839 | 1855 |
{ |
1856 |
V9fsPDU *pdu = opaque; |
|
1857 |
V9fsState *s = pdu->s; |
|
1840 | 1858 |
int32_t dfid, flags, mode; |
1841 | 1859 |
gid_t gid; |
1842 | 1860 |
V9fsLcreateState *vs; |
... | ... | |
1882 | 1900 |
complete_pdu(s, pdu, err); |
1883 | 1901 |
} |
1884 | 1902 |
|
1885 |
static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
|
|
1903 |
static void v9fs_fsync(void *opaque)
|
|
1886 | 1904 |
{ |
1905 |
V9fsPDU *pdu = opaque; |
|
1906 |
V9fsState *s = pdu->s; |
|
1887 | 1907 |
int32_t fid; |
1888 | 1908 |
size_t offset = 7; |
1889 | 1909 |
V9fsFidState *fidp; |
... | ... | |
1901 | 1921 |
v9fs_post_do_fsync(s, pdu, err); |
1902 | 1922 |
} |
1903 | 1923 |
|
1904 |
static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
|
|
1924 |
static void v9fs_clunk(void *opaque)
|
|
1905 | 1925 |
{ |
1926 |
V9fsPDU *pdu = opaque; |
|
1927 |
V9fsState *s = pdu->s; |
|
1906 | 1928 |
int32_t fid; |
1907 | 1929 |
size_t offset = 7; |
1908 | 1930 |
int err; |
... | ... | |
2067 | 2089 |
qemu_free(vs); |
2068 | 2090 |
} |
2069 | 2091 |
|
2070 |
static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
|
|
2092 |
static void v9fs_read(void *opaque)
|
|
2071 | 2093 |
{ |
2094 |
V9fsPDU *pdu = opaque; |
|
2095 |
V9fsState *s = pdu->s; |
|
2072 | 2096 |
int32_t fid; |
2073 | 2097 |
V9fsReadState *vs; |
2074 | 2098 |
ssize_t err = 0; |
... | ... | |
2206 | 2230 |
return; |
2207 | 2231 |
} |
2208 | 2232 |
|
2209 |
static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
|
|
2233 |
static void v9fs_readdir(void *opaque)
|
|
2210 | 2234 |
{ |
2235 |
V9fsPDU *pdu = opaque; |
|
2236 |
V9fsState *s = pdu->s; |
|
2211 | 2237 |
int32_t fid; |
2212 | 2238 |
V9fsReadDirState *vs; |
2213 | 2239 |
ssize_t err = 0; |
... | ... | |
2239 | 2265 |
out: |
2240 | 2266 |
complete_pdu(s, pdu, err); |
2241 | 2267 |
qemu_free(vs); |
2242 |
return; |
|
2243 | 2268 |
} |
2244 | 2269 |
|
2245 | 2270 |
static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs, |
... | ... | |
2318 | 2343 |
qemu_free(vs); |
2319 | 2344 |
} |
2320 | 2345 |
|
2321 |
static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
|
|
2346 |
static void v9fs_write(void *opaque)
|
|
2322 | 2347 |
{ |
2348 |
V9fsPDU *pdu = opaque; |
|
2349 |
V9fsState *s = pdu->s; |
|
2323 | 2350 |
int32_t fid; |
2324 | 2351 |
V9fsWriteState *vs; |
2325 | 2352 |
ssize_t err; |
... | ... | |
2552 | 2579 |
v9fs_post_create(s, vs, err); |
2553 | 2580 |
} |
2554 | 2581 |
|
2555 |
static void v9fs_create(V9fsState *s, V9fsPDU *pdu)
|
|
2582 |
static void v9fs_create(void *opaque)
|
|
2556 | 2583 |
{ |
2584 |
V9fsPDU *pdu = opaque; |
|
2585 |
V9fsState *s = pdu->s; |
|
2557 | 2586 |
int32_t fid; |
2558 | 2587 |
V9fsCreateState *vs; |
2559 | 2588 |
int err = 0; |
... | ... | |
2614 | 2643 |
v9fs_post_symlink(s, vs, err); |
2615 | 2644 |
} |
2616 | 2645 |
|
2617 |
static void v9fs_symlink(V9fsState *s, V9fsPDU *pdu)
|
|
2646 |
static void v9fs_symlink(void *opaque)
|
|
2618 | 2647 |
{ |
2648 |
V9fsPDU *pdu = opaque; |
|
2649 |
V9fsState *s = pdu->s; |
|
2619 | 2650 |
int32_t dfid; |
2620 | 2651 |
V9fsSymlinkState *vs; |
2621 | 2652 |
int err = 0; |
... | ... | |
2650 | 2681 |
qemu_free(vs); |
2651 | 2682 |
} |
2652 | 2683 |
|
2653 |
static void v9fs_flush(V9fsState *s, V9fsPDU *pdu)
|
|
2684 |
static void v9fs_flush(void *opaque)
|
|
2654 | 2685 |
{ |
2686 |
V9fsPDU *pdu = opaque; |
|
2687 |
V9fsState *s = pdu->s; |
|
2655 | 2688 |
/* A nop call with no return */ |
2656 | 2689 |
complete_pdu(s, pdu, 7); |
2690 |
return; |
|
2657 | 2691 |
} |
2658 | 2692 |
|
2659 |
static void v9fs_link(V9fsState *s, V9fsPDU *pdu)
|
|
2693 |
static void v9fs_link(void *opaque)
|
|
2660 | 2694 |
{ |
2695 |
V9fsPDU *pdu = opaque; |
|
2696 |
V9fsState *s = pdu->s; |
|
2661 | 2697 |
int32_t dfid, oldfid; |
2662 | 2698 |
V9fsFidState *dfidp, *oldfidp; |
2663 | 2699 |
V9fsString name, fullname; |
... | ... | |
2709 | 2745 |
qemu_free(vs); |
2710 | 2746 |
} |
2711 | 2747 |
|
2712 |
static void v9fs_remove(V9fsState *s, V9fsPDU *pdu)
|
|
2748 |
static void v9fs_remove(void *opaque)
|
|
2713 | 2749 |
{ |
2750 |
V9fsPDU *pdu = opaque; |
|
2751 |
V9fsState *s = pdu->s; |
|
2714 | 2752 |
int32_t fid; |
2715 | 2753 |
V9fsRemoveState *vs; |
2716 | 2754 |
int err = 0; |
... | ... | |
2876 | 2914 |
qemu_free(vs); |
2877 | 2915 |
} |
2878 | 2916 |
|
2879 |
static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
|
|
2917 |
static void v9fs_rename(void *opaque)
|
|
2880 | 2918 |
{ |
2919 |
V9fsPDU *pdu = opaque; |
|
2920 |
V9fsState *s = pdu->s; |
|
2881 | 2921 |
int32_t fid; |
2882 | 2922 |
V9fsRenameState *vs; |
2883 | 2923 |
ssize_t err = 0; |
... | ... | |
3001 | 3041 |
qemu_free(vs); |
3002 | 3042 |
} |
3003 | 3043 |
|
3004 |
static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
|
|
3044 |
static void v9fs_wstat(void *opaque)
|
|
3005 | 3045 |
{ |
3046 |
V9fsPDU *pdu = opaque; |
|
3047 |
V9fsState *s = pdu->s; |
|
3006 | 3048 |
int32_t fid; |
3007 | 3049 |
V9fsWstatState *vs; |
3008 | 3050 |
int err = 0; |
... | ... | |
3086 | 3128 |
qemu_free(vs); |
3087 | 3129 |
} |
3088 | 3130 |
|
3089 |
static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu)
|
|
3131 |
static void v9fs_statfs(void *opaque)
|
|
3090 | 3132 |
{ |
3133 |
V9fsPDU *pdu = opaque; |
|
3134 |
V9fsState *s = pdu->s; |
|
3091 | 3135 |
V9fsStatfsState *vs; |
3092 | 3136 |
ssize_t err = 0; |
3093 | 3137 |
|
... | ... | |
3112 | 3156 |
out: |
3113 | 3157 |
complete_pdu(s, vs->pdu, err); |
3114 | 3158 |
qemu_free(vs); |
3159 |
return; |
|
3115 | 3160 |
} |
3116 | 3161 |
|
3117 | 3162 |
static void v9fs_mknod_post_lstat(V9fsState *s, V9fsMkState *vs, int err) |
... | ... | |
3148 | 3193 |
qemu_free(vs); |
3149 | 3194 |
} |
3150 | 3195 |
|
3151 |
static void v9fs_mknod(V9fsState *s, V9fsPDU *pdu)
|
|
3196 |
static void v9fs_mknod(void *opaque)
|
|
3152 | 3197 |
{ |
3198 |
V9fsPDU *pdu = opaque; |
|
3199 |
V9fsState *s = pdu->s; |
|
3153 | 3200 |
int32_t fid; |
3154 | 3201 |
V9fsMkState *vs; |
3155 | 3202 |
int err = 0; |
... | ... | |
3194 | 3241 |
* So when a TLOCK request comes, always return success |
3195 | 3242 |
*/ |
3196 | 3243 |
|
3197 |
static void v9fs_lock(V9fsState *s, V9fsPDU *pdu)
|
|
3244 |
static void v9fs_lock(void *opaque)
|
|
3198 | 3245 |
{ |
3246 |
V9fsPDU *pdu = opaque; |
|
3247 |
V9fsState *s = pdu->s; |
|
3199 | 3248 |
int32_t fid, err = 0; |
3200 | 3249 |
V9fsLockState *vs; |
3201 | 3250 |
|
... | ... | |
3239 | 3288 |
* handling is done by client's VFS layer. |
3240 | 3289 |
*/ |
3241 | 3290 |
|
3242 |
static void v9fs_getlock(V9fsState *s, V9fsPDU *pdu)
|
|
3291 |
static void v9fs_getlock(void *opaque)
|
|
3243 | 3292 |
{ |
3293 |
V9fsPDU *pdu = opaque; |
|
3294 |
V9fsState *s = pdu->s; |
|
3244 | 3295 |
int32_t fid, err = 0; |
3245 | 3296 |
V9fsGetlockState *vs; |
3246 | 3297 |
|
... | ... | |
3308 | 3359 |
qemu_free(vs); |
3309 | 3360 |
} |
3310 | 3361 |
|
3311 |
static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu)
|
|
3362 |
static void v9fs_mkdir(void *opaque)
|
|
3312 | 3363 |
{ |
3364 |
V9fsPDU *pdu = opaque; |
|
3365 |
V9fsState *s = pdu->s; |
|
3313 | 3366 |
int32_t fid; |
3314 | 3367 |
V9fsMkState *vs; |
3315 | 3368 |
int err = 0; |
... | ... | |
3432 | 3485 |
qemu_free(vs); |
3433 | 3486 |
} |
3434 | 3487 |
|
3435 |
static void v9fs_xattrwalk(V9fsState *s, V9fsPDU *pdu)
|
|
3488 |
static void v9fs_xattrwalk(void *opaque)
|
|
3436 | 3489 |
{ |
3490 |
V9fsPDU *pdu = opaque; |
|
3491 |
V9fsState *s = pdu->s; |
|
3437 | 3492 |
ssize_t err = 0; |
3438 | 3493 |
V9fsXattrState *vs; |
3439 | 3494 |
int32_t fid, newfid; |
... | ... | |
3486 | 3541 |
qemu_free(vs); |
3487 | 3542 |
} |
3488 | 3543 |
|
3489 |
static void v9fs_xattrcreate(V9fsState *s, V9fsPDU *pdu)
|
|
3544 |
static void v9fs_xattrcreate(void *opaque)
|
|
3490 | 3545 |
{ |
3546 |
V9fsPDU *pdu = opaque; |
|
3547 |
V9fsState *s = pdu->s; |
|
3491 | 3548 |
int flags; |
3492 | 3549 |
int32_t fid; |
3493 | 3550 |
ssize_t err = 0; |
... | ... | |
3540 | 3597 |
qemu_free(vs); |
3541 | 3598 |
} |
3542 | 3599 |
|
3543 |
static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
|
|
3600 |
static void v9fs_readlink(void *opaque)
|
|
3544 | 3601 |
{ |
3602 |
V9fsPDU *pdu = opaque; |
|
3603 |
V9fsState *s = pdu->s; |
|
3545 | 3604 |
int32_t fid; |
3546 | 3605 |
V9fsReadLinkState *vs; |
3547 | 3606 |
int err = 0; |
... | ... | |
3568 | 3627 |
qemu_free(vs); |
3569 | 3628 |
} |
3570 | 3629 |
|
3571 |
typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu); |
|
3572 |
|
|
3573 |
static pdu_handler_t *pdu_handlers[] = { |
|
3630 |
static CoroutineEntry *pdu_co_handlers[] = { |
|
3574 | 3631 |
[P9_TREADDIR] = v9fs_readdir, |
3575 | 3632 |
[P9_TSTATFS] = v9fs_statfs, |
3576 | 3633 |
[P9_TGETATTR] = v9fs_getattr, |
... | ... | |
3605 | 3662 |
[P9_TREMOVE] = v9fs_remove, |
3606 | 3663 |
}; |
3607 | 3664 |
|
3608 |
static void v9fs_op_not_supp(V9fsState *s, V9fsPDU *pdu)
|
|
3665 |
static void v9fs_op_not_supp(void *opaque)
|
|
3609 | 3666 |
{ |
3610 |
complete_pdu(s, pdu, -EOPNOTSUPP); |
|
3667 |
V9fsPDU *pdu = opaque; |
|
3668 |
complete_pdu(pdu->s, pdu, -EOPNOTSUPP); |
|
3611 | 3669 |
} |
3612 | 3670 |
|
3613 | 3671 |
static void submit_pdu(V9fsState *s, V9fsPDU *pdu) |
3614 | 3672 |
{ |
3615 |
pdu_handler_t *handler; |
|
3673 |
Coroutine *co; |
|
3674 |
CoroutineEntry *handler; |
|
3616 | 3675 |
|
3617 | 3676 |
if (debug_9p_pdu) { |
3618 | 3677 |
pprint_pdu(pdu); |
3619 | 3678 |
} |
3620 |
if (pdu->id >= ARRAY_SIZE(pdu_handlers) || |
|
3621 |
(pdu_handlers[pdu->id] == NULL)) { |
|
3679 |
if (pdu->id >= ARRAY_SIZE(pdu_co_handlers) ||
|
|
3680 |
(pdu_co_handlers[pdu->id] == NULL)) {
|
|
3622 | 3681 |
handler = v9fs_op_not_supp; |
3623 | 3682 |
} else { |
3624 |
handler = pdu_handlers[pdu->id]; |
|
3683 |
handler = pdu_co_handlers[pdu->id];
|
|
3625 | 3684 |
} |
3626 |
handler(s, pdu); |
|
3685 |
co = qemu_coroutine_create(handler); |
|
3686 |
qemu_coroutine_enter(co, pdu); |
|
3627 | 3687 |
} |
3628 | 3688 |
|
3629 | 3689 |
void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq) |
... | ... | |
3635 | 3695 |
while ((pdu = alloc_pdu(s)) && |
3636 | 3696 |
(len = virtqueue_pop(vq, &pdu->elem)) != 0) { |
3637 | 3697 |
uint8_t *ptr; |
3638 |
|
|
3698 |
pdu->s = s; |
|
3639 | 3699 |
BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0); |
3640 | 3700 |
BUG_ON(pdu->elem.out_sg[0].iov_len < 7); |
3641 | 3701 |
|
... | ... | |
3644 | 3704 |
memcpy(&pdu->size, ptr, 4); |
3645 | 3705 |
pdu->id = ptr[4]; |
3646 | 3706 |
memcpy(&pdu->tag, ptr + 5, 2); |
3647 |
|
|
3648 | 3707 |
submit_pdu(s, pdu); |
3649 | 3708 |
} |
3650 |
|
|
3651 | 3709 |
free_pdu(s, pdu); |
3652 | 3710 |
} |
Also available in: Unified diff