Create a redundant grain directory and table. Previously we were
cheating by assigning the same sector offset to both directories, but it seems that VirtualBox doesn't like that. Neither does qemu from the looks of it. We now actually write the directory and table twice. MFC after: 3 days
This commit is contained in:
parent
37fbf89826
commit
6219349311
@ -110,7 +110,7 @@ static int
|
||||
vmdk_write(int fd)
|
||||
{
|
||||
struct vmdk_header hdr;
|
||||
uint32_t *gt, *gd;
|
||||
uint32_t *gt, *gd, *rgd;
|
||||
char *buf, *desc;
|
||||
off_t cur, lim;
|
||||
uint64_t imagesz;
|
||||
@ -143,25 +143,37 @@ vmdk_write(int fd)
|
||||
le32enc(&hdr.ngtes, VMDK_NGTES);
|
||||
|
||||
sec = desc_len / VMDK_SECTOR_SIZE + 1;
|
||||
le64enc(&hdr.rgd_offset, sec);
|
||||
le64enc(&hdr.gd_offset, sec);
|
||||
|
||||
ngrains = imagesz / grainsz;
|
||||
ngts = (ngrains + VMDK_NGTES - 1) / VMDK_NGTES;
|
||||
gdsz = (ngts * sizeof(uint32_t) + VMDK_SECTOR_SIZE - 1) &
|
||||
~(VMDK_SECTOR_SIZE - 1);
|
||||
|
||||
gd = calloc(gdsz, 1);
|
||||
if (gd == NULL) {
|
||||
free(desc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
le64enc(&hdr.gd_offset, sec);
|
||||
sec += gdsz / VMDK_SECTOR_SIZE;
|
||||
for (n = 0; n < ngts; n++) {
|
||||
le32enc(gd + n, sec);
|
||||
sec += VMDK_NGTES * sizeof(uint32_t) / VMDK_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
rgd = calloc(gdsz, 1);
|
||||
if (rgd == NULL) {
|
||||
free(gd);
|
||||
free(desc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
le64enc(&hdr.rgd_offset, sec);
|
||||
sec += gdsz / VMDK_SECTOR_SIZE;
|
||||
for (n = 0; n < ngts; n++) {
|
||||
le32enc(rgd + n, sec);
|
||||
sec += VMDK_NGTES * sizeof(uint32_t) / VMDK_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
sec = (sec + grainsz - 1) & ~(grainsz - 1);
|
||||
|
||||
if (verbose)
|
||||
@ -174,6 +186,7 @@ vmdk_write(int fd)
|
||||
gtsz = ngts * VMDK_NGTES * sizeof(uint32_t);
|
||||
gt = calloc(gtsz, 1);
|
||||
if (gt == NULL) {
|
||||
free(rgd);
|
||||
free(gd);
|
||||
free(desc);
|
||||
return (ENOMEM);
|
||||
@ -198,13 +211,18 @@ vmdk_write(int fd)
|
||||
error = errno;
|
||||
if (!error && sparse_write(fd, gt, gtsz) < 0)
|
||||
error = errno;
|
||||
if (!error && sparse_write(fd, rgd, gdsz) < 0)
|
||||
error = errno;
|
||||
if (!error && sparse_write(fd, gt, gtsz) < 0)
|
||||
error = errno;
|
||||
free(gt);
|
||||
free(rgd);
|
||||
free(gd);
|
||||
free(desc);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
cur = VMDK_SECTOR_SIZE + desc_len + gdsz + gtsz;
|
||||
cur = VMDK_SECTOR_SIZE + desc_len + (gdsz + gtsz) * 2;
|
||||
lim = sec * VMDK_SECTOR_SIZE;
|
||||
if (cur < lim) {
|
||||
buf = calloc(VMDK_SECTOR_SIZE, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user