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 
    racily instantiated while it was in progress: a SHMEM_PAGEIN flag is set 
    this might have happened.  But holepunching gets no chance to clear that 
    at the start of vmtruncate_range, so it's always set (unless a truncate came
    just before), so holepunch almost always does this second
    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) 
    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);
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

Reply via email to