diff options
Diffstat (limited to 'fs/sysfs/bin.c')
| -rw-r--r-- | fs/sysfs/bin.c | 259 |
1 files changed, 0 insertions, 259 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c deleted file mode 100644 index 006fc64227d..00000000000 --- a/fs/sysfs/bin.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * fs/sysfs/bin.c - sysfs binary file implementation - * - * Copyright (c) 2003 Patrick Mochel - * Copyright (c) 2003 Matthew Wilcox - * Copyright (c) 2004 Silicon Graphics, Inc. - * Copyright (c) 2007 SUSE Linux Products GmbH - * Copyright (c) 2007 Tejun Heo <teheo@suse.de> - * - * This file is released under the GPLv2. - * - * Please see Documentation/filesystems/sysfs.txt for more information. - */ - -#undef DEBUG - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/kobject.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -#include <asm/uaccess.h> - -#include "sysfs.h" - -struct bin_buffer { - struct mutex mutex; - void *buffer; - int mmapped; -}; - -static int -fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) -{ - struct sysfs_dirent *attr_sd = dentry->d_fsdata; - struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; - struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; - int rc; - - /* need attr_sd for attr, its parent for kobj */ - if (!sysfs_get_active_two(attr_sd)) - return -ENODEV; - - rc = -EIO; - if (attr->read) - rc = attr->read(kobj, attr, buffer, off, count); - - sysfs_put_active_two(attr_sd); - - return rc; -} - -static ssize_t -read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) -{ - struct bin_buffer *bb = file->private_data; - struct dentry *dentry = file->f_path.dentry; - int size = dentry->d_inode->i_size; - loff_t offs = *off; - int count = min_t(size_t, bytes, PAGE_SIZE); - - if (size) { - if (offs > size) - return 0; - if (offs + count > size) - count = size - offs; - } - - mutex_lock(&bb->mutex); - - count = fill_read(dentry, bb->buffer, offs, count); - if (count < 0) - goto out_unlock; - - if (copy_to_user(userbuf, bb->buffer, count)) { - count = -EFAULT; - goto out_unlock; - } - - pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count); - - *off = offs + count; - - out_unlock: - mutex_unlock(&bb->mutex); - return count; -} - -static int -flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) -{ - struct sysfs_dirent *attr_sd = dentry->d_fsdata; - struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; - struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; - int rc; - - /* need attr_sd for attr, its parent for kobj */ - if (!sysfs_get_active_two(attr_sd)) - return -ENODEV; - - rc = -EIO; - if (attr->write) - rc = attr->write(kobj, attr, buffer, offset, count); - - sysfs_put_active_two(attr_sd); - - return rc; -} - -static ssize_t write(struct file *file, const char __user *userbuf, - size_t bytes, loff_t *off) -{ - struct bin_buffer *bb = file->private_data; - struct dentry *dentry = file->f_path.dentry; - int size = dentry->d_inode->i_size; - loff_t offs = *off; - int count = min_t(size_t, bytes, PAGE_SIZE); - - if (size) { - if (offs > size) - return 0; - if (offs + count > size) - count = size - offs; - } - - mutex_lock(&bb->mutex); - - if (copy_from_user(bb->buffer, userbuf, count)) { - count = -EFAULT; - goto out_unlock; - } - - count = flush_write(dentry, bb->buffer, offs, count); - if (count > 0) - *off = offs + count; - - out_unlock: - mutex_unlock(&bb->mutex); - return count; -} - -static int mmap(struct file *file, struct vm_area_struct *vma) -{ - struct bin_buffer *bb = file->private_data; - struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; - struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; - struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; - int rc; - - mutex_lock(&bb->mutex); - - /* need attr_sd for attr, its parent for kobj */ - if (!sysfs_get_active_two(attr_sd)) - return -ENODEV; - - rc = -EINVAL; - if (attr->mmap) - rc = attr->mmap(kobj, attr, vma); - - if (rc == 0 && !bb->mmapped) - bb->mmapped = 1; - else - sysfs_put_active_two(attr_sd); - - mutex_unlock(&bb->mutex); - - return rc; -} - -static int open(struct inode * inode, struct file * file) -{ - struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; - struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; - struct bin_buffer *bb = NULL; - int error; - - /* binary file operations requires both @sd and its parent */ - if (!sysfs_get_active_two(attr_sd)) - return -ENODEV; - - error = -EACCES; - if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap)) - goto err_out; - if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap)) - goto err_out; - - error = -ENOMEM; - bb = kzalloc(sizeof(*bb), GFP_KERNEL); - if (!bb) - goto err_out; - - bb->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!bb->buffer) - goto err_out; - - mutex_init(&bb->mutex); - file->private_data = bb; - - /* open succeeded, put active references */ - sysfs_put_active_two(attr_sd); - return 0; - - err_out: - sysfs_put_active_two(attr_sd); - kfree(bb); - return error; -} - -static int release(struct inode * inode, struct file * file) -{ - struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; - struct bin_buffer *bb = file->private_data; - - if (bb->mmapped) - sysfs_put_active_two(attr_sd); - kfree(bb->buffer); - kfree(bb); - return 0; -} - -const struct file_operations bin_fops = { - .read = read, - .write = write, - .mmap = mmap, - .llseek = generic_file_llseek, - .open = open, - .release = release, -}; - -/** - * sysfs_create_bin_file - create binary file for object. - * @kobj: object. - * @attr: attribute descriptor. - */ - -int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr) -{ - BUG_ON(!kobj || !kobj->sd || !attr); - - return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR); -} - - -/** - * sysfs_remove_bin_file - remove binary file for object. - * @kobj: object. - * @attr: attribute descriptor. - */ - -void sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr) -{ - sysfs_hash_and_remove(kobj->sd, attr->attr.name); -} - -EXPORT_SYMBOL_GPL(sysfs_create_bin_file); -EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); |
