Revision 6e9ea0c0 block-vpc.c
b/block-vpc.c | ||
---|---|---|
433 | 433 |
* |
434 | 434 |
* Note that the geometry doesn't always exactly match total_sectors but |
435 | 435 |
* may round it down. |
436 |
* |
|
437 |
* Returns 0 on success, -EFBIG if the size is larger than 127 GB |
|
436 | 438 |
*/ |
437 |
static void calculate_geometry(int64_t total_sectors, uint16_t* cyls,
|
|
439 |
static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
|
|
438 | 440 |
uint8_t* heads, uint8_t* secs_per_cyl) |
439 | 441 |
{ |
440 | 442 |
uint32_t cyls_times_heads; |
441 | 443 |
|
442 | 444 |
if (total_sectors > 65535 * 16 * 255) |
443 |
total_sectors = 65535 * 16 * 255;
|
|
445 |
return -EFBIG;
|
|
444 | 446 |
|
445 | 447 |
if (total_sectors > 65535 * 16 * 63) { |
446 | 448 |
*secs_per_cyl = 255; |
... | ... | |
470 | 472 |
// Note: Rounding up deviates from the Virtual PC behaviour |
471 | 473 |
// However, we need this to avoid truncating images in qemu-img convert |
472 | 474 |
*cyls = (cyls_times_heads + *heads - 1) / *heads; |
475 |
|
|
476 |
return 0; |
|
473 | 477 |
} |
474 | 478 |
|
475 | 479 |
static int vpc_create(const char *filename, int64_t total_sectors, |
... | ... | |
493 | 497 |
return -EIO; |
494 | 498 |
|
495 | 499 |
// Calculate matching total_size and geometry |
496 |
calculate_geometry(total_sectors, &cyls, &heads, &secs_per_cyl); |
|
500 |
if (calculate_geometry(total_sectors, &cyls, &heads, &secs_per_cyl)) |
|
501 |
return -EFBIG; |
|
497 | 502 |
total_sectors = (int64_t) cyls * heads * secs_per_cyl; |
498 | 503 |
|
499 | 504 |
// Prepare the Hard Disk Footer |
Also available in: Unified diff