• Ryusuke Konishi's avatar
    nilfs2: fix lock order reversal in nilfs_clean_segments ioctl · 4f6b8288
    Ryusuke Konishi authored
    This is a companion patch to ("nilfs2: fix possible circular locking
    for get information ioctls").
    
    This corrects lock order reversal between mm->mmap_sem and
    nilfs->ns_segctor_sem in nilfs_clean_segments() which was detected by
    lockdep check:
    
     =======================================================
     [ INFO: possible circular locking dependency detected ]
     2.6.30-rc3-nilfs-00003-g360bdc1 #7
     -------------------------------------------------------
     mmap/5294 is trying to acquire lock:
      (&nilfs->ns_segctor_sem){++++.+}, at: [<d0d0e846>] nilfs_transaction_begin+0xb6/0x10c [nilfs2]
    
     but task is already holding lock:
      (&mm->mmap_sem){++++++}, at: [<c043700a>] do_page_fault+0x1d8/0x30a
    
     which lock already depends on the new lock.
    
     the existing dependency chain (in reverse order) is:
    
     -> #1 (&mm->mmap_sem){++++++}:
            [<c01470a5>] __lock_acquire+0x1066/0x13b0
            [<c01474a9>] lock_acquire+0xba/0xdd
            [<c01836bc>] might_fault+0x68/0x88
            [<c023c61d>] copy_from_user+0x2a/0x111
            [<d0d120d0>] nilfs_ioctl_prepare_clean_segments+0x1d/0xf1 [nilfs2]
            [<d0d0e2aa>] nilfs_clean_segments+0x6d/0x1b9 [nilfs2]
            [<d0d11f68>] nilfs_ioctl+0x2ad/0x318 [nilfs2]
            [<c01a3be7>] vfs_ioctl+0x22/0x69
            [<c01a408e>] do_vfs_ioctl+0x460/0x499
            [<c01a4107>] sys_ioctl+0x40/0x5a
            [<c01031a4>] sysenter_do_call+0x12/0x38
            [<ffffffff>] 0xffffffff
    
     -> #0 (&nilfs->ns_segctor_sem){++++.+}:
            [<c0146e0b>] __lock_acquire+0xdcc/0x13b0
            [<c01474a9>] lock_acquire+0xba/0xdd
            [<c0433f1d>] down_read+0x2a/0x3e
            [<d0d0e846>] nilfs_transaction_begin+0xb6/0x10c [nilfs2]
            [<d0cfe0e5>] nilfs_page_mkwrite+0xe7/0x154 [nilfs2]
            [<c0183b0b>] __do_fault+0x165/0x376
            [<c01855cd>] handle_mm_fault+0x287/0x5d1
            [<c043712d>] do_page_fault+0x2fb/0x30a
            [<c0435462>] error_code+0x72/0x78
            [<ffffffff>] 0xffffffff
    
    where nilfs_clean_segments() holds:
    
      nilfs->ns_segctor_sem -> copy_from_user()
                                 --> page fault -> mm->mmap_sem
    
    And, page fault path may hold:
    
      page fault -> mm->mmap_sem
             --> nilfs_page_mkwrite() -> nilfs->ns_segctor_sem
    
    Even though nilfs_clean_segments() does not perform write access on
    given user pages, it may cause deadlock because nilfs->ns_segctor_sem
    is shared per device and mm->mmap_sem can be shared with other tasks.
    
    To avoid this problem, this patch moves all calls of copy_from_user()
    outside the nilfs->ns_segctor_sem lock in the ioctl.
    Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
    4f6b8288
segment.c 78.2 KB