summaryrefslogtreecommitdiff
path: root/fs/efivarfs
diff options
context:
space:
mode:
authorAnisse Astier <an.astier@criteo.com>2023-05-17 17:38:12 +0200
committerArd Biesheuvel <ardb@kernel.org>2023-05-17 18:21:34 +0200
commitd86ff3333cb1d5f42d8898fb5fdb304e143c0237 (patch)
treeb2ff1411537adc4dd46d5a69207dafc79f3de994 /fs/efivarfs
parent0153431c85af3d4470ac8c59a3f854a3926dff86 (diff)
efivarfs: expose used and total size
When writing EFI variables, one might get errors with no other message on why it fails. Being able to see how much is used by EFI variables helps analyzing such issues. Since this is not a conventional filesystem, block size is intentionally set to 1 instead of PAGE_SIZE. x86 quirks of reserved size are taken into account; so that available and free size can be different, further helping debugging space issues. With this patch, one can see the remaining space in EFI variable storage via efivarfs, like this: $ df -h /sys/firmware/efi/efivars/ Filesystem Size Used Avail Use% Mounted on efivarfs 176K 106K 66K 62% /sys/firmware/efi/efivars Signed-off-by: Anisse Astier <an.astier@criteo.com> [ardb: - rename efi_reserved_space() to efivar_reserved_space() - whitespace/coding style tweaks] Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Diffstat (limited to 'fs/efivarfs')
-rw-r--r--fs/efivarfs/super.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 482d612b716b..e028fafa04f3 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -13,6 +13,7 @@
#include <linux/ucs2_string.h>
#include <linux/slab.h>
#include <linux/magic.h>
+#include <linux/statfs.h>
#include "internal.h"
@@ -23,8 +24,44 @@ static void efivarfs_evict_inode(struct inode *inode)
clear_inode(inode);
}
+static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ const u32 attr = EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS;
+ u64 storage_space, remaining_space, max_variable_size;
+ efi_status_t status;
+
+ status = efivar_query_variable_info(attr, &storage_space, &remaining_space,
+ &max_variable_size);
+ if (status != EFI_SUCCESS)
+ return efi_status_to_err(status);
+
+ /*
+ * This is not a normal filesystem, so no point in pretending it has a block
+ * size; we declare f_bsize to 1, so that we can then report the exact value
+ * sent by EFI QueryVariableInfo in f_blocks and f_bfree
+ */
+ buf->f_bsize = 1;
+ buf->f_namelen = NAME_MAX;
+ buf->f_blocks = storage_space;
+ buf->f_bfree = remaining_space;
+ buf->f_type = dentry->d_sb->s_magic;
+
+ /*
+ * In f_bavail we declare the free space that the kernel will allow writing
+ * when the storage_paranoia x86 quirk is active. To use more, users
+ * should boot the kernel with efi_no_storage_paranoia.
+ */
+ if (remaining_space > efivar_reserved_space())
+ buf->f_bavail = remaining_space - efivar_reserved_space();
+ else
+ buf->f_bavail = 0;
+
+ return 0;
+}
static const struct super_operations efivarfs_ops = {
- .statfs = simple_statfs,
+ .statfs = efivarfs_statfs,
.drop_inode = generic_delete_inode,
.evict_inode = efivarfs_evict_inode,
};