An lseek with SEEK_DATA or SEEK_HOLE on a compressed file can fail with
ENXIO, which resulted in data not being read.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3124
Signed-off-by: Mohamed Akram <mohd.akram@outlook.com>
---
block/file-posix.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/block/file-posix.c b/block/file-posix.c
index 8c738674c..7a3f66e59 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -3203,6 +3203,19 @@ static int find_allocation(BlockDriverState *bs, off_t start,
*/
offs = lseek(s->fd, start, SEEK_DATA);
if (offs < 0) {
+#ifdef __APPLE__
+ /* On macOS, this error does not always mean that there is no data.
+ * Check if we can get the trailing hole, which should be guaranteed.
+ * If that fails, then SEEK_DATA/SEEK_HOLE won't work for this file. */
+ if (errno == ENXIO) {
+ if (start < raw_getlength(bs) &&
+ lseek(s->fd, start, SEEK_HOLE) < 0 &&
+ errno == ENXIO) {
+ return -ENOTSUP;
+ }
+ return -ENXIO;
+ }
+#endif
return -errno; /* D3 or D4 */
}
--
2.51.0