diff options
author | Marcel Moolenaar <marcel@FreeBSD.org> | 2014-07-15 04:39:23 +0000 |
---|---|---|
committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2014-07-15 04:39:23 +0000 |
commit | a0f136e1c5497e52f8cb65dab8baf18b57a6d585 (patch) | |
tree | 2602f3f98edd6c6d4a9873d48cbac8b567d2f01a /usr.bin/mkimg/vmdk.c | |
parent | 8a29851f8077f7c64d0be0215bbae3f9a9b4a7c1 (diff) | |
download | src-a0f136e1c5497e52f8cb65dab8baf18b57a6d585.tar.gz src-a0f136e1c5497e52f8cb65dab8baf18b57a6d585.zip |
Add image_data() for checking whether a sequence of blocks has data.
Use this for VHD and VMDK to avoid allocating space in the image
for empty sectors.
Note that this negatively affects performance because mkimg uses a
temporary file for the intermediate storage. When mkimg has better
internal book keeping, performance can be significantly improved.
Notes
Notes:
svn path=/head/; revision=268646
Diffstat (limited to 'usr.bin/mkimg/vmdk.c')
-rw-r--r-- | usr.bin/mkimg/vmdk.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/usr.bin/mkimg/vmdk.c b/usr.bin/mkimg/vmdk.c index af5f786d9809..176b97ba7c97 100644 --- a/usr.bin/mkimg/vmdk.c +++ b/usr.bin/mkimg/vmdk.c @@ -114,8 +114,9 @@ vmdk_write(int fd) char *buf, *desc; off_t cur, lim; uint64_t imagesz; + lba_t blkofs, blkcnt; size_t gdsz, gtsz; - uint32_t sec; + uint32_t sec, cursec; int error, desc_len, n, ngrains, ngts; imagesz = (image_get_size() * secsz) / VMDK_SECTOR_SIZE; @@ -178,8 +179,15 @@ vmdk_write(int fd) return (ENOMEM); } - for (n = 0; n < ngrains; n++) - le32enc(gt + n, sec + n * grainsz); + cursec = sec; + blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; + for (n = 0; n < ngrains; n++) { + blkofs = n * blkcnt; + if (image_data(blkofs, blkcnt)) { + le32enc(gt + n, cursec); + cursec += grainsz; + } + } error = 0; if (!error && sparse_write(fd, &hdr, VMDK_SECTOR_SIZE) < 0) @@ -210,9 +218,19 @@ vmdk_write(int fd) if (buf != NULL) free(buf); } - if (!error) - error = image_copyout(fd); - return (error); + if (error) + return (error); + + blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; + for (n = 0; n < ngrains; n++) { + blkofs = n * blkcnt; + if (image_data(blkofs, blkcnt)) { + error = image_copyout_region(fd, blkofs, blkcnt); + if (error) + return (error); + } + } + return (image_copyout_done(fd)); } static struct mkimg_format vmdk_format = { |