aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r--fs/sysfs/file.c65
1 files changed, 13 insertions, 52 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 310430baf572..d673d9b5d33f 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -50,29 +50,15 @@ static struct sysfs_ops subsys_sysfs_ops = {
50 .store = subsys_attr_store, 50 .store = subsys_attr_store,
51}; 51};
52 52
53/** 53struct sysfs_buffer {
54 * add_to_collection - add buffer to a collection 54 size_t count;
55 * @buffer: buffer to be added 55 loff_t pos;
56 * @node: inode of set to add to 56 char * page;
57 */ 57 struct sysfs_ops * ops;
58 58 struct semaphore sem;
59static inline void 59 int needs_read_fill;
60add_to_collection(struct sysfs_buffer *buffer, struct inode *node) 60 int event;
61{ 61};
62 struct sysfs_buffer_collection *set = node->i_private;
63
64 mutex_lock(&node->i_mutex);
65 list_add(&buffer->associates, &set->associates);
66 mutex_unlock(&node->i_mutex);
67}
68
69static inline void
70remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
71{
72 mutex_lock(&node->i_mutex);
73 list_del(&buffer->associates);
74 mutex_unlock(&node->i_mutex);
75}
76 62
77/** 63/**
78 * fill_read_buffer - allocate and fill buffer from object. 64 * fill_read_buffer - allocate and fill buffer from object.
@@ -144,10 +130,7 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
144 130
145 down(&buffer->sem); 131 down(&buffer->sem);
146 if (buffer->needs_read_fill) { 132 if (buffer->needs_read_fill) {
147 if (buffer->orphaned) 133 retval = fill_read_buffer(file->f_path.dentry,buffer);
148 retval = -ENODEV;
149 else
150 retval = fill_read_buffer(file->f_path.dentry,buffer);
151 if (retval) 134 if (retval)
152 goto out; 135 goto out;
153 } 136 }
@@ -246,16 +229,11 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
246 ssize_t len; 229 ssize_t len;
247 230
248 down(&buffer->sem); 231 down(&buffer->sem);
249 if (buffer->orphaned) {
250 len = -ENODEV;
251 goto out;
252 }
253 len = fill_write_buffer(buffer, buf, count); 232 len = fill_write_buffer(buffer, buf, count);
254 if (len > 0) 233 if (len > 0)
255 len = flush_write_buffer(file->f_path.dentry, buffer, len); 234 len = flush_write_buffer(file->f_path.dentry, buffer, len);
256 if (len > 0) 235 if (len > 0)
257 *ppos += len; 236 *ppos += len;
258out:
259 up(&buffer->sem); 237 up(&buffer->sem);
260 return len; 238 return len;
261} 239}
@@ -265,7 +243,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
265 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 243 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
266 struct attribute *attr = attr_sd->s_elem.attr.attr; 244 struct attribute *attr = attr_sd->s_elem.attr.attr;
267 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 245 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
268 struct sysfs_buffer_collection *set;
269 struct sysfs_buffer * buffer; 246 struct sysfs_buffer * buffer;
270 struct sysfs_ops * ops = NULL; 247 struct sysfs_ops * ops = NULL;
271 int error; 248 int error;
@@ -289,26 +266,14 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
289 else 266 else
290 ops = &subsys_sysfs_ops; 267 ops = &subsys_sysfs_ops;
291 268
269 error = -EACCES;
270
292 /* No sysfs operations, either from having no subsystem, 271 /* No sysfs operations, either from having no subsystem,
293 * or the subsystem have no operations. 272 * or the subsystem have no operations.
294 */ 273 */
295 error = -EACCES;
296 if (!ops) 274 if (!ops)
297 goto err_mput; 275 goto err_mput;
298 276
299 /* make sure we have a collection to add our buffers to */
300 mutex_lock(&inode->i_mutex);
301 if (!(set = inode->i_private)) {
302 error = -ENOMEM;
303 if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL)))
304 goto err_mput;
305 else
306 INIT_LIST_HEAD(&set->associates);
307 }
308 mutex_unlock(&inode->i_mutex);
309
310 error = -EACCES;
311
312 /* File needs write support. 277 /* File needs write support.
313 * The inode's perms must say it's ok, 278 * The inode's perms must say it's ok,
314 * and we must have a store method. 279 * and we must have a store method.
@@ -335,11 +300,9 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
335 if (!buffer) 300 if (!buffer)
336 goto err_mput; 301 goto err_mput;
337 302
338 INIT_LIST_HEAD(&buffer->associates);
339 init_MUTEX(&buffer->sem); 303 init_MUTEX(&buffer->sem);
340 buffer->needs_read_fill = 1; 304 buffer->needs_read_fill = 1;
341 buffer->ops = ops; 305 buffer->ops = ops;
342 add_to_collection(buffer, inode);
343 file->private_data = buffer; 306 file->private_data = buffer;
344 307
345 /* open succeeded, put active references and pin attr_sd */ 308 /* open succeeded, put active references and pin attr_sd */
@@ -358,10 +321,8 @@ static int sysfs_release(struct inode * inode, struct file * filp)
358{ 321{
359 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; 322 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
360 struct attribute *attr = attr_sd->s_elem.attr.attr; 323 struct attribute *attr = attr_sd->s_elem.attr.attr;
361 struct sysfs_buffer * buffer = filp->private_data; 324 struct sysfs_buffer *buffer = filp->private_data;
362 325
363 if (buffer)
364 remove_from_collection(buffer, inode);
365 sysfs_put(attr_sd); 326 sysfs_put(attr_sd);
366 /* After this point, attr should not be accessed. */ 327 /* After this point, attr should not be accessed. */
367 module_put(attr->owner); 328 module_put(attr->owner);