From: Al Viro <viro@zeniv.linux.org.uk>
To: James Bottomley <James.Bottomley@hansenpartnership.com>
Cc: linux-fsdevel@vger.kernel.org, torvalds@linux-foundation.org,
brauner@kernel.org, jack@suse.cz, raven@themaw.net,
miklos@szeredi.hu, neil@brown.name, a.hindborg@kernel.org,
linux-mm@kvack.org, linux-efi@vger.kernel.org,
ocfs2-devel@lists.linux.dev, kees@kernel.org,
rostedt@goodmis.org, gregkh@linuxfoundation.org,
linux-usb@vger.kernel.org, paul@paul-moore.com,
casey@schaufler-ca.com, linuxppc-dev@lists.ozlabs.org,
john.johansen@canonical.com, selinux@vger.kernel.org,
borntraeger@linux.ibm.com, bpf@vger.kernel.org
Subject: Re: [PATCH v2 22/50] convert efivarfs
Date: Tue, 28 Oct 2025 21:08:05 +0000 [thread overview]
Message-ID: <20251028210805.GP2441659@ZenIV> (raw)
In-Reply-To: <20251028174540.GN2441659@ZenIV>
On Tue, Oct 28, 2025 at 05:45:40PM +0000, Al Viro wrote:
> FWIW, having a special path for "we are in foofs_fill_super(), fuck
> the locking - nobody's going to access it anyway" is not a great
> idea, simply because the helpers tend to get reused on codepaths
> where we can't cut corners that way.
BTW, looking through efivarfs codebase now... *both* callers
of efivarfs_create_dentry() end up doing dcache lookups, with variously
convoluted call chains. Look: efivarfs_check_missing() has an explicit
try_lookup_noperm() before the call of efivarfs_create_dentry().
efivarfs_callback() doesn't, but it's called via
efivar_init(efivarfs_callback, sb, true)
and with the last argument being true efivar_init() will precede the call
of the callback with efivarfs_variable_is_present(). Guess what does that
thing (never used anywhere else) do? Right, the call of try_lookup_noperm().
Why do we bother with that? What's wrong with having efivarfs_create_dentry()
returning -EEXIST in case of dentry already being there and turning the
chunk in efivar_init() into
err = func(variable_name, vendor_guid,
variable_name_size, data);
if (err == -EEXIST) {
if (duplicate_check)
dup_variable_bug(variable_name,
&vendor_guid,
variable_name_size);
else
err = 0;
}
if (err)
status = EFI_NOT_FOUND;
Note that both possible callbacks become almost identical and I wouldn't
be surprised if that "almost" is actually "completely"... <checks> yep.
So I'm not sure we want that callback to be an argument, but that's
a separate followup. For now, do you see any problems with the following
patch? [Completely untested, on top of the posted series]
diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h
index f913b6824289..045d53fd0f3c 100644
--- a/fs/efivarfs/internal.h
+++ b/fs/efivarfs/internal.h
@@ -55,8 +55,6 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
size_t len);
char *efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor);
-bool efivarfs_variable_is_present(efi_char16_t *variable_name,
- efi_guid_t *vendor, void *data);
extern const struct file_operations efivarfs_file_operations;
extern const struct inode_operations efivarfs_dir_inode_operations;
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 298ab3c929eb..80ed81bbd4a5 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -189,52 +189,6 @@ static const struct dentry_operations efivarfs_d_ops = {
.d_hash = efivarfs_d_hash,
};
-static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
-{
- struct dentry *d;
- struct qstr q;
- int err;
-
- q.name = name;
- q.len = strlen(name);
-
- err = efivarfs_d_hash(parent, &q);
- if (err)
- return ERR_PTR(err);
-
- d = d_alloc(parent, &q);
- if (d)
- return d;
-
- return ERR_PTR(-ENOMEM);
-}
-
-bool efivarfs_variable_is_present(efi_char16_t *variable_name,
- efi_guid_t *vendor, void *data)
-{
- char *name = efivar_get_utf8name(variable_name, vendor);
- struct super_block *sb = data;
- struct dentry *dentry;
-
- if (!name)
- /*
- * If the allocation failed there'll already be an
- * error in the log (and likely a huge and growing
- * number of them since they system will be under
- * extreme memory pressure), so simply assume
- * collision for safety but don't add to the log
- * flood.
- */
- return true;
-
- dentry = try_lookup_noperm(&QSTR(name), sb->s_root);
- kfree(name);
- if (!IS_ERR_OR_NULL(dentry))
- dput(dentry);
-
- return dentry != NULL;
-}
-
static int efivarfs_create_dentry(struct super_block *sb, efi_char16_t *name16,
unsigned long name_size, efi_guid_t vendor,
char *name)
@@ -244,7 +198,7 @@ static int efivarfs_create_dentry(struct super_block *sb, efi_char16_t *name16,
struct dentry *dentry, *root = sb->s_root;
unsigned long size = 0;
int len;
- int err = -ENOMEM;
+ int err = 0;
bool is_removable = false;
/* length of the variable name itself: remove GUID and separator */
@@ -253,41 +207,36 @@ static int efivarfs_create_dentry(struct super_block *sb, efi_char16_t *name16,
if (efivar_variable_is_removable(vendor, name, len))
is_removable = true;
+ dentry = simple_start_creating(root, name);
+ if (IS_ERR(dentry)) {
+ err = PTR_ERR(dentry);
+ goto out_name;
+ }
+
inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0,
is_removable);
- if (!inode)
- goto fail_name;
+ if (unlikely(!inode)) {
+ err = -ENOMEM;
+ goto out_dentry;
+ }
entry = efivar_entry(inode);
memcpy(entry->var.VariableName, name16, name_size);
memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
- dentry = efivarfs_alloc_dentry(root, name);
- if (IS_ERR(dentry)) {
- err = PTR_ERR(dentry);
- goto fail_inode;
- }
-
__efivar_entry_get(entry, NULL, &size, NULL);
- /* copied by the above to local storage in the dentry. */
- kfree(name);
-
inode_lock(inode);
inode->i_private = entry;
i_size_write(inode, size + sizeof(__u32)); /* attributes + data */
inode_unlock(inode);
d_make_persistent(dentry, inode);
- dput(dentry);
-
- return 0;
-fail_inode:
- iput(inode);
-fail_name:
+out_dentry:
+ simple_done_creating(dentry);
+out_name:
kfree(name);
-
return err;
}
@@ -407,42 +356,6 @@ static const struct fs_context_operations efivarfs_context_ops = {
.free = efivarfs_free,
};
-static int efivarfs_check_missing(efi_char16_t *name16, efi_guid_t vendor,
- unsigned long name_size, void *data)
-{
- char *name;
- struct super_block *sb = data;
- struct dentry *dentry;
- int err;
-
- if (guid_equal(&vendor, &LINUX_EFI_RANDOM_SEED_TABLE_GUID))
- return 0;
-
- name = efivar_get_utf8name(name16, &vendor);
- if (!name)
- return -ENOMEM;
-
- dentry = try_lookup_noperm(&QSTR(name), sb->s_root);
- if (IS_ERR(dentry)) {
- err = PTR_ERR(dentry);
- goto out;
- }
-
- if (!dentry) {
- /* found missing entry */
- pr_info("efivarfs: creating variable %s\n", name);
- return efivarfs_create_dentry(sb, name16, name_size, vendor, name);
- }
-
- dput(dentry);
- err = 0;
-
- out:
- kfree(name);
-
- return err;
-}
-
static struct file_system_type efivarfs_type;
static int efivarfs_freeze_fs(struct super_block *sb)
@@ -493,7 +406,7 @@ static int efivarfs_unfreeze_fs(struct super_block *sb)
}
}
- efivar_init(efivarfs_check_missing, sb, false);
+ efivar_init(efivarfs_callback, sb, false);
pr_info("efivarfs: finished resyncing variable state\n");
return 0;
}
diff --git a/fs/efivarfs/vars.c b/fs/efivarfs/vars.c
index 6edc10958ecf..d893e928891a 100644
--- a/fs/efivarfs/vars.c
+++ b/fs/efivarfs/vars.c
@@ -407,6 +407,8 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
case EFI_SUCCESS:
variable_name_size = var_name_strnsize(variable_name,
variable_name_size);
+ err = func(variable_name, vendor_guid,
+ variable_name_size, data);
/*
* Some firmware implementations return the
@@ -416,18 +418,16 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
* we'll ever see a different variable name,
* and may end up looping here forever.
*/
- if (duplicate_check &&
- efivarfs_variable_is_present(variable_name,
- &vendor_guid, data)) {
- dup_variable_bug(variable_name, &vendor_guid,
- variable_name_size);
- status = EFI_NOT_FOUND;
- } else {
- err = func(variable_name, vendor_guid,
- variable_name_size, data);
- if (err)
- status = EFI_NOT_FOUND;
+ if (err == -EEXIST) {
+ if (duplicate_check)
+ dup_variable_bug(variable_name,
+ &vendor_guid,
+ variable_name_size);
+ else
+ err = 0;
}
+ if (err)
+ status = EFI_NOT_FOUND;
break;
case EFI_UNSUPPORTED:
err = -EOPNOTSUPP;
next prev parent reply other threads:[~2025-10-28 21:08 UTC|newest]
Thread overview: 101+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-28 0:45 [PATCH v2 00/50] tree-in-dcache stuff Al Viro
2025-10-28 0:45 ` [PATCH v2 01/50] fuse_ctl_add_conn(): fix nlink breakage in case of early failure Al Viro
2025-10-28 0:45 ` [PATCH v2 02/50] tracefs: fix a leak in eventfs_create_events_dir() Al Viro
2025-10-28 1:15 ` Steven Rostedt
2025-10-28 0:45 ` [PATCH v2 03/50] new helper: simple_remove_by_name() Al Viro
2025-10-28 0:45 ` [PATCH v2 04/50] new helper: simple_done_creating() Al Viro
2025-10-28 0:45 ` [PATCH v2 05/50] introduce a flag for explicitly marking persistently pinned dentries Al Viro
2025-10-28 0:45 ` [PATCH v2 06/50] primitives for maintaining persisitency Al Viro
2025-10-28 12:38 ` James Bottomley
2025-10-29 5:10 ` Al Viro
2025-10-29 15:25 ` James Bottomley
2025-10-28 0:45 ` [PATCH v2 07/50] convert simple_{link,unlink,rmdir,rename,fill_super}() to new primitives Al Viro
2025-10-29 14:02 ` [External] : " Mark Tinguely
2025-10-29 17:55 ` Al Viro
2025-10-28 0:45 ` [PATCH v2 08/50] convert ramfs and tmpfs Al Viro
2025-10-28 0:45 ` [PATCH v2 09/50] procfs: make /self and /thread_self dentries persistent Al Viro
2025-10-28 0:45 ` [PATCH v2 10/50] configfs, securityfs: kill_litter_super() not needed Al Viro
2025-10-28 23:58 ` Paul Moore
2025-10-29 6:18 ` Andreas Hindborg
2025-10-28 0:45 ` [PATCH v2 11/50] convert xenfs Al Viro
2025-10-28 0:45 ` [PATCH v2 12/50] convert smackfs Al Viro
2025-10-28 0:45 ` [PATCH v2 13/50] convert hugetlbfs Al Viro
2025-10-28 0:45 ` [PATCH v2 14/50] convert mqueue Al Viro
2025-10-28 0:45 ` [PATCH v2 15/50] convert bpf Al Viro
2025-10-28 0:45 ` [PATCH v2 16/50] convert dlmfs Al Viro
2025-10-28 0:45 ` [PATCH v2 17/50] convert fuse_ctl Al Viro
2025-10-28 0:45 ` [PATCH v2 18/50] convert pstore Al Viro
2025-11-04 1:43 ` Kees Cook
2025-10-28 0:45 ` [PATCH v2 19/50] convert tracefs Al Viro
2025-10-28 15:37 ` Steven Rostedt
2025-10-28 0:45 ` [PATCH v2 20/50] convert debugfs Al Viro
2025-10-28 0:45 ` [PATCH v2 21/50] debugfs: remove duplicate checks in callers of start_creating() Al Viro
2025-10-28 0:45 ` [PATCH v2 22/50] convert efivarfs Al Viro
2025-10-28 12:53 ` James Bottomley
2025-10-28 17:45 ` Al Viro
2025-10-28 21:08 ` Al Viro [this message]
2025-10-28 21:34 ` Ard Biesheuvel
2025-10-29 18:08 ` Al Viro
2025-10-29 18:26 ` Ard Biesheuvel
2025-10-29 18:57 ` James Bottomley
2025-10-29 19:37 ` Al Viro
2025-10-29 19:48 ` James Bottomley
2025-10-30 13:35 ` Ard Biesheuvel
2025-11-05 11:47 ` Christian Brauner
2025-11-05 13:09 ` James Bottomley
2025-11-05 13:16 ` Christian Brauner
2025-11-05 13:33 ` James Bottomley
2025-11-05 13:46 ` Christian Brauner
2025-11-05 14:01 ` James Bottomley
2025-11-05 15:23 ` Christian Brauner
2025-11-05 13:43 ` Christian Brauner
2025-11-09 20:40 ` Al Viro
2025-11-11 10:56 ` Christian Brauner
2025-11-19 21:15 ` [REGRESSION] " Chris Bainbridge
2025-11-25 9:00 ` Christian Brauner
2025-11-05 14:34 ` Ard Biesheuvel
2025-10-28 0:45 ` [PATCH v2 23/50] convert spufs Al Viro
2025-10-28 1:15 ` bot+bpf-ci
2025-10-28 1:33 ` Al Viro
2025-10-28 0:45 ` [PATCH v2 24/50] convert ibmasmfs Al Viro
2025-10-28 0:45 ` [PATCH v2 25/50] ibmasmfs: get rid of ibmasmfs_dir_ops Al Viro
2025-10-28 0:45 ` [PATCH v2 26/50] convert devpts Al Viro
2025-10-28 0:45 ` [PATCH v2 27/50] binderfs: use simple_start_creating() Al Viro
2025-10-28 0:45 ` [PATCH v2 28/50] binderfs_binder_ctl_create(): kill a bogus check Al Viro
2025-10-28 0:45 ` [PATCH v2 29/50] convert binderfs Al Viro
2025-10-28 0:45 ` [PATCH v2 30/50] autofs_{rmdir,unlink}: dentry->d_fsdata->dentry == dentry there Al Viro
2025-10-28 0:45 ` [PATCH v2 31/50] convert autofs Al Viro
2025-10-28 1:55 ` Al Viro
2025-10-28 5:32 ` Linus Torvalds
2025-10-28 0:45 ` [PATCH v2 32/50] convert binfmt_misc Al Viro
2025-10-28 0:45 ` [PATCH v2 33/50] selinuxfs: don't stash the dentry of /policy_capabilities Al Viro
2025-10-29 0:08 ` Paul Moore
2025-10-29 15:19 ` Stephen Smalley
2025-10-28 0:45 ` [PATCH v2 34/50] selinuxfs: new helper for attaching files to tree Al Viro
2025-10-28 23:51 ` Paul Moore
2025-10-29 15:22 ` Stephen Smalley
2025-10-28 0:45 ` [PATCH v2 35/50] convert selinuxfs Al Viro
2025-10-29 0:02 ` Paul Moore
2025-10-29 3:24 ` Al Viro
2025-10-29 14:49 ` Paul Moore
2025-10-29 15:06 ` Stephen Smalley
2025-10-28 0:45 ` [PATCH v2 36/50] functionfs: switch to simple_remove_by_name() Al Viro
2025-10-28 8:47 ` Greg KH
2025-10-28 0:45 ` [PATCH v2 37/50] convert functionfs Al Viro
2025-10-28 0:45 ` [PATCH v2 38/50] gadgetfs: switch to simple_remove_by_name() Al Viro
2025-10-28 0:45 ` [PATCH v2 39/50] convert gadgetfs Al Viro
2025-10-28 0:45 ` [PATCH v2 40/50] hypfs: don't pin dentries twice Al Viro
2025-10-28 0:46 ` [PATCH v2 41/50] hypfs: switch hypfs_create_str() to returning int Al Viro
2025-10-28 0:46 ` [PATCH v2 42/50] hypfs: swich hypfs_create_u64() " Al Viro
2025-10-28 0:46 ` [PATCH v2 43/50] convert hypfs Al Viro
2025-10-28 0:46 ` [PATCH v2 44/50] convert rpc_pipefs Al Viro
2025-10-28 0:46 ` [PATCH v2 45/50] convert nfsctl Al Viro
2025-10-28 0:46 ` [PATCH v2 46/50] convert rust_binderfs Al Viro
2025-10-28 0:46 ` [PATCH v2 47/50] get rid of kill_litter_super() Al Viro
2025-10-28 0:46 ` [PATCH v2 48/50] convert securityfs Al Viro
2025-10-29 0:10 ` Paul Moore
2025-10-28 0:46 ` [PATCH v2 49/50] kill securityfs_recursive_remove() Al Viro
2025-10-29 0:04 ` Paul Moore
2025-10-28 0:46 ` [PATCH v2 50/50] d_make_discardable(): warn if given a non-persistent dentry Al Viro
2025-10-28 0:59 ` [PATCH v2 00/50] tree-in-dcache stuff Al Viro
2025-10-28 5:33 ` Linus Torvalds
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=20251028210805.GP2441659@ZenIV \
--to=viro@zeniv.linux.org.uk \
--cc=James.Bottomley@hansenpartnership.com \
--cc=a.hindborg@kernel.org \
--cc=borntraeger@linux.ibm.com \
--cc=bpf@vger.kernel.org \
--cc=brauner@kernel.org \
--cc=casey@schaufler-ca.com \
--cc=gregkh@linuxfoundation.org \
--cc=jack@suse.cz \
--cc=john.johansen@canonical.com \
--cc=kees@kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-usb@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=miklos@szeredi.hu \
--cc=neil@brown.name \
--cc=ocfs2-devel@lists.linux.dev \
--cc=paul@paul-moore.com \
--cc=raven@themaw.net \
--cc=rostedt@goodmis.org \
--cc=selinux@vger.kernel.org \
--cc=torvalds@linux-foundation.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.