diff options
Diffstat (limited to 'fs/sysfs/file.c')
| -rw-r--r-- | fs/sysfs/file.c | 47 | 
1 files changed, 34 insertions, 13 deletions
| diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index dc30d9e31683..e222b2582746 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
| @@ -53,7 +53,7 @@ struct sysfs_buffer { | |||
| 53 | size_t count; | 53 | size_t count; | 
| 54 | loff_t pos; | 54 | loff_t pos; | 
| 55 | char * page; | 55 | char * page; | 
| 56 | struct sysfs_ops * ops; | 56 | const struct sysfs_ops * ops; | 
| 57 | struct mutex mutex; | 57 | struct mutex mutex; | 
| 58 | int needs_read_fill; | 58 | int needs_read_fill; | 
| 59 | int event; | 59 | int event; | 
| @@ -75,7 +75,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
| 75 | { | 75 | { | 
| 76 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 76 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 
| 77 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 77 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 
| 78 | struct sysfs_ops * ops = buffer->ops; | 78 | const struct sysfs_ops * ops = buffer->ops; | 
| 79 | int ret = 0; | 79 | int ret = 0; | 
| 80 | ssize_t count; | 80 | ssize_t count; | 
| 81 | 81 | ||
| @@ -85,13 +85,13 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
| 85 | return -ENOMEM; | 85 | return -ENOMEM; | 
| 86 | 86 | ||
| 87 | /* need attr_sd for attr and ops, its parent for kobj */ | 87 | /* need attr_sd for attr and ops, its parent for kobj */ | 
| 88 | if (!sysfs_get_active_two(attr_sd)) | 88 | if (!sysfs_get_active(attr_sd)) | 
| 89 | return -ENODEV; | 89 | return -ENODEV; | 
| 90 | 90 | ||
| 91 | buffer->event = atomic_read(&attr_sd->s_attr.open->event); | 91 | buffer->event = atomic_read(&attr_sd->s_attr.open->event); | 
| 92 | count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); | 92 | count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); | 
| 93 | 93 | ||
| 94 | sysfs_put_active_two(attr_sd); | 94 | sysfs_put_active(attr_sd); | 
| 95 | 95 | ||
| 96 | /* | 96 | /* | 
| 97 | * The code works fine with PAGE_SIZE return but it's likely to | 97 | * The code works fine with PAGE_SIZE return but it's likely to | 
| @@ -199,16 +199,16 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t | |||
| 199 | { | 199 | { | 
| 200 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 200 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 
| 201 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 201 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 
| 202 | struct sysfs_ops * ops = buffer->ops; | 202 | const struct sysfs_ops * ops = buffer->ops; | 
| 203 | int rc; | 203 | int rc; | 
| 204 | 204 | ||
| 205 | /* need attr_sd for attr and ops, its parent for kobj */ | 205 | /* need attr_sd for attr and ops, its parent for kobj */ | 
| 206 | if (!sysfs_get_active_two(attr_sd)) | 206 | if (!sysfs_get_active(attr_sd)) | 
| 207 | return -ENODEV; | 207 | return -ENODEV; | 
| 208 | 208 | ||
| 209 | rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); | 209 | rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); | 
| 210 | 210 | ||
| 211 | sysfs_put_active_two(attr_sd); | 211 | sysfs_put_active(attr_sd); | 
| 212 | 212 | ||
| 213 | return rc; | 213 | return rc; | 
| 214 | } | 214 | } | 
| @@ -335,7 +335,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
| 335 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 335 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 
| 336 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 336 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 
| 337 | struct sysfs_buffer *buffer; | 337 | struct sysfs_buffer *buffer; | 
| 338 | struct sysfs_ops *ops; | 338 | const struct sysfs_ops *ops; | 
| 339 | int error = -EACCES; | 339 | int error = -EACCES; | 
| 340 | char *p; | 340 | char *p; | 
| 341 | 341 | ||
| @@ -344,7 +344,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
| 344 | memmove(last_sysfs_file, p, strlen(p) + 1); | 344 | memmove(last_sysfs_file, p, strlen(p) + 1); | 
| 345 | 345 | ||
| 346 | /* need attr_sd for attr and ops, its parent for kobj */ | 346 | /* need attr_sd for attr and ops, its parent for kobj */ | 
| 347 | if (!sysfs_get_active_two(attr_sd)) | 347 | if (!sysfs_get_active(attr_sd)) | 
| 348 | return -ENODEV; | 348 | return -ENODEV; | 
| 349 | 349 | ||
| 350 | /* every kobject with an attribute needs a ktype assigned */ | 350 | /* every kobject with an attribute needs a ktype assigned */ | 
| @@ -393,13 +393,13 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
| 393 | goto err_free; | 393 | goto err_free; | 
| 394 | 394 | ||
| 395 | /* open succeeded, put active references */ | 395 | /* open succeeded, put active references */ | 
| 396 | sysfs_put_active_two(attr_sd); | 396 | sysfs_put_active(attr_sd); | 
| 397 | return 0; | 397 | return 0; | 
| 398 | 398 | ||
| 399 | err_free: | 399 | err_free: | 
| 400 | kfree(buffer); | 400 | kfree(buffer); | 
| 401 | err_out: | 401 | err_out: | 
| 402 | sysfs_put_active_two(attr_sd); | 402 | sysfs_put_active(attr_sd); | 
| 403 | return error; | 403 | return error; | 
| 404 | } | 404 | } | 
| 405 | 405 | ||
| @@ -437,12 +437,12 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | |||
| 437 | struct sysfs_open_dirent *od = attr_sd->s_attr.open; | 437 | struct sysfs_open_dirent *od = attr_sd->s_attr.open; | 
| 438 | 438 | ||
| 439 | /* need parent for the kobj, grab both */ | 439 | /* need parent for the kobj, grab both */ | 
| 440 | if (!sysfs_get_active_two(attr_sd)) | 440 | if (!sysfs_get_active(attr_sd)) | 
| 441 | goto trigger; | 441 | goto trigger; | 
| 442 | 442 | ||
| 443 | poll_wait(filp, &od->poll, wait); | 443 | poll_wait(filp, &od->poll, wait); | 
| 444 | 444 | ||
| 445 | sysfs_put_active_two(attr_sd); | 445 | sysfs_put_active(attr_sd); | 
| 446 | 446 | ||
| 447 | if (buffer->event != atomic_read(&od->event)) | 447 | if (buffer->event != atomic_read(&od->event)) | 
| 448 | goto trigger; | 448 | goto trigger; | 
| @@ -509,6 +509,7 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd, | |||
| 509 | if (!sd) | 509 | if (!sd) | 
| 510 | return -ENOMEM; | 510 | return -ENOMEM; | 
| 511 | sd->s_attr.attr = (void *)attr; | 511 | sd->s_attr.attr = (void *)attr; | 
| 512 | sysfs_dirent_init_lockdep(sd); | ||
| 512 | 513 | ||
| 513 | sysfs_addrm_start(&acxt, dir_sd); | 514 | sysfs_addrm_start(&acxt, dir_sd); | 
| 514 | rc = sysfs_add_one(&acxt, sd); | 515 | rc = sysfs_add_one(&acxt, sd); | 
| @@ -542,6 +543,18 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) | |||
| 542 | 543 | ||
| 543 | } | 544 | } | 
| 544 | 545 | ||
| 546 | int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) | ||
| 547 | { | ||
| 548 | int err = 0; | ||
| 549 | int i; | ||
| 550 | |||
| 551 | for (i = 0; ptr[i] && !err; i++) | ||
| 552 | err = sysfs_create_file(kobj, ptr[i]); | ||
| 553 | if (err) | ||
| 554 | while (--i >= 0) | ||
| 555 | sysfs_remove_file(kobj, ptr[i]); | ||
| 556 | return err; | ||
| 557 | } | ||
| 545 | 558 | ||
| 546 | /** | 559 | /** | 
| 547 | * sysfs_add_file_to_group - add an attribute file to a pre-existing group. | 560 | * sysfs_add_file_to_group - add an attribute file to a pre-existing group. | 
| @@ -614,6 +627,12 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) | |||
| 614 | sysfs_hash_and_remove(kobj->sd, attr->name); | 627 | sysfs_hash_and_remove(kobj->sd, attr->name); | 
| 615 | } | 628 | } | 
| 616 | 629 | ||
| 630 | void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) | ||
| 631 | { | ||
| 632 | int i; | ||
| 633 | for (i = 0; ptr[i]; i++) | ||
| 634 | sysfs_remove_file(kobj, ptr[i]); | ||
| 635 | } | ||
| 617 | 636 | ||
| 618 | /** | 637 | /** | 
| 619 | * sysfs_remove_file_from_group - remove an attribute file from a group. | 638 | * sysfs_remove_file_from_group - remove an attribute file from a group. | 
| @@ -732,3 +751,5 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | |||
| 732 | 751 | ||
| 733 | EXPORT_SYMBOL_GPL(sysfs_create_file); | 752 | EXPORT_SYMBOL_GPL(sysfs_create_file); | 
| 734 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | 753 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | 
| 754 | EXPORT_SYMBOL_GPL(sysfs_remove_files); | ||
| 755 | EXPORT_SYMBOL_GPL(sysfs_create_files); | ||
