• Bradley Bolen's avatar
    ubi: block: Fix locking for idr_alloc/idr_remove · 022af489
    Bradley Bolen authored
    commit 7f29ae9f upstream.
    
    This fixes a race with idr_alloc where gd->first_minor can be set to the
    same value for two simultaneous calls to ubiblock_create.  Each instance
    calls device_add_disk with the same first_minor.  device_add_disk calls
    bdi_register_owner which generates several warnings.
    
    WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
    sysfs_warn_dup+0x68/0x88
    sysfs: cannot create duplicate filename '/devices/virtual/bdi/252:2'
    
    WARNING: CPU: 1 PID: 179 at kernel-source/lib/kobject.c:240
    kobject_add_internal+0x1ec/0x2f8
    kobject_add_internal failed for 252:2 with -EEXIST, don't try to
    register things with the same name in the same directory
    
    WARNING: CPU: 1 PID: 179 at kernel-source/fs/sysfs/dir.c:31
    sysfs_warn_dup+0x68/0x88
    sysfs: cannot create duplicate filename '/dev/block/252:2'
    
    However, device_add_disk does not error out when bdi_register_owner
    returns an error.  Control continues until reaching blk_register_queue.
    It then BUGs.
    
    kernel BUG at kernel-source/fs/sysfs/group.c:113!
    [<c01e26cc>] (internal_create_group) from [<c01e2950>]
    (sysfs_create_group+0x20/0x24)
    [<c01e2950>] (sysfs_create_group) from [<c00e3d38>]
    (blk_trace_init_sysfs+0x18/0x20)
    [<c00e3d38>] (blk_trace_init_sysfs) from [<c02bdfbc>]
    (blk_register_queue+0xd8/0x154)
    [<c02bdfbc>] (blk_register_queue) from [<c02cec84>]
    (device_add_disk+0x194/0x44c)
    [<c02cec84>] (device_add_disk) from [<c0436ec8>]
    (ubiblock_create+0x284/0x2e0)
    [<c0436ec8>] (ubiblock_create) from [<c0427bb8>]
    (vol_cdev_ioctl+0x450/0x554)
    [<c0427bb8>] (vol_cdev_ioctl) from [<c0189110>] (vfs_ioctl+0x30/0x44)
    [<c0189110>] (vfs_ioctl) from [<c01892e0>] (do_vfs_ioctl+0xa0/0x790)
    [<c01892e0>] (do_vfs_ioctl) from [<c0189a14>] (SyS_ioctl+0x44/0x68)
    [<c0189a14>] (SyS_ioctl) from [<c0010640>] (ret_fast_syscall+0x0/0x34)
    
    Locking idr_alloc/idr_remove removes the race and keeps gd->first_minor
    unique.
    
    Fixes: 2bf50d42 ("UBI: block: Dynamically allocate minor numbers")
    Signed-off-by: default avatarBradley Bolen <bradleybolen@gmail.com>
    Reviewed-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
    Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    022af489
block.c 16.8 KB