diff options
author | Michal Marek <mmarek@suse.cz> | 2010-08-04 07:59:13 -0400 |
---|---|---|
committer | Michal Marek <mmarek@suse.cz> | 2010-08-04 07:59:13 -0400 |
commit | 772320e84588dcbe1600ffb83e5f328f2209ac2a (patch) | |
tree | a7de21b79340aeaa17c58126f6b801b82c77b53a /fs/sysfs/file.c | |
parent | 1ce53adf13a54375d2a5c7cdbe341b2558389615 (diff) | |
parent | 9fe6206f400646a2322096b56c59891d530e8d51 (diff) |
Merge commit 'v2.6.35' into kbuild/kbuild
Conflicts:
arch/powerpc/Makefile
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r-- | fs/sysfs/file.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index dc30d9e31683..1beaa739d0a6 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; |
@@ -478,9 +478,12 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr) | |||
478 | mutex_lock(&sysfs_mutex); | 478 | mutex_lock(&sysfs_mutex); |
479 | 479 | ||
480 | if (sd && dir) | 480 | if (sd && dir) |
481 | sd = sysfs_find_dirent(sd, dir); | 481 | /* Only directories are tagged, so no need to pass |
482 | * a tag explicitly. | ||
483 | */ | ||
484 | sd = sysfs_find_dirent(sd, NULL, dir); | ||
482 | if (sd && attr) | 485 | if (sd && attr) |
483 | sd = sysfs_find_dirent(sd, attr); | 486 | sd = sysfs_find_dirent(sd, NULL, attr); |
484 | if (sd) | 487 | if (sd) |
485 | sysfs_notify_dirent(sd); | 488 | sysfs_notify_dirent(sd); |
486 | 489 | ||
@@ -509,6 +512,7 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd, | |||
509 | if (!sd) | 512 | if (!sd) |
510 | return -ENOMEM; | 513 | return -ENOMEM; |
511 | sd->s_attr.attr = (void *)attr; | 514 | sd->s_attr.attr = (void *)attr; |
515 | sysfs_dirent_init_lockdep(sd); | ||
512 | 516 | ||
513 | sysfs_addrm_start(&acxt, dir_sd); | 517 | sysfs_addrm_start(&acxt, dir_sd); |
514 | rc = sysfs_add_one(&acxt, sd); | 518 | rc = sysfs_add_one(&acxt, sd); |
@@ -542,6 +546,18 @@ int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) | |||
542 | 546 | ||
543 | } | 547 | } |
544 | 548 | ||
549 | int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) | ||
550 | { | ||
551 | int err = 0; | ||
552 | int i; | ||
553 | |||
554 | for (i = 0; ptr[i] && !err; i++) | ||
555 | err = sysfs_create_file(kobj, ptr[i]); | ||
556 | if (err) | ||
557 | while (--i >= 0) | ||
558 | sysfs_remove_file(kobj, ptr[i]); | ||
559 | return err; | ||
560 | } | ||
545 | 561 | ||
546 | /** | 562 | /** |
547 | * sysfs_add_file_to_group - add an attribute file to a pre-existing group. | 563 | * sysfs_add_file_to_group - add an attribute file to a pre-existing group. |
@@ -556,7 +572,7 @@ int sysfs_add_file_to_group(struct kobject *kobj, | |||
556 | int error; | 572 | int error; |
557 | 573 | ||
558 | if (group) | 574 | if (group) |
559 | dir_sd = sysfs_get_dirent(kobj->sd, group); | 575 | dir_sd = sysfs_get_dirent(kobj->sd, NULL, group); |
560 | else | 576 | else |
561 | dir_sd = sysfs_get(kobj->sd); | 577 | dir_sd = sysfs_get(kobj->sd); |
562 | 578 | ||
@@ -586,7 +602,7 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
586 | mutex_lock(&sysfs_mutex); | 602 | mutex_lock(&sysfs_mutex); |
587 | 603 | ||
588 | rc = -ENOENT; | 604 | rc = -ENOENT; |
589 | sd = sysfs_find_dirent(kobj->sd, attr->name); | 605 | sd = sysfs_find_dirent(kobj->sd, NULL, attr->name); |
590 | if (!sd) | 606 | if (!sd) |
591 | goto out; | 607 | goto out; |
592 | 608 | ||
@@ -611,9 +627,15 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file); | |||
611 | 627 | ||
612 | void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) | 628 | void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) |
613 | { | 629 | { |
614 | sysfs_hash_and_remove(kobj->sd, attr->name); | 630 | sysfs_hash_and_remove(kobj->sd, NULL, attr->name); |
615 | } | 631 | } |
616 | 632 | ||
633 | void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) | ||
634 | { | ||
635 | int i; | ||
636 | for (i = 0; ptr[i]; i++) | ||
637 | sysfs_remove_file(kobj, ptr[i]); | ||
638 | } | ||
617 | 639 | ||
618 | /** | 640 | /** |
619 | * sysfs_remove_file_from_group - remove an attribute file from a group. | 641 | * sysfs_remove_file_from_group - remove an attribute file from a group. |
@@ -627,11 +649,11 @@ void sysfs_remove_file_from_group(struct kobject *kobj, | |||
627 | struct sysfs_dirent *dir_sd; | 649 | struct sysfs_dirent *dir_sd; |
628 | 650 | ||
629 | if (group) | 651 | if (group) |
630 | dir_sd = sysfs_get_dirent(kobj->sd, group); | 652 | dir_sd = sysfs_get_dirent(kobj->sd, NULL, group); |
631 | else | 653 | else |
632 | dir_sd = sysfs_get(kobj->sd); | 654 | dir_sd = sysfs_get(kobj->sd); |
633 | if (dir_sd) { | 655 | if (dir_sd) { |
634 | sysfs_hash_and_remove(dir_sd, attr->name); | 656 | sysfs_hash_and_remove(dir_sd, NULL, attr->name); |
635 | sysfs_put(dir_sd); | 657 | sysfs_put(dir_sd); |
636 | } | 658 | } |
637 | } | 659 | } |
@@ -732,3 +754,5 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | |||
732 | 754 | ||
733 | EXPORT_SYMBOL_GPL(sysfs_create_file); | 755 | EXPORT_SYMBOL_GPL(sysfs_create_file); |
734 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | 756 | EXPORT_SYMBOL_GPL(sysfs_remove_file); |
757 | EXPORT_SYMBOL_GPL(sysfs_remove_files); | ||
758 | EXPORT_SYMBOL_GPL(sysfs_create_files); | ||