On Fri, Mar 29, 2024 at 07:38:17AM -0500, Eric Blake wrote: > On Thu, Mar 28, 2024 at 04:39:04PM -0400, Stefan Hajnoczi wrote: > > Run the tests with: > > > > $ make TARGETS=block_seek_hole -C tools/selftests run_tests > > > > Signed-off-by: Stefan Hajnoczi <stefanha@xxxxxxxxxx> > > --- > > tools/testing/selftests/Makefile | 1 + > > .../selftests/block_seek_hole/Makefile | 17 +++ > > .../testing/selftests/block_seek_hole/config | 1 + > > .../selftests/block_seek_hole/map_holes.py | 37 +++++++ > > .../testing/selftests/block_seek_hole/test.py | 103 ++++++++++++++++++ > > 5 files changed, 159 insertions(+) > > create mode 100644 tools/testing/selftests/block_seek_hole/Makefile > > create mode 100644 tools/testing/selftests/block_seek_hole/config > > create mode 100755 tools/testing/selftests/block_seek_hole/map_holes.py > > create mode 100755 tools/testing/selftests/block_seek_hole/test.py > > > > > + > > +def map_holes(fd): > > + end = os.lseek(fd, 0, os.SEEK_END) > > + offset = 0 > > + > > + print('TYPE START END SIZE') > > + > > + while offset < end: > > + contents = 'DATA' > > + new_offset = os.lseek(fd, offset, os.SEEK_HOLE) > > + if new_offset == offset: > > + contents = 'HOLE' > > + try: > > + new_offset = os.lseek(fd, offset, os.SEEK_DATA) > > + except OSError as err: > > + if err.errno == errno.ENXIO: > > + new_offset = end > > + else: > > + raise err > > + assert new_offset != offset > > + print(f'{contents} {offset} {new_offset} {new_offset - offset}') > > + offset = new_offset > > Over the years, I've seen various SEEK_HOLE implementation bugs where > things work great on the initial boundary, but fail when requested on > an offset not aligned to the start of the extent boundary. It would > probably be worth enhancing the test to prove that: > > if lseek(fd, offset, SEEK_HOLE) == offset: > new_offset = lseek(fd, offset, SEEK_DATA) > assert new_offset > offset > assert lseek(fd, new_offset - 1, SEEK_HOLE) == new_offset - 1 > else: > assert lseek(fd, offset, SEEK_DATA) == offset > new_offset = lseek(fd, offset, SEEK_HOLE) > assert new_offset > offset > assert lseek(fd, new_offset - 1, SEEK_DATA) == new_offset - 1 > > Among other things, this would prove that even though block devices > generally operate on a minimum granularity of a sector, lseek() still > gives byte-accurate results for a random offset that falls in the > middle of a sector, and doesn't accidentally round down reporting an > offset less than the value passed in to the request. Sure. I'll add a test for that. Stefan
Attachment:
signature.asc
Description: PGP signature