Revision 51762288 block.c

b/block.c
352 352
    return drv;
353 353
}
354 354

  
355
/**
356
 * Set the current 'total_sectors' value
357
 */
358
static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
359
{
360
    BlockDriver *drv = bs->drv;
361

  
362
    /* query actual device if possible, otherwise just trust the hint */
363
    if (drv->bdrv_getlength) {
364
        int64_t length = drv->bdrv_getlength(bs);
365
        if (length < 0) {
366
            return length;
367
        }
368
        hint = length >> BDRV_SECTOR_BITS;
369
    }
370

  
371
    bs->total_sectors = hint;
372
    return 0;
373
}
374

  
355 375
/*
356 376
 * Common part for opening disk images and files
357 377
 */
......
363 383
    assert(drv != NULL);
364 384

  
365 385
    bs->file = NULL;
386
    bs->total_sectors = 0;
366 387
    bs->is_temporary = 0;
367 388
    bs->encrypted = 0;
368 389
    bs->valid_key = 0;
......
416 437
    }
417 438

  
418 439
    bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
419
    if (drv->bdrv_getlength) {
420
        bs->total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
440

  
441
    ret = refresh_total_sectors(bs, bs->total_sectors);
442
    if (ret < 0) {
443
        goto free_and_fail;
421 444
    }
445

  
422 446
#ifndef _WIN32
423 447
    if (bs->is_temporary) {
424 448
        unlink(filename);
......
959 983
int bdrv_truncate(BlockDriverState *bs, int64_t offset)
960 984
{
961 985
    BlockDriver *drv = bs->drv;
986
    int ret;
962 987
    if (!drv)
963 988
        return -ENOMEDIUM;
964 989
    if (!drv->bdrv_truncate)
965 990
        return -ENOTSUP;
966 991
    if (bs->read_only)
967 992
        return -EACCES;
968
    return drv->bdrv_truncate(bs, offset);
993
    ret = drv->bdrv_truncate(bs, offset);
994
    if (ret == 0) {
995
        ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
996
    }
997
    return ret;
969 998
}
970 999

  
971 1000
/**
......
976 1005
    BlockDriver *drv = bs->drv;
977 1006
    if (!drv)
978 1007
        return -ENOMEDIUM;
979
    if (!drv->bdrv_getlength) {
980
        /* legacy mode */
1008

  
1009
    /* Fixed size devices use the total_sectors value for speed instead of
1010
       issuing a length query (like lseek) on each call.  Also, legacy block
1011
       drivers don't provide a bdrv_getlength function and must use
1012
       total_sectors. */
1013
    if (!bs->growable || !drv->bdrv_getlength) {
981 1014
        return bs->total_sectors * BDRV_SECTOR_SIZE;
982 1015
    }
983 1016
    return drv->bdrv_getlength(bs);

Also available in: Unified diff