// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2012 Red Hat, Inc.
 * Copyright (C) 2012 Jeremy Kerr <jeremy.kerr@canonical.com>
 */

#include <linux/efi.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/mount.h>

#include "internal.h"

static ssize_t efivarfs_file_write(struct file *file,
		const char __user *userbuf, size_t count, loff_t *ppos)
{
	struct efivar_entry *var = file->private_data;
	void *data;
	u32 attributes;
	struct inode *inode = file->f_mapping->host;
	unsigned long datasize = count - sizeof(attributes);
	ssize_t bytes;
	bool set = false;

	if (count < sizeof(attributes))
		return -EINVAL;

	if (copy_from_user(&attributes, userbuf, sizeof(attributes)))
		return -EFAULT;

	if (attributes & ~(EFI_VARIABLE_MASK))
		return -EINVAL;

	data = memdup_user(userbuf + sizeof(attributes), datasize);
	if (IS_ERR(data))
		return PTR_ERR(data);

	inode_lock(inode);
	if (var->removed) {
		/*
		 * file got removed; don't allow a set.  Caused by an
		 * unsuccessful create or successful delete write
		 * racing with us.
		 */
		bytes = -EIO;
		goto out;
	}

	bytes = efivar_entry_set_get_size(var, attributes, &datasize,
					  data, &set);
	if (!set) {
		if (bytes == -ENOENT)
			bytes = -EIO;
		goto out;
	}

	if (bytes == -ENOENT) {
		/*
		 * zero size signals to release that the write deleted
		 * the variable
		 */
		i_size_write(inode, 0);
	} else {
		i_size_write(inode, datasize + sizeof(attributes));
		inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
	}

	bytes = count;

out:
	inode_unlock(inode);

	kfree(data);

	return bytes;
}

static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
		size_t count, loff_t *ppos)
{
	struct efivar_entry *var = file->private_data;
	unsigned long datasize = 0;
	u32 attributes;
	void *data;
	ssize_t size = 0;
	int err;

	while (!__ratelimit(&file->f_cred->user->ratelimit))
		msleep(50);

	err = efivar_entry_size(var, &datasize);

	/*
	 * efivarfs represents uncommitted variables with
	 * zero-length files. Reading them should return EOF.
	 */
	if (err == -ENOENT)
		return 0;
	else if (err)
		return err;

	data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL);

	if (!data)
		return -ENOMEM;

	size = efivar_entry_get(var, &attributes, &datasize,
				data + sizeof(attributes));
	if (size)
		goto out_free;

	memcpy(data, &attributes, sizeof(attributes));
	size = simple_read_from_buffer(userbuf, count, ppos,
				       data, datasize + sizeof(attributes));
out_free:
	kfree(data);

	return size;
}

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);
	inode_unlock(inode);

	if (var->removed)
		simple_recursive_removal(file->f_path.dentry, NULL);

	return 0;
}

static int efivarfs_file_open(struct inode *inode, struct file *file)
{
	struct efivar_entry *entry = inode->i_private;

	file->private_data = entry;

	inode_lock(inode);
	entry->open_count++;
	inode_unlock(inode);

	return 0;
}

const struct file_operations efivarfs_file_operations = {
	.open		= efivarfs_file_open,
	.read		= efivarfs_file_read,
	.write		= efivarfs_file_write,
	.release	= efivarfs_file_release,
};
