Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=16a100190d39592d1d56ff5a0b978b20288c3427 Commit: 16a100190d39592d1d56ff5a0b978b20288c3427 Parent: 1ae7000630e3c05b6f7e3dfc76472f1bca6c1788 Author: Hugh Dickins <[EMAIL PROTECTED]> AuthorDate: Thu Mar 29 01:20:37 2007 -0700 Committer: Linus Torvalds <[EMAIL PROTECTED]> CommitDate: Thu Mar 29 08:22:25 2007 -0700
[PATCH] holepunch: fix disconnected pages after second truncate shmem_truncate_range has its own truncate_inode_pages_range, to free any pages racily instantiated while it was in progress: a SHMEM_PAGEIN flag is set when this might have happened. But holepunching gets no chance to clear that flag at the start of vmtruncate_range, so it's always set (unless a truncate came just before), so holepunch almost always does this second truncate_inode_pages_range. shmem holepunch has unlikely swap<->file races hereabouts whatever we do (without a fuller rework than is fit for this release): I was going to skip the second truncate in the punch_hole case, but Miklos points out that would make holepunch correctness more vulnerable to swapoff. So keep the second truncate, but follow it by an unmap_mapping_range to eliminate the disconnected pages (freed from pagecache while still mapped in userspace) that it might have left behind. Signed-off-by: Hugh Dickins <[EMAIL PROTECTED]> Cc: Miklos Szeredi <[EMAIL PROTECTED]> Cc: Badari Pulavarty <[EMAIL PROTECTED]> Cc: Nick Piggin <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> --- mm/shmem.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 578ecea..b2a35eb 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -674,8 +674,16 @@ done2: * generic_delete_inode did it, before we lowered next_index. * Also, though shmem_getpage checks i_size before adding to * cache, no recheck after: so fix the narrow window there too. + * + * Recalling truncate_inode_pages_range and unmap_mapping_range + * every time for punch_hole (which never got a chance to clear + * SHMEM_PAGEIN at the start of vmtruncate_range) is expensive, + * yet hardly ever necessary: try to optimize them out later. */ truncate_inode_pages_range(inode->i_mapping, start, end); + if (punch_hole) + unmap_mapping_range(inode->i_mapping, start, + end - start, 1); } spin_lock(&info->lock); - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html