Hi, I think there is a race between truncate and do_generic_mapping_read. do_generic_mapping_read() { check i_size -> ok no_cached_page: allocate a page add_to_page_cache readpage } And what can happen is truncate gets to the file after i_size is checked and before the page is added to the page cache. I asked Hugh about this because a quick search showed he was the last one to make a noise about this kind of thing. He wasn't up to speed with the current code, but agreed it looks fishy. OK, I made a debug patch to printk and schedule_timeout in this race window so I can easily truncate the file. When this happens, it turns out that the readpage thinks it is reading a hole and fills the page with zeros -> invalid result? I have attached a patch which uses i_lock to close this race AFAIKS. Lightly tested only. I can't experimentally verify that it closes the race because I have not been able to reproduce it without changing the code. Comments? Too ugly? Have I've missed something?