]> git.proxmox.com Git - mirror_qemu.git/commit - block/raw-posix.c
raw-posix: The SEEK_HOLE code is flawed, rewrite it
authorMarkus Armbruster <armbru@redhat.com>
Mon, 17 Nov 2014 10:18:34 +0000 (11:18 +0100)
committerMax Reitz <mreitz@redhat.com>
Tue, 18 Nov 2014 08:45:48 +0000 (09:45 +0100)
commitd1f06fe665acdd7aa7a46a5ef88172c3d7d3028e
treeba6a5d1efdf046406c004d13d981b446309b6af9
parentc4875e5b2216cf5427459e619b10f75083565792
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>
block/raw-posix.c