Result: Merged (2026-10-23 04:09, kubevirt/containerized-data-importer#4318). Actually, this was gathered from GitHub PRs, comments, timelines, inspection logs, the CDI source (the base commit of the PR
9cd4fbdb), drafts of the contribution ledger, and raw cluster list data. Times are in KST (Korea Standard Time).
Table of Contents
- TL;DR
- 1. What was the problem: Which side loses the 6%?
- 2. Cause: Which lines in the documentation and code?
- 3. What was changed: Diff summary
- 4. Reaction: Silent approval and one e2e override
- 5. What we learned: Tips for open-source contribution
- Links
TL;DR
| PR | kubevirt/containerized-data-importer#4318 doc: explain how filesystem overhead changes PVC and image size |
| Changes | doc/datavolumes.md two paragraphs in , and one paragraph in doc/cdi-config.md . 22 lines added, 0 deletions |
| Reaction | No review comments. A maintainer added /lgtm·/approve, and later overrode an e2e /override |
| Result | PR opened 10-17 00:50 → Approved 10-22 21:53 → Merged 10-23 04:09, approximately 6 days, 3 hours, and 18 minutes |
1. What was the problem: Which side loses the 6%?
When CDI writes a disk image to a Filesystem mode volume, it leaves extra space (filesystem overhead) for filesystem metadata. The default value is 0.06 .
The documentation had two sentences.
doc/datavolumes.md: In Filesystem mode, CDI "requests a PVC large enough to hold both the image and the filesystem metadata," and this logic applies only tospec.storage.doc/cdi-config.md:filesystemOverheadis the "amount to leave behind" on Filesystem volumes.
Neither sentence states the resulting byte sizes for the PVC and the disk image. Reading "leaves 6%" easily brings to mind a picture where the PVC is set to the requested size and the 6% is carved out from within it. As noted in the PR body, when we determined the VM root disk size based on this documentation, we guessed that requesting 10Gi would result in the guest seeing about 9.4GiB. In reality, it was the opposite: when using spec.storage , the guest disk is exactly 10GiB, and the PVC is what grows.
The actual measurements in the PR body were taken on the TT Lab cluster with CDI v1.66.0, the default overhead 0.06, and an NFS storage class (Filesystem mode).
DataVolume spec.storage request |
PVC request (bytes) | Same value |
|---|---|---|
| 10Gi | 11381663335 | ceil(10737418240 × 1.06) |
| 60Gi | 68289980007 | ceil(64424509440 × 1.06) |
| 80Gi | 91053306676 | ceil(85899345920 × 1.06) |
For the 10Gi volume, inside the virt-launcher pod, we verified qemu-img info with disk.img of virtual size: 10 GiB (10737418240 bytes) .
The raw data remains uneven. The PVC size for the 10Gi volume 11381663335 is still visible in the cluster list from the ledger saved on 2026-10-17 (measure/kv/02-workloads.txt, a 59-day-old PVC). The values for 60Gi and 80Gi and the qemu-img output exist only in the PR body and draft, with no raw output files.
2. Cause: Which lines in the documentation and code?
Line numbers are based on the PR's base commit 9cd4fbdb .
Documentation side
Calculations are done by two functions
The calculation formula has been as follows since #3779("Fix math for overhead size calculation", merged 2025-07-03).
- PVC request =
align(size, 1MiB) × (1 + overhead)rounded up.pkg/util/util.golines 234–243 ofGetRequiredSpace. The comment also notes that the extra space is calculated as the "ratio of the total new size including the aligned image." - Image size =
min(여유 공간, PVC 요청) ÷ (1 + overhead)rounded down to the nearest 1MiB.util.golines 225–232 ofGetUsableSpaceandpkg/importer/data-processor.golines 360–389 ofcalculateTargetSize. The comment explains that the reason for rounding down is to prevent qemu-img from rounding up and exceeding the available space.
Following this through directly with 10Gi looks like this: 10Gi is 10,737,418,240 bytes, which is already a multiple of 1MiB, so it remains unchanged even after alignment. Multiplying by 1.06 gives 11,381,663,334.4, and rounding up gives 11,381,663,335 (the first row of the table in Section 1). If there is enough free space in this PVC, 11,381,663,335 ÷ 1.06 slightly exceeds 10,737,418,240, and rounding down to the nearest 1MiB brings it back to 10,737,418,240, which is 10GiB. Therefore, the guest disk ends up being exactly the requested size (calculated).
Conversely, if the actual free space of the provisioned filesystem is smaller than the PVC request, the image shrinks accordingly. An issue regarding this calculation failing with smaller images #4024 is open as of 2026-10-29.
3. What was changed: Summary of the diff
Calculation formulas and examples were added to both documents. Not a single existing sentence was deleted.
# doc/datavolumes.md, spec.storage 의 여분 설명 바로 뒤
+In that case the requested size is the size of the disk image, and CDI requests a PVC of
+`size * (1 + overhead)`, where `size` is rounded up to a multiple of 1MiB ...
+For example, with the default overhead, a DataVolume that requests `storage: 10Gi`
+creates a PVC that requests `11381663335` bytes (`10Gi * 1.06`), and the resulting
+`disk.img` has a virtual size of `10Gi`. If the filesystem on the provisioned volume has
+less free space than the PVC request, the image is sized down ... (see #4024).
+
+With `DataVolume.spec.pvc` the PVC is created with the requested size as is, but the
+overhead is still reserved inside it when CDI writes the image (import, upload or blank),
+so the disk image ends up smaller than the requested size (about `size / (1 + overhead)`).
# doc/cdi-config.md, filesystemOverhead 설명 뒤
+The overhead is a fraction of the disk image size, added on top of it. ...
spec.pvc sentences were not measured. It was stated in the PR body that they were written after reading the code path where all three paths—import, upload, and blank disk—determine the image size using GetUsableSpace (unmeasured). ② in the diagram illustrates that case.
The use of AI was disclosed in the commit footers Co-Authored-By: Claude Opus 5.5 and Signed-off-by, along with a single sentence at the end of the body: "This change was drafted with the help of AI and reviewed by me." KubeVirt's AI contribution policystates that even automatically generated tool outputs like
Co-authored-by are acceptable. The commit is SSH-signed (verified on GitHub).
4. Reaction: Silent approval and one e2e override
| Time | Day |
|---|---|
| 10-17 00:50 | PR opened. prow applied the release-note-none·size/S label, a notice stating "untrusted authors cannot directly trigger tests," and assigned two reviewers. |
| 10-22 21:53 | A maintainer posted /lgtm and /approve in a single comment. |
| 10-22 22:06 | Coveralls coverage report |
| 10-23 04:07 | The same maintainer added /override pull-containerized-data-importer-e2e-ceph |
| 10-23 04:09 | tide merged |
There were not a single review comment. The original notes contained plans: "Documentation PRs also run 18 e2e tests, a collaborator needs to type /test all ," and "If it is quiet around October 20, /cc the reviewer who wrote the analysis for #4024." Looking at the timeline, that /cc was not done, and another maintainer approved it first on the sixth day.
The /override two minutes before the merge was an action where a maintainer with override privileges forced the result of a single ceph-using e2e test to pass. The reason for the override is not stated in the PR. Since it was a documentation-only PR, it appears to have been deemed that the e2e results were unrelated to the changes. After the merge, all 21 GitHub checks appear to have passed.
The same issue was also covered in "Reading KubeVirt Source Code" Part 6. At the time of writing that article, this PR was under review.
5. Lessons learned: Open-source contribution tips
- 「When a document mentions a ratio, specify what the baseline is."Leaving 6%" can be read both as "taking 6% off the PVC" and "adding 6% to the image." Showing a single number (10Gi → 11,381,663,335 bytes) immediately eliminates one of the two interpretations.
- 「Write numbers in documentation so they can be re-calculated by code.In the PR's table,
ceil(10737418240 × 1.06)was included so reviewers could verify it using just a calculator without needing a cluster. This is likely one of the reasons there were zero review comments. - 「Separate measured data from code-read data at the sentence level.」
spec.storageThe side was actual measurements, whilespec.pvcwas explicitly separated in the text as read from the code path. Avoid sweeping statements like "fully verified" so reviewers know where to look closer. - 「Preserve raw data in your personal notes, not just in the PR body.The values for 60Gi and 80Gi currently exist only in the PR body. If you use the same calculation again later and have the original output, you won't need to write "exists only in the body" like this post does.
A word from Titi. When I say, "Please pack 10 kilos into the box," they say the box value comes out 6% higher, citing the thickness of the box walls. So I thought a 10-kilo box would only hold 9.4 kilos. But when I weighed it, the contents were exactly 10 kilos, and the box itself had gotten bigger! When I added a single line to the instructions saying, "If you pack 10 kilos, we will provide a 10.6-kilo box," an "Approved" stamp was silently applied.
Links
All materials were accessed on 2026-10-29.
- PR: kubevirt/containerized-data-importer#4318 (Merge commit
0bafeaa7) - Modified documentation (base commit):
doc/datavolumes.md,doc/cdi-config.md - Calculation code (base commit):
GetUsableSpace·GetRequiredSpace,calculateTargetSize - Related: #3779 calculation fix, issue #4024
- Log fix near the same function: Part 9, containerized-data-importer#4320