Skip to content

Commit abcc0cb

Browse files
jankaraaxboe
authored andcommitted
bcache: Alloc holder object before async registration
Allocate holder object (cache or cached_dev) before offloading the rest of the startup to async work. This will allow us to open the block block device with proper holder. Signed-off-by: Jan Kara <jack@suse.cz> Acked-by: Coly Li <colyli@suse.de> Reviewed-by: Kent Overstreet <kent.overstreet@linux.dev> Link: https://lore.kernel.org/r/20230622164658.12861-1-jack@suse.cz Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent c36591f commit abcc0cb

1 file changed

Lines changed: 25 additions & 41 deletions

File tree

drivers/md/bcache/super.c

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,29 +2448,21 @@ struct async_reg_args {
24482448
struct cache_sb *sb;
24492449
struct cache_sb_disk *sb_disk;
24502450
struct block_device *bdev;
2451+
void *holder;
24512452
};
24522453

24532454
static void register_bdev_worker(struct work_struct *work)
24542455
{
24552456
int fail = false;
24562457
struct async_reg_args *args =
24572458
container_of(work, struct async_reg_args, reg_work.work);
2458-
struct cached_dev *dc;
2459-
2460-
dc = kzalloc(sizeof(*dc), GFP_KERNEL);
2461-
if (!dc) {
2462-
fail = true;
2463-
put_page(virt_to_page(args->sb_disk));
2464-
blkdev_put(args->bdev, bcache_kobj);
2465-
goto out;
2466-
}
24672459

24682460
mutex_lock(&bch_register_lock);
2469-
if (register_bdev(args->sb, args->sb_disk, args->bdev, dc) < 0)
2461+
if (register_bdev(args->sb, args->sb_disk, args->bdev, args->holder)
2462+
< 0)
24702463
fail = true;
24712464
mutex_unlock(&bch_register_lock);
24722465

2473-
out:
24742466
if (fail)
24752467
pr_info("error %s: fail to register backing device\n",
24762468
args->path);
@@ -2485,21 +2477,11 @@ static void register_cache_worker(struct work_struct *work)
24852477
int fail = false;
24862478
struct async_reg_args *args =
24872479
container_of(work, struct async_reg_args, reg_work.work);
2488-
struct cache *ca;
2489-
2490-
ca = kzalloc(sizeof(*ca), GFP_KERNEL);
2491-
if (!ca) {
2492-
fail = true;
2493-
put_page(virt_to_page(args->sb_disk));
2494-
blkdev_put(args->bdev, bcache_kobj);
2495-
goto out;
2496-
}
24972480

24982481
/* blkdev_put() will be called in bch_cache_release() */
2499-
if (register_cache(args->sb, args->sb_disk, args->bdev, ca) != 0)
2482+
if (register_cache(args->sb, args->sb_disk, args->bdev, args->holder))
25002483
fail = true;
25012484

2502-
out:
25032485
if (fail)
25042486
pr_info("error %s: fail to register cache device\n",
25052487
args->path);
@@ -2520,6 +2502,13 @@ static void register_device_async(struct async_reg_args *args)
25202502
queue_delayed_work(system_wq, &args->reg_work, 10);
25212503
}
25222504

2505+
static void *alloc_holder_object(struct cache_sb *sb)
2506+
{
2507+
if (SB_IS_BDEV(sb))
2508+
return kzalloc(sizeof(struct cached_dev), GFP_KERNEL);
2509+
return kzalloc(sizeof(struct cache), GFP_KERNEL);
2510+
}
2511+
25232512
static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
25242513
const char *buffer, size_t size)
25252514
{
@@ -2528,6 +2517,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
25282517
struct cache_sb *sb;
25292518
struct cache_sb_disk *sb_disk;
25302519
struct block_device *bdev;
2520+
void *holder;
25312521
ssize_t ret;
25322522
bool async_registration = false;
25332523

@@ -2585,6 +2575,13 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
25852575
if (err)
25862576
goto out_blkdev_put;
25872577

2578+
holder = alloc_holder_object(sb);
2579+
if (!holder) {
2580+
ret = -ENOMEM;
2581+
err = "cannot allocate memory";
2582+
goto out_put_sb_page;
2583+
}
2584+
25882585
err = "failed to register device";
25892586

25902587
if (async_registration) {
@@ -2595,44 +2592,29 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
25952592
if (!args) {
25962593
ret = -ENOMEM;
25972594
err = "cannot allocate memory";
2598-
goto out_put_sb_page;
2595+
goto out_free_holder;
25992596
}
26002597

26012598
args->path = path;
26022599
args->sb = sb;
26032600
args->sb_disk = sb_disk;
26042601
args->bdev = bdev;
2602+
args->holder = holder;
26052603
register_device_async(args);
26062604
/* No wait and returns to user space */
26072605
goto async_done;
26082606
}
26092607

26102608
if (SB_IS_BDEV(sb)) {
2611-
struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
2612-
2613-
if (!dc) {
2614-
ret = -ENOMEM;
2615-
err = "cannot allocate memory";
2616-
goto out_put_sb_page;
2617-
}
2618-
26192609
mutex_lock(&bch_register_lock);
2620-
ret = register_bdev(sb, sb_disk, bdev, dc);
2610+
ret = register_bdev(sb, sb_disk, bdev, holder);
26212611
mutex_unlock(&bch_register_lock);
26222612
/* blkdev_put() will be called in cached_dev_free() */
26232613
if (ret < 0)
26242614
goto out_free_sb;
26252615
} else {
2626-
struct cache *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
2627-
2628-
if (!ca) {
2629-
ret = -ENOMEM;
2630-
err = "cannot allocate memory";
2631-
goto out_put_sb_page;
2632-
}
2633-
26342616
/* blkdev_put() will be called in bch_cache_release() */
2635-
ret = register_cache(sb, sb_disk, bdev, ca);
2617+
ret = register_cache(sb, sb_disk, bdev, holder);
26362618
if (ret)
26372619
goto out_free_sb;
26382620
}
@@ -2644,6 +2626,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
26442626
async_done:
26452627
return size;
26462628

2629+
out_free_holder:
2630+
kfree(holder);
26472631
out_put_sb_page:
26482632
put_page(virt_to_page(sb_disk));
26492633
out_blkdev_put:

0 commit comments

Comments
 (0)