From: Chris Webb <chris@arachsys.com>
To: Kent Overstreet <kent.overstreet@gmail.com>,
linux-bcachefs@vger.kernel.org
Subject: [PATCH] bcachefs: Return -ENOKEY/EINVAL when mount decryption fails
Date: Thu, 4 Nov 2021 21:03:16 +0000 [thread overview]
Message-ID: <20211104210316.GA22353@arachsys.com> (raw)
bch2_fs_encryption_init() correctly passes back -ENOKEY from request_key()
when no unlock key is found, or -EINVAL if superblock decryption fails
because of an invalid key. However, these get absorbed into a generic NULL
return from bch2_fs_alloc() and later returned to user space as -ENOMEM,
leading to a misleading error from mount(1):
mount(2) system call failed: Out of memory.
Return explicit error pointers out of bch2_fs_alloc() and handle them in
both callers, so the user instead sees
mount(2) system call failed: Required key not available.
when attempting to mount a filesystem which is still locked.
Signed-off-by: Chris Webb <chris@arachsys.com>
---
Notes:
v1: Generated to apply against v5.13 bcachefs kernel (2021-10-14)
v2: Updated to apply against v5.15 bcachefs kernel (2021-11-04)
fs/bcachefs/super.c | 51 ++++++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 17 deletions(-)
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index dc8f641504be..9cd296feb312 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -638,12 +638,15 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
struct bch_fs *c;
unsigned i, iter_size;
const char *err;
+ int ret = 0;
pr_verbose_init(opts, "");
c = kvpmalloc(sizeof(struct bch_fs), GFP_KERNEL|__GFP_ZERO);
- if (!c)
+ if (!c) {
+ c = ERR_PTR(-ENOMEM);
goto out;
+ }
__module_get(THIS_MODULE);
@@ -724,13 +727,16 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
mutex_init(&c->sectors_available_lock);
- if (percpu_init_rwsem(&c->mark_lock))
+ if (percpu_init_rwsem(&c->mark_lock)) {
+ ret = -ENOMEM;
goto err;
+ }
mutex_lock(&c->sb_lock);
if (bch2_sb_to_fs(c, sb)) {
mutex_unlock(&c->sb_lock);
+ ret = -ENOMEM;
goto err;
}
@@ -745,8 +751,10 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
c->block_bits = ilog2(c->opts.block_size);
c->btree_foreground_merge_threshold = BTREE_FOREGROUND_MERGE_THRESHOLD(c);
- if (bch2_fs_init_fault("fs_alloc"))
+ if (bch2_fs_init_fault("fs_alloc")) {
+ ret = -ENOMEM;
goto err;
+ }
iter_size = sizeof(struct sort_iter) +
(btree_blocks(c) + 1) * 2 *
@@ -787,10 +795,15 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
bch2_fs_btree_interior_update_init(c) ||
bch2_fs_subvolumes_init(c) ||
bch2_fs_io_init(c) ||
- bch2_fs_encryption_init(c) ||
bch2_fs_compress_init(c) ||
bch2_fs_ec_init(c) ||
- bch2_fs_fsio_init(c))
+ bch2_fs_fsio_init(c)) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = bch2_fs_encryption_init(c);
+ if (ret)
goto err;
if (c->opts.nochanges)
@@ -799,8 +812,10 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
mi = bch2_sb_get_members(c->disk_sb.sb);
for (i = 0; i < c->sb.nr_devices; i++)
if (bch2_dev_exists(c->disk_sb.sb, mi, i) &&
- bch2_dev_alloc(c, i))
+ bch2_dev_alloc(c, i)) {
+ ret = -ENOMEM;
goto err;
+ }
bch2_journal_entry_res_resize(&c->journal,
&c->btree_root_journal_res,
@@ -815,14 +830,15 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
mutex_unlock(&bch_fs_list_lock);
if (err) {
bch_err(c, "bch2_fs_online() error: %s", err);
+ ret = -ENOMEM;
goto err;
}
out:
- pr_verbose_init(opts, "ret %i", c ? 0 : -ENOMEM);
+ pr_verbose_init(opts, "ret %i", PTR_ERR_OR_ZERO(c));
return c;
err:
bch2_fs_free(c);
- c = NULL;
+ c = ERR_PTR(ret);
goto out;
}
@@ -1939,10 +1955,11 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
i++;
}
- ret = -ENOMEM;
c = bch2_fs_alloc(sb[best_sb].sb, opts);
- if (!c)
+ if (IS_ERR(c)) {
+ ret = PTR_ERR(c);
goto err;
+ }
err = "bch2_dev_online() error";
down_write(&c->state_lock);
@@ -1973,7 +1990,7 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
devices[0], err);
ret = -EINVAL;
err:
- if (c)
+ if (!IS_ERR_OR_NULL(c))
bch2_fs_stop(c);
for (i = 0; i < nr_devices; i++)
bch2_free_super(&sb[i]);
@@ -2002,12 +2019,12 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb,
if (err)
goto err;
} else {
- c = bch2_fs_alloc(sb->sb, opts);
- err = "cannot allocate memory";
- if (!c)
- goto err;
-
allocated_fs = true;
+ c = bch2_fs_alloc(sb->sb, opts);
+
+ err = "bch2_fs_alloc() error";
+ if (IS_ERR(c))
+ goto err;
}
err = "bch2_dev_online() error";
@@ -2033,7 +2050,7 @@ static const char *__bch2_fs_open_incremental(struct bch_sb_handle *sb,
err:
mutex_unlock(&bch_fs_list_lock);
- if (allocated_fs)
+ if (allocated_fs && !IS_ERR(c))
bch2_fs_stop(c);
else if (c)
closure_put(&c->cl);
next reply other threads:[~2021-11-04 21:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-04 21:03 Chris Webb [this message]
2021-11-06 16:46 ` [PATCH] bcachefs: Return -ENOKEY/EINVAL when mount decryption fails Kent Overstreet
2021-11-06 17:09 ` Chris Webb
-- strict thread matches above, loose matches on Subject: below --
2021-10-14 12:40 Chris Webb
2021-10-14 12:52 ` Chris Webb
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211104210316.GA22353@arachsys.com \
--to=chris@arachsys.com \
--cc=kent.overstreet@gmail.com \
--cc=linux-bcachefs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox