/* -*- mode: c; c-basic-offset: 8; -*-
 * vim: noexpandtab sw=8 ts=8 sts=0:
 *
 * file.c - operations for regular (text) files.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 *
 * Based on sysfs:
 * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
 *
 * configfs Copyright (C) 2005 Oracle.  All rights reserved.
 */

#include <linux/fs.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>

#include <linux/configfs.h>
#include "configfs_internal.h"

/*
 * A simple attribute can only be 4096 characters.  Why 4k?  Because the
 * original code limited it to PAGE_SIZE.  That's a bad idea, though,
 * because an attribute of 16k on ia64 won't work on x86.  So we limit to
 * 4k, our minimum common page size.
 */
#define SIMPLE_ATTR_SIZE 4096

struct configfs_buffer {
	size_t			count;
	loff_t			pos;
	char			* page;
	struct configfs_item_operations	* ops;
	struct mutex		mutex;
	int			needs_read_fill;
	bool			read_in_progress;
	bool			write_in_progress;
	char			*bin_buffer;
	int			bin_buffer_size;
};


/**
 *	fill_read_buffer - allocate and fill buffer from item.
 *	@dentry:	dentry pointer.
 *	@buffer:	data buffer for file.
 *
 *	Allocate @buffer->page, if it hasn't been already, then call the
 *	config_item's show() method to fill the buffer with this attribute's
 *	data.
 *	This is called only once, on the file's first read.
 */
static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer)
{
	struct configfs_attribute * attr = to_attr(dentry);
	struct config_item * item = to_item(dentry->d_parent);
	int ret = 0;
	ssize_t count;

	if (!buffer->page)
		buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
	if (!buffer->page)
		return -ENOMEM;

	count = attr->show(item, buffer->page);

	BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE);
	if (count >= 0) {
		buffer->needs_read_fill = 0;
		buffer->count = count;
	} else
		ret = count;
	return ret;
}

/**
 *	configfs_read_file - read an attribute.
 *	@file:	file pointer.
 *	@buf:	buffer to fill.
 *	@count:	number of bytes to read.
 *	@ppos:	starting offset in file.
 *
 *	Userspace wants to read an attribute file. The attribute descriptor
 *	is in the file's ->d_fsdata. The target item is in the directory's
 *	->d_fsdata.
 *
 *	We call fill_read_buffer() to allocate and fill the buffer from the
 *	item's show() method exactly once (if the read is happening from
 *	the beginning of the file). That should fill the entire buffer with
 *	all the data the item has to offer for that attribute.
 *	We then call flush_read_buffer() to copy the buffer to userspace
 *	in the increments specified.
 */

static ssize_t
configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
	struct configfs_buffer * buffer = file->private_data;
	ssize_t retval = 0;

	mutex_lock(&buffer->mutex);
	if (buffer->needs_read_fill) {
		if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
			goto out;
	}
	pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
		 __func__, count, *ppos, buffer->page);
	retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
					 buffer->count);
out:
	mutex_unlock(&buffer->mutex);
	return retval;
}

/**
 *	configfs_read_bin_file - read a binary attribute.
 *	@file:	file pointer.
 *	@buf:	buffer to fill.
 *	@count:	number of bytes to read.
 *	@ppos:	starting offset in file.
 *
 *	Userspace wants to read a binary attribute file. The attribute
 *	descriptor is in the file's ->d_fsdata. The target item is in the
 *	directory's ->d_fsdata.
 *
 *	We check whether we need to refill the buffer. If so we will
 *	call the attributes' attr->read() twice. The first time we
 *	will pass a NULL as a buffer pointer, which the attributes' method
 *	will use to return the size of the buffer required. If no error
 *	occurs we will allocate the buffer using vmalloc and call
 *	attr->read() again passing that buffer as an argument.
 *	Then we just copy to user-space using simple_read_from_buffer.
 */

static ssize_t
configfs_read_bin_file(struct file *file, char __user *buf,
		       size_t count, loff_t *ppos)
{
	struct configfs_buffer *buffer = file->private_data;
	struct dentry *dentry = file->f_path.dentry;
	struct config_item *item = to_item(dentry->d_parent);
	struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry);
	ssize_t retval = 0;
	ssize_t len = min_t(size_t, count, PAGE_SIZE);

	mutex_lock(&buffer->mutex);

	/* we don't support switching read/write modes */
	if (buffer->write_in_progress) {
		retval = -ETXTBSY;
		goto out;
	}
	buffer->read_in_progress = 1;

	if (buffer->needs_read_fill) {
		/* perform first read with buf == NULL to get extent */
		len = bin_attr->read(item, NULL, 0);
		if (len <= 0) {
			retval = len;
			goto out;
		}

		/* do not exceed the maximum value */
		if (bin_attr->cb_max_size && len > bin_attr->cb_max_size) {
			retval = -EFBIG;
			goto out;
		}

		buffer->bin_buffer = vmalloc(len);
		if (buffer->bin_buffer == NULL) {
			retval = -ENOMEM;
			goto out;
		}
		buffer->bin_buffer_size = len;

		/* perform second read to fill buffer */
		len = bin_attr->read(item, buffer->bin_buffer, len);
		if (len < 0) {
			retval = len;
			vfree(buffer->bin_buffer);
			buffer->bin_buffer_size = 0;
			buffer->bin_buffer = NULL;
			goto out;
		}

		buffer->needs_read_fill = 0;
	}

	retval = simple_read_from_buffer(buf, count, ppos, buffer->bin_buffer,
					buffer->bin_buffer_size);
out:
	mutex_unlock(&buffer->mutex);
	return retval;
}


/**
 *	fill_write_buffer - copy buffer from userspace.
 *	@buffer:	data buffer for file.
 *	@buf:		data from user.
 *	@count:		number of bytes in @userbuf.
 *
 *	Allocate @buffer->page if it hasn't been already, then
 *	copy the user-supplied buffer into it.
 */

static int
fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size_t count)
{
	int error;

	if (!buffer->page)
		buffer->page = (char *)__get_free_pages(GFP_KERNEL, 0);
	if (!buffer->page)
		return -ENOMEM;

	if (count >= SIMPLE_ATTR_SIZE)
		count = SIMPLE_ATTR_SIZE - 1;
	error = copy_from_user(buffer->page,buf,count);
	buffer->needs_read_fill = 1;
	/* if buf is assumed to contain a string, terminate it by \0,
	 * so e.g. sscanf() can scan the string easily */
	buffer->page[count] = 0;
	return error ? -EFAULT : count;
}


/**
 *	flush_write_buffer - push buffer to config_item.
 *	@dentry:	dentry to the attribute
 *	@buffer:	data buffer for file.
 *	@count:		number of bytes
 *
 *	Get the correct pointers for the config_item and the attribute we're
 *	dealing with, then call the store() method for the attribute,
 *	passing the buffer that we acquired in fill_write_buffer().
 */

static int
flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count)
{
	struct configfs_attribute * attr = to_attr(dentry);
	struct config_item * item = to_item(dentry->d_parent);

	return attr->store(item, buffer->page, count);
}


/**
 *	configfs_write_file - write an attribute.
 *	@file:	file pointer
 *	@buf:	data to write
 *	@count:	number of bytes
 *	@ppos:	starting offset
 *
 *	Similar to configfs_read_file(), though working in the opposite direction.
 *	We allocate and fill the data from the user in fill_write_buffer(),
 *	then push it to the config_item in flush_write_buffer().
 *	There is no easy way for us to know if userspace is only doing a partial
 *	write, so we don't support them. We expect the entire buffer to come
 *	on the first write.
 *	Hint: if you're writing a value, first read the file, modify only the
 *	the value you're changing, then write entire buffer back.
 */

static ssize_t
configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	struct configfs_buffer * buffer = file->private_data;
	ssize_t len;

	mutex_lock(&buffer->mutex);
	len = fill_write_buffer(buffer, buf, count);
	if (len > 0)
		len = flush_write_buffer(file->f_path.dentry, buffer, len);
	if (len > 0)
		*ppos += len;
	mutex_unlock(&buffer->mutex);
	return len;
}

/**
 *	configfs_write_bin_file - write a binary attribute.
 *	@file:	file pointer
 *	@buf:	data to write
 *	@count:	number of bytes
 *	@ppos:	starting offset
 *
 *	Writing to a binary attribute file is similar to a normal read.
 *	We buffer the consecutive writes (binary attribute files do not
 *	support lseek) in a continuously growing buffer, but we don't
 *	commit until the close of the file.
 */

static ssize_t
configfs_write_bin_file(struct file *file, const char __user *buf,
			size_t count, loff_t *ppos)
{
	struct configfs_buffer *buffer = file->private_data;
	struct dentry *dentry = file->f_path.dentry;
	struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry);
	void *tbuf = NULL;
	ssize_t len;

	mutex_lock(&buffer->mutex);

	/* we don't support switching read/write modes */
	if (buffer->read_in_progress) {
		len = -ETXTBSY;
		goto out;
	}
	buffer->write_in_progress = 1;

	/* buffer grows? */
	if (*ppos + count > buffer->bin_buffer_size) {

		if (bin_attr->cb_max_size &&
			*ppos + count > bin_attr->cb_max_size) {
			len = -EFBIG;
			goto out;
		}

		tbuf = vmalloc(*ppos + count);
		if (tbuf == NULL) {
			len = -ENOMEM;
			goto out;
		}

		/* copy old contents */
		if (buffer->bin_buffer) {
			memcpy(tbuf, buffer->bin_buffer,
				buffer->bin_buffer_size);
			vfree(buffer->bin_buffer);
		}

		/* clear the new area */
		memset(tbuf + buffer->bin_buffer_size, 0,
			*ppos + count - buffer->bin_buffer_size);
		buffer->bin_buffer = tbuf;
		buffer->bin_buffer_size = *ppos + count;
	}

	len = simple_write_to_buffer(buffer->bin_buffer,
			buffer->bin_buffer_size, ppos, buf, count);
out:
	mutex_unlock(&buffer->mutex);
	return len;
}

static int check_perm(struct inode * inode, struct file * file, int type)
{
	struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent);
	struct configfs_attribute * attr = to_attr(file->f_path.dentry);
	struct configfs_bin_attribute *bin_attr = NULL;
	struct configfs_buffer * buffer;
	struct configfs_item_operations * ops = NULL;
	int error = 0;

	if (!item || !attr)
		goto Einval;

	if (type & CONFIGFS_ITEM_BIN_ATTR)
		bin_attr = to_bin_attr(file->f_path.dentry);

	/* Grab the module reference for this attribute if we have one */
	if (!try_module_get(attr->ca_owner)) {
		error = -ENODEV;
		goto Done;
	}

	if (item->ci_type)
		ops = item->ci_type->ct_item_ops;
	else
		goto Eaccess;

	/* File needs write support.
	 * The inode's perms must say it's ok,
	 * and we must have a store method.
	 */
	if (file->f_mode & FMODE_WRITE) {
		if (!(inode->i_mode & S_IWUGO))
			goto Eaccess;

		if ((type & CONFIGFS_ITEM_ATTR) && !attr->store)
			goto Eaccess;

		if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->write)
			goto Eaccess;
	}

	/* File needs read support.
	 * The inode's perms must say it's ok, and we there
	 * must be a show method for it.
	 */
	if (file->f_mode & FMODE_READ) {
		if (!(inode->i_mode & S_IRUGO))
			goto Eaccess;

		if ((type & CONFIGFS_ITEM_ATTR) && !attr->show)
			goto Eaccess;

		if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->read)
			goto Eaccess;
	}

	/* No error? Great, allocate a buffer for the file, and store it
	 * it in file->private_data for easy access.
	 */
	buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL);
	if (!buffer) {
		error = -ENOMEM;
		goto Enomem;
	}
	mutex_init(&buffer->mutex);
	buffer->needs_read_fill = 1;
	buffer->read_in_progress = 0;
	buffer->write_in_progress = 0;
	buffer->ops = ops;
	file->private_data = buffer;
	goto Done;

 Einval:
	error = -EINVAL;
	goto Done;
 Eaccess:
	error = -EACCES;
 Enomem:
	module_put(attr->ca_owner);
 Done:
	if (error && item)
		config_item_put(item);
	return error;
}

static int configfs_release(struct inode *inode, struct file *filp)
{
	struct config_item * item = to_item(filp->f_path.dentry->d_parent);
	struct configfs_attribute * attr = to_attr(filp->f_path.dentry);
	struct module * owner = attr->ca_owner;
	struct configfs_buffer * buffer = filp->private_data;

	if (item)
		config_item_put(item);
	/* After this point, attr should not be accessed. */
	module_put(owner);

	if (buffer) {
		if (buffer->page)
			free_page((unsigned long)buffer->page);
		mutex_destroy(&buffer->mutex);
		kfree(buffer);
	}
	return 0;
}

static int configfs_open_file(struct inode *inode, struct file *filp)
{
	return check_perm(inode, filp, CONFIGFS_ITEM_ATTR);
}

static int configfs_open_bin_file(struct inode *inode, struct file *filp)
{
	return check_perm(inode, filp, CONFIGFS_ITEM_BIN_ATTR);
}

static int configfs_release_bin_file(struct inode *inode, struct file *filp)
{
	struct configfs_buffer *buffer = filp->private_data;
	struct dentry *dentry = filp->f_path.dentry;
	struct config_item *item = to_item(dentry->d_parent);
	struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry);
	ssize_t len = 0;
	int ret;

	buffer->read_in_progress = 0;

	if (buffer->write_in_progress) {
		buffer->write_in_progress = 0;

		len = bin_attr->write(item, buffer->bin_buffer,
				buffer->bin_buffer_size);

		/* vfree on NULL is safe */
		vfree(buffer->bin_buffer);
		buffer->bin_buffer = NULL;
		buffer->bin_buffer_size = 0;
		buffer->needs_read_fill = 1;
	}

	ret = configfs_release(inode, filp);
	if (len < 0)
		return len;
	return ret;
}


const struct file_operations configfs_file_operations = {
	.read		= configfs_read_file,
	.write		= configfs_write_file,
	.llseek		= generic_file_llseek,
	.open		= configfs_open_file,
	.release	= configfs_release,
};

const struct file_operations configfs_bin_file_operations = {
	.read		= configfs_read_bin_file,
	.write		= configfs_write_bin_file,
	.llseek		= NULL,		/* bin file is not seekable */
	.open		= configfs_open_bin_file,
	.release	= configfs_release_bin_file,
};

/**
 *	configfs_create_file - create an attribute file for an item.
 *	@item:	item we're creating for.
 *	@attr:	atrribute descriptor.
 */

int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr)
{
	struct dentry *dir = item->ci_dentry;
	struct configfs_dirent *parent_sd = dir->d_fsdata;
	umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
	int error = 0;

	inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL);
	error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode,
				     CONFIGFS_ITEM_ATTR);
	inode_unlock(d_inode(dir));

	return error;
}

/**
 *	configfs_create_bin_file - create a binary attribute file for an item.
 *	@item:	item we're creating for.
 *	@attr:	atrribute descriptor.
 */

int configfs_create_bin_file(struct config_item *item,
		const struct configfs_bin_attribute *bin_attr)
{
	struct dentry *dir = item->ci_dentry;
	struct configfs_dirent *parent_sd = dir->d_fsdata;
	umode_t mode = (bin_attr->cb_attr.ca_mode & S_IALLUGO) | S_IFREG;
	int error = 0;

	inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL);
	error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode,
				     CONFIGFS_ITEM_BIN_ATTR);
	inode_unlock(dir->d_inode);

	return error;
}
