Revision 09508d13

b/block/qcow2-refcount.c
278 278
    int64_t refcount_block_offset = 0;
279 279
    int64_t table_index = -1, old_table_index;
280 280
    int first_index = -1, last_index = -1;
281
    int ret;
281 282

  
282 283
#ifdef DEBUG_ALLOC2
283 284
    printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
......
292 293
    {
293 294
        int block_index, refcount;
294 295
        int64_t cluster_index = cluster_offset >> s->cluster_bits;
296
        int64_t new_block;
295 297

  
296 298
        /* Only write refcount block to disk when we are done with it */
297 299
        old_table_index = table_index;
......
309 311
        }
310 312

  
311 313
        /* Load the refcount block and allocate it if needed */
312
        refcount_block_offset = alloc_refcount_block(bs, cluster_index);
313
        if (refcount_block_offset < 0) {
314
            return refcount_block_offset;
314
        new_block = alloc_refcount_block(bs, cluster_index);
315
        if (new_block < 0) {
316
            ret = new_block;
317
            goto fail;
315 318
        }
319
        refcount_block_offset = new_block;
316 320

  
317 321
        /* we can update the count and save it */
318 322
        block_index = cluster_index &
......
326 330

  
327 331
        refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
328 332
        refcount += addend;
329
        if (refcount < 0 || refcount > 0xffff)
330
            return -EINVAL;
333
        if (refcount < 0 || refcount > 0xffff) {
334
            ret = -EINVAL;
335
            goto fail;
336
        }
331 337
        if (refcount == 0 && cluster_index < s->free_cluster_index) {
332 338
            s->free_cluster_index = cluster_index;
333 339
        }
334 340
        s->refcount_block_cache[block_index] = cpu_to_be16(refcount);
335 341
    }
336 342

  
343
    ret = 0;
344
fail:
345

  
337 346
    /* Write last changed block to disk */
338 347
    if (refcount_block_offset != 0) {
339 348
        if (write_refcount_block_entries(s, refcount_block_offset,
340 349
            first_index, last_index) < 0)
341 350
        {
342
            return -EIO;
351
            return ret < 0 ? ret : -EIO;
343 352
        }
344 353
    }
345 354

  
346
    return 0;
355
    /*
356
     * Try do undo any updates if an error is returned (This may succeed in
357
     * some cases like ENOSPC for allocating a new refcount block)
358
     */
359
    if (ret < 0) {
360
        int dummy;
361
        dummy = update_refcount(bs, offset, cluster_offset - offset, -addend);
362
    }
363

  
364
    return ret;
347 365
}
348 366

  
349 367
/* addend must be 1 or -1 */

Also available in: Unified diff