aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@engr.sgi.com>2004-12-20 18:37:07 -0800
committerGreg Kroah-Hartman <greg@kroah.com>2004-12-20 18:37:07 -0800
commit9df7c5fcecfa1a0fb844232e3b12d2b4c690741c (patch)
tree97f61befc6661816c566051374dfca59a6053e71 /fs
parentfcf7104e3c6e9a4b2db96204e8f06efbe14cf258 (diff)
downloadhistory-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.c27
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,