Blame view
fs/sysfs/file.c
13.4 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
6d66f5cd2 sysfs: add copyri... |
2 3 4 5 6 7 8 9 10 |
* fs/sysfs/file.c - sysfs regular (text) file implementation * * Copyright (c) 2001-3 Patrick Mochel * Copyright (c) 2007 SUSE Linux Products GmbH * Copyright (c) 2007 Tejun Heo <teheo@suse.de> * * This file is released under the GPLv2. * * Please see Documentation/filesystems/sysfs.txt for more information. |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 |
*/ #include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include <linux/kobject.h> |
815d2d50d driver core: debu... |
15 |
#include <linux/kallsyms.h> |
c6f877338 SYSFS: Explicitly... |
16 |
#include <linux/slab.h> |
94bebf4d1 Driver core: fix ... |
17 |
#include <linux/list.h> |
52e8c209d sysfs/file.c - us... |
18 |
#include <linux/mutex.h> |
13c589d5b sysfs: use seq_fi... |
19 |
#include <linux/seq_file.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 |
#include "sysfs.h" |
414985ae2 sysfs, kernfs: mo... |
22 |
#include "../kernfs/kernfs-internal.h" |
f6acf8bb6 sysfs, kernfs: in... |
23 24 |
/* |
324a56e16 kernfs: s/sysfs_d... |
25 |
* Determine ktype->sysfs_ops for the given kernfs_node. This function |
375b611e6 sysfs: remove sys... |
26 27 |
* must be called while holding an active reference. */ |
324a56e16 kernfs: s/sysfs_d... |
28 |
static const struct sysfs_ops *sysfs_file_ops(struct kernfs_node *kn) |
375b611e6 sysfs: remove sys... |
29 |
{ |
adc5e8b58 kernfs: drop s_ p... |
30 |
struct kobject *kobj = kn->parent->priv; |
375b611e6 sysfs: remove sys... |
31 |
|
df23fc39b kernfs: s/sysfs/k... |
32 |
if (kn->flags & KERNFS_LOCKDEP) |
324a56e16 kernfs: s/sysfs_d... |
33 |
lockdep_assert_held(kn); |
375b611e6 sysfs: remove sys... |
34 35 |
return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; } |
13c589d5b sysfs: use seq_fi... |
36 37 38 39 |
/* * Reads on sysfs are handled through seq_file, which takes care of hairy * details like buffering and seeking. The following function pipes * sysfs_ops->show() result through seq_file. |
1da177e4c Linux-2.6.12-rc2 |
40 |
*/ |
c2b19daf6 sysfs, kernfs: pr... |
41 |
static int sysfs_kf_seq_show(struct seq_file *sf, void *v) |
1da177e4c Linux-2.6.12-rc2 |
42 |
{ |
c525aaddc kernfs: s/sysfs/k... |
43 |
struct kernfs_open_file *of = sf->private; |
adc5e8b58 kernfs: drop s_ p... |
44 |
struct kobject *kobj = of->kn->parent->priv; |
324a56e16 kernfs: s/sysfs_d... |
45 |
const struct sysfs_ops *ops = sysfs_file_ops(of->kn); |
1da177e4c Linux-2.6.12-rc2 |
46 |
ssize_t count; |
c2b19daf6 sysfs, kernfs: pr... |
47 |
char *buf; |
1da177e4c Linux-2.6.12-rc2 |
48 |
|
f5c16f29b sysfs: make sure ... |
49 |
/* acquire buffer and ensure that it's >= PAGE_SIZE and clear */ |
13c589d5b sysfs: use seq_fi... |
50 51 52 53 54 |
count = seq_get_buf(sf, &buf); if (count < PAGE_SIZE) { seq_commit(sf, -1); return 0; } |
f5c16f29b sysfs: make sure ... |
55 |
memset(buf, 0, PAGE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
56 |
|
13c589d5b sysfs: use seq_fi... |
57 |
/* |
c2b19daf6 sysfs, kernfs: pr... |
58 59 |
* Invoke show(). Control may reach here via seq file lseek even * if @ops->show() isn't implemented. |
13c589d5b sysfs: use seq_fi... |
60 |
*/ |
c2b19daf6 sysfs, kernfs: pr... |
61 |
if (ops->show) { |
324a56e16 kernfs: s/sysfs_d... |
62 |
count = ops->show(kobj, of->kn->priv, buf); |
c2b19daf6 sysfs, kernfs: pr... |
63 64 65 |
if (count < 0) return count; } |
0ab66088c sysfs: implement ... |
66 |
|
8118a859d sysfs: fix off-by... |
67 68 69 70 |
/* * The code works fine with PAGE_SIZE return but it's likely to * indicate truncated result or overflow in normal use cases. */ |
815d2d50d driver core: debu... |
71 72 73 74 75 76 77 |
if (count >= (ssize_t)PAGE_SIZE) { print_symbol("fill_read_buffer: %s returned bad count ", (unsigned long)ops->show); /* Try to struggle along */ count = PAGE_SIZE - 1; } |
13c589d5b sysfs: use seq_fi... |
78 79 |
seq_commit(sf, count); return 0; |
1da177e4c Linux-2.6.12-rc2 |
80 |
} |
c525aaddc kernfs: s/sysfs/k... |
81 |
static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf, |
c2b19daf6 sysfs, kernfs: pr... |
82 |
size_t count, loff_t pos) |
2f0c6b759 sysfs: add sysfs_... |
83 |
{ |
324a56e16 kernfs: s/sysfs_d... |
84 |
struct bin_attribute *battr = of->kn->priv; |
adc5e8b58 kernfs: drop s_ p... |
85 |
struct kobject *kobj = of->kn->parent->priv; |
c2b19daf6 sysfs, kernfs: pr... |
86 |
loff_t size = file_inode(of->file)->i_size; |
2f0c6b759 sysfs: add sysfs_... |
87 |
|
c2b19daf6 sysfs, kernfs: pr... |
88 |
if (!count) |
2f0c6b759 sysfs: add sysfs_... |
89 90 91 |
return 0; if (size) { |
eaa5cd926 fs: sysfs: don't ... |
92 |
if (pos >= size) |
2f0c6b759 sysfs: add sysfs_... |
93 |
return 0; |
c2b19daf6 sysfs, kernfs: pr... |
94 95 |
if (pos + count > size) count = size - pos; |
2f0c6b759 sysfs: add sysfs_... |
96 |
} |
c2b19daf6 sysfs, kernfs: pr... |
97 98 99 100 101 |
if (!battr->read) return -EIO; return battr->read(of->file, kobj, battr, buf, pos, count); } |
4ef67a8c9 sysfs/kernfs: mak... |
102 103 104 105 106 107 |
/* kernfs read callback for regular sysfs files with pre-alloc */ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf, size_t count, loff_t pos) { const struct sysfs_ops *ops = sysfs_file_ops(of->kn); struct kobject *kobj = of->kn->parent->priv; |
c8a139d00 sysfs: be careful... |
108 |
ssize_t len; |
4ef67a8c9 sysfs/kernfs: mak... |
109 110 111 112 113 |
/* * If buf != of->prealloc_buf, we don't know how * large it is, so cannot safely pass it to ->show */ |
17d0774f8 sysfs: correctly ... |
114 |
if (WARN_ON_ONCE(buf != of->prealloc_buf)) |
4ef67a8c9 sysfs/kernfs: mak... |
115 |
return 0; |
65da3484d sysfs: correctly ... |
116 |
len = ops->show(kobj, of->kn->priv, buf); |
c8a139d00 sysfs: be careful... |
117 118 |
if (len < 0) return len; |
17d0774f8 sysfs: correctly ... |
119 120 121 122 123 124 |
if (pos) { if (len <= pos) return 0; len -= pos; memmove(buf, buf + pos, len); } |
c8a139d00 sysfs: be careful... |
125 |
return min_t(ssize_t, count, len); |
4ef67a8c9 sysfs/kernfs: mak... |
126 |
} |
50b38ca08 sysfs, kernfs: pr... |
127 |
/* kernfs write callback for regular sysfs files */ |
c525aaddc kernfs: s/sysfs/k... |
128 |
static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf, |
50b38ca08 sysfs, kernfs: pr... |
129 |
size_t count, loff_t pos) |
1da177e4c Linux-2.6.12-rc2 |
130 |
{ |
324a56e16 kernfs: s/sysfs_d... |
131 |
const struct sysfs_ops *ops = sysfs_file_ops(of->kn); |
adc5e8b58 kernfs: drop s_ p... |
132 |
struct kobject *kobj = of->kn->parent->priv; |
0ab66088c sysfs: implement ... |
133 |
|
50b38ca08 sysfs, kernfs: pr... |
134 135 |
if (!count) return 0; |
0ab66088c sysfs: implement ... |
136 |
|
324a56e16 kernfs: s/sysfs_d... |
137 |
return ops->store(kobj, of->kn->priv, buf, count); |
50b38ca08 sysfs, kernfs: pr... |
138 |
} |
f9b9a6217 sysfs: prepare pa... |
139 |
|
50b38ca08 sysfs, kernfs: pr... |
140 |
/* kernfs write callback for bin sysfs files */ |
c525aaddc kernfs: s/sysfs/k... |
141 |
static ssize_t sysfs_kf_bin_write(struct kernfs_open_file *of, char *buf, |
50b38ca08 sysfs, kernfs: pr... |
142 143 |
size_t count, loff_t pos) { |
324a56e16 kernfs: s/sysfs_d... |
144 |
struct bin_attribute *battr = of->kn->priv; |
adc5e8b58 kernfs: drop s_ p... |
145 |
struct kobject *kobj = of->kn->parent->priv; |
50b38ca08 sysfs, kernfs: pr... |
146 |
loff_t size = file_inode(of->file)->i_size; |
f9b9a6217 sysfs: prepare pa... |
147 |
|
50b38ca08 sysfs, kernfs: pr... |
148 149 |
if (size) { if (size <= pos) |
093689605 fs: sysfs: return... |
150 |
return -EFBIG; |
50b38ca08 sysfs, kernfs: pr... |
151 |
count = min_t(ssize_t, count, size - pos); |
f9b9a6217 sysfs: prepare pa... |
152 |
} |
50b38ca08 sysfs, kernfs: pr... |
153 154 |
if (!count) return 0; |
0ab66088c sysfs: implement ... |
155 |
|
50b38ca08 sysfs, kernfs: pr... |
156 157 |
if (!battr->write) return -EIO; |
1da177e4c Linux-2.6.12-rc2 |
158 |
|
50b38ca08 sysfs, kernfs: pr... |
159 |
return battr->write(of->file, kobj, battr, buf, pos, count); |
1da177e4c Linux-2.6.12-rc2 |
160 |
} |
c525aaddc kernfs: s/sysfs/k... |
161 |
static int sysfs_kf_bin_mmap(struct kernfs_open_file *of, |
fdbffaa47 sysfs, kernfs: pr... |
162 163 |
struct vm_area_struct *vma) { |
324a56e16 kernfs: s/sysfs_d... |
164 |
struct bin_attribute *battr = of->kn->priv; |
adc5e8b58 kernfs: drop s_ p... |
165 |
struct kobject *kobj = of->kn->parent->priv; |
fdbffaa47 sysfs, kernfs: pr... |
166 |
|
fdbffaa47 sysfs, kernfs: pr... |
167 168 |
return battr->mmap(of->file, kobj, battr, vma); } |
324a56e16 kernfs: s/sysfs_d... |
169 |
void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr) |
4508a7a73 [PATCH] sysfs: Al... |
170 |
{ |
324a56e16 kernfs: s/sysfs_d... |
171 |
struct kernfs_node *kn = kobj->sd, *tmp; |
51225039f sysfs: make direc... |
172 |
|
324a56e16 kernfs: s/sysfs_d... |
173 174 |
if (kn && dir) kn = kernfs_find_and_get(kn, dir); |
024f64711 sysfs, kernfs: in... |
175 |
else |
324a56e16 kernfs: s/sysfs_d... |
176 |
kernfs_get(kn); |
024f64711 sysfs, kernfs: in... |
177 |
|
324a56e16 kernfs: s/sysfs_d... |
178 179 180 181 |
if (kn && attr) { tmp = kernfs_find_and_get(kn, attr); kernfs_put(kn); kn = tmp; |
024f64711 sysfs, kernfs: in... |
182 |
} |
51225039f sysfs: make direc... |
183 |
|
324a56e16 kernfs: s/sysfs_d... |
184 185 186 |
if (kn) { kernfs_notify(kn); kernfs_put(kn); |
024f64711 sysfs, kernfs: in... |
187 |
} |
4508a7a73 [PATCH] sysfs: Al... |
188 189 |
} EXPORT_SYMBOL_GPL(sysfs_notify); |
f6acf8bb6 sysfs, kernfs: in... |
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
static const struct kernfs_ops sysfs_file_kfops_empty = { }; static const struct kernfs_ops sysfs_file_kfops_ro = { .seq_show = sysfs_kf_seq_show, }; static const struct kernfs_ops sysfs_file_kfops_wo = { .write = sysfs_kf_write, }; static const struct kernfs_ops sysfs_file_kfops_rw = { .seq_show = sysfs_kf_seq_show, .write = sysfs_kf_write, }; |
4ef67a8c9 sysfs/kernfs: mak... |
205 206 207 208 |
static const struct kernfs_ops sysfs_prealloc_kfops_ro = { .read = sysfs_kf_read, .prealloc = true, }; |
2b75869bb sysfs/kernfs: all... |
209 210 211 212 213 214 |
static const struct kernfs_ops sysfs_prealloc_kfops_wo = { .write = sysfs_kf_write, .prealloc = true, }; static const struct kernfs_ops sysfs_prealloc_kfops_rw = { |
4ef67a8c9 sysfs/kernfs: mak... |
215 |
.read = sysfs_kf_read, |
2b75869bb sysfs/kernfs: all... |
216 217 218 |
.write = sysfs_kf_write, .prealloc = true, }; |
f6acf8bb6 sysfs, kernfs: in... |
219 220 221 222 223 224 225 226 227 228 229 |
static const struct kernfs_ops sysfs_bin_kfops_ro = { .read = sysfs_kf_bin_read, }; static const struct kernfs_ops sysfs_bin_kfops_wo = { .write = sysfs_kf_bin_write, }; static const struct kernfs_ops sysfs_bin_kfops_rw = { .read = sysfs_kf_bin_read, .write = sysfs_kf_bin_write, |
9b2db6e18 sysfs: bail early... |
230 231 232 233 234 |
}; static const struct kernfs_ops sysfs_bin_kfops_mmap = { .read = sysfs_kf_bin_read, .write = sysfs_kf_bin_write, |
f6acf8bb6 sysfs, kernfs: in... |
235 236 |
.mmap = sysfs_kf_bin_mmap, }; |
324a56e16 kernfs: s/sysfs_d... |
237 |
int sysfs_add_file_mode_ns(struct kernfs_node *parent, |
a7dc66dfb sysfs, kernfs: re... |
238 |
const struct attribute *attr, bool is_bin, |
496f73944 sysfs, kernfs: in... |
239 |
umode_t mode, const void *ns) |
1da177e4c Linux-2.6.12-rc2 |
240 |
{ |
517e64f57 sysfs, kernfs: re... |
241 |
struct lock_class_key *key = NULL; |
f6acf8bb6 sysfs, kernfs: in... |
242 |
const struct kernfs_ops *ops; |
324a56e16 kernfs: s/sysfs_d... |
243 |
struct kernfs_node *kn; |
471bd7b78 sysfs, kernfs: ad... |
244 |
loff_t size; |
1da177e4c Linux-2.6.12-rc2 |
245 |
|
a7dc66dfb sysfs, kernfs: re... |
246 |
if (!is_bin) { |
324a56e16 kernfs: s/sysfs_d... |
247 |
struct kobject *kobj = parent->priv; |
f6acf8bb6 sysfs, kernfs: in... |
248 249 250 251 252 253 254 255 |
const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops; /* every kobject with an attribute needs a ktype assigned */ if (WARN(!sysfs_ops, KERN_ERR "missing sysfs attribute operations for kobject: %s ", kobject_name(kobj))) return -EINVAL; |
2b75869bb sysfs/kernfs: all... |
256 257 258 259 260 |
if (sysfs_ops->show && sysfs_ops->store) { if (mode & SYSFS_PREALLOC) ops = &sysfs_prealloc_kfops_rw; else ops = &sysfs_file_kfops_rw; |
4ef67a8c9 sysfs/kernfs: mak... |
261 262 263 264 265 266 |
} else if (sysfs_ops->show) { if (mode & SYSFS_PREALLOC) ops = &sysfs_prealloc_kfops_ro; else ops = &sysfs_file_kfops_ro; } else if (sysfs_ops->store) { |
2b75869bb sysfs/kernfs: all... |
267 268 269 270 271 |
if (mode & SYSFS_PREALLOC) ops = &sysfs_prealloc_kfops_wo; else ops = &sysfs_file_kfops_wo; } else |
f6acf8bb6 sysfs, kernfs: in... |
272 |
ops = &sysfs_file_kfops_empty; |
471bd7b78 sysfs, kernfs: ad... |
273 274 |
size = PAGE_SIZE; |
f6acf8bb6 sysfs, kernfs: in... |
275 276 |
} else { struct bin_attribute *battr = (void *)attr; |
9b2db6e18 sysfs: bail early... |
277 278 279 |
if (battr->mmap) ops = &sysfs_bin_kfops_mmap; else if (battr->read && battr->write) |
f6acf8bb6 sysfs, kernfs: in... |
280 281 282 283 284 285 286 |
ops = &sysfs_bin_kfops_rw; else if (battr->read) ops = &sysfs_bin_kfops_ro; else if (battr->write) ops = &sysfs_bin_kfops_wo; else ops = &sysfs_file_kfops_empty; |
471bd7b78 sysfs, kernfs: ad... |
287 288 |
size = battr->size; |
f6acf8bb6 sysfs, kernfs: in... |
289 |
} |
517e64f57 sysfs, kernfs: re... |
290 291 292 293 |
#ifdef CONFIG_DEBUG_LOCK_ALLOC if (!attr->ignore_lockdep) key = attr->key ?: (struct lock_class_key *)&attr->skey; #endif |
2b75869bb sysfs/kernfs: all... |
294 |
kn = __kernfs_create_file(parent, attr->name, mode & 0777, size, ops, |
dfeb0750b kernfs: remove KE... |
295 |
(void *)attr, ns, key); |
324a56e16 kernfs: s/sysfs_d... |
296 297 298 299 |
if (IS_ERR(kn)) { if (PTR_ERR(kn) == -EEXIST) sysfs_warn_dup(parent, attr->name); return PTR_ERR(kn); |
496f73944 sysfs, kernfs: in... |
300 301 302 |
} return 0; } |
324a56e16 kernfs: s/sysfs_d... |
303 |
int sysfs_add_file(struct kernfs_node *parent, const struct attribute *attr, |
a7dc66dfb sysfs, kernfs: re... |
304 |
bool is_bin) |
0f4238958 [SCSI] sysfs: mak... |
305 |
{ |
324a56e16 kernfs: s/sysfs_d... |
306 |
return sysfs_add_file_mode_ns(parent, attr, is_bin, attr->mode, NULL); |
0f4238958 [SCSI] sysfs: mak... |
307 |
} |
1da177e4c Linux-2.6.12-rc2 |
308 |
/** |
58292cbe6 sysfs: make attr ... |
309 310 311 312 |
* sysfs_create_file_ns - create an attribute file for an object with custom ns * @kobj: object we're creating for * @attr: attribute descriptor * @ns: namespace the new file should belong to |
1da177e4c Linux-2.6.12-rc2 |
313 |
*/ |
58292cbe6 sysfs: make attr ... |
314 315 |
int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr, const void *ns) |
1da177e4c Linux-2.6.12-rc2 |
316 |
{ |
608e266a2 sysfs: make kobj ... |
317 |
BUG_ON(!kobj || !kobj->sd || !attr); |
1da177e4c Linux-2.6.12-rc2 |
318 |
|
a7dc66dfb sysfs, kernfs: re... |
319 |
return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode, ns); |
1da177e4c Linux-2.6.12-rc2 |
320 321 |
} |
58292cbe6 sysfs: make attr ... |
322 |
EXPORT_SYMBOL_GPL(sysfs_create_file_ns); |
1da177e4c Linux-2.6.12-rc2 |
323 |
|
1c205ae18 sysfs: Add sysfs_... |
324 325 326 327 328 329 330 331 332 333 334 335 |
int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) { int err = 0; int i; for (i = 0; ptr[i] && !err; i++) err = sysfs_create_file(kobj, ptr[i]); if (err) while (--i >= 0) sysfs_remove_file(kobj, ptr[i]); return err; } |
1b866757f sysfs: fix placem... |
336 |
EXPORT_SYMBOL_GPL(sysfs_create_files); |
1da177e4c Linux-2.6.12-rc2 |
337 338 |
/** |
dfa87c824 sysfs: allow attr... |
339 340 341 342 343 344 345 346 |
* sysfs_add_file_to_group - add an attribute file to a pre-existing group. * @kobj: object we're acting for. * @attr: attribute descriptor. * @group: group name. */ int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group) { |
324a56e16 kernfs: s/sysfs_d... |
347 |
struct kernfs_node *parent; |
dfa87c824 sysfs: allow attr... |
348 |
int error; |
ccf73cf33 sysfs, kernfs: in... |
349 |
if (group) { |
324a56e16 kernfs: s/sysfs_d... |
350 |
parent = kernfs_find_and_get(kobj->sd, group); |
ccf73cf33 sysfs, kernfs: in... |
351 |
} else { |
324a56e16 kernfs: s/sysfs_d... |
352 353 |
parent = kobj->sd; kernfs_get(parent); |
ccf73cf33 sysfs, kernfs: in... |
354 |
} |
11f24fbdf [SCSI] sysfs: fix... |
355 |
|
324a56e16 kernfs: s/sysfs_d... |
356 |
if (!parent) |
608e266a2 sysfs: make kobj ... |
357 |
return -ENOENT; |
324a56e16 kernfs: s/sysfs_d... |
358 359 |
error = sysfs_add_file(parent, attr, false); kernfs_put(parent); |
608e266a2 sysfs: make kobj ... |
360 |
|
dfa87c824 sysfs: allow attr... |
361 362 363 |
return error; } EXPORT_SYMBOL_GPL(sysfs_add_file_to_group); |
1da177e4c Linux-2.6.12-rc2 |
364 |
/** |
31e5abe9a [PATCH] sysfs: ad... |
365 366 367 368 369 370 |
* sysfs_chmod_file - update the modified mode value on an object attribute. * @kobj: object we're acting for. * @attr: attribute descriptor. * @mode: file permissions. * */ |
49c19400f sysfs: sysfs_chmo... |
371 |
int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, |
48176a973 switch sysfs_chmo... |
372 |
umode_t mode) |
31e5abe9a [PATCH] sysfs: ad... |
373 |
{ |
324a56e16 kernfs: s/sysfs_d... |
374 |
struct kernfs_node *kn; |
bc062b1b5 [PATCH] sysfs: fi... |
375 |
struct iattr newattrs; |
51225039f sysfs: make direc... |
376 |
int rc; |
324a56e16 kernfs: s/sysfs_d... |
377 378 |
kn = kernfs_find_and_get(kobj->sd, attr->name); if (!kn) |
5d60418e5 sysfs, kernfs: in... |
379 |
return -ENOENT; |
f88123eaf sysfs: fix sysfs_... |
380 |
|
adc5e8b58 kernfs: drop s_ p... |
381 |
newattrs.ia_mode = (mode & S_IALLUGO) | (kn->mode & ~S_IALLUGO); |
4c6974f51 sysfs: Simplify s... |
382 |
newattrs.ia_valid = ATTR_MODE; |
f88123eaf sysfs: fix sysfs_... |
383 |
|
324a56e16 kernfs: s/sysfs_d... |
384 |
rc = kernfs_setattr(kn, &newattrs); |
5d60418e5 sysfs, kernfs: in... |
385 |
|
324a56e16 kernfs: s/sysfs_d... |
386 |
kernfs_put(kn); |
51225039f sysfs: make direc... |
387 |
return rc; |
31e5abe9a [PATCH] sysfs: ad... |
388 389 |
} EXPORT_SYMBOL_GPL(sysfs_chmod_file); |
31e5abe9a [PATCH] sysfs: ad... |
390 |
/** |
c984f4d1d scsi: sysfs: Intr... |
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
* sysfs_break_active_protection - break "active" protection * @kobj: The kernel object @attr is associated with. * @attr: The attribute to break the "active" protection for. * * With sysfs, just like kernfs, deletion of an attribute is postponed until * all active .show() and .store() callbacks have finished unless this function * is called. Hence this function is useful in methods that implement self * deletion. */ struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, const struct attribute *attr) { struct kernfs_node *kn; kobject_get(kobj); kn = kernfs_find_and_get(kobj->sd, attr->name); if (kn) kernfs_break_active_protection(kn); return kn; } EXPORT_SYMBOL_GPL(sysfs_break_active_protection); /** * sysfs_unbreak_active_protection - restore "active" protection * @kn: Pointer returned by sysfs_break_active_protection(). * * Undo the effects of sysfs_break_active_protection(). Since this function * calls kernfs_put() on the kernfs node that corresponds to the 'attr' * argument passed to sysfs_break_active_protection() that attribute may have * been removed between the sysfs_break_active_protection() and * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after * this function has returned. */ void sysfs_unbreak_active_protection(struct kernfs_node *kn) { struct kobject *kobj = kn->parent->priv; kernfs_unbreak_active_protection(kn); kernfs_put(kn); kobject_put(kobj); } EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection); /** |
58292cbe6 sysfs: make attr ... |
435 436 437 438 |
* sysfs_remove_file_ns - remove an object attribute with a custom ns tag * @kobj: object we're acting for * @attr: attribute descriptor * @ns: namespace tag of the file to remove |
1da177e4c Linux-2.6.12-rc2 |
439 |
* |
58292cbe6 sysfs: make attr ... |
440 |
* Hash the attribute name and namespace tag and kill the victim. |
1da177e4c Linux-2.6.12-rc2 |
441 |
*/ |
58292cbe6 sysfs: make attr ... |
442 443 |
void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, const void *ns) |
1da177e4c Linux-2.6.12-rc2 |
444 |
{ |
324a56e16 kernfs: s/sysfs_d... |
445 |
struct kernfs_node *parent = kobj->sd; |
487505c25 sysfs: Implement ... |
446 |
|
324a56e16 kernfs: s/sysfs_d... |
447 |
kernfs_remove_by_name_ns(parent, attr->name, ns); |
1da177e4c Linux-2.6.12-rc2 |
448 |
} |
58292cbe6 sysfs: make attr ... |
449 |
EXPORT_SYMBOL_GPL(sysfs_remove_file_ns); |
1da177e4c Linux-2.6.12-rc2 |
450 |
|
6b0afc2a2 kernfs, sysfs, dr... |
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
/** * sysfs_remove_file_self - remove an object attribute from its own method * @kobj: object we're acting for * @attr: attribute descriptor * * See kernfs_remove_self() for details. */ bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr) { struct kernfs_node *parent = kobj->sd; struct kernfs_node *kn; bool ret; kn = kernfs_find_and_get(parent, attr->name); if (WARN_ON_ONCE(!kn)) return false; ret = kernfs_remove_self(kn); kernfs_put(kn); return ret; } |
1b18dc2be sysfs: fix up spa... |
473 |
void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr) |
1c205ae18 sysfs: Add sysfs_... |
474 475 476 477 478 |
{ int i; for (i = 0; ptr[i]; i++) sysfs_remove_file(kobj, ptr[i]); } |
1b866757f sysfs: fix placem... |
479 |
EXPORT_SYMBOL_GPL(sysfs_remove_files); |
1da177e4c Linux-2.6.12-rc2 |
480 |
|
dfa87c824 sysfs: allow attr... |
481 482 483 484 485 486 487 488 489 |
/** * sysfs_remove_file_from_group - remove an attribute file from a group. * @kobj: object we're acting for. * @attr: attribute descriptor. * @group: group name. */ void sysfs_remove_file_from_group(struct kobject *kobj, const struct attribute *attr, const char *group) { |
324a56e16 kernfs: s/sysfs_d... |
490 |
struct kernfs_node *parent; |
dfa87c824 sysfs: allow attr... |
491 |
|
ccf73cf33 sysfs, kernfs: in... |
492 |
if (group) { |
324a56e16 kernfs: s/sysfs_d... |
493 |
parent = kernfs_find_and_get(kobj->sd, group); |
ccf73cf33 sysfs, kernfs: in... |
494 |
} else { |
324a56e16 kernfs: s/sysfs_d... |
495 496 |
parent = kobj->sd; kernfs_get(parent); |
ccf73cf33 sysfs, kernfs: in... |
497 |
} |
324a56e16 kernfs: s/sysfs_d... |
498 499 500 |
if (parent) { kernfs_remove_by_name(parent, attr->name); kernfs_put(parent); |
dfa87c824 sysfs: allow attr... |
501 502 503 |
} } EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); |
3124eb167 sysfs: merge regu... |
504 505 506 507 508 509 510 511 512 |
/** * sysfs_create_bin_file - create binary file for object. * @kobj: object. * @attr: attribute descriptor. */ int sysfs_create_bin_file(struct kobject *kobj, const struct bin_attribute *attr) { BUG_ON(!kobj || !kobj->sd || !attr); |
a7dc66dfb sysfs, kernfs: re... |
513 |
return sysfs_add_file(kobj->sd, &attr->attr, true); |
3124eb167 sysfs: merge regu... |
514 515 516 517 518 519 520 521 522 523 524 |
} EXPORT_SYMBOL_GPL(sysfs_create_bin_file); /** * sysfs_remove_bin_file - remove binary file for object. * @kobj: object. * @attr: attribute descriptor. */ void sysfs_remove_bin_file(struct kobject *kobj, const struct bin_attribute *attr) { |
879f40d19 sysfs, kernfs: in... |
525 |
kernfs_remove_by_name(kobj->sd, attr->attr.name); |
3124eb167 sysfs: merge regu... |
526 527 |
} EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); |