diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-27 14:25:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-27 14:25:00 -0400 |
commit | 064922a805ec7aadfafdd27aa6b4908d737c3c1d (patch) | |
tree | 922d058f751964ccf73f5705d7c492b6d45a9425 /fs | |
parent | 42cadc86008aae0fd9ff31642dc01ed50723cf32 (diff) | |
parent | ecc1241e80a0bdc854b1602a44be3ad106753d4f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (40 commits)
[SCSI] jazz_esp, sgiwd93, sni_53c710, sun3x_esp: fix platform driver hotplug/coldplug
[SCSI] aic7xxx: add const
[SCSI] aic7xxx: add static
[SCSI] aic7xxx: Update _shipped files
[SCSI] aic7xxx: teach aicasm to not emit unused debug code/data
[SCSI] qla2xxx: Update version number to 8.02.01-k2.
[SCSI] qla2xxx: Correct regression in relogin code.
[SCSI] qla2xxx: Correct misc. endian and byte-ordering issues.
[SCSI] qla2xxx: make qla2x00_issue_iocb_timeout() static
[SCSI] qla2xxx: qla_os.c, make 2 functions static
[SCSI] qla2xxx: Re-register FDMI information after a LIP.
[SCSI] qla2xxx: Correct SRB usage-after-completion/free issues.
[SCSI] qla2xxx: Correct ISP84XX verify-chip response handling.
[SCSI] qla2xxx: Wakeup DPC thread to process any deferred-work requests.
[SCSI] qla2xxx: Collapse RISC-RAM retrieval code during a firmware-dump.
[SCSI] m68k: new mac_esp scsi driver
[SCSI] zfcp: Add some statistics provided by the FCP adapter to the sysfs
[SCSI] zfcp: Print some messages only during ERP
[SCSI] zfcp: Wait for free SBAL during exchange config
[SCSI] scsi_transport_fc: fc_user_scan correction
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/file.c | 14 | ||||
-rw-r--r-- | fs/sysfs/group.c | 83 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 2 |
3 files changed, 82 insertions, 17 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index ade9a7e6a757..dbdfabbfd609 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -477,11 +477,10 @@ const struct file_operations sysfs_file_operations = { | |||
477 | .poll = sysfs_poll, | 477 | .poll = sysfs_poll, |
478 | }; | 478 | }; |
479 | 479 | ||
480 | 480 | int sysfs_add_file_mode(struct sysfs_dirent *dir_sd, | |
481 | int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, | 481 | const struct attribute *attr, int type, mode_t amode) |
482 | int type) | ||
483 | { | 482 | { |
484 | umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; | 483 | umode_t mode = (amode & S_IALLUGO) | S_IFREG; |
485 | struct sysfs_addrm_cxt acxt; | 484 | struct sysfs_addrm_cxt acxt; |
486 | struct sysfs_dirent *sd; | 485 | struct sysfs_dirent *sd; |
487 | int rc; | 486 | int rc; |
@@ -502,6 +501,13 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, | |||
502 | } | 501 | } |
503 | 502 | ||
504 | 503 | ||
504 | int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, | ||
505 | int type) | ||
506 | { | ||
507 | return sysfs_add_file_mode(dir_sd, attr, type, attr->mode); | ||
508 | } | ||
509 | |||
510 | |||
505 | /** | 511 | /** |
506 | * sysfs_create_file - create an attribute file for an object. | 512 | * sysfs_create_file - create an attribute file for an object. |
507 | * @kobj: object we're creating for. | 513 | * @kobj: object we're creating for. |
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 477904915032..eeba38417b1d 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
@@ -23,35 +23,50 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
23 | int i; | 23 | int i; |
24 | 24 | ||
25 | for (i = 0, attr = grp->attrs; *attr; i++, attr++) | 25 | for (i = 0, attr = grp->attrs; *attr; i++, attr++) |
26 | if (!grp->is_visible || | 26 | sysfs_hash_and_remove(dir_sd, (*attr)->name); |
27 | grp->is_visible(kobj, *attr, i)) | ||
28 | sysfs_hash_and_remove(dir_sd, (*attr)->name); | ||
29 | } | 27 | } |
30 | 28 | ||
31 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 29 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
32 | const struct attribute_group *grp) | 30 | const struct attribute_group *grp, int update) |
33 | { | 31 | { |
34 | struct attribute *const* attr; | 32 | struct attribute *const* attr; |
35 | int error = 0, i; | 33 | int error = 0, i; |
36 | 34 | ||
37 | for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) | 35 | for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { |
38 | if (!grp->is_visible || | 36 | mode_t mode = 0; |
39 | grp->is_visible(kobj, *attr, i)) | 37 | |
40 | error |= | 38 | /* in update mode, we're changing the permissions or |
41 | sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); | 39 | * visibility. Do this by first removing then |
40 | * re-adding (if required) the file */ | ||
41 | if (update) | ||
42 | sysfs_hash_and_remove(dir_sd, (*attr)->name); | ||
43 | if (grp->is_visible) { | ||
44 | mode = grp->is_visible(kobj, *attr, i); | ||
45 | if (!mode) | ||
46 | continue; | ||
47 | } | ||
48 | error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR, | ||
49 | (*attr)->mode | mode); | ||
50 | if (unlikely(error)) | ||
51 | break; | ||
52 | } | ||
42 | if (error) | 53 | if (error) |
43 | remove_files(dir_sd, kobj, grp); | 54 | remove_files(dir_sd, kobj, grp); |
44 | return error; | 55 | return error; |
45 | } | 56 | } |
46 | 57 | ||
47 | 58 | ||
48 | int sysfs_create_group(struct kobject * kobj, | 59 | static int internal_create_group(struct kobject *kobj, int update, |
49 | const struct attribute_group * grp) | 60 | const struct attribute_group *grp) |
50 | { | 61 | { |
51 | struct sysfs_dirent *sd; | 62 | struct sysfs_dirent *sd; |
52 | int error; | 63 | int error; |
53 | 64 | ||
54 | BUG_ON(!kobj || !kobj->sd); | 65 | BUG_ON(!kobj || (!update && !kobj->sd)); |
66 | |||
67 | /* Updates may happen before the object has been instantiated */ | ||
68 | if (unlikely(update && !kobj->sd)) | ||
69 | return -EINVAL; | ||
55 | 70 | ||
56 | if (grp->name) { | 71 | if (grp->name) { |
57 | error = sysfs_create_subdir(kobj, grp->name, &sd); | 72 | error = sysfs_create_subdir(kobj, grp->name, &sd); |
@@ -60,7 +75,7 @@ int sysfs_create_group(struct kobject * kobj, | |||
60 | } else | 75 | } else |
61 | sd = kobj->sd; | 76 | sd = kobj->sd; |
62 | sysfs_get(sd); | 77 | sysfs_get(sd); |
63 | error = create_files(sd, kobj, grp); | 78 | error = create_files(sd, kobj, grp, update); |
64 | if (error) { | 79 | if (error) { |
65 | if (grp->name) | 80 | if (grp->name) |
66 | sysfs_remove_subdir(sd); | 81 | sysfs_remove_subdir(sd); |
@@ -69,6 +84,47 @@ int sysfs_create_group(struct kobject * kobj, | |||
69 | return error; | 84 | return error; |
70 | } | 85 | } |
71 | 86 | ||
87 | /** | ||
88 | * sysfs_create_group - given a directory kobject, create an attribute group | ||
89 | * @kobj: The kobject to create the group on | ||
90 | * @grp: The attribute group to create | ||
91 | * | ||
92 | * This function creates a group for the first time. It will explicitly | ||
93 | * warn and error if any of the attribute files being created already exist. | ||
94 | * | ||
95 | * Returns 0 on success or error. | ||
96 | */ | ||
97 | int sysfs_create_group(struct kobject *kobj, | ||
98 | const struct attribute_group *grp) | ||
99 | { | ||
100 | return internal_create_group(kobj, 0, grp); | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * sysfs_update_group - given a directory kobject, create an attribute group | ||
105 | * @kobj: The kobject to create the group on | ||
106 | * @grp: The attribute group to create | ||
107 | * | ||
108 | * This function updates an attribute group. Unlike | ||
109 | * sysfs_create_group(), it will explicitly not warn or error if any | ||
110 | * of the attribute files being created already exist. Furthermore, | ||
111 | * if the visibility of the files has changed through the is_visible() | ||
112 | * callback, it will update the permissions and add or remove the | ||
113 | * relevant files. | ||
114 | * | ||
115 | * The primary use for this function is to call it after making a change | ||
116 | * that affects group visibility. | ||
117 | * | ||
118 | * Returns 0 on success or error. | ||
119 | */ | ||
120 | int sysfs_update_group(struct kobject *kobj, | ||
121 | const struct attribute_group *grp) | ||
122 | { | ||
123 | return internal_create_group(kobj, 1, grp); | ||
124 | } | ||
125 | |||
126 | |||
127 | |||
72 | void sysfs_remove_group(struct kobject * kobj, | 128 | void sysfs_remove_group(struct kobject * kobj, |
73 | const struct attribute_group * grp) | 129 | const struct attribute_group * grp) |
74 | { | 130 | { |
@@ -95,4 +151,5 @@ void sysfs_remove_group(struct kobject * kobj, | |||
95 | 151 | ||
96 | 152 | ||
97 | EXPORT_SYMBOL_GPL(sysfs_create_group); | 153 | EXPORT_SYMBOL_GPL(sysfs_create_group); |
154 | EXPORT_SYMBOL_GPL(sysfs_update_group); | ||
98 | EXPORT_SYMBOL_GPL(sysfs_remove_group); | 155 | EXPORT_SYMBOL_GPL(sysfs_remove_group); |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index ff17f8da9b43..ce4e15f8aaeb 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -154,6 +154,8 @@ extern const struct file_operations sysfs_file_operations; | |||
154 | int sysfs_add_file(struct sysfs_dirent *dir_sd, | 154 | int sysfs_add_file(struct sysfs_dirent *dir_sd, |
155 | const struct attribute *attr, int type); | 155 | const struct attribute *attr, int type); |
156 | 156 | ||
157 | int sysfs_add_file_mode(struct sysfs_dirent *dir_sd, | ||
158 | const struct attribute *attr, int type, mode_t amode); | ||
157 | /* | 159 | /* |
158 | * bin.c | 160 | * bin.c |
159 | */ | 161 | */ |