Commit b3856da7 authored by Jan Kara's avatar Jan Kara Committed by Christian Brauner

bcache: Fixup error handling in register_cache()

Coverity has noticed that the printing of error message in
register_cache() uses already freed bdev_handle to get to bdev. In fact
the problem has been there even before commit "bcache: Convert to
bdev_open_by_path()" just a bit more subtle one - cache object itself
could have been freed by the time we looked at ca->bdev and we don't
hold any reference to bdev either so even that could in principle go
away (due to device unplug or similar). Fix all these problems by
printing the error message before closing the bdev.

Fixes: dc893f51d24a ("bcache: Convert to bdev_open_by_path()")
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20231004093757.11560-1-jack@suse.czAsked-by: default avatarColy Li <colyli@suse.de>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent e340dd63
...@@ -2354,6 +2354,13 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk, ...@@ -2354,6 +2354,13 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
ret = cache_alloc(ca); ret = cache_alloc(ca);
if (ret != 0) { if (ret != 0) {
if (ret == -ENOMEM)
err = "cache_alloc(): -ENOMEM";
else if (ret == -EPERM)
err = "cache_alloc(): cache device is too small";
else
err = "cache_alloc(): unknown error";
pr_notice("error %pg: %s\n", bdev_handle->bdev, err);
/* /*
* If we failed here, it means ca->kobj is not initialized yet, * If we failed here, it means ca->kobj is not initialized yet,
* kobject_put() won't be called and there is no chance to * kobject_put() won't be called and there is no chance to
...@@ -2361,17 +2368,12 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk, ...@@ -2361,17 +2368,12 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
* we explicitly call bdev_release() here. * we explicitly call bdev_release() here.
*/ */
bdev_release(bdev_handle); bdev_release(bdev_handle);
if (ret == -ENOMEM) return ret;
err = "cache_alloc(): -ENOMEM";
else if (ret == -EPERM)
err = "cache_alloc(): cache device is too small";
else
err = "cache_alloc(): unknown error";
goto err;
} }
if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) { if (kobject_add(&ca->kobj, bdev_kobj(bdev_handle->bdev), "bcache")) {
err = "error calling kobject_add"; pr_notice("error %pg: error calling kobject_add\n",
bdev_handle->bdev);
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
...@@ -2389,11 +2391,6 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk, ...@@ -2389,11 +2391,6 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
out: out:
kobject_put(&ca->kobj); kobject_put(&ca->kobj);
err:
if (err)
pr_notice("error %pg: %s\n", ca->bdev_handle->bdev, err);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment