On Mon 14-09-20 14:00:34, Matthew Wilcox (Oracle) wrote: > Rewrite shmem_seek_hole_data() and move it to filemap.c. > > Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> ... > +/** > + * mapping_seek_hole_data - Seek for SEEK_DATA / SEEK_HOLE in the page cache. > + * @mapping: Address space to search. > + * @start: First byte to consider. > + * @end: Limit of search (exclusive). > + * @whence: Either SEEK_HOLE or SEEK_DATA. > + * > + * If the page cache knows which blocks contain holes and which blocks > + * contain data, your filesystem can use this function to implement > + * SEEK_HOLE and SEEK_DATA. This is useful for filesystems which are > + * entirely memory-based such as tmpfs, and filesystems which support > + * unwritten extents. > + * > + * Return: The requested offset on successs, or -ENXIO if @whence specifies > + * SEEK_DATA and there is no data after @start. There is an implicit hole > + * after @end - 1, so SEEK_HOLE returns @end if all the bytes between @start > + * and @end contain data. > + */ > +loff_t mapping_seek_hole_data(struct address_space *mapping, loff_t start, > + loff_t end, int whence) > +{ > + XA_STATE(xas, &mapping->i_pages, start >> PAGE_SHIFT); > + pgoff_t max = (end - 1) / PAGE_SIZE; > + bool seek_data = (whence == SEEK_DATA); > + struct page *page; > + > + if (end <= start) > + return -ENXIO; > + > + rcu_read_lock(); > + while ((page = xas_find_get_entry(&xas, max, XA_PRESENT))) { > + loff_t pos = xas.xa_index * PAGE_SIZE; OK, but for ordinary filesystems this could be problematic because of exceptional entries? Also for shmem you've dropped the PageUptodate check which I'm not sure is safe? Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR