diff --git a/scripts/lib/wic/filemap.py b/scripts/lib/wic/filemap.py index 85b39d5d74..2554e8312c 100644 --- a/scripts/lib/wic/filemap.py +++ b/scripts/lib/wic/filemap.py @@ -201,6 +201,13 @@ class FilemapSeek(_FilemapBase): _FilemapBase.__init__(self, image, log) self._log.debug("FilemapSeek: initializing") + # Open a separate file handle for SEEK_DATA/SEEK_HOLE probes so + # that the lseek() calls do not disturb the BufferedReader state + # of self._f_image, which sparse_copy() uses for data reading. + # Sharing a single fd between os.lseek() and buffered read() + # has the potential to cause data corruption. + self._f_seek = open(self._image_path, 'rb') + self._probe_seek_hole() def _probe_seek_hole(self): @@ -244,7 +251,7 @@ class FilemapSeek(_FilemapBase): def block_is_mapped(self, block): """Refer the '_FilemapBase' class for the documentation.""" - offs = _lseek(self._f_image, block * self.block_size, _SEEK_DATA) + offs = _lseek(self._f_seek, block * self.block_size, _SEEK_DATA) if offs == -1: result = False else: @@ -265,11 +272,11 @@ class FilemapSeek(_FilemapBase): limit = end + count * self.block_size while True: - start = _lseek(self._f_image, end, whence1) + start = _lseek(self._f_seek, end, whence1) if start == -1 or start >= limit or start == self.image_size: break - end = _lseek(self._f_image, start, whence2) + end = _lseek(self._f_seek, start, whence2) if end == -1 or end == self.image_size: end = self.blocks_cnt * self.block_size if end > limit: