]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/sysfs/file.c
sysfs: collapse fs/sysfs/bin.c::fill_read() into read()
[mirror_ubuntu-bionic-kernel.git] / fs / sysfs / file.c
CommitLineData
1da177e4 1/*
6d66f5cd
TH
2 * fs/sysfs/file.c - sysfs regular (text) file implementation
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
9 *
10 * Please see Documentation/filesystems/sysfs.txt for more information.
1da177e4
LT
11 */
12
13#include <linux/module.h>
1da177e4 14#include <linux/kobject.h>
815d2d50 15#include <linux/kallsyms.h>
c6f87733 16#include <linux/slab.h>
93265d13 17#include <linux/fsnotify.h>
5f45f1a7 18#include <linux/namei.h>
4508a7a7 19#include <linux/poll.h>
94bebf4d 20#include <linux/list.h>
52e8c209 21#include <linux/mutex.h>
ae87221d 22#include <linux/limits.h>
060cc749 23#include <linux/uaccess.h>
13c589d5 24#include <linux/seq_file.h>
1da177e4
LT
25
26#include "sysfs.h"
27
85a4ffad 28/*
58282d8d 29 * There's one sysfs_open_file for each open file and one sysfs_open_dirent
c75ec764 30 * for each sysfs_dirent with one or more open files.
85a4ffad 31 *
c75ec764
TH
32 * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open is
33 * protected by sysfs_open_dirent_lock.
34 *
13c589d5
TH
35 * filp->private_data points to seq_file whose ->private points to
36 * sysfs_open_file. sysfs_open_files are chained at
58282d8d 37 * sysfs_open_dirent->files, which is protected by sysfs_open_file_mutex.
85a4ffad 38 */
d7b37889 39static DEFINE_SPINLOCK(sysfs_open_dirent_lock);
c75ec764 40static DEFINE_MUTEX(sysfs_open_file_mutex);
85a4ffad
TH
41
42struct sysfs_open_dirent {
43 atomic_t refcnt;
a4e8b912
TH
44 atomic_t event;
45 wait_queue_head_t poll;
58282d8d 46 struct list_head files; /* goes through sysfs_open_file.list */
85a4ffad
TH
47};
48
58282d8d 49struct sysfs_open_file {
bcafe4ee
TH
50 struct sysfs_dirent *sd;
51 struct file *file;
52e8c209 52 struct mutex mutex;
73107cb3 53 int event;
85a4ffad 54 struct list_head list;
73107cb3 55};
1da177e4 56
13c589d5
TH
57static struct sysfs_open_file *sysfs_of(struct file *file)
58{
59 return ((struct seq_file *)file->private_data)->private;
60}
61
375b611e
TH
62/*
63 * Determine ktype->sysfs_ops for the given sysfs_dirent. This function
64 * must be called while holding an active reference.
65 */
66static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd)
67{
68 struct kobject *kobj = sd->s_parent->s_dir.kobj;
69
70 lockdep_assert_held(sd);
71 return kobj->ktype ? kobj->ktype->sysfs_ops : NULL;
72}
73
13c589d5
TH
74/*
75 * Reads on sysfs are handled through seq_file, which takes care of hairy
76 * details like buffering and seeking. The following function pipes
77 * sysfs_ops->show() result through seq_file.
1da177e4 78 */
13c589d5 79static int sysfs_seq_show(struct seq_file *sf, void *v)
1da177e4 80{
13c589d5
TH
81 struct sysfs_open_file *of = sf->private;
82 struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
375b611e 83 const struct sysfs_ops *ops;
13c589d5 84 char *buf;
1da177e4
LT
85 ssize_t count;
86
13c589d5
TH
87 /* acquire buffer and ensure that it's >= PAGE_SIZE */
88 count = seq_get_buf(sf, &buf);
89 if (count < PAGE_SIZE) {
90 seq_commit(sf, -1);
91 return 0;
92 }
1da177e4 93
13c589d5
TH
94 /*
95 * Need @of->sd for attr and ops, its parent for kobj. @of->mutex
96 * nests outside active ref and is just to ensure that the ops
97 * aren't called concurrently for the same open file.
98 */
99 mutex_lock(&of->mutex);
100 if (!sysfs_get_active(of->sd)) {
101 mutex_unlock(&of->mutex);
0ab66088 102 return -ENODEV;
13c589d5 103 }
0ab66088 104
13c589d5 105 of->event = atomic_read(&of->sd->s_attr.open->event);
375b611e 106
13c589d5
TH
107 /*
108 * Lookup @ops and invoke show(). Control may reach here via seq
109 * file lseek even if @ops->show() isn't implemented.
110 */
111 ops = sysfs_file_ops(of->sd);
112 if (ops->show)
113 count = ops->show(kobj, of->sd->s_attr.attr, buf);
114 else
115 count = 0;
0ab66088 116
13c589d5
TH
117 sysfs_put_active(of->sd);
118 mutex_unlock(&of->mutex);
119
120 if (count < 0)
121 return count;
0ab66088 122
8118a859
MX
123 /*
124 * The code works fine with PAGE_SIZE return but it's likely to
125 * indicate truncated result or overflow in normal use cases.
126 */
815d2d50
AM
127 if (count >= (ssize_t)PAGE_SIZE) {
128 print_symbol("fill_read_buffer: %s returned bad count\n",
129 (unsigned long)ops->show);
130 /* Try to struggle along */
131 count = PAGE_SIZE - 1;
132 }
13c589d5
TH
133 seq_commit(sf, count);
134 return 0;
1da177e4
LT
135}
136
1da177e4 137/**
8ef445f0
TH
138 * flush_write_buffer - push buffer to kobject
139 * @of: open file
140 * @buf: data buffer for file
141 * @count: number of bytes
1da177e4 142 *
8ef445f0
TH
143 * Get the correct pointers for the kobject and the attribute we're dealing
144 * with, then call the store() method for it with @buf.
1da177e4 145 */
8ef445f0
TH
146static int flush_write_buffer(struct sysfs_open_file *of, char *buf,
147 size_t count)
1da177e4 148{
bcafe4ee 149 struct kobject *kobj = of->sd->s_parent->s_dir.kobj;
375b611e 150 const struct sysfs_ops *ops;
8ef445f0 151 int rc = 0;
0ab66088 152
8ef445f0
TH
153 /*
154 * Need @of->sd for attr and ops, its parent for kobj. @of->mutex
155 * nests outside active ref and is just to ensure that the ops
156 * aren't called concurrently for the same open file.
157 */
158 mutex_lock(&of->mutex);
159 if (!sysfs_get_active(of->sd)) {
160 mutex_unlock(&of->mutex);
0ab66088 161 return -ENODEV;
8ef445f0 162 }
0ab66088 163
bcafe4ee 164 ops = sysfs_file_ops(of->sd);
8ef445f0 165 rc = ops->store(kobj, of->sd->s_attr.attr, buf, count);
0ab66088 166
bcafe4ee 167 sysfs_put_active(of->sd);
8ef445f0 168 mutex_unlock(&of->mutex);
1da177e4 169
0ab66088 170 return rc;
1da177e4
LT
171}
172
1da177e4 173/**
8ef445f0
TH
174 * sysfs_write_file - write an attribute
175 * @file: file pointer
176 * @user_buf: data to write
177 * @count: number of bytes
178 * @ppos: starting offset
179 *
180 * Copy data in from userland and pass it to the matching
181 * sysfs_ops->store() by invoking flush_write_buffer().
1da177e4 182 *
8ef445f0
TH
183 * There is no easy way for us to know if userspace is only doing a partial
184 * write, so we don't support them. We expect the entire buffer to come on
185 * the first write. Hint: if you're writing a value, first read the file,
186 * modify only the the value you're changing, then write entire buffer
187 * back.
1da177e4 188 */
8ef445f0 189static ssize_t sysfs_write_file(struct file *file, const char __user *user_buf,
ddfd6d07 190 size_t count, loff_t *ppos)
1da177e4 191{
13c589d5 192 struct sysfs_open_file *of = sysfs_of(file);
8ef445f0
TH
193 ssize_t len = min_t(size_t, count, PAGE_SIZE - 1);
194 char *buf;
1da177e4 195
8ef445f0
TH
196 if (!len)
197 return 0;
198
199 buf = kmalloc(len + 1, GFP_KERNEL);
200 if (!buf)
201 return -ENOMEM;
202
203 if (copy_from_user(buf, user_buf, len)) {
204 len = -EFAULT;
205 goto out_free;
206 }
207 buf[len] = '\0'; /* guarantee string termination */
208
209 len = flush_write_buffer(of, buf, len);
1da177e4
LT
210 if (len > 0)
211 *ppos += len;
8ef445f0
TH
212out_free:
213 kfree(buf);
1da177e4
LT
214 return len;
215}
216
85a4ffad
TH
217/**
218 * sysfs_get_open_dirent - get or create sysfs_open_dirent
219 * @sd: target sysfs_dirent
58282d8d 220 * @of: sysfs_open_file for this instance of open
85a4ffad
TH
221 *
222 * If @sd->s_attr.open exists, increment its reference count;
58282d8d 223 * otherwise, create one. @of is chained to the files list.
85a4ffad
TH
224 *
225 * LOCKING:
226 * Kernel thread context (may sleep).
227 *
228 * RETURNS:
229 * 0 on success, -errno on failure.
230 */
231static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
58282d8d 232 struct sysfs_open_file *of)
85a4ffad
TH
233{
234 struct sysfs_open_dirent *od, *new_od = NULL;
235
236 retry:
c75ec764 237 mutex_lock(&sysfs_open_file_mutex);
83db93f4 238 spin_lock_irq(&sysfs_open_dirent_lock);
85a4ffad
TH
239
240 if (!sd->s_attr.open && new_od) {
241 sd->s_attr.open = new_od;
242 new_od = NULL;
243 }
244
245 od = sd->s_attr.open;
246 if (od) {
247 atomic_inc(&od->refcnt);
58282d8d 248 list_add_tail(&of->list, &od->files);
85a4ffad
TH
249 }
250
83db93f4 251 spin_unlock_irq(&sysfs_open_dirent_lock);
c75ec764 252 mutex_unlock(&sysfs_open_file_mutex);
85a4ffad
TH
253
254 if (od) {
255 kfree(new_od);
256 return 0;
257 }
258
259 /* not there, initialize a new one and retry */
260 new_od = kmalloc(sizeof(*new_od), GFP_KERNEL);
261 if (!new_od)
262 return -ENOMEM;
263
264 atomic_set(&new_od->refcnt, 0);
a4e8b912
TH
265 atomic_set(&new_od->event, 1);
266 init_waitqueue_head(&new_od->poll);
58282d8d 267 INIT_LIST_HEAD(&new_od->files);
85a4ffad
TH
268 goto retry;
269}
270
271/**
272 * sysfs_put_open_dirent - put sysfs_open_dirent
273 * @sd: target sysfs_dirent
58282d8d 274 * @of: associated sysfs_open_file
85a4ffad 275 *
58282d8d
TH
276 * Put @sd->s_attr.open and unlink @of from the files list. If
277 * reference count reaches zero, disassociate and free it.
85a4ffad
TH
278 *
279 * LOCKING:
280 * None.
281 */
282static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
58282d8d 283 struct sysfs_open_file *of)
85a4ffad
TH
284{
285 struct sysfs_open_dirent *od = sd->s_attr.open;
83db93f4 286 unsigned long flags;
85a4ffad 287
c75ec764 288 mutex_lock(&sysfs_open_file_mutex);
83db93f4 289 spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
85a4ffad 290
58282d8d 291 list_del(&of->list);
85a4ffad
TH
292 if (atomic_dec_and_test(&od->refcnt))
293 sd->s_attr.open = NULL;
294 else
295 od = NULL;
296
83db93f4 297 spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
c75ec764 298 mutex_unlock(&sysfs_open_file_mutex);
85a4ffad
TH
299
300 kfree(od);
301}
302
94bebf4d 303static int sysfs_open_file(struct inode *inode, struct file *file)
1da177e4 304{
3e519038 305 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
b1fc3d61 306 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
58282d8d 307 struct sysfs_open_file *of;
52cf25d0 308 const struct sysfs_ops *ops;
000f2a4d 309 int error = -EACCES;
1da177e4 310
0ab66088 311 /* need attr_sd for attr and ops, its parent for kobj */
e72ceb8c 312 if (!sysfs_get_active(attr_sd))
0ab66088 313 return -ENODEV;
1da177e4 314
000f2a4d 315 /* every kobject with an attribute needs a ktype assigned */
375b611e
TH
316 ops = sysfs_file_ops(attr_sd);
317 if (WARN(!ops, KERN_ERR
318 "missing sysfs attribute operations for kobject: %s\n",
319 kobject_name(kobj)))
7b595756 320 goto err_out;
1da177e4
LT
321
322 /* File needs write support.
ab9bf4be 323 * The inode's perms must say it's ok,
1da177e4
LT
324 * and we must have a store method.
325 */
326 if (file->f_mode & FMODE_WRITE) {
1da177e4 327 if (!(inode->i_mode & S_IWUGO) || !ops->store)
7b595756 328 goto err_out;
1da177e4
LT
329 }
330
331 /* File needs read support.
332 * The inode's perms must say it's ok, and we there
333 * must be a show method for it.
334 */
335 if (file->f_mode & FMODE_READ) {
336 if (!(inode->i_mode & S_IRUGO) || !ops->show)
7b595756 337 goto err_out;
1da177e4
LT
338 }
339
13c589d5 340 /* allocate a sysfs_open_file for the file */
0ab66088 341 error = -ENOMEM;
58282d8d
TH
342 of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
343 if (!of)
7b595756 344 goto err_out;
1da177e4 345
58282d8d 346 mutex_init(&of->mutex);
bcafe4ee
TH
347 of->sd = attr_sd;
348 of->file = file;
13c589d5
TH
349
350 /*
351 * Always instantiate seq_file even if read access is not
352 * implemented or requested. This unifies private data access and
353 * most files are readable anyway.
354 */
355 error = single_open(file, sysfs_seq_show, of);
356 if (error)
357 goto err_free;
358
359 /* seq_file clears PWRITE unconditionally, restore it if WRITE */
360 if (file->f_mode & FMODE_WRITE)
361 file->f_mode |= FMODE_PWRITE;
0ab66088 362
85a4ffad 363 /* make sure we have open dirent struct */
58282d8d 364 error = sysfs_get_open_dirent(attr_sd, of);
85a4ffad 365 if (error)
13c589d5 366 goto err_close;
85a4ffad 367
b05f0548 368 /* open succeeded, put active references */
e72ceb8c 369 sysfs_put_active(attr_sd);
0ab66088
TH
370 return 0;
371
13c589d5
TH
372err_close:
373 single_release(inode, file);
374err_free:
58282d8d 375 kfree(of);
13c589d5 376err_out:
e72ceb8c 377 sysfs_put_active(attr_sd);
1da177e4
LT
378 return error;
379}
380
85a4ffad 381static int sysfs_release(struct inode *inode, struct file *filp)
1da177e4 382{
85a4ffad 383 struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
13c589d5 384 struct sysfs_open_file *of = sysfs_of(filp);
1da177e4 385
58282d8d 386 sysfs_put_open_dirent(sd, of);
13c589d5 387 single_release(inode, filp);
58282d8d 388 kfree(of);
50ab1a72 389
1da177e4
LT
390 return 0;
391}
392
4508a7a7
N
393/* Sysfs attribute files are pollable. The idea is that you read
394 * the content and then you use 'poll' or 'select' to wait for
395 * the content to change. When the content changes (assuming the
396 * manager for the kobject supports notification), poll will
397 * return POLLERR|POLLPRI, and select will return the fd whether
398 * it is waiting for read, write, or exceptions.
399 * Once poll/select indicates that the value has changed, you
2424b5dd 400 * need to close and re-open the file, or seek to 0 and read again.
4508a7a7
N
401 * Reminder: this only works for attributes which actively support
402 * it, and it is not possible to test an attribute from userspace
a93720ee 403 * to see if it supports poll (Neither 'poll' nor 'select' return
4508a7a7
N
404 * an appropriate error code). When in doubt, set a suitable timeout value.
405 */
406static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
407{
13c589d5 408 struct sysfs_open_file *of = sysfs_of(filp);
0ab66088 409 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
a4e8b912 410 struct sysfs_open_dirent *od = attr_sd->s_attr.open;
0ab66088
TH
411
412 /* need parent for the kobj, grab both */
e72ceb8c 413 if (!sysfs_get_active(attr_sd))
0ab66088 414 goto trigger;
4508a7a7 415
a4e8b912 416 poll_wait(filp, &od->poll, wait);
4508a7a7 417
e72ceb8c 418 sysfs_put_active(attr_sd);
0ab66088 419
58282d8d 420 if (of->event != atomic_read(&od->event))
0ab66088 421 goto trigger;
4508a7a7 422
1af3557a 423 return DEFAULT_POLLMASK;
0ab66088
TH
424
425 trigger:
1af3557a 426 return DEFAULT_POLLMASK|POLLERR|POLLPRI;
4508a7a7
N
427}
428
f1282c84
NB
429void sysfs_notify_dirent(struct sysfs_dirent *sd)
430{
431 struct sysfs_open_dirent *od;
83db93f4 432 unsigned long flags;
f1282c84 433
83db93f4 434 spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
f1282c84 435
fc60bb83
ND
436 if (!WARN_ON(sysfs_type(sd) != SYSFS_KOBJ_ATTR)) {
437 od = sd->s_attr.open;
438 if (od) {
439 atomic_inc(&od->event);
440 wake_up_interruptible(&od->poll);
441 }
f1282c84
NB
442 }
443
83db93f4 444 spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
f1282c84
NB
445}
446EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
447
8c0e3998 448void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
4508a7a7 449{
51225039 450 struct sysfs_dirent *sd = k->sd;
4508a7a7 451
51225039
TH
452 mutex_lock(&sysfs_mutex);
453
454 if (sd && dir)
cfec0bc8 455 sd = sysfs_find_dirent(sd, dir, NULL);
51225039 456 if (sd && attr)
cfec0bc8 457 sd = sysfs_find_dirent(sd, attr, NULL);
f1282c84
NB
458 if (sd)
459 sysfs_notify_dirent(sd);
51225039
TH
460
461 mutex_unlock(&sysfs_mutex);
4508a7a7
N
462}
463EXPORT_SYMBOL_GPL(sysfs_notify);
464
4b6f5d20 465const struct file_operations sysfs_file_operations = {
13c589d5 466 .read = seq_read,
1da177e4 467 .write = sysfs_write_file,
13c589d5 468 .llseek = seq_lseek,
1da177e4
LT
469 .open = sysfs_open_file,
470 .release = sysfs_release,
4508a7a7 471 .poll = sysfs_poll,
1da177e4
LT
472};
473
58292cbe
TH
474int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
475 const struct attribute *attr, int type,
476 umode_t amode, const void *ns)
1da177e4 477{
0f423895 478 umode_t mode = (amode & S_IALLUGO) | S_IFREG;
fb6896da 479 struct sysfs_addrm_cxt acxt;
a26cd722 480 struct sysfs_dirent *sd;
23dc2799 481 int rc;
1da177e4 482
3007e997
TH
483 sd = sysfs_new_dirent(attr->name, mode, type);
484 if (!sd)
485 return -ENOMEM;
487505c2
EB
486
487 sd->s_ns = ns;
b1fc3d61 488 sd->s_attr.attr = (void *)attr;
a2db6842 489 sysfs_dirent_init_lockdep(sd);
1da177e4 490
d69ac5a0
TH
491 sysfs_addrm_start(&acxt);
492 rc = sysfs_add_one(&acxt, sd, dir_sd);
23dc2799 493 sysfs_addrm_finish(&acxt);
a26cd722 494
23dc2799 495 if (rc)
967e35dc 496 sysfs_put(sd);
3007e997 497
23dc2799 498 return rc;
1da177e4
LT
499}
500
501
0f423895
JB
502int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
503 int type)
504{
58292cbe 505 return sysfs_add_file_mode_ns(dir_sd, attr, type, attr->mode, NULL);
0f423895
JB
506}
507
1da177e4 508/**
58292cbe
TH
509 * sysfs_create_file_ns - create an attribute file for an object with custom ns
510 * @kobj: object we're creating for
511 * @attr: attribute descriptor
512 * @ns: namespace the new file should belong to
1da177e4 513 */
58292cbe
TH
514int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
515 const void *ns)
1da177e4 516{
608e266a 517 BUG_ON(!kobj || !kobj->sd || !attr);
1da177e4 518
58292cbe
TH
519 return sysfs_add_file_mode_ns(kobj->sd, attr, SYSFS_KOBJ_ATTR,
520 attr->mode, ns);
1da177e4
LT
521
522}
58292cbe 523EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
1da177e4 524
1c205ae1
AK
525int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
526{
527 int err = 0;
528 int i;
529
530 for (i = 0; ptr[i] && !err; i++)
531 err = sysfs_create_file(kobj, ptr[i]);
532 if (err)
533 while (--i >= 0)
534 sysfs_remove_file(kobj, ptr[i]);
535 return err;
536}
1b866757 537EXPORT_SYMBOL_GPL(sysfs_create_files);
1da177e4 538
dfa87c82
AS
539/**
540 * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
541 * @kobj: object we're acting for.
542 * @attr: attribute descriptor.
543 * @group: group name.
544 */
545int sysfs_add_file_to_group(struct kobject *kobj,
546 const struct attribute *attr, const char *group)
547{
608e266a 548 struct sysfs_dirent *dir_sd;
dfa87c82
AS
549 int error;
550
11f24fbd 551 if (group)
388975cc 552 dir_sd = sysfs_get_dirent(kobj->sd, group);
11f24fbd
JB
553 else
554 dir_sd = sysfs_get(kobj->sd);
555
608e266a
TH
556 if (!dir_sd)
557 return -ENOENT;
558
559 error = sysfs_add_file(dir_sd, attr, SYSFS_KOBJ_ATTR);
560 sysfs_put(dir_sd);
561
dfa87c82
AS
562 return error;
563}
564EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
565
31e5abe9
KS
566/**
567 * sysfs_chmod_file - update the modified mode value on an object attribute.
568 * @kobj: object we're acting for.
569 * @attr: attribute descriptor.
570 * @mode: file permissions.
571 *
572 */
49c19400 573int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
48176a97 574 umode_t mode)
31e5abe9 575{
06fc0d66 576 struct sysfs_dirent *sd;
bc062b1b 577 struct iattr newattrs;
51225039
TH
578 int rc;
579
06fc0d66 580 mutex_lock(&sysfs_mutex);
51225039 581
06fc0d66 582 rc = -ENOENT;
cfec0bc8 583 sd = sysfs_find_dirent(kobj->sd, attr->name, NULL);
06fc0d66 584 if (!sd)
51225039 585 goto out;
f88123ea 586
06fc0d66 587 newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO);
4c6974f5 588 newattrs.ia_valid = ATTR_MODE;
06fc0d66 589 rc = sysfs_sd_setattr(sd, &newattrs);
f88123ea 590
51225039 591 out:
06fc0d66 592 mutex_unlock(&sysfs_mutex);
51225039 593 return rc;
31e5abe9
KS
594}
595EXPORT_SYMBOL_GPL(sysfs_chmod_file);
596
1da177e4 597/**
58292cbe
TH
598 * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
599 * @kobj: object we're acting for
600 * @attr: attribute descriptor
601 * @ns: namespace tag of the file to remove
1da177e4 602 *
58292cbe 603 * Hash the attribute name and namespace tag and kill the victim.
1da177e4 604 */
58292cbe
TH
605void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
606 const void *ns)
1da177e4 607{
58292cbe 608 struct sysfs_dirent *dir_sd = kobj->sd;
487505c2 609
cfec0bc8 610 sysfs_hash_and_remove(dir_sd, attr->name, ns);
1da177e4 611}
58292cbe 612EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
1da177e4 613
1b18dc2b 614void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
1c205ae1
AK
615{
616 int i;
617 for (i = 0; ptr[i]; i++)
618 sysfs_remove_file(kobj, ptr[i]);
619}
1b866757 620EXPORT_SYMBOL_GPL(sysfs_remove_files);
1da177e4 621
dfa87c82
AS
622/**
623 * sysfs_remove_file_from_group - remove an attribute file from a group.
624 * @kobj: object we're acting for.
625 * @attr: attribute descriptor.
626 * @group: group name.
627 */
628void sysfs_remove_file_from_group(struct kobject *kobj,
629 const struct attribute *attr, const char *group)
630{
608e266a 631 struct sysfs_dirent *dir_sd;
dfa87c82 632
11f24fbd 633 if (group)
388975cc 634 dir_sd = sysfs_get_dirent(kobj->sd, group);
11f24fbd
JB
635 else
636 dir_sd = sysfs_get(kobj->sd);
608e266a 637 if (dir_sd) {
cfec0bc8 638 sysfs_hash_and_remove(dir_sd, attr->name, NULL);
608e266a 639 sysfs_put(dir_sd);
dfa87c82
AS
640 }
641}
642EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group);
643
d9a9cdfb 644struct sysfs_schedule_callback_struct {
66942064
AC
645 struct list_head workq_list;
646 struct kobject *kobj;
d9a9cdfb
AS
647 void (*func)(void *);
648 void *data;
523ded71 649 struct module *owner;
d9a9cdfb
AS
650 struct work_struct work;
651};
652
d110271e 653static struct workqueue_struct *sysfs_workqueue;
66942064
AC
654static DEFINE_MUTEX(sysfs_workq_mutex);
655static LIST_HEAD(sysfs_workq);
d9a9cdfb
AS
656static void sysfs_schedule_callback_work(struct work_struct *work)
657{
658 struct sysfs_schedule_callback_struct *ss = container_of(work,
659 struct sysfs_schedule_callback_struct, work);
660
661 (ss->func)(ss->data);
662 kobject_put(ss->kobj);
523ded71 663 module_put(ss->owner);
66942064
AC
664 mutex_lock(&sysfs_workq_mutex);
665 list_del(&ss->workq_list);
666 mutex_unlock(&sysfs_workq_mutex);
d9a9cdfb
AS
667 kfree(ss);
668}
669
670/**
671 * sysfs_schedule_callback - helper to schedule a callback for a kobject
672 * @kobj: object we're acting for.
673 * @func: callback function to invoke later.
674 * @data: argument to pass to @func.
523ded71 675 * @owner: module owning the callback code
d9a9cdfb
AS
676 *
677 * sysfs attribute methods must not unregister themselves or their parent
678 * kobject (which would amount to the same thing). Attempts to do so will
679 * deadlock, since unregistration is mutually exclusive with driver
680 * callbacks.
681 *
682 * Instead methods can call this routine, which will attempt to allocate
683 * and schedule a workqueue request to call back @func with @data as its
684 * argument in the workqueue's process context. @kobj will be pinned
685 * until @func returns.
686 *
687 * Returns 0 if the request was submitted, -ENOMEM if storage could not
66942064
AC
688 * be allocated, -ENODEV if a reference to @owner isn't available,
689 * -EAGAIN if a callback has already been scheduled for @kobj.
d9a9cdfb
AS
690 */
691int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
523ded71 692 void *data, struct module *owner)
d9a9cdfb 693{
66942064 694 struct sysfs_schedule_callback_struct *ss, *tmp;
d9a9cdfb 695
523ded71
AS
696 if (!try_module_get(owner))
697 return -ENODEV;
66942064
AC
698
699 mutex_lock(&sysfs_workq_mutex);
700 list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
701 if (ss->kobj == kobj) {
d110271e 702 module_put(owner);
66942064
AC
703 mutex_unlock(&sysfs_workq_mutex);
704 return -EAGAIN;
705 }
706 mutex_unlock(&sysfs_workq_mutex);
707
d110271e 708 if (sysfs_workqueue == NULL) {
086a377e 709 sysfs_workqueue = create_singlethread_workqueue("sysfsd");
d110271e
AC
710 if (sysfs_workqueue == NULL) {
711 module_put(owner);
712 return -ENOMEM;
713 }
714 }
715
d9a9cdfb 716 ss = kmalloc(sizeof(*ss), GFP_KERNEL);
523ded71
AS
717 if (!ss) {
718 module_put(owner);
d9a9cdfb 719 return -ENOMEM;
523ded71 720 }
d9a9cdfb
AS
721 kobject_get(kobj);
722 ss->kobj = kobj;
723 ss->func = func;
724 ss->data = data;
523ded71 725 ss->owner = owner;
d9a9cdfb 726 INIT_WORK(&ss->work, sysfs_schedule_callback_work);
66942064
AC
727 INIT_LIST_HEAD(&ss->workq_list);
728 mutex_lock(&sysfs_workq_mutex);
729 list_add_tail(&ss->workq_list, &sysfs_workq);
730 mutex_unlock(&sysfs_workq_mutex);
d110271e 731 queue_work(sysfs_workqueue, &ss->work);
d9a9cdfb
AS
732 return 0;
733}
734EXPORT_SYMBOL_GPL(sysfs_schedule_callback);