• Sergey Senozhatsky's avatar
    zram: close race by open overriding · f405c445
    Sergey Senozhatsky authored
    [ Original patch from Minchan Kim <minchan@kernel.org> ]
    
    Commit ba6b17d6 ("zram: fix umount-reset_store-mount race
    condition") introduced bdev->bd_mutex to protect a race between mount
    and reset.  At that time, we don't have dynamic zram-add/remove feature
    so it was okay.
    
    However, as we introduce dynamic device feature, bd_mutex became
    trouble.
    
    	CPU 0
    
    echo 1 > /sys/block/zram<id>/reset
      -> kernfs->s_active(A)
        -> zram:reset_store->bd_mutex(B)
    
    	CPU 1
    
    echo <id> > /sys/class/zram/zram-remove
      ->zram:zram_remove: bd_mutex(B)
      -> sysfs_remove_group
        -> kernfs->s_active(A)
    
    IOW, AB -> BA deadlock
    
    The reason we are holding bd_mutex for zram_remove is to prevent
    any incoming open /dev/zram[0-9]. Otherwise, we could remove zram
    others already have opened. But it causes above deadlock problem.
    
    To fix the problem, this patch overrides block_device.open and
    it returns -EBUSY if zram asserts he claims zram to reset so any
    incoming open will be failed so we don't need to hold bd_mutex
    for zram_remove ayn more.
    
    This patch is to prepare for zram-add/remove feature.
    
    [sergey.senozhatsky@gmail.com: simplify reset_store()]
    Signed-off-by: default avatarMinchan Kim <minchan@kernel.org>
    Acked-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    f405c445
zram_drv.c 31.8 KB