Revision 8d3b1a2d

b/block.c
2131 2131
}
2132 2132

  
2133 2133
/*
2134
 * Process a synchronous request using coroutines
2134
 * Process a vectored synchronous request using coroutines
2135 2135
 */
2136
static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
2137
                      int nb_sectors, bool is_write)
2136
static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num,
2137
                       QEMUIOVector *qiov, bool is_write)
2138 2138
{
2139
    QEMUIOVector qiov;
2140
    struct iovec iov = {
2141
        .iov_base = (void *)buf,
2142
        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
2143
    };
2144 2139
    Coroutine *co;
2145 2140
    RwCo rwco = {
2146 2141
        .bs = bs,
2147 2142
        .sector_num = sector_num,
2148
        .nb_sectors = nb_sectors,
2149
        .qiov = &qiov,
2143
        .nb_sectors = qiov->size >> BDRV_SECTOR_BITS,
2144
        .qiov = qiov,
2150 2145
        .is_write = is_write,
2151 2146
        .ret = NOT_DONE,
2152 2147
    };
2153

  
2154
    qemu_iovec_init_external(&qiov, &iov, 1);
2148
    assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0);
2155 2149

  
2156 2150
    /**
2157 2151
     * In sync call context, when the vcpu is blocked, this throttling timer
......
2177 2171
    return rwco.ret;
2178 2172
}
2179 2173

  
2174
/*
2175
 * Process a synchronous request using coroutines
2176
 */
2177
static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
2178
                      int nb_sectors, bool is_write)
2179
{
2180
    QEMUIOVector qiov;
2181
    struct iovec iov = {
2182
        .iov_base = (void *)buf,
2183
        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
2184
    };
2185

  
2186
    qemu_iovec_init_external(&qiov, &iov, 1);
2187
    return bdrv_rwv_co(bs, sector_num, &qiov, is_write);
2188
}
2189

  
2180 2190
/* return < 0 if error. See bdrv_write() for the return codes */
2181 2191
int bdrv_read(BlockDriverState *bs, int64_t sector_num,
2182 2192
              uint8_t *buf, int nb_sectors)
......
2210 2220
    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
2211 2221
}
2212 2222

  
2223
int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov)
2224
{
2225
    return bdrv_rwv_co(bs, sector_num, qiov, true);
2226
}
2227

  
2213 2228
int bdrv_pread(BlockDriverState *bs, int64_t offset,
2214 2229
               void *buf, int count1)
2215 2230
{
......
2255 2270
    return count1;
2256 2271
}
2257 2272

  
2258
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
2259
                const void *buf, int count1)
2273
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
2260 2274
{
2261 2275
    uint8_t tmp_buf[BDRV_SECTOR_SIZE];
2262 2276
    int len, nb_sectors, count;
2263 2277
    int64_t sector_num;
2264 2278
    int ret;
2265 2279

  
2266
    count = count1;
2280
    count = qiov->size;
2281

  
2267 2282
    /* first write to align to sector start */
2268 2283
    len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
2269 2284
    if (len > count)
......
2272 2287
    if (len > 0) {
2273 2288
        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2274 2289
            return ret;
2275
        memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
2290
        qemu_iovec_to_buf(qiov, 0, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)),
2291
                          len);
2276 2292
        if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
2277 2293
            return ret;
2278 2294
        count -= len;
2279 2295
        if (count == 0)
2280
            return count1;
2296
            return qiov->size;
2281 2297
        sector_num++;
2282
        buf += len;
2283 2298
    }
2284 2299

  
2285 2300
    /* write the sectors "in place" */
2286 2301
    nb_sectors = count >> BDRV_SECTOR_BITS;
2287 2302
    if (nb_sectors > 0) {
2288
        if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
2303
        QEMUIOVector qiov_inplace;
2304

  
2305
        qemu_iovec_init(&qiov_inplace, qiov->niov);
2306
        qemu_iovec_concat(&qiov_inplace, qiov, len,
2307
                          nb_sectors << BDRV_SECTOR_BITS);
2308
        ret = bdrv_writev(bs, sector_num, &qiov_inplace);
2309
        qemu_iovec_destroy(&qiov_inplace);
2310
        if (ret < 0) {
2289 2311
            return ret;
2312
        }
2313

  
2290 2314
        sector_num += nb_sectors;
2291 2315
        len = nb_sectors << BDRV_SECTOR_BITS;
2292
        buf += len;
2293 2316
        count -= len;
2294 2317
    }
2295 2318

  
......
2297 2320
    if (count > 0) {
2298 2321
        if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
2299 2322
            return ret;
2300
        memcpy(tmp_buf, buf, count);
2323
        qemu_iovec_to_buf(qiov, qiov->size - count, tmp_buf, count);
2301 2324
        if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
2302 2325
            return ret;
2303 2326
    }
2304
    return count1;
2327
    return qiov->size;
2328
}
2329

  
2330
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
2331
                const void *buf, int count1)
2332
{
2333
    QEMUIOVector qiov;
2334
    struct iovec iov = {
2335
        .iov_base   = (void *) buf,
2336
        .iov_len    = count1,
2337
    };
2338

  
2339
    qemu_iovec_init_external(&qiov, &iov, 1);
2340
    return bdrv_pwritev(bs, offset, &qiov);
2305 2341
}
2306 2342

  
2307 2343
/*
b/block/qcow2.c
1658 1658
    BDRVQcowState *s = bs->opaque;
1659 1659
    int growable = bs->growable;
1660 1660
    int ret;
1661
    void *buf;
1662

  
1663
    buf = qemu_blockalign(bs, qiov->size);
1664
    qemu_iovec_to_buf(qiov, 0, buf, qiov->size);
1665 1661

  
1666 1662
    BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
1667 1663
    bs->growable = 1;
1668
    ret = bdrv_pwrite(bs, qcow2_vm_state_offset(s) + pos, buf, qiov->size);
1664
    ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
1669 1665
    bs->growable = growable;
1670 1666

  
1671
    qemu_vfree(buf);
1672

  
1673 1667
    return ret;
1674 1668
}
1675 1669

  
b/include/block/block.h
166 166
                          uint8_t *buf, int nb_sectors);
167 167
int bdrv_write(BlockDriverState *bs, int64_t sector_num,
168 168
               const uint8_t *buf, int nb_sectors);
169
int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov);
169 170
int bdrv_pread(BlockDriverState *bs, int64_t offset,
170 171
               void *buf, int count);
171 172
int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
172 173
                const void *buf, int count);
174
int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
173 175
int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
174 176
    const void *buf, int count);
175 177
int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,

Also available in: Unified diff