diff options
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r-- | fs/sysfs/file.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 589abee16a39..4ad3721a991c 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -184,6 +184,17 @@ static const struct kernfs_ops sysfs_file_kfops_rw = { | |||
184 | .write = sysfs_kf_write, | 184 | .write = sysfs_kf_write, |
185 | }; | 185 | }; |
186 | 186 | ||
187 | static const struct kernfs_ops sysfs_prealloc_kfops_wo = { | ||
188 | .write = sysfs_kf_write, | ||
189 | .prealloc = true, | ||
190 | }; | ||
191 | |||
192 | static const struct kernfs_ops sysfs_prealloc_kfops_rw = { | ||
193 | .seq_show = sysfs_kf_seq_show, | ||
194 | .write = sysfs_kf_write, | ||
195 | .prealloc = true, | ||
196 | }; | ||
197 | |||
187 | static const struct kernfs_ops sysfs_bin_kfops_ro = { | 198 | static const struct kernfs_ops sysfs_bin_kfops_ro = { |
188 | .read = sysfs_kf_bin_read, | 199 | .read = sysfs_kf_bin_read, |
189 | }; | 200 | }; |
@@ -222,13 +233,19 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, | |||
222 | kobject_name(kobj))) | 233 | kobject_name(kobj))) |
223 | return -EINVAL; | 234 | return -EINVAL; |
224 | 235 | ||
225 | if (sysfs_ops->show && sysfs_ops->store) | 236 | if (sysfs_ops->show && sysfs_ops->store) { |
226 | ops = &sysfs_file_kfops_rw; | 237 | if (mode & SYSFS_PREALLOC) |
227 | else if (sysfs_ops->show) | 238 | ops = &sysfs_prealloc_kfops_rw; |
239 | else | ||
240 | ops = &sysfs_file_kfops_rw; | ||
241 | } else if (sysfs_ops->show) | ||
228 | ops = &sysfs_file_kfops_ro; | 242 | ops = &sysfs_file_kfops_ro; |
229 | else if (sysfs_ops->store) | 243 | else if (sysfs_ops->store) { |
230 | ops = &sysfs_file_kfops_wo; | 244 | if (mode & SYSFS_PREALLOC) |
231 | else | 245 | ops = &sysfs_prealloc_kfops_wo; |
246 | else | ||
247 | ops = &sysfs_file_kfops_wo; | ||
248 | } else | ||
232 | ops = &sysfs_file_kfops_empty; | 249 | ops = &sysfs_file_kfops_empty; |
233 | 250 | ||
234 | size = PAGE_SIZE; | 251 | size = PAGE_SIZE; |
@@ -253,7 +270,7 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent, | |||
253 | if (!attr->ignore_lockdep) | 270 | if (!attr->ignore_lockdep) |
254 | key = attr->key ?: (struct lock_class_key *)&attr->skey; | 271 | key = attr->key ?: (struct lock_class_key *)&attr->skey; |
255 | #endif | 272 | #endif |
256 | kn = __kernfs_create_file(parent, attr->name, mode, size, ops, | 273 | kn = __kernfs_create_file(parent, attr->name, mode & 0777, size, ops, |
257 | (void *)attr, ns, true, key); | 274 | (void *)attr, ns, true, key); |
258 | if (IS_ERR(kn)) { | 275 | if (IS_ERR(kn)) { |
259 | if (PTR_ERR(kn) == -EEXIST) | 276 | if (PTR_ERR(kn) == -EEXIST) |