• Sergey Senozhatsky's avatar
    zram: rework reset and destroy path · a096cafc
    Sergey Senozhatsky authored
    We need to return set_capacity(disk, 0) from reset_store() back to
    zram_reset_device(), a catch by Ganesh Mahendran.  Potentially, we can
    race set_capacity() calls from init and reset paths.
    
    The problem is that zram_reset_device() is also getting called from
    zram_exit(), which performs operations in misleading reversed order -- we
    first create_device() and then init it, while zram_exit() perform
    destroy_device() first and then does zram_reset_device().  This is done to
    remove sysfs group before we reset device, so we can continue with device
    reset/destruction not being raced by sysfs attr write (f.e.  disksize).
    
    Apart from that, destroy_device() releases zram->disk (but we still have
    ->disk pointer), so we cannot acces zram->disk in later
    zram_reset_device() call, which may cause additional errors in the future.
    
    So, this patch rework and cleanup destroy path.
    
    1) remove several unneeded goto labels in zram_init()
    
    2) factor out zram_init() error path and zram_exit() into
       destroy_devices() function, which takes the number of devices to
       destroy as its argument.
    
    3) remove sysfs group in destroy_devices() first, so we can reorder
       operations -- reset device (as expected) goes before disk destroy and
       queue cleanup.  So we can always access ->disk in zram_reset_device().
    
    4) and, finally, return set_capacity() back under ->init_lock.
    
    [akpm@linux-foundation.org: tweak comment]
    Signed-off-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
    Reported-by: default avatarGanesh Mahendran <opensource.ganesh@gmail.com>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Jerome Marchand <jmarchan@redhat.com>
    Cc: Nitin Gupta <ngupta@vflare.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    a096cafc
zram_drv.c 27.7 KB