• Miklos Szeredi's avatar
    mm: prevent concurrent unmap_mapping_range() on the same inode · 2aa15890
    Miklos Szeredi authored
    Michael Leun reported that running parallel opens on a fuse filesystem
    can trigger a "kernel BUG at mm/truncate.c:475"
    
    Gurudas Pai reported the same bug on NFS.
    
    The reason is, unmap_mapping_range() is not prepared for more than
    one concurrent invocation per inode.  For example:
    
      thread1: going through a big range, stops in the middle of a vma and
         stores the restart address in vm_truncate_count.
    
      thread2: comes in with a small (e.g. single page) unmap request on
         the same vma, somewhere before restart_address, finds that the
         vma was already unmapped up to the restart address and happily
         returns without doing anything.
    
    Another scenario would be two big unmap requests, both having to
    restart the unmapping and each one setting vm_truncate_count to its
    own value.  This could go on forever without any of them being able to
    finish.
    
    Truncate and hole punching already serialize with i_mutex.  Other
    callers of unmap_mapping_range() do not, and it's difficult to get
    i_mutex protection for all callers.  In particular ->d_revalidate(),
    which calls invalidate_inode_pages2_range() in fuse, may be called
    with or without i_mutex.
    
    This patch adds a new mutex to 'struct address_space' to prevent
    running multiple concurrent unmap_mapping_range() on the same mapping.
    
    [ We'll hopefully get rid of all this with the upcoming mm
      preemptibility series by Peter Zijlstra, the "mm: Remove i_mmap_mutex
      lockbreak" patch in particular.  But that is for 2.6.39 ]
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
    Reported-by: default avatarMichael Leun <lkml20101129@newton.leun.net>
    Reported-by: default avatarGurudas Pai <gurudas.pai@oracle.com>
    Tested-by: default avatarGurudas Pai <gurudas.pai@oracle.com>
    Acked-by: default avatarHugh Dickins <hughd@google.com>
    Cc: stable@kernel.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    2aa15890
main.c 4.68 KB