Messages in this thread |  | | Date | Mon, 23 Oct 2000 12:57:57 -0700 (PDT) | From | Linus Torvalds <> | Subject | Re: 2.4.0-test10-pre3:Oops in mm/filemap.c:filemap_write_pa |
| |
On Mon, 23 Oct 2000, Petr Vandrovec wrote: > > I'll take a better look at the truncate case (I consider the invalidate > > case closed). Do you have a simple test-program around? > > Well, I cannot say simple. As I was not able to reproduce it with only > one task, code below:
Ok, without running this I can already guess at what's up.
One process does the "truncate()", and races with another process that does a page-in.
The truncate code does
notify_change(ATTR_SIZE);
which will basically cause a "vmtruncate(inode, newsize)".
Just before this happened, the other process gets a page fault, and does a page_cache_read(). Now, because we are low on memory (this is why it only shows up when you're swapping), that read will take a while. During that time, the vmtruncate() starts to execute, and sets inode->i_size to the new value (that would cause us to no longer accept a page fault - but we already got past that check in the faulting process). It will then invalidate all the inode pages > i_size.
Now, the page faulting process comes back, and puts the page into the VM space. Never mind that it has in the meantime gotten i_mapping = NULL due to the other process doing the truncate.
Now, if I'm right, you should be able to add something like
if (!old_page->mapping) printk("mapping went away from under us\n");
to just before the "return old_page()" case in the success path of filemap_nopage() (mm/filemap.c), and you should see that printk() trigger when the bug happens.
(There are other users too that are not synchronized wrt inode size changes and could get an access to a page past the end of the file this way - I just think that filemap_nopage is probably the one where this is most easily seen).
The above is obviously not a bug-fix, it's just a validation of the theory.
Al, any ideas? I have this feeling that the simplest fix is just to leave the race open, and make truncate_complete_page() just leave such a "racy" page in the page cache. It will still race, and the invalid page will still exist, but the end result should be harmless.
Linus
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |