FVD is quite simple. It uses three on-disk metadata structures.
A bit in the bitmap tracks the state of a block. The bit is 0 if the block is in the base image, and the bit is 1 if the block is in the FVD image. The default size of a block is 64KB, same as the cluster size of QCOW2. To represent the state of a 1TB base image, FVD only needs a 2MB bitmap, which can be easily cached in memory. This bitmap also implements copy-on-read and adaptive prefetching.
One entry in the lookup table maps the virtual disk address of a chunk to an offset in the FVD image where the chunk is stored. The default size of a chunk is 1MB, as that in VirtualBox VDI (VMware VMDK and Microsoft VHD use a chunk size of 2MB). For a 1TB virtual disk, the size of the lookup table is 4MB. Because of the small size, there is no need to use a two-level lookup table as that in QCOW2.
When the bitmap and/or the lookup table need be modified, the changes are saved in the journal, as opposed to updating the bitmap and/or table directly. When the journal is full (which happens infrequently), the entire bitmap and the entire lookup table are flushed to disk, and the journal can be recycled for reuse. The flush is quick, because the bitmap and the lookup table are small.
Separating the implementations of copy-on-write and storage allocation has several advantages. First, the lookup table can be optionally disabled so that FVD gets the most efficient RAW-image-like data layout. Second, it makes the metadata smaller and easier to cache. The bitmap is small because of its efficient representation, and the lookup table is small because of the large chunk size. Third, this separation enables optimizations that reduce metadata update overhead (see the paper).
The journal provides several benefits. First, updating both the bitmap and the lookup table requires only a single write to journal. Second, K concurrent updates to any potions of the bitmap or the lookup table are converted to K sequential writes in the journal, which can be merged into a single write by the host Linux kernel. Third, it increases concurrency by avoiding locking the bitmap or the lookup table. For example, updating one bit in the bitmap requires writing a 512-byte sector to the on-disk bitmap. This bitmap sector covers a total of 512*8*64K=256MB data, and any two writes to that same bitmap sector cannot proceed concurrently. The journal solves this problem and eliminates unnecessary locking.
FVD can do storage allocation, copy-on-write, copy-on-read, and adaptive prefetching, with the following two important features.