On Fri, Apr 23, 2021 at 07:29:31PM +0200, Jan Kara wrote: > Currently, serializing operations such as page fault, read, or readahead > against hole punching is rather difficult. The basic race scheme is > like: > > fallocate(FALLOC_FL_PUNCH_HOLE) read / fault / .. > truncate_inode_pages_range() > <create pages in page > cache here> > <update fs block mapping and free blocks> > > Now the problem is in this way read / page fault / readahead can > instantiate pages in page cache with potentially stale data (if blocks > get quickly reused). Avoiding this race is not simple - page locks do > not work because we want to make sure there are *no* pages in given > range. One of the things I've had in mind for a while is moving the DAX locked entry concept into the page cache proper. It would avoid creating the new semaphore, at the cost of taking the i_pages lock twice (once to insert the entries that cover the range, and once to delete the entries). It'd have pretty much the same effect, though -- read/fault/... would block until the entry was deleted from the page cache.