• Mel Gorman's avatar
    mm: swap: unlock swapfile inode mutex before closing file on bad swapfiles · 9bae11d3
    Mel Gorman authored
    commit 52c50567 upstream.
    
    If an administrator tries to swapon a file backed by NFS, the inode mutex is
    taken (as it is for any swapfile) but later identified to be a bad swapfile
    due to the lack of bmap and tries to cleanup. During cleanup, an attempt is
    made to close the file but with inode->i_mutex still held. Closing an NFS
    file syncs it which tries to acquire the inode mutex leading to deadlock. If
    lockdep is enabled the following appears on the console;
    
        =============================================
        [ INFO: possible recursive locking detected ]
        2.6.38-rc8-autobuild #1
        ---------------------------------------------
        swapon/2192 is trying to acquire lock:
         (&sb->s_type->i_mutex_key#13){+.+.+.}, at: vfs_fsync_range+0x47/0x7c
    
        but task is already holding lock:
         (&sb->s_type->i_mutex_key#13){+.+.+.}, at: sys_swapon+0x28d/0xae7
    
        other info that might help us debug this:
        1 lock held by swapon/2192:
         #0:  (&sb->s_type->i_mutex_key#13){+.+.+.}, at: sys_swapon+0x28d/0xae7
    
        stack backtrace:
        Pid: 2192, comm: swapon Not tainted 2.6.38-rc8-autobuild #1
        Call Trace:
            __lock_acquire+0x2eb/0x1623
            find_get_pages_tag+0x14a/0x174
            pagevec_lookup_tag+0x25/0x2e
            vfs_fsync_range+0x47/0x7c
            lock_acquire+0xd3/0x100
            vfs_fsync_range+0x47/0x7c
            nfs_flush_one+0x0/0xdf [nfs]
            mutex_lock_nested+0x40/0x2b1
            vfs_fsync_range+0x47/0x7c
            vfs_fsync_range+0x47/0x7c
            vfs_fsync+0x1c/0x1e
            nfs_file_flush+0x64/0x69 [nfs]
            filp_close+0x43/0x72
            sys_swapon+0xa39/0xae7
            sysret_check+0x2e/0x69
            system_call_fastpath+0x16/0x1b
    
    This patch releases the mutex if its held before calling filep_close()
    so swapon fails as expected without deadlock when the swapfile is backed
    by NFS.  If accepted for 2.6.39, it should also be considered a -stable
    candidate for 2.6.38 and 2.6.37.
    Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
    Acked-by: default avatarHugh Dickins <hughd@google.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    9bae11d3
swapfile.c 65.6 KB