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; |