aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/mkimg/vmdk.c
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2014-07-15 04:39:23 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2014-07-15 04:39:23 +0000
commita0f136e1c5497e52f8cb65dab8baf18b57a6d585 (patch)
tree2602f3f98edd6c6d4a9873d48cbac8b567d2f01a /usr.bin/mkimg/vmdk.c
parent8a29851f8077f7c64d0be0215bbae3f9a9b4a7c1 (diff)
downloadsrc-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.c30
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 = {