Messages in this thread | | | Date | Fri, 3 Dec 1999 16:31:13 +0100 | From | Jan Kara <> | Subject | Race in truncate in 2.3 kernels? |
| |
Hello.
Consider following situation:
Process1: Wants to read some page in file. So block_read_full_page() is called. It gets page but founds it's not uptodate. So we go on page_not_ _uptodate and block. Process2: Calls truncate on the file. It will capture the i_sem, lower the size and do vmtruncate() which calls truncate_inode_pages(). This function will shamelessly delete the page from inode even if it has holders... Then ext2_truncate() blocks. Process1: Wakes up - it finds out that page is still not uptodate and so calls readpage() on it. Readpage() will recreate the buffers() and happily maps it.
So as the result we have page with mapped buffers going to free_page...
Similar race would be: Process1: Wants to read some page in file -> block_read_full_page(). Page not in memory -> page_cache_alloc() - blocks (I suppose it can block as otherwise we are dropping spinlocks without reason...). Process2: Truncate - lower size, vmtruncate(), blocks in ext2_truncate(). Process1: Wakes up - adds page to pagecache and to inode, calls readpage() which will create buffers and map them.
As the result we have page after i_size and with mapped buffer and freed blocks under those buffers. Funny things happen when we grow the file again...
Am I missing something?
Honza.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |