I also added a generator cache to FileHandle. This way, multiple
reads to a generated file (i.e in a synthfs) can transparently
handle multiple calls to read() without the contents changing
between calls.
The cache is discarded at EOF (or when the FileHandle is destroyed.)
BlockDevice was the wrong name for this abstraction, since a block device
is a type of file in a unix system, and we should use that name for that
concept in the fs implementation.