Revision 793ed47a block.c

b/block.c
2217 2217
 */
2218 2218
static void tracked_request_begin(BdrvTrackedRequest *req,
2219 2219
                                  BlockDriverState *bs,
2220
                                  int64_t sector_num,
2221
                                  int nb_sectors, bool is_write)
2220
                                  int64_t offset,
2221
                                  unsigned int bytes, bool is_write)
2222 2222
{
2223 2223
    *req = (BdrvTrackedRequest){
2224 2224
        .bs = bs,
2225
        .sector_num = sector_num,
2226
        .nb_sectors = nb_sectors,
2225
        .offset = offset,
2226
        .bytes = bytes,
2227 2227
        .is_write = is_write,
2228 2228
        .co = qemu_coroutine_self(),
2229 2229
    };
......
2254 2254
    }
2255 2255
}
2256 2256

  
2257
static void round_bytes_to_clusters(BlockDriverState *bs,
2258
                                    int64_t offset, unsigned int bytes,
2259
                                    int64_t *cluster_offset,
2260
                                    unsigned int *cluster_bytes)
2261
{
2262
    BlockDriverInfo bdi;
2263

  
2264
    if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
2265
        *cluster_offset = offset;
2266
        *cluster_bytes = bytes;
2267
    } else {
2268
        *cluster_offset = QEMU_ALIGN_DOWN(offset, bdi.cluster_size);
2269
        *cluster_bytes = QEMU_ALIGN_UP(offset - *cluster_offset + bytes,
2270
                                       bdi.cluster_size);
2271
    }
2272
}
2273

  
2257 2274
static bool tracked_request_overlaps(BdrvTrackedRequest *req,
2258
                                     int64_t sector_num, int nb_sectors) {
2275
                                     int64_t offset, unsigned int bytes)
2276
{
2259 2277
    /*        aaaa   bbbb */
2260
    if (sector_num >= req->sector_num + req->nb_sectors) {
2278
    if (offset >= req->offset + req->bytes) {
2261 2279
        return false;
2262 2280
    }
2263 2281
    /* bbbb   aaaa        */
2264
    if (req->sector_num >= sector_num + nb_sectors) {
2282
    if (req->offset >= offset + bytes) {
2265 2283
        return false;
2266 2284
    }
2267 2285
    return true;
2268 2286
}
2269 2287

  
2270 2288
static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs,
2271
        int64_t sector_num, int nb_sectors)
2289
        int64_t offset, unsigned int bytes)
2272 2290
{
2273 2291
    BdrvTrackedRequest *req;
2274
    int64_t cluster_sector_num;
2275
    int cluster_nb_sectors;
2292
    int64_t cluster_offset;
2293
    unsigned int cluster_bytes;
2276 2294
    bool retry;
2277 2295

  
2278 2296
    /* If we touch the same cluster it counts as an overlap.  This guarantees
......
2281 2299
     * CoR read and write operations are atomic and guest writes cannot
2282 2300
     * interleave between them.
2283 2301
     */
2284
    bdrv_round_to_clusters(bs, sector_num, nb_sectors,
2285
                           &cluster_sector_num, &cluster_nb_sectors);
2302
    round_bytes_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes);
2286 2303

  
2287 2304
    do {
2288 2305
        retry = false;
2289 2306
        QLIST_FOREACH(req, &bs->tracked_requests, list) {
2290
            if (tracked_request_overlaps(req, cluster_sector_num,
2291
                                         cluster_nb_sectors)) {
2307
            if (tracked_request_overlaps(req, cluster_offset, cluster_bytes)) {
2292 2308
                /* Hitting this means there was a reentrant request, for
2293 2309
                 * example, a block driver issuing nested requests.  This must
2294 2310
                 * never happen since it means deadlock.
......
2908 2924
    }
2909 2925

  
2910 2926
    if (bs->copy_on_read_in_flight) {
2911
        wait_for_overlapping_requests(bs, sector_num, nb_sectors);
2927
        wait_for_overlapping_requests(bs, offset, bytes);
2912 2928
    }
2913 2929

  
2914
    tracked_request_begin(&req, bs, sector_num, nb_sectors, false);
2930
    tracked_request_begin(&req, bs, offset, bytes, false);
2915 2931

  
2916 2932
    if (flags & BDRV_REQ_COPY_ON_READ) {
2917 2933
        int pnum;
......
3160 3176
    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
3161 3177

  
3162 3178
    if (bs->copy_on_read_in_flight) {
3163
        wait_for_overlapping_requests(bs, sector_num, nb_sectors);
3179
        wait_for_overlapping_requests(bs, offset, bytes);
3164 3180
    }
3165 3181

  
3166
    tracked_request_begin(&req, bs, sector_num, nb_sectors, true);
3182
    tracked_request_begin(&req, bs, offset, bytes, true);
3167 3183

  
3168 3184
    ret = notifier_with_return_list_notify(&bs->before_write_notifiers, &req);
3169 3185

  

Also available in: Unified diff