X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fsysfs%2Fbin.c;h=d4aaa88d02144b4f6618d8f79dbd76aea6efe16a;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=d455725102fbdba786ac255a943e910bdd078331;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index d45572510..d4aaa88d0 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -1,5 +1,9 @@ /* * bin.c - binary file operations for sysfs. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Matthew Wilcox + * Copyright (c) 2004 Silicon Graphics, Inc. */ #undef DEBUG @@ -17,8 +21,11 @@ static int fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) { - struct bin_attribute * attr = dentry->d_fsdata; - struct kobject * kobj = dentry->d_parent->d_fsdata; + struct bin_attribute * attr = to_bin_attr(dentry); + struct kobject * kobj = to_kobj(dentry->d_parent); + + if (!attr->read) + return -EINVAL; return attr->read(kobj, buffer, off, count); } @@ -60,8 +67,11 @@ read(struct file * file, char __user * userbuf, size_t count, loff_t * off) static int flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) { - struct bin_attribute *attr = dentry->d_fsdata; - struct kobject *kobj = dentry->d_parent->d_fsdata; + struct bin_attribute *attr = to_bin_attr(dentry); + struct kobject *kobj = to_kobj(dentry->d_parent); + + if (!attr->write) + return -EINVAL; return attr->write(kobj, buffer, offset, count); } @@ -92,10 +102,22 @@ static ssize_t write(struct file * file, const char __user * userbuf, return count; } +static int mmap(struct file *file, struct vm_area_struct *vma) +{ + struct dentry *dentry = file->f_dentry; + struct bin_attribute *attr = to_bin_attr(dentry); + struct kobject *kobj = to_kobj(dentry->d_parent); + + if (!attr->mmap) + return -EINVAL; + + return attr->mmap(kobj, attr, vma); +} + static int open(struct inode * inode, struct file * file) { struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent); - struct bin_attribute * attr = file->f_dentry->d_fsdata; + struct bin_attribute * attr = to_bin_attr(file->f_dentry); int error = -EINVAL; if (!kobj || !attr) @@ -107,9 +129,9 @@ static int open(struct inode * inode, struct file * file) goto Done; error = -EACCES; - if ((file->f_mode & FMODE_WRITE) && !attr->write) + if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap)) goto Error; - if ((file->f_mode & FMODE_READ) && !attr->read) + if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap)) goto Error; error = -ENOMEM; @@ -130,8 +152,8 @@ static int open(struct inode * inode, struct file * file) static int release(struct inode * inode, struct file * file) { - struct kobject * kobj = file->f_dentry->d_parent->d_fsdata; - struct bin_attribute * attr = file->f_dentry->d_fsdata; + struct kobject * kobj = to_kobj(file->f_dentry->d_parent); + struct bin_attribute * attr = to_bin_attr(file->f_dentry); u8 * buffer = file->private_data; if (kobj) @@ -141,9 +163,10 @@ static int release(struct inode * inode, struct file * file) return 0; } -static struct file_operations bin_fops = { +struct file_operations bin_fops = { .read = read, .write = write, + .mmap = mmap, .llseek = generic_file_llseek, .open = open, .release = release, @@ -158,31 +181,9 @@ static struct file_operations bin_fops = { int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr) { - struct dentry * dentry; - struct dentry * parent; - int error = 0; + BUG_ON(!kobj || !kobj->dentry || !attr); - if (!kobj || !attr) - return -EINVAL; - - parent = kobj->dentry; - - down(&parent->d_inode->i_sem); - dentry = sysfs_get_dentry(parent,attr->attr.name); - if (!IS_ERR(dentry)) { - dentry->d_fsdata = (void *)attr; - error = sysfs_create(dentry, - (attr->attr.mode & S_IALLUGO) | S_IFREG, - NULL); - if (!error) { - dentry->d_inode->i_size = attr->size; - dentry->d_inode->i_fop = &bin_fops; - } - dput(dentry); - } else - error = PTR_ERR(dentry); - up(&parent->d_inode->i_sem); - return error; + return sysfs_add_file(kobj->dentry, &attr->attr, SYSFS_KOBJ_BIN_ATTR); } @@ -199,5 +200,5 @@ int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr) return 0; } -EXPORT_SYMBOL(sysfs_create_bin_file); -EXPORT_SYMBOL(sysfs_remove_bin_file); +EXPORT_SYMBOL_GPL(sysfs_create_bin_file); +EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);