Revision 93c65b47
b/block-raw-posix.c | ||
---|---|---|
1378 | 1378 |
} |
1379 | 1379 |
#endif /* !linux && !FreeBSD */ |
1380 | 1380 |
|
1381 |
#if defined(__linux__) || defined(__FreeBSD__) |
|
1382 |
static int hdev_create(const char *filename, int64_t total_size, |
|
1383 |
const char *backing_file, int flags) |
|
1384 |
{ |
|
1385 |
int fd; |
|
1386 |
int ret = 0; |
|
1387 |
struct stat stat_buf; |
|
1388 |
|
|
1389 |
if (flags || backing_file) |
|
1390 |
return -ENOTSUP; |
|
1391 |
|
|
1392 |
fd = open(filename, O_WRONLY | O_BINARY); |
|
1393 |
if (fd < 0) |
|
1394 |
return -EIO; |
|
1395 |
|
|
1396 |
if (fstat(fd, &stat_buf) < 0) |
|
1397 |
ret = -EIO; |
|
1398 |
else if (!S_ISBLK(stat_buf.st_mode)) |
|
1399 |
ret = -EIO; |
|
1400 |
else if (lseek(fd, 0, SEEK_END) < total_size * 512) |
|
1401 |
ret = -ENOSPC; |
|
1402 |
|
|
1403 |
close(fd); |
|
1404 |
return ret; |
|
1405 |
} |
|
1406 |
|
|
1407 |
#else /* !(linux || freebsd) */ |
|
1408 |
|
|
1409 |
static int hdev_create(const char *filename, int64_t total_size, |
|
1410 |
const char *backing_file, int flags) |
|
1411 |
{ |
|
1412 |
return -ENOTSUP; |
|
1413 |
} |
|
1414 |
#endif |
|
1415 |
|
|
1381 | 1416 |
BlockDriver bdrv_host_device = { |
1382 | 1417 |
.format_name = "host_device", |
1383 | 1418 |
.instance_size = sizeof(BDRVRawState), |
1384 | 1419 |
.bdrv_open = hdev_open, |
1385 | 1420 |
.bdrv_close = raw_close, |
1421 |
.bdrv_create = hdev_create, |
|
1386 | 1422 |
.bdrv_flush = raw_flush, |
1387 | 1423 |
|
1388 | 1424 |
#ifdef CONFIG_AIO |
b/qemu-img.c | ||
---|---|---|
493 | 493 |
ret = bdrv_create(drv, out_filename, total_sectors, out_baseimg, flags); |
494 | 494 |
if (ret < 0) { |
495 | 495 |
if (ret == -ENOTSUP) { |
496 |
error("Formatting not supported for file format '%s'", fmt); |
|
496 |
error("Formatting not supported for file format '%s'", out_fmt);
|
|
497 | 497 |
} else { |
498 | 498 |
error("Error while formatting '%s'", out_filename); |
499 | 499 |
} |
... | ... | |
592 | 592 |
if (n > bs_offset + bs_sectors - sector_num) |
593 | 593 |
n = bs_offset + bs_sectors - sector_num; |
594 | 594 |
|
595 |
/* If the output image is being created as a copy on write image, |
|
596 |
assume that sectors which are unallocated in the input image |
|
597 |
are present in both the output's and input's base images (no |
|
598 |
need to copy them). */ |
|
599 |
if (out_baseimg) { |
|
600 |
if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, n, &n1)) { |
|
601 |
sector_num += n1; |
|
602 |
continue; |
|
603 |
} |
|
604 |
/* The next 'n1' sectors are allocated in the input image. Copy |
|
605 |
only those as they may be followed by unallocated sectors. */ |
|
606 |
n = n1; |
|
595 |
if (drv != &bdrv_host_device) { |
|
596 |
if (!bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, |
|
597 |
n, &n1)) { |
|
598 |
sector_num += n1; |
|
599 |
continue; |
|
600 |
} |
|
601 |
/* The next 'n1' sectors are allocated in the input image. Copy |
|
602 |
only those as they may be followed by unallocated sectors. */ |
|
603 |
n = n1; |
|
604 |
} else { |
|
605 |
n1 = n; |
|
607 | 606 |
} |
608 | 607 |
|
609 | 608 |
if (bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n) < 0) |
... | ... | |
615 | 614 |
while (n > 0) { |
616 | 615 |
/* If the output image is being created as a copy on write image, |
617 | 616 |
copy all sectors even the ones containing only NUL bytes, |
618 |
because they may differ from the sectors in the base image. */ |
|
619 |
if (out_baseimg || is_allocated_sectors(buf1, n, &n1)) { |
|
617 |
because they may differ from the sectors in the base image. |
|
618 |
|
|
619 |
If the output is to a host device, we also write out |
|
620 |
sectors that are entirely 0, since whatever data was |
|
621 |
already there is garbage, not 0s. */ |
|
622 |
if (drv == &bdrv_host_device || out_baseimg || |
|
623 |
is_allocated_sectors(buf1, n, &n1)) { |
|
620 | 624 |
if (bdrv_write(out_bs, sector_num, buf1, n1) < 0) |
621 | 625 |
error("error while writing"); |
622 | 626 |
} |
Also available in: Unified diff