diff options
| author | Andrew Morton <akpm@osdl.org> | 2005-01-07 22:03:18 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-01-07 22:03:18 -0800 |
| commit | 918798e7b49f275970304c17b8449de4b728ec38 (patch) | |
| tree | 511fb330b9506f37dd1e74552fc4fc9f001e05fa /include/linux | |
| parent | ba1f08f14b523e1722ee423eb729663e3fa5b192 (diff) | |
[PATCH] invalidate_inode_pages2() mmap coherency fix
- When invalidating pages, take care to shoot down any ptes which map them
as well.
This ensures that the next mmap access to the page will generate a major
fault, so NFS's server-side modifications are picked up.
This also allows us to call invalidate_complete_page() on all pages, so
filesytems such as ext3 get a chance to invalidate the buffer_heads.
- Don't mark in-pagetable pages as non-uptodate any more. That broke a
previous guarantee that mapped-into-user-process pages are always uptodate.
- Check the return value of invalidate_complete_page(). It can fail if
someone redirties a page after generic_file_direct_IO() write it back.
But we still have a problem. If invalidate_inode_pages2() calls
unmap_mapping_range(), that can cause zap_pte_range() to dirty the pagecache
pages. That will redirty the page's buffers and will cause
invalidate_complete_page() to fail.
So, in generic_file_direct_IO() we do a complete pte shootdown on the file
up-front, prior to writing back dirty pagecache. This is only done for
O_DIRECT writes. It _could_ be done for O_DIRECT reads too, providing full
mmap-vs-direct-IO coherency for both O_DIRECT reads and O_DIRECT writes, but
permitting the pte shootdown on O_DIRECT reads trivially allows people to nuke
other people's mapped pagecache.
NFS also uses invalidate_inode_pages2() for handling server-side modification
notifications. But in the NFS case the clear_page_dirty() in
invalidate_inode_pages2() is sufficient, because NFS doesn't have to worry
about the "dirty buffers against a clean page" problem. (I think)
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/fs.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h index cd0b31b4afba..31391d59ddc2 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1345,7 +1345,7 @@ static inline void invalidate_remote_inode(struct inode *inode) S_ISLNK(inode->i_mode)) invalidate_inode_pages(inode->i_mapping); } -extern void invalidate_inode_pages2(struct address_space *mapping); +extern int invalidate_inode_pages2(struct address_space *mapping); extern void write_inode_now(struct inode *, int); extern int filemap_fdatawrite(struct address_space *); extern int filemap_flush(struct address_space *); |
