[PATCH v2] file-posix: Fix seeking compressed files on macOS

Mohamed Akram posted 1 patch 1 month ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/6B1AA32F-A327-4F91-9560-6845D9F94120@outlook.com
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>
block/file-posix.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
[PATCH v2] file-posix: Fix seeking compressed files on macOS
Posted by Mohamed Akram 1 month ago
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