diff options
author | Markus Armbruster <armbru@redhat.com> | 2014-11-17 11:18:34 +0100 |
---|---|---|
committer | Max Reitz <mreitz@redhat.com> | 2014-11-18 09:45:48 +0100 |
commit | d1f06fe665acdd7aa7a46a5ef88172c3d7d3028e (patch) | |
tree | ba6a5d1efdf046406c004d13d981b446309b6af9 /xen-common.c | |
parent | c4875e5b2216cf5427459e619b10f75083565792 (diff) | |
download | qemu-d1f06fe665acdd7aa7a46a5ef88172c3d7d3028e.zip qemu-d1f06fe665acdd7aa7a46a5ef88172c3d7d3028e.tar.gz qemu-d1f06fe665acdd7aa7a46a5ef88172c3d7d3028e.tar.bz2 |
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 'xen-common.c')
0 files changed, 0 insertions, 0 deletions