Revision 8449360c hw/virtio-9p.c
b/hw/virtio-9p.c | ||
---|---|---|
97 | 97 |
return s->ops->lseek(&s->ctx, fd, offset, whence); |
98 | 98 |
} |
99 | 99 |
|
100 |
static int v9fs_do_writev(V9fsState *s, int fd, const struct iovec *iov, |
|
101 |
int iovcnt) |
|
102 |
{ |
|
103 |
return s->ops->writev(&s->ctx, fd, iov, iovcnt); |
|
104 |
} |
|
105 |
|
|
100 | 106 |
static void v9fs_string_init(V9fsString *str) |
101 | 107 |
{ |
102 | 108 |
str->data = NULL; |
... | ... | |
1534 | 1540 |
qemu_free(vs); |
1535 | 1541 |
} |
1536 | 1542 |
|
1543 |
typedef struct V9fsWriteState { |
|
1544 |
V9fsPDU *pdu; |
|
1545 |
size_t offset; |
|
1546 |
int32_t len; |
|
1547 |
int32_t count; |
|
1548 |
int32_t total; |
|
1549 |
int64_t off; |
|
1550 |
V9fsFidState *fidp; |
|
1551 |
struct iovec iov[128]; /* FIXME: bad, bad, bad */ |
|
1552 |
struct iovec *sg; |
|
1553 |
int cnt; |
|
1554 |
} V9fsWriteState; |
|
1555 |
|
|
1556 |
static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs, |
|
1557 |
ssize_t err) |
|
1558 |
{ |
|
1559 |
if (err < 0) { |
|
1560 |
/* IO error return the error */ |
|
1561 |
err = -errno; |
|
1562 |
goto out; |
|
1563 |
} |
|
1564 |
vs->total += vs->len; |
|
1565 |
vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt); |
|
1566 |
if (vs->total < vs->count && vs->len > 0) { |
|
1567 |
do { |
|
1568 |
if (0) { |
|
1569 |
print_sg(vs->sg, vs->cnt); |
|
1570 |
} |
|
1571 |
vs->len = v9fs_do_writev(s, vs->fidp->fd, vs->sg, vs->cnt); |
|
1572 |
} while (vs->len == -1 && errno == EINTR); |
|
1573 |
if (vs->len == -1) { |
|
1574 |
err = -errno; |
|
1575 |
} |
|
1576 |
v9fs_write_post_writev(s, vs, err); |
|
1577 |
return; |
|
1578 |
} |
|
1579 |
vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total); |
|
1580 |
|
|
1581 |
err = vs->offset; |
|
1582 |
out: |
|
1583 |
complete_pdu(s, vs->pdu, err); |
|
1584 |
qemu_free(vs); |
|
1585 |
} |
|
1586 |
|
|
1587 |
static void v9fs_write_post_lseek(V9fsState *s, V9fsWriteState *vs, ssize_t err) |
|
1588 |
{ |
|
1589 |
if (err == -1) { |
|
1590 |
err = -errno; |
|
1591 |
goto out; |
|
1592 |
} |
|
1593 |
vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt); |
|
1594 |
|
|
1595 |
if (vs->total < vs->count) { |
|
1596 |
do { |
|
1597 |
if (0) { |
|
1598 |
print_sg(vs->sg, vs->cnt); |
|
1599 |
} |
|
1600 |
vs->len = v9fs_do_writev(s, vs->fidp->fd, vs->sg, vs->cnt); |
|
1601 |
} while (vs->len == -1 && errno == EINTR); |
|
1602 |
if (vs->len == -1) { |
|
1603 |
err = -errno; |
|
1604 |
} |
|
1605 |
v9fs_write_post_writev(s, vs, err); |
|
1606 |
return; |
|
1607 |
} |
|
1608 |
|
|
1609 |
out: |
|
1610 |
complete_pdu(s, vs->pdu, err); |
|
1611 |
qemu_free(vs); |
|
1612 |
} |
|
1613 |
|
|
1537 | 1614 |
static void v9fs_write(V9fsState *s, V9fsPDU *pdu) |
1538 | 1615 |
{ |
1539 |
if (debug_9p_pdu) { |
|
1540 |
pprint_pdu(pdu); |
|
1616 |
int32_t fid; |
|
1617 |
V9fsWriteState *vs; |
|
1618 |
ssize_t err; |
|
1619 |
|
|
1620 |
vs = qemu_malloc(sizeof(*vs)); |
|
1621 |
|
|
1622 |
vs->pdu = pdu; |
|
1623 |
vs->offset = 7; |
|
1624 |
vs->sg = vs->iov; |
|
1625 |
vs->total = 0; |
|
1626 |
vs->len = 0; |
|
1627 |
|
|
1628 |
pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count, |
|
1629 |
vs->sg, &vs->cnt); |
|
1630 |
|
|
1631 |
vs->fidp = lookup_fid(s, fid); |
|
1632 |
if (vs->fidp == NULL) { |
|
1633 |
err = -EINVAL; |
|
1634 |
goto out; |
|
1541 | 1635 |
} |
1636 |
|
|
1637 |
if (vs->fidp->fd == -1) { |
|
1638 |
err = -EINVAL; |
|
1639 |
goto out; |
|
1640 |
} |
|
1641 |
|
|
1642 |
err = v9fs_do_lseek(s, vs->fidp->fd, vs->off, SEEK_SET); |
|
1643 |
|
|
1644 |
v9fs_write_post_lseek(s, vs, err); |
|
1645 |
return; |
|
1646 |
|
|
1647 |
out: |
|
1648 |
complete_pdu(s, vs->pdu, err); |
|
1649 |
qemu_free(vs); |
|
1542 | 1650 |
} |
1543 | 1651 |
|
1544 | 1652 |
static void v9fs_create(V9fsState *s, V9fsPDU *pdu) |
Also available in: Unified diff