diff options
Diffstat (limited to 'fs/sysfs/bin.c')
| -rw-r--r-- | fs/sysfs/bin.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 5afe2a26f5d8..006fc64227dd 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
| @@ -1,9 +1,15 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * bin.c - binary file operations for sysfs. | 2 | * fs/sysfs/bin.c - sysfs binary file implementation |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2003 Patrick Mochel | 4 | * Copyright (c) 2003 Patrick Mochel |
| 5 | * Copyright (c) 2003 Matthew Wilcox | 5 | * Copyright (c) 2003 Matthew Wilcox |
| 6 | * Copyright (c) 2004 Silicon Graphics, Inc. | 6 | * Copyright (c) 2004 Silicon Graphics, Inc. |
| 7 | * Copyright (c) 2007 SUSE Linux Products GmbH | ||
| 8 | * Copyright (c) 2007 Tejun Heo <teheo@suse.de> | ||
| 9 | * | ||
| 10 | * This file is released under the GPLv2. | ||
| 11 | * | ||
| 12 | * Please see Documentation/filesystems/sysfs.txt for more information. | ||
| 7 | */ | 13 | */ |
| 8 | 14 | ||
| 9 | #undef DEBUG | 15 | #undef DEBUG |
| @@ -14,9 +20,9 @@ | |||
| 14 | #include <linux/kobject.h> | 20 | #include <linux/kobject.h> |
| 15 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 16 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/mutex.h> | ||
| 17 | 24 | ||
| 18 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 19 | #include <asm/semaphore.h> | ||
| 20 | 26 | ||
| 21 | #include "sysfs.h" | 27 | #include "sysfs.h" |
| 22 | 28 | ||
| @@ -30,8 +36,8 @@ static int | |||
| 30 | fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) | 36 | fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) |
| 31 | { | 37 | { |
| 32 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 38 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; |
| 33 | struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; | 39 | struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; |
| 34 | struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; | 40 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
| 35 | int rc; | 41 | int rc; |
| 36 | 42 | ||
| 37 | /* need attr_sd for attr, its parent for kobj */ | 43 | /* need attr_sd for attr, its parent for kobj */ |
| @@ -87,8 +93,8 @@ static int | |||
| 87 | flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) | 93 | flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) |
| 88 | { | 94 | { |
| 89 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 95 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; |
| 90 | struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; | 96 | struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; |
| 91 | struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; | 97 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
| 92 | int rc; | 98 | int rc; |
| 93 | 99 | ||
| 94 | /* need attr_sd for attr, its parent for kobj */ | 100 | /* need attr_sd for attr, its parent for kobj */ |
| @@ -140,8 +146,8 @@ static int mmap(struct file *file, struct vm_area_struct *vma) | |||
| 140 | { | 146 | { |
| 141 | struct bin_buffer *bb = file->private_data; | 147 | struct bin_buffer *bb = file->private_data; |
| 142 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 148 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 143 | struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; | 149 | struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; |
| 144 | struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; | 150 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
| 145 | int rc; | 151 | int rc; |
| 146 | 152 | ||
| 147 | mutex_lock(&bb->mutex); | 153 | mutex_lock(&bb->mutex); |
| @@ -167,12 +173,12 @@ static int mmap(struct file *file, struct vm_area_struct *vma) | |||
| 167 | static int open(struct inode * inode, struct file * file) | 173 | static int open(struct inode * inode, struct file * file) |
| 168 | { | 174 | { |
| 169 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 175 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
| 170 | struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; | 176 | struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; |
| 171 | struct bin_buffer *bb = NULL; | 177 | struct bin_buffer *bb = NULL; |
| 172 | int error; | 178 | int error; |
| 173 | 179 | ||
| 174 | /* need attr_sd for attr */ | 180 | /* binary file operations requires both @sd and its parent */ |
| 175 | if (!sysfs_get_active(attr_sd)) | 181 | if (!sysfs_get_active_two(attr_sd)) |
| 176 | return -ENODEV; | 182 | return -ENODEV; |
| 177 | 183 | ||
| 178 | error = -EACCES; | 184 | error = -EACCES; |
| @@ -193,13 +199,12 @@ static int open(struct inode * inode, struct file * file) | |||
| 193 | mutex_init(&bb->mutex); | 199 | mutex_init(&bb->mutex); |
| 194 | file->private_data = bb; | 200 | file->private_data = bb; |
| 195 | 201 | ||
| 196 | /* open succeeded, put active reference and pin attr_sd */ | 202 | /* open succeeded, put active references */ |
| 197 | sysfs_put_active(attr_sd); | 203 | sysfs_put_active_two(attr_sd); |
| 198 | sysfs_get(attr_sd); | ||
| 199 | return 0; | 204 | return 0; |
| 200 | 205 | ||
| 201 | err_out: | 206 | err_out: |
| 202 | sysfs_put_active(attr_sd); | 207 | sysfs_put_active_two(attr_sd); |
| 203 | kfree(bb); | 208 | kfree(bb); |
| 204 | return error; | 209 | return error; |
| 205 | } | 210 | } |
| @@ -211,7 +216,6 @@ static int release(struct inode * inode, struct file * file) | |||
| 211 | 216 | ||
| 212 | if (bb->mmapped) | 217 | if (bb->mmapped) |
| 213 | sysfs_put_active_two(attr_sd); | 218 | sysfs_put_active_two(attr_sd); |
| 214 | sysfs_put(attr_sd); | ||
| 215 | kfree(bb->buffer); | 219 | kfree(bb->buffer); |
| 216 | kfree(bb); | 220 | kfree(bb); |
| 217 | return 0; | 221 | return 0; |
