Skip to content

Commit

Permalink
efivarfs: Return an error if we fail to read a variable
Browse files Browse the repository at this point in the history
Instead of always returning 0 in efivarfs_file_read(), even when we
fail to successfully read the variable, convert the EFI status to
something meaningful and return that to the caller. This way the user
will have some hint as to why the read failed.

Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
  • Loading branch information
Matt Fleming committed Oct 30, 2012
1 parent 310ad75 commit 7253eab
Showing 1 changed file with 36 additions and 26 deletions.
62 changes: 36 additions & 26 deletions drivers/firmware/efivars.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,36 @@ static int efivarfs_file_open(struct inode *inode, struct file *file)
return 0;
}

static int efi_status_to_err(efi_status_t status)
{
int err;

switch (status) {
case EFI_INVALID_PARAMETER:
err = -EINVAL;
break;
case EFI_OUT_OF_RESOURCES:
err = -ENOSPC;
break;
case EFI_DEVICE_ERROR:
err = -EIO;
break;
case EFI_WRITE_PROTECTED:
err = -EROFS;
break;
case EFI_SECURITY_VIOLATION:
err = -EACCES;
break;
case EFI_NOT_FOUND:
err = -ENOENT;
break;
default:
err = -EINVAL;
}

return err;
}

static ssize_t efivarfs_file_write(struct file *file,
const char __user *userbuf, size_t count, loff_t *ppos)
{
Expand Down Expand Up @@ -711,29 +741,7 @@ static ssize_t efivarfs_file_write(struct file *file,
spin_unlock(&efivars->lock);
kfree(data);

switch (status) {
case EFI_INVALID_PARAMETER:
count = -EINVAL;
break;
case EFI_OUT_OF_RESOURCES:
count = -ENOSPC;
break;
case EFI_DEVICE_ERROR:
count = -EIO;
break;
case EFI_WRITE_PROTECTED:
count = -EROFS;
break;
case EFI_SECURITY_VIOLATION:
count = -EACCES;
break;
case EFI_NOT_FOUND:
count = -ENOENT;
break;
default:
count = -EINVAL;
}
return count;
return efi_status_to_err(status);
}

/*
Expand Down Expand Up @@ -791,12 +799,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
spin_unlock(&efivars->lock);

if (status != EFI_BUFFER_TOO_SMALL)
return 0;
return efi_status_to_err(status);

data = kmalloc(datasize + 4, GFP_KERNEL);

if (!data)
return 0;
return -ENOMEM;

spin_lock(&efivars->lock);
status = efivars->ops->get_variable(var->var.VariableName,
Expand All @@ -805,8 +813,10 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
(data + 4));
spin_unlock(&efivars->lock);

if (status != EFI_SUCCESS)
if (status != EFI_SUCCESS) {
size = efi_status_to_err(status);
goto out_free;
}

memcpy(data, &attributes, 4);
size = simple_read_from_buffer(userbuf, count, ppos,
Expand Down

0 comments on commit 7253eab

Please sign in to comment.