As of this writing, it's been more than 10 years since the original question. And, I daresay that the answer currently isn't as obvious, as it earlier may have been.
BTRFS has an interesting feature for use on the VM host: snapshots on subvolumes. Effectively, it allows you to create a snapshot of a "directory" (a subvolume, really). A subvolume can contain a number of files.
It is true that, as a COW filesystem, btrfs really suffers a spanking from a VM working with its disk image. That is, unless you disable the COW algorithm. You can disable the COW in two ways:
nodatacow mount option, on the whole volume (doesn't work selectively on subvolumes)
chattr -C . To check the result, use
lsattr. If you want this to apply on a subdirectory or a subvolume, apply the "no COW" attribute on the freshly created subdir or subvolume, so that any files newly created would inherit that attribute.
Turning off COW will have the result, that BTRFS will avoid doing the COW trick if at all possible. Only when absolutely necessary, such as when a snapshot gets created and is in use, a minimal amount of COW still happens.
In the guest, I'd use any reliable FS with a maintained codebase, that is preferably not a resource hog. Ext4 sounds like "not a bad option".
To save disk space on the host, you can tell namely QEMU to observe the "discard" or TRIM disk commands coming from the VM guest.
-drive definition, include
In the VM guest instance, you have a choice:
a) do not use the "discard" option when mounting volumes. Traditionally, with flash SSD drives, the discard/TRIM operation tends to be blocking and lengthy. It harms runtime performance. Thus, since shortly after the discard/TRIM has been implemented in Linux, the advice has been: prefer to steer clear of TRIM, and only run
fstrim -av every once in a while manually, when it suits you, i.e. at a time when the system load is low. There have also been some optimizations of the disk IO subsystem, to achieve traffic patterns that result in "TRIM-like behavior and allocation efficiency" without actually using the TRIM/discard command.
Two older articles on the topic: 1 , 2 .
b) in case you do not have an SSD underneath, i.e. you disk drives are actually spinning rust, you can still use TRIM/discard in a VM guest to signal to the VM host, that it can release some space in the underlying QCOW2 image. "Punch a hole", literally. The QCOW2 image is sparse, and by releasing unused space properly, you'll save a lot of actual disk capacity.
I don't have a longer-term experience, I have effectively just installed such a system (host + 1 guest, about 55 GB of data in two QCOW2 images) and it seems to work fairly well. While migrating the OS and data from bare metal into the VM, I kept observing the sytem with top and iostat, and the numbers rolling on the screen seemd perfectly plausible.
In the way of optimizations, I am using the
noatime mount option in both the host and the guest, and I also like to adjust the dirty_ratio, dirty_background_ratio and dirty_expire_centisecs to increase the "writeback cache". Seems to work for me.