[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250115141458.9182-1-o451686892@gmail.com>
Date: Wed, 15 Jan 2025 22:14:58 +0800
From: Weizhao Ouyang <o451686892@...il.com>
To: Jonathan Corbet <corbet@....net>,
Jeremy Kerr <jk@...abs.org>,
Ard Biesheuvel <ardb@...nel.org>,
Weizhao Ouyang <o451686892@...il.com>,
Tim Schumacher <timschumi@....de>
Cc: linux-doc@...r.kernel.org,
linux-kernel@...r.kernel.org,
linux-efi@...r.kernel.org
Subject: [RFC PATCH] efivarfs: Introduce efivarfs refresh remount
Currently, when setting efi variables through the runtime service,
efivarfs cannot sync variable updates properly. Introduce efivarfs
refresh remount to support efivarfs information updates from other
sources.
Signed-off-by: Weizhao Ouyang <o451686892@...il.com>
---
Documentation/filesystems/efivarfs.rst | 6 ++++
fs/efivarfs/super.c | 40 +++++++++++++++++++++++++-
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/Documentation/filesystems/efivarfs.rst b/Documentation/filesystems/efivarfs.rst
index f646c3f0980f..58461e02ad01 100644
--- a/Documentation/filesystems/efivarfs.rst
+++ b/Documentation/filesystems/efivarfs.rst
@@ -18,6 +18,12 @@ efivarfs is typically mounted like this::
mount -t efivarfs none /sys/firmware/efi/efivars
+To support efivar updates from other sources (efi_test ioctl, runtime
+driver, etc.), set ``efivarfs.refresh=1``. After that, remount will
+update the efivar information in efivarfs, like this::
+
+ mount -t efivarfs none /sys/firmware/efi/efivars -o remount
+
Due to the presence of numerous firmware bugs where removing non-standard
UEFI variables causes the system firmware to fail to POST, efivarfs
files that are not well-known standardized variables are created
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index beba15673be8..7ae22ca120e3 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -277,6 +277,44 @@ static const struct fs_parameter_spec efivarfs_parameters[] = {
{},
};
+static bool efivarfs_refresh_default __read_mostly;
+module_param_named(refresh, efivarfs_refresh_default, bool, 0444);
+
+static void efivarfs_clean_dentry(struct dentry *dentry)
+{
+ struct dentry *child;
+
+ if (!dentry)
+ return;
+
+ if (d_is_dir(dentry)) {
+ spin_lock(&dentry->d_lock);
+ hlist_for_each_entry(child, &dentry->d_children, d_sib) {
+ if (child)
+ efivarfs_clean_dentry(child);
+ }
+ spin_unlock(&dentry->d_lock);
+ } else {
+ d_invalidate(dentry);
+ }
+}
+
+static int efivarfs_refresh(struct fs_context *fc)
+{
+ struct efivarfs_fs_info *sbi = fc->s_fs_info;
+
+ if (!efivarfs_refresh_default)
+ return 0;
+
+ if (!fc->root)
+ return -EINVAL;
+
+ efivarfs_clean_dentry(fc->root);
+ efivar_init(efivarfs_callback, fc->root->d_sb, &sbi->efivarfs_list);
+
+ return 0;
+}
+
static int efivarfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
{
struct efivarfs_fs_info *sbi = fc->s_fs_info;
@@ -351,7 +389,7 @@ static int efivarfs_reconfigure(struct fs_context *fc)
return -EINVAL;
}
- return 0;
+ return efivarfs_refresh(fc);
}
static const struct fs_context_operations efivarfs_context_ops = {
--
2.45.2
Powered by blists - more mailing lists