Right now, the cache and cow filters always round up requests to blksize
boundaries (blksize for cache is dynamically determined at connection
start, for cow is fixed as BLKSIZE). Which is fine for the bulk of the
underlying file, but can cause problems when reading past EOF for a
partial tail of an underlying plugin. We aren't validating that filter
calls to next_ops are within bounds; and even if the plugin tolerates
the past-EOF read, we aren't guaranteeing that the client will always
read 0 bytes in the past-EOF tail.
Several ideas of fixing it, each with some drawbacks:
+ in cache/cow_get_size(), truncate the plugin's size down to blksize
prior to calling blk_set_size() (renders the plugin's tail unusable)
+ reject serving images that aren't already aligned to blksize (avoids
missing bytes or worrying about past-EOF slop, but can be mean, unless...)
+ document that for unaligned images, you can use --filter=cache
--filter=truncate round-up=BLKSIZE, to let the truncate filter take care
of our slop (doesn't play nicely with the fact that we can only use a
filter once, if a user wants to also use --filter=truncate prior to
--filter=cache)
+ rewrite both the cache/blk.c and cow/blk.c handlers to pay more
attention to unaligned EOF (code duplication)
+ teach filters.c next_ops to auto-cap filter requests into valid ranges
prior to calling into the next layer (trickier than it looks, especially
if we later add NBD resize extension support)
+ others?
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org