summary refs log tree commit diff stats
path: root/qemu-file-unix.c
diff options
context:
space:
mode:
authorMarkus Armbruster <armbru@redhat.com>2014-11-17 11:18:34 +0100
committerMax Reitz <mreitz@redhat.com>2014-11-18 09:45:48 +0100
commitd1f06fe665acdd7aa7a46a5ef88172c3d7d3028e (patch)
treeba6a5d1efdf046406c004d13d981b446309b6af9 /qemu-file-unix.c
parentc4875e5b2216cf5427459e619b10f75083565792 (diff)
downloadfocaccia-qemu-d1f06fe665acdd7aa7a46a5ef88172c3d7d3028e.tar.gz
focaccia-qemu-d1f06fe665acdd7aa7a46a5ef88172c3d7d3028e.zip
raw-posix: The SEEK_HOLE code is flawed, rewrite it
On systems where SEEK_HOLE in a trailing hole seeks to EOF (Solaris,
but not Linux), try_seek_hole() reports trailing data instead.

Additionally, unlikely lseek() failures are treated badly:

* When SEEK_HOLE fails, try_seek_hole() reports trailing data.  For
  -ENXIO, there's in fact a trailing hole.  Can happen only when
  something truncated the file since we opened it.

* When SEEK_HOLE succeeds, SEEK_DATA fails, and SEEK_END succeeds,
  then try_seek_hole() reports a trailing hole.  This is okay only
  when SEEK_DATA failed with -ENXIO (which means the non-trailing hole
  found by SEEK_HOLE has since become trailing somehow).  For other
  failures (unlikely), it's wrong.

* When SEEK_HOLE succeeds, SEEK_DATA fails, SEEK_END fails (unlikely),
  then try_seek_hole() reports bogus data [-1,start), which its caller
  raw_co_get_block_status() turns into zero sectors of data.  Could
  theoretically lead to infinite loops in code that attempts to scan
  data vs. hole forward.

Rewrite from scratch, with very careful comments.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'qemu-file-unix.c')
0 files changed, 0 insertions, 0 deletions