Skip to content

Commit 5f81278

Browse files
Tetsuo Handavijay-suman
Tetsuo Handa
authored andcommitted
brd: remove brd_devices_mutex mutex
[ Upstream commit 0035893 ] If brd_alloc() from brd_probe() is called before brd_alloc() from brd_init() is called, module loading will fail with -EEXIST error. To close this race, call __register_blkdev() just before leaving brd_init(). Then, we can remove brd_devices_mutex mutex, for brd_device list will no longer be accessed concurrently. Signed-off-by: Tetsuo Handa <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Luis Chamberlain <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]> Stable-dep-of: 826cc42 ("brd: defer automatic disk creation until module initialization succeeds") Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 60f89db56246452443625cf36bb67f9b0acf6b94) Signed-off-by: Vijayendra Suman <[email protected]>
1 parent bbacb90 commit 5f81278

File tree

1 file changed

+30
-43
lines changed

1 file changed

+30
-43
lines changed

drivers/block/brd.c

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,6 @@ __setup("ramdisk_size=", ramdisk_size);
362362
* (should share code eventually).
363363
*/
364364
static LIST_HEAD(brd_devices);
365-
static DEFINE_MUTEX(brd_devices_mutex);
366365
static struct dentry *brd_debugfs_dir;
367366

368367
static int brd_alloc(int i)
@@ -372,21 +371,14 @@ static int brd_alloc(int i)
372371
char buf[DISK_NAME_LEN];
373372
int err = -ENOMEM;
374373

375-
mutex_lock(&brd_devices_mutex);
376-
list_for_each_entry(brd, &brd_devices, brd_list) {
377-
if (brd->brd_number == i) {
378-
mutex_unlock(&brd_devices_mutex);
374+
list_for_each_entry(brd, &brd_devices, brd_list)
375+
if (brd->brd_number == i)
379376
return -EEXIST;
380-
}
381-
}
382377
brd = kzalloc(sizeof(*brd), GFP_KERNEL);
383-
if (!brd) {
384-
mutex_unlock(&brd_devices_mutex);
378+
if (!brd)
385379
return -ENOMEM;
386-
}
387380
brd->brd_number = i;
388381
list_add_tail(&brd->brd_list, &brd_devices);
389-
mutex_unlock(&brd_devices_mutex);
390382

391383
spin_lock_init(&brd->brd_lock);
392384
INIT_RADIX_TREE(&brd->brd_pages, GFP_ATOMIC);
@@ -431,9 +423,7 @@ static int brd_alloc(int i)
431423
out_cleanup_disk:
432424
blk_cleanup_disk(disk);
433425
out_free_dev:
434-
mutex_lock(&brd_devices_mutex);
435426
list_del(&brd->brd_list);
436-
mutex_unlock(&brd_devices_mutex);
437427
kfree(brd);
438428
return err;
439429
}
@@ -443,15 +433,19 @@ static void brd_probe(dev_t dev)
443433
brd_alloc(MINOR(dev) / max_part);
444434
}
445435

446-
static void brd_del_one(struct brd_device *brd)
436+
static void brd_cleanup(void)
447437
{
448-
del_gendisk(brd->brd_disk);
449-
blk_cleanup_disk(brd->brd_disk);
450-
brd_free_pages(brd);
451-
mutex_lock(&brd_devices_mutex);
452-
list_del(&brd->brd_list);
453-
mutex_unlock(&brd_devices_mutex);
454-
kfree(brd);
438+
struct brd_device *brd, *next;
439+
440+
debugfs_remove_recursive(brd_debugfs_dir);
441+
442+
list_for_each_entry_safe(brd, next, &brd_devices, brd_list) {
443+
del_gendisk(brd->brd_disk);
444+
blk_cleanup_disk(brd->brd_disk);
445+
brd_free_pages(brd);
446+
list_del(&brd->brd_list);
447+
kfree(brd);
448+
}
455449
}
456450

457451
static inline void brd_check_and_reset_par(void)
@@ -475,9 +469,18 @@ static inline void brd_check_and_reset_par(void)
475469

476470
static int __init brd_init(void)
477471
{
478-
struct brd_device *brd, *next;
479472
int err, i;
480473

474+
brd_check_and_reset_par();
475+
476+
brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
477+
478+
for (i = 0; i < rd_nr; i++) {
479+
err = brd_alloc(i);
480+
if (err)
481+
goto out_free;
482+
}
483+
481484
/*
482485
* brd module now has a feature to instantiate underlying device
483486
* structure on-demand, provided that there is an access dev node.
@@ -493,42 +496,26 @@ static int __init brd_init(void)
493496
* dynamically.
494497
*/
495498

496-
if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe))
497-
return -EIO;
498-
499-
brd_check_and_reset_par();
500-
501-
brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
502-
503-
for (i = 0; i < rd_nr; i++) {
504-
err = brd_alloc(i);
505-
if (err)
506-
goto out_free;
499+
if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe)) {
500+
err = -EIO;
501+
goto out_free;
507502
}
508503

509504
pr_info("brd: module loaded\n");
510505
return 0;
511506

512507
out_free:
513-
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
514-
debugfs_remove_recursive(brd_debugfs_dir);
515-
516-
list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
517-
brd_del_one(brd);
508+
brd_cleanup();
518509

519510
pr_info("brd: module NOT loaded !!!\n");
520511
return err;
521512
}
522513

523514
static void __exit brd_exit(void)
524515
{
525-
struct brd_device *brd, *next;
526516

527517
unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
528-
debugfs_remove_recursive(brd_debugfs_dir);
529-
530-
list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
531-
brd_del_one(brd);
518+
brd_cleanup();
532519

533520
pr_info("brd: module unloaded\n");
534521
}

0 commit comments

Comments
 (0)