Revision 453f9a16

b/block.c
2183 2183
    // Check for mergable requests
2184 2184
    num_reqs = multiwrite_merge(bs, reqs, num_reqs, mcb);
2185 2185

  
2186
    // Run the aio requests
2186
    /*
2187
     * Run the aio requests. As soon as one request can't be submitted
2188
     * successfully, fail all requests that are not yet submitted (we must
2189
     * return failure for all requests anyway)
2190
     *
2191
     * num_requests cannot be set to the right value immediately: If
2192
     * bdrv_aio_writev fails for some request, num_requests would be too high
2193
     * and therefore multiwrite_cb() would never recognize the multiwrite
2194
     * request as completed. We also cannot use the loop variable i to set it
2195
     * when the first request fails because the callback may already have been
2196
     * called for previously submitted requests. Thus, num_requests must be
2197
     * incremented for each request that is submitted.
2198
     *
2199
     * The problem that callbacks may be called early also means that we need
2200
     * to take care that num_requests doesn't become 0 before all requests are
2201
     * submitted - multiwrite_cb() would consider the multiwrite request
2202
     * completed. A dummy request that is "completed" by a manual call to
2203
     * multiwrite_cb() takes care of this.
2204
     */
2205
    mcb->num_requests = 1;
2206

  
2187 2207
    for (i = 0; i < num_reqs; i++) {
2208
        mcb->num_requests++;
2188 2209
        acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov,
2189 2210
            reqs[i].nb_sectors, multiwrite_cb, mcb);
2190 2211

  
......
2192 2213
            // We can only fail the whole thing if no request has been
2193 2214
            // submitted yet. Otherwise we'll wait for the submitted AIOs to
2194 2215
            // complete and report the error in the callback.
2195
            if (mcb->num_requests == 0) {
2196
                reqs[i].error = -EIO;
2216
            if (i == 0) {
2197 2217
                goto fail;
2198 2218
            } else {
2199
                mcb->num_requests++;
2200 2219
                multiwrite_cb(mcb, -EIO);
2201 2220
                break;
2202 2221
            }
2203
        } else {
2204
            mcb->num_requests++;
2205 2222
        }
2206 2223
    }
2207 2224

  
2225
    /* Complete the dummy request */
2226
    multiwrite_cb(mcb, 0);
2227

  
2208 2228
    return 0;
2209 2229

  
2210 2230
fail:
2231
    for (i = 0; i < mcb->num_callbacks; i++) {
2232
        reqs[i].error = -EIO;
2233
    }
2211 2234
    qemu_free(mcb);
2212 2235
    return -1;
2213 2236
}

Also available in: Unified diff