#include "sysfs.h"
/*
- * There's one sysfs_buffer for each open file and one sysfs_open_dirent
+ * There's one sysfs_open_file for each open file and one sysfs_open_dirent
* for each sysfs_dirent with one or more open files.
*
* sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open is
* protected by sysfs_open_dirent_lock.
*
- * filp->private_data points to sysfs_buffer which is chained at
- * sysfs_open_dirent->buffers, which is protected by sysfs_open_file_mutex.
+ * filp->private_data points to sysfs_open_file which is chained at
+ * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex.
*/
static DEFINE_SPINLOCK(sysfs_open_dirent_lock);
static DEFINE_MUTEX(sysfs_open_file_mutex);
atomic_t refcnt;
atomic_t event;
wait_queue_head_t poll;
- struct list_head buffers; /* goes through sysfs_buffer.list */
+ struct list_head files; /* goes through sysfs_open_file.list */
};
-struct sysfs_buffer {
+struct sysfs_open_file {
size_t count;
char *page;
struct mutex mutex;
* This is called only once, on the file's first read unless an error
* is returned.
*/
-static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)
+static int fill_read_buffer(struct dentry *dentry, struct sysfs_open_file *of)
{
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
int ret = 0;
ssize_t count;
- if (!buffer->page)
- buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
- if (!buffer->page)
+ if (!of->page)
+ of->page = (char *) get_zeroed_page(GFP_KERNEL);
+ if (!of->page)
return -ENOMEM;
/* need attr_sd for attr and ops, its parent for kobj */
if (!sysfs_get_active(attr_sd))
return -ENODEV;
- buffer->event = atomic_read(&attr_sd->s_attr.open->event);
+ of->event = atomic_read(&attr_sd->s_attr.open->event);
ops = sysfs_file_ops(attr_sd);
- count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
+ count = ops->show(kobj, attr_sd->s_attr.attr, of->page);
sysfs_put_active(attr_sd);
count = PAGE_SIZE - 1;
}
if (count >= 0)
- buffer->count = count;
+ of->count = count;
else
ret = count;
return ret;
static ssize_t
sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
- struct sysfs_buffer *buffer = file->private_data;
+ struct sysfs_open_file *of = file->private_data;
ssize_t retval = 0;
- mutex_lock(&buffer->mutex);
+ mutex_lock(&of->mutex);
/*
* Fill on zero offset and the first read so that silly things like
* "dd bs=1 skip=N" can work on sysfs files.
*/
- if (*ppos == 0 || !buffer->page) {
- retval = fill_read_buffer(file->f_path.dentry, buffer);
+ if (*ppos == 0 || !of->page) {
+ retval = fill_read_buffer(file->f_path.dentry, of);
if (retval)
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);
+ __func__, count, *ppos, of->page);
+ retval = simple_read_from_buffer(buf, count, ppos, of->page, of->count);
out:
- mutex_unlock(&buffer->mutex);
+ mutex_unlock(&of->mutex);
return retval;
}
/**
* fill_write_buffer - copy buffer from userspace.
- * @buffer: data buffer for file.
+ * @of: open file struct.
* @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.
+ * Allocate @of->page if it hasn't been already, then copy the
+ * user-supplied buffer into it.
*/
-static int fill_write_buffer(struct sysfs_buffer *buffer,
+static int fill_write_buffer(struct sysfs_open_file *of,
const char __user *buf, size_t count)
{
int error;
- if (!buffer->page)
- buffer->page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!buffer->page)
+ if (!of->page)
+ of->page = (char *)get_zeroed_page(GFP_KERNEL);
+ if (!of->page)
return -ENOMEM;
if (count >= PAGE_SIZE)
count = PAGE_SIZE - 1;
- error = copy_from_user(buffer->page, buf, count);
+ error = copy_from_user(of->page, buf, count);
/*
* 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;
+ of->page[count] = 0;
return error ? -EFAULT : count;
}
/**
* flush_write_buffer - push buffer to kobject.
* @dentry: dentry to the attribute
- * @buffer: data buffer for file.
+ * @of: open file
* @count: number of bytes
*
* Get the correct pointers for the kobject and the attribute we're
* passing the buffer that we acquired in fill_write_buffer().
*/
static int flush_write_buffer(struct dentry *dentry,
- struct sysfs_buffer *buffer, size_t count)
+ struct sysfs_open_file *of, size_t count)
{
struct sysfs_dirent *attr_sd = dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
return -ENODEV;
ops = sysfs_file_ops(attr_sd);
- rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);
+ rc = ops->store(kobj, attr_sd->s_attr.attr, of->page, count);
sysfs_put_active(attr_sd);
static ssize_t sysfs_write_file(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
- struct sysfs_buffer *buffer = file->private_data;
+ struct sysfs_open_file *of = file->private_data;
ssize_t len;
- mutex_lock(&buffer->mutex);
- len = fill_write_buffer(buffer, buf, count);
+ mutex_lock(&of->mutex);
+ len = fill_write_buffer(of, buf, count);
if (len > 0)
- len = flush_write_buffer(file->f_path.dentry, buffer, len);
+ len = flush_write_buffer(file->f_path.dentry, of, len);
if (len > 0)
*ppos += len;
- mutex_unlock(&buffer->mutex);
+ mutex_unlock(&of->mutex);
return len;
}
/**
* sysfs_get_open_dirent - get or create sysfs_open_dirent
* @sd: target sysfs_dirent
- * @buffer: sysfs_buffer for this instance of open
+ * @of: sysfs_open_file for this instance of open
*
* If @sd->s_attr.open exists, increment its reference count;
- * otherwise, create one. @buffer is chained to the buffers
- * list.
+ * otherwise, create one. @of is chained to the files list.
*
* LOCKING:
* Kernel thread context (may sleep).
* 0 on success, -errno on failure.
*/
static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
- struct sysfs_buffer *buffer)
+ struct sysfs_open_file *of)
{
struct sysfs_open_dirent *od, *new_od = NULL;
od = sd->s_attr.open;
if (od) {
atomic_inc(&od->refcnt);
- list_add_tail(&buffer->list, &od->buffers);
+ list_add_tail(&of->list, &od->files);
}
spin_unlock_irq(&sysfs_open_dirent_lock);
atomic_set(&new_od->refcnt, 0);
atomic_set(&new_od->event, 1);
init_waitqueue_head(&new_od->poll);
- INIT_LIST_HEAD(&new_od->buffers);
+ INIT_LIST_HEAD(&new_od->files);
goto retry;
}
/**
* sysfs_put_open_dirent - put sysfs_open_dirent
* @sd: target sysfs_dirent
- * @buffer: associated sysfs_buffer
+ * @of: associated sysfs_open_file
*
- * Put @sd->s_attr.open and unlink @buffer from the buffers list.
- * If reference count reaches zero, disassociate and free it.
+ * Put @sd->s_attr.open and unlink @of from the files list. If
+ * reference count reaches zero, disassociate and free it.
*
* LOCKING:
* None.
*/
static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
- struct sysfs_buffer *buffer)
+ struct sysfs_open_file *of)
{
struct sysfs_open_dirent *od = sd->s_attr.open;
unsigned long flags;
mutex_lock(&sysfs_open_file_mutex);
spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
- list_del(&buffer->list);
+ list_del(&of->list);
if (atomic_dec_and_test(&od->refcnt))
sd->s_attr.open = NULL;
else
{
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
- struct sysfs_buffer *buffer;
+ struct sysfs_open_file *of;
const struct sysfs_ops *ops;
int error = -EACCES;
goto err_out;
}
- /* No error? Great, allocate a buffer for the file, and store it
- * it in file->private_data for easy access.
+ /*
+ * No error? Great, allocate a sysfs_open_file for the file, and
+ * store it it in file->private_data for easy access.
*/
error = -ENOMEM;
- buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
- if (!buffer)
+ of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
+ if (!of)
goto err_out;
- mutex_init(&buffer->mutex);
- file->private_data = buffer;
+ mutex_init(&of->mutex);
+ file->private_data = of;
/* make sure we have open dirent struct */
- error = sysfs_get_open_dirent(attr_sd, buffer);
+ error = sysfs_get_open_dirent(attr_sd, of);
if (error)
goto err_free;
return 0;
err_free:
- kfree(buffer);
+ kfree(of);
err_out:
sysfs_put_active(attr_sd);
return error;
static int sysfs_release(struct inode *inode, struct file *filp)
{
struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
- struct sysfs_buffer *buffer = filp->private_data;
+ struct sysfs_open_file *of = filp->private_data;
- sysfs_put_open_dirent(sd, buffer);
+ sysfs_put_open_dirent(sd, of);
- if (buffer->page)
- free_page((unsigned long)buffer->page);
- kfree(buffer);
+ if (of->page)
+ free_page((unsigned long)of->page);
+ kfree(of);
return 0;
}
*/
static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
{
- struct sysfs_buffer *buffer = filp->private_data;
+ struct sysfs_open_file *of = filp->private_data;
struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
struct sysfs_open_dirent *od = attr_sd->s_attr.open;
sysfs_put_active(attr_sd);
- if (buffer->event != atomic_read(&od->event))
+ if (of->event != atomic_read(&od->event))
goto trigger;
return DEFAULT_POLLMASK;