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