diff options
author | Jesse Barnes <jbarnes@engr.sgi.com> | 2004-12-20 18:37:07 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2004-12-20 18:37:07 -0800 |
commit | 9df7c5fcecfa1a0fb844232e3b12d2b4c690741c (patch) | |
tree | 97f61befc6661816c566051374dfca59a6053e71 /fs | |
parent | fcf7104e3c6e9a4b2db96204e8f06efbe14cf258 (diff) | |
download | history-9df7c5fcecfa1a0fb844232e3b12d2b4c690741c.tar.gz |
[PATCH] sysfs: add mmap support to struct bin_attribute files
This patch adds an mmap method and some more error checking to struct
bin_attribute--good for things like exporting PCI resources directly. I
wasn't sure about the return values for the case where an attribute is
missing a given method, and it looks like mm.h can't be included in sysfs.h,
so I had to forward declare struct vm_area_struct. Other than that, it works
fine for my test cases.
Signed-off-by: Jesse Barnes <jbarnes@sgi.com>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/bin.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 1ce077888aec37..d4aaa88d02144b 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 @@ -20,6 +24,9 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) 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); } @@ -63,6 +70,9 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) 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,6 +102,18 @@ 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); @@ -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; @@ -144,6 +166,7 @@ static int release(struct inode * inode, struct file * file) struct file_operations bin_fops = { .read = read, .write = write, + .mmap = mmap, .llseek = generic_file_llseek, .open = open, .release = release, |