Skip to content

Commit 7e365c7

Browse files
James Bottomleyardbiesheuvel
authored andcommitted
efivarfs: make variable_is_present use dcache lookup
Instead of searching the variable entry list for a variable, use the dcache lookup functions to find it instead. Also add an efivarfs_ prefix to the function now it is no longer static. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 1aba87f commit 7e365c7

File tree

3 files changed

+33
-24
lines changed

3 files changed

+33
-24
lines changed

fs/efivarfs/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
5656
bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
5757
size_t len);
5858
char *efivar_get_utf8name(const efi_char16_t *name16, efi_guid_t *vendor);
59+
bool efivarfs_variable_is_present(efi_char16_t *variable_name,
60+
efi_guid_t *vendor, void *data);
5961

6062
extern const struct file_operations efivarfs_file_operations;
6163
extern const struct inode_operations efivarfs_dir_inode_operations;

fs/efivarfs/super.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,35 @@ static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
181181
return ERR_PTR(-ENOMEM);
182182
}
183183

184+
bool efivarfs_variable_is_present(efi_char16_t *variable_name,
185+
efi_guid_t *vendor, void *data)
186+
{
187+
char *name = efivar_get_utf8name(variable_name, vendor);
188+
struct super_block *sb = data;
189+
struct dentry *dentry;
190+
struct qstr qstr;
191+
192+
if (!name)
193+
/*
194+
* If the allocation failed there'll already be an
195+
* error in the log (and likely a huge and growing
196+
* number of them since they system will be under
197+
* extreme memory pressure), so simply assume
198+
* collision for safety but don't add to the log
199+
* flood.
200+
*/
201+
return true;
202+
203+
qstr.name = name;
204+
qstr.len = strlen(name);
205+
dentry = d_hash_and_lookup(sb->s_root, &qstr);
206+
kfree(name);
207+
if (!IS_ERR_OR_NULL(dentry))
208+
dput(dentry);
209+
210+
return dentry != NULL;
211+
}
212+
184213
static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
185214
unsigned long name_size, void *data,
186215
struct list_head *list)

fs/efivarfs/vars.c

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -313,28 +313,6 @@ efivar_variable_is_removable(efi_guid_t vendor, const char *var_name,
313313
return found;
314314
}
315315

316-
static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor,
317-
struct list_head *head)
318-
{
319-
struct efivar_entry *entry, *n;
320-
unsigned long strsize1, strsize2;
321-
bool found = false;
322-
323-
strsize1 = ucs2_strsize(variable_name, EFI_VAR_NAME_LEN);
324-
list_for_each_entry_safe(entry, n, head, list) {
325-
strsize2 = ucs2_strsize(entry->var.VariableName, EFI_VAR_NAME_LEN);
326-
if (strsize1 == strsize2 &&
327-
!memcmp(variable_name, &(entry->var.VariableName),
328-
strsize2) &&
329-
!efi_guidcmp(entry->var.VendorGuid,
330-
*vendor)) {
331-
found = true;
332-
break;
333-
}
334-
}
335-
return found;
336-
}
337-
338316
/*
339317
* Returns the size of variable_name, in bytes, including the
340318
* terminating NULL character, or variable_name_size if no NULL
@@ -439,8 +417,8 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
439417
* we'll ever see a different variable name,
440418
* and may end up looping here forever.
441419
*/
442-
if (variable_is_present(variable_name, &vendor_guid,
443-
head)) {
420+
if (efivarfs_variable_is_present(variable_name,
421+
&vendor_guid, data)) {
444422
dup_variable_bug(variable_name, &vendor_guid,
445423
variable_name_size);
446424
status = EFI_NOT_FOUND;

0 commit comments

Comments
 (0)