From fc20737d8b85691ecabab3739ed7d06c9b7bc00f Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 26 Feb 2025 16:48:26 -0500 Subject: [PATCH] efivarfs: allow creation of zero length files Temporarily allow the creation of zero length files in efivarfs so the 'fwupd' user space firmware update tool can continue to operate. This hack should be reverted as soon as the fwupd mechanisms for updating firmware have been fixed. fwupd has been coded to open a firmware file, close it, remove the immutable bit and write to it. Since commit 908af31f4896 ("efivarfs: fix error on write to new variable leaving remnants") this behaviour results in the first close removing the file which causes the second write to fail. To allow fwupd to keep working code up an indicator of size 1 if a write fails and only remove the file on that condition (so create at zero size is allowed). Tested-by: Richard Hughes Signed-off-by: James Bottomley [ardb: replace LVFS with fwupd, as suggested by Richard] Signed-off-by: Ard Biesheuvel --- fs/efivarfs/file.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index cb1b6d0c34545..c294a8fc566da 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -57,10 +57,11 @@ static ssize_t efivarfs_file_write(struct file *file, if (bytes == -ENOENT) { /* - * zero size signals to release that the write deleted - * the variable + * FIXME: temporary workaround for fwupdate, signal + * failed write with a 1 to keep created but not + * written files */ - i_size_write(inode, 0); + i_size_write(inode, 1); } else { i_size_write(inode, datasize + sizeof(attributes)); inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); @@ -124,7 +125,8 @@ static int efivarfs_file_release(struct inode *inode, struct file *file) struct efivar_entry *var = inode->i_private; inode_lock(inode); - var->removed = (--var->open_count == 0 && i_size_read(inode) == 0); + /* FIXME: temporary work around for fwupdate */ + var->removed = (--var->open_count == 0 && i_size_read(inode) == 1); inode_unlock(inode); if (var->removed) -- 2.39.5