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