aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/bin.c13
-rw-r--r--fs/sysfs/dir.c61
-rw-r--r--fs/sysfs/file.c82
-rw-r--r--fs/sysfs/group.c92
-rw-r--r--fs/sysfs/inode.c21
-rw-r--r--fs/sysfs/mount.c13
-rw-r--r--fs/sysfs/symlink.c18
-rw-r--r--fs/sysfs/sysfs.h18
8 files changed, 189 insertions, 129 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 15c68f9489ae..c590cabd57bb 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -22,8 +22,7 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25 25#include <linux/uaccess.h>
26#include <asm/uaccess.h>
27 26
28#include "sysfs.h" 27#include "sysfs.h"
29 28
@@ -391,7 +390,7 @@ out_unlock:
391 return rc; 390 return rc;
392} 391}
393 392
394static int open(struct inode * inode, struct file * file) 393static int open(struct inode *inode, struct file *file)
395{ 394{
396 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 395 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
397 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; 396 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
@@ -435,7 +434,7 @@ static int open(struct inode * inode, struct file * file)
435 return error; 434 return error;
436} 435}
437 436
438static int release(struct inode * inode, struct file * file) 437static int release(struct inode *inode, struct file *file)
439{ 438{
440 struct bin_buffer *bb = file->private_data; 439 struct bin_buffer *bb = file->private_data;
441 440
@@ -481,7 +480,6 @@ void unmap_bin_file(struct sysfs_dirent *attr_sd)
481 * @kobj: object. 480 * @kobj: object.
482 * @attr: attribute descriptor. 481 * @attr: attribute descriptor.
483 */ 482 */
484
485int sysfs_create_bin_file(struct kobject *kobj, 483int sysfs_create_bin_file(struct kobject *kobj,
486 const struct bin_attribute *attr) 484 const struct bin_attribute *attr)
487{ 485{
@@ -489,19 +487,16 @@ int sysfs_create_bin_file(struct kobject *kobj,
489 487
490 return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR); 488 return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR);
491} 489}
492 490EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
493 491
494/** 492/**
495 * sysfs_remove_bin_file - remove binary file for object. 493 * sysfs_remove_bin_file - remove binary file for object.
496 * @kobj: object. 494 * @kobj: object.
497 * @attr: attribute descriptor. 495 * @attr: attribute descriptor.
498 */ 496 */
499
500void sysfs_remove_bin_file(struct kobject *kobj, 497void sysfs_remove_bin_file(struct kobject *kobj,
501 const struct bin_attribute *attr) 498 const struct bin_attribute *attr)
502{ 499{
503 sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name); 500 sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name);
504} 501}
505
506EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
507EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); 502EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index e068e744dbdd..4d83cedb9fcb 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -46,7 +46,7 @@ static unsigned int sysfs_name_hash(const void *ns, const char *name)
46 unsigned int len = strlen(name); 46 unsigned int len = strlen(name);
47 while (len--) 47 while (len--)
48 hash = partial_name_hash(*name++, hash); 48 hash = partial_name_hash(*name++, hash);
49 hash = ( end_name_hash(hash) ^ hash_ptr( (void *)ns, 31 ) ); 49 hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
50 hash &= 0x7fffffffU; 50 hash &= 0x7fffffffU;
51 /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */ 51 /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
52 if (hash < 1) 52 if (hash < 1)
@@ -258,7 +258,7 @@ static void sysfs_free_ino(unsigned int ino)
258 spin_unlock(&sysfs_ino_lock); 258 spin_unlock(&sysfs_ino_lock);
259} 259}
260 260
261void release_sysfs_dirent(struct sysfs_dirent * sd) 261void release_sysfs_dirent(struct sysfs_dirent *sd)
262{ 262{
263 struct sysfs_dirent *parent_sd; 263 struct sysfs_dirent *parent_sd;
264 264
@@ -297,7 +297,6 @@ static int sysfs_dentry_delete(const struct dentry *dentry)
297static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags) 297static int sysfs_dentry_revalidate(struct dentry *dentry, unsigned int flags)
298{ 298{
299 struct sysfs_dirent *sd; 299 struct sysfs_dirent *sd;
300 int is_dir;
301 int type; 300 int type;
302 301
303 if (flags & LOOKUP_RCU) 302 if (flags & LOOKUP_RCU)
@@ -341,18 +340,15 @@ out_bad:
341 * is performed at its new name the dentry will be readded 340 * is performed at its new name the dentry will be readded
342 * to the dcache hashes. 341 * to the dcache hashes.
343 */ 342 */
344 is_dir = (sysfs_type(sd) == SYSFS_DIR);
345 mutex_unlock(&sysfs_mutex); 343 mutex_unlock(&sysfs_mutex);
346 if (is_dir) { 344
347 /* If we have submounts we must allow the vfs caches 345 /* If we have submounts we must allow the vfs caches
348 * to lie about the state of the filesystem to prevent 346 * to lie about the state of the filesystem to prevent
349 * leaks and other nasty things. 347 * leaks and other nasty things.
350 */ 348 */
351 if (have_submounts(dentry)) 349 if (check_submounts_and_drop(dentry) != 0)
352 goto out_valid; 350 goto out_valid;
353 shrink_dcache_parent(dentry); 351
354 }
355 d_drop(dentry);
356 return 0; 352 return 0;
357} 353}
358 354
@@ -451,7 +447,7 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
451 447
452 if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { 448 if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) {
453 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", 449 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
454 sysfs_ns_type(acxt->parent_sd)? "required": "invalid", 450 sysfs_ns_type(acxt->parent_sd) ? "required" : "invalid",
455 acxt->parent_sd->s_name, sd->s_name); 451 acxt->parent_sd->s_name, sd->s_name);
456 return -EINVAL; 452 return -EINVAL;
457 } 453 }
@@ -619,7 +615,7 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
619 615
620 if (!!sysfs_ns_type(parent_sd) != !!ns) { 616 if (!!sysfs_ns_type(parent_sd) != !!ns) {
621 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", 617 WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n",
622 sysfs_ns_type(parent_sd)? "required": "invalid", 618 sysfs_ns_type(parent_sd) ? "required" : "invalid",
623 parent_sd->s_name, name); 619 parent_sd->s_name, name);
624 return NULL; 620 return NULL;
625 } 621 }
@@ -674,7 +670,7 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
674 enum kobj_ns_type type, const void *ns, const char *name, 670 enum kobj_ns_type type, const void *ns, const char *name,
675 struct sysfs_dirent **p_sd) 671 struct sysfs_dirent **p_sd)
676{ 672{
677 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 673 umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
678 struct sysfs_addrm_cxt acxt; 674 struct sysfs_addrm_cxt acxt;
679 struct sysfs_dirent *sd; 675 struct sysfs_dirent *sd;
680 int rc; 676 int rc;
@@ -735,9 +731,9 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
735 731
736/** 732/**
737 * sysfs_create_dir - create a directory for an object. 733 * sysfs_create_dir - create a directory for an object.
738 * @kobj: object we're creating directory for. 734 * @kobj: object we're creating directory for.
739 */ 735 */
740int sysfs_create_dir(struct kobject * kobj) 736int sysfs_create_dir(struct kobject *kobj)
741{ 737{
742 enum kobj_ns_type type; 738 enum kobj_ns_type type;
743 struct sysfs_dirent *parent_sd, *sd; 739 struct sysfs_dirent *parent_sd, *sd;
@@ -764,8 +760,8 @@ int sysfs_create_dir(struct kobject * kobj)
764 return error; 760 return error;
765} 761}
766 762
767static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, 763static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
768 unsigned int flags) 764 unsigned int flags)
769{ 765{
770 struct dentry *ret = NULL; 766 struct dentry *ret = NULL;
771 struct dentry *parent = dentry->d_parent; 767 struct dentry *parent = dentry->d_parent;
@@ -857,7 +853,7 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
857 * what used to be sysfs_rmdir() below, instead of calling separately. 853 * what used to be sysfs_rmdir() below, instead of calling separately.
858 */ 854 */
859 855
860void sysfs_remove_dir(struct kobject * kobj) 856void sysfs_remove_dir(struct kobject *kobj)
861{ 857{
862 struct sysfs_dirent *sd = kobj->sd; 858 struct sysfs_dirent *sd = kobj->sd;
863 859
@@ -896,7 +892,9 @@ int sysfs_rename(struct sysfs_dirent *sd,
896 sd->s_name = new_name; 892 sd->s_name = new_name;
897 } 893 }
898 894
899 /* Move to the appropriate place in the appropriate directories rbtree. */ 895 /*
896 * Move to the appropriate place in the appropriate directories rbtree.
897 */
900 sysfs_unlink_sibling(sd); 898 sysfs_unlink_sibling(sd);
901 sysfs_get(new_parent_sd); 899 sysfs_get(new_parent_sd);
902 sysfs_put(sd->s_parent); 900 sysfs_put(sd->s_parent);
@@ -988,20 +986,21 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns,
988 struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) 986 struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos)
989{ 987{
990 pos = sysfs_dir_pos(ns, parent_sd, ino, pos); 988 pos = sysfs_dir_pos(ns, parent_sd, ino, pos);
991 if (pos) do { 989 if (pos)
992 struct rb_node *node = rb_next(&pos->s_rb); 990 do {
993 if (!node) 991 struct rb_node *node = rb_next(&pos->s_rb);
994 pos = NULL; 992 if (!node)
995 else 993 pos = NULL;
996 pos = to_sysfs_dirent(node); 994 else
997 } while (pos && pos->s_ns != ns); 995 pos = to_sysfs_dirent(node);
996 } while (pos && pos->s_ns != ns);
998 return pos; 997 return pos;
999} 998}
1000 999
1001static int sysfs_readdir(struct file *file, struct dir_context *ctx) 1000static int sysfs_readdir(struct file *file, struct dir_context *ctx)
1002{ 1001{
1003 struct dentry *dentry = file->f_path.dentry; 1002 struct dentry *dentry = file->f_path.dentry;
1004 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 1003 struct sysfs_dirent *parent_sd = dentry->d_fsdata;
1005 struct sysfs_dirent *pos = file->private_data; 1004 struct sysfs_dirent *pos = file->private_data;
1006 enum kobj_ns_type type; 1005 enum kobj_ns_type type;
1007 const void *ns; 1006 const void *ns;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d2bb7ed8fa74..15ef5eb13663 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -20,7 +20,7 @@
20#include <linux/list.h> 20#include <linux/list.h>
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22#include <linux/limits.h> 22#include <linux/limits.h>
23#include <asm/uaccess.h> 23#include <linux/uaccess.h>
24 24
25#include "sysfs.h" 25#include "sysfs.h"
26 26
@@ -45,8 +45,8 @@ struct sysfs_open_dirent {
45struct sysfs_buffer { 45struct sysfs_buffer {
46 size_t count; 46 size_t count;
47 loff_t pos; 47 loff_t pos;
48 char * page; 48 char *page;
49 const struct sysfs_ops * ops; 49 const struct sysfs_ops *ops;
50 struct mutex mutex; 50 struct mutex mutex;
51 int needs_read_fill; 51 int needs_read_fill;
52 int event; 52 int event;
@@ -59,16 +59,16 @@ struct sysfs_buffer {
59 * @buffer: data buffer for file. 59 * @buffer: data buffer for file.
60 * 60 *
61 * Allocate @buffer->page, if it hasn't been already, then call the 61 * Allocate @buffer->page, if it hasn't been already, then call the
62 * kobject's show() method to fill the buffer with this attribute's 62 * kobject's show() method to fill the buffer with this attribute's
63 * data. 63 * data.
64 * This is called only once, on the file's first read unless an error 64 * This is called only once, on the file's first read unless an error
65 * is returned. 65 * is returned.
66 */ 66 */
67static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) 67static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)
68{ 68{
69 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 69 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
70 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 70 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
71 const struct sysfs_ops * ops = buffer->ops; 71 const struct sysfs_ops *ops = buffer->ops;
72 int ret = 0; 72 int ret = 0;
73 ssize_t count; 73 ssize_t count;
74 74
@@ -106,7 +106,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
106} 106}
107 107
108/** 108/**
109 * sysfs_read_file - read an attribute. 109 * sysfs_read_file - read an attribute.
110 * @file: file pointer. 110 * @file: file pointer.
111 * @buf: buffer to fill. 111 * @buf: buffer to fill.
112 * @count: number of bytes to read. 112 * @count: number of bytes to read.
@@ -127,12 +127,12 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
127static ssize_t 127static ssize_t
128sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) 128sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
129{ 129{
130 struct sysfs_buffer * buffer = file->private_data; 130 struct sysfs_buffer *buffer = file->private_data;
131 ssize_t retval = 0; 131 ssize_t retval = 0;
132 132
133 mutex_lock(&buffer->mutex); 133 mutex_lock(&buffer->mutex);
134 if (buffer->needs_read_fill || *ppos == 0) { 134 if (buffer->needs_read_fill || *ppos == 0) {
135 retval = fill_read_buffer(file->f_path.dentry,buffer); 135 retval = fill_read_buffer(file->f_path.dentry, buffer);
136 if (retval) 136 if (retval)
137 goto out; 137 goto out;
138 } 138 }
@@ -154,9 +154,8 @@ out:
154 * Allocate @buffer->page if it hasn't been already, then 154 * Allocate @buffer->page if it hasn't been already, then
155 * copy the user-supplied buffer into it. 155 * copy the user-supplied buffer into it.
156 */ 156 */
157 157static int fill_write_buffer(struct sysfs_buffer *buffer,
158static int 158 const char __user *buf, size_t count)
159fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t count)
160{ 159{
161 int error; 160 int error;
162 161
@@ -167,7 +166,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
167 166
168 if (count >= PAGE_SIZE) 167 if (count >= PAGE_SIZE)
169 count = PAGE_SIZE - 1; 168 count = PAGE_SIZE - 1;
170 error = copy_from_user(buffer->page,buf,count); 169 error = copy_from_user(buffer->page, buf, count);
171 buffer->needs_read_fill = 1; 170 buffer->needs_read_fill = 1;
172 /* if buf is assumed to contain a string, terminate it by \0, 171 /* if buf is assumed to contain a string, terminate it by \0,
173 so e.g. sscanf() can scan the string easily */ 172 so e.g. sscanf() can scan the string easily */
@@ -183,16 +182,15 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
183 * @count: number of bytes 182 * @count: number of bytes
184 * 183 *
185 * Get the correct pointers for the kobject and the attribute we're 184 * Get the correct pointers for the kobject and the attribute we're
186 * dealing with, then call the store() method for the attribute, 185 * dealing with, then call the store() method for the attribute,
187 * passing the buffer that we acquired in fill_write_buffer(). 186 * passing the buffer that we acquired in fill_write_buffer().
188 */ 187 */
189 188static int flush_write_buffer(struct dentry *dentry,
190static int 189 struct sysfs_buffer *buffer, size_t count)
191flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count)
192{ 190{
193 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 191 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
194 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 192 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
195 const struct sysfs_ops * ops = buffer->ops; 193 const struct sysfs_ops *ops = buffer->ops;
196 int rc; 194 int rc;
197 195
198 /* need attr_sd for attr and ops, its parent for kobj */ 196 /* need attr_sd for attr and ops, its parent for kobj */
@@ -219,15 +217,14 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t
219 * then push it to the kobject in flush_write_buffer(). 217 * then push it to the kobject in flush_write_buffer().
220 * There is no easy way for us to know if userspace is only doing a partial 218 * There is no easy way for us to know if userspace is only doing a partial
221 * write, so we don't support them. We expect the entire buffer to come 219 * write, so we don't support them. We expect the entire buffer to come
222 * on the first write. 220 * on the first write.
223 * Hint: if you're writing a value, first read the file, modify only the 221 * Hint: if you're writing a value, first read the file, modify only the
224 * the value you're changing, then write entire buffer back. 222 * the value you're changing, then write entire buffer back.
225 */ 223 */
226 224static ssize_t sysfs_write_file(struct file *file, const char __user *buf,
227static ssize_t 225 size_t count, loff_t *ppos)
228sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
229{ 226{
230 struct sysfs_buffer * buffer = file->private_data; 227 struct sysfs_buffer *buffer = file->private_data;
231 ssize_t len; 228 ssize_t len;
232 229
233 mutex_lock(&buffer->mutex); 230 mutex_lock(&buffer->mutex);
@@ -339,13 +336,14 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
339 if (kobj->ktype && kobj->ktype->sysfs_ops) 336 if (kobj->ktype && kobj->ktype->sysfs_ops)
340 ops = kobj->ktype->sysfs_ops; 337 ops = kobj->ktype->sysfs_ops;
341 else { 338 else {
342 WARN(1, KERN_ERR "missing sysfs attribute operations for " 339 WARN(1, KERN_ERR
343 "kobject: %s\n", kobject_name(kobj)); 340 "missing sysfs attribute operations for kobject: %s\n",
341 kobject_name(kobj));
344 goto err_out; 342 goto err_out;
345 } 343 }
346 344
347 /* File needs write support. 345 /* File needs write support.
348 * The inode's perms must say it's ok, 346 * The inode's perms must say it's ok,
349 * and we must have a store method. 347 * and we must have a store method.
350 */ 348 */
351 if (file->f_mode & FMODE_WRITE) { 349 if (file->f_mode & FMODE_WRITE) {
@@ -420,7 +418,7 @@ static int sysfs_release(struct inode *inode, struct file *filp)
420 */ 418 */
421static unsigned int sysfs_poll(struct file *filp, poll_table *wait) 419static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
422{ 420{
423 struct sysfs_buffer * buffer = filp->private_data; 421 struct sysfs_buffer *buffer = filp->private_data;
424 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; 422 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
425 struct sysfs_open_dirent *od = attr_sd->s_attr.open; 423 struct sysfs_open_dirent *od = attr_sd->s_attr.open;
426 424
@@ -518,8 +516,9 @@ static int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
518 ns = ops->namespace(kobj, attr); 516 ns = ops->namespace(kobj, attr);
519out: 517out:
520 if (err) { 518 if (err) {
521 WARN(1, KERN_ERR "missing sysfs namespace attribute operation for " 519 WARN(1, KERN_ERR
522 "kobject: %s\n", kobject_name(kobj)); 520 "missing sysfs namespace attribute operation for kobject: %s\n",
521 kobject_name(kobj));
523 } 522 }
524 *pns = ns; 523 *pns = ns;
525 return err; 524 return err;
@@ -566,17 +565,17 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
566 565
567/** 566/**
568 * sysfs_create_file - create an attribute file for an object. 567 * sysfs_create_file - create an attribute file for an object.
569 * @kobj: object we're creating for. 568 * @kobj: object we're creating for.
570 * @attr: attribute descriptor. 569 * @attr: attribute descriptor.
571 */ 570 */
572 571int sysfs_create_file(struct kobject *kobj, const struct attribute *attr)
573int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
574{ 572{
575 BUG_ON(!kobj || !kobj->sd || !attr); 573 BUG_ON(!kobj || !kobj->sd || !attr);
576 574
577 return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR); 575 return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);
578 576
579} 577}
578EXPORT_SYMBOL_GPL(sysfs_create_file);
580 579
581int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) 580int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
582{ 581{
@@ -590,6 +589,7 @@ int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
590 sysfs_remove_file(kobj, ptr[i]); 589 sysfs_remove_file(kobj, ptr[i]);
591 return err; 590 return err;
592} 591}
592EXPORT_SYMBOL_GPL(sysfs_create_files);
593 593
594/** 594/**
595 * sysfs_add_file_to_group - add an attribute file to a pre-existing group. 595 * sysfs_add_file_to_group - add an attribute file to a pre-existing group.
@@ -654,7 +654,6 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
654} 654}
655EXPORT_SYMBOL_GPL(sysfs_chmod_file); 655EXPORT_SYMBOL_GPL(sysfs_chmod_file);
656 656
657
658/** 657/**
659 * sysfs_remove_file - remove an object attribute. 658 * sysfs_remove_file - remove an object attribute.
660 * @kobj: object we're acting for. 659 * @kobj: object we're acting for.
@@ -662,8 +661,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
662 * 661 *
663 * Hash the attribute name and kill the victim. 662 * Hash the attribute name and kill the victim.
664 */ 663 */
665 664void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr)
666void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
667{ 665{
668 const void *ns; 666 const void *ns;
669 667
@@ -672,13 +670,15 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
672 670
673 sysfs_hash_and_remove(kobj->sd, ns, attr->name); 671 sysfs_hash_and_remove(kobj->sd, ns, attr->name);
674} 672}
673EXPORT_SYMBOL_GPL(sysfs_remove_file);
675 674
676void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) 675void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
677{ 676{
678 int i; 677 int i;
679 for (i = 0; ptr[i]; i++) 678 for (i = 0; ptr[i]; i++)
680 sysfs_remove_file(kobj, ptr[i]); 679 sysfs_remove_file(kobj, ptr[i]);
681} 680}
681EXPORT_SYMBOL_GPL(sysfs_remove_files);
682 682
683/** 683/**
684 * sysfs_remove_file_from_group - remove an attribute file from a group. 684 * sysfs_remove_file_from_group - remove an attribute file from a group.
@@ -793,9 +793,3 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
793 return 0; 793 return 0;
794} 794}
795EXPORT_SYMBOL_GPL(sysfs_schedule_callback); 795EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
796
797
798EXPORT_SYMBOL_GPL(sysfs_create_file);
799EXPORT_SYMBOL_GPL(sysfs_remove_file);
800EXPORT_SYMBOL_GPL(sysfs_remove_files);
801EXPORT_SYMBOL_GPL(sysfs_create_files);
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 09a1a25cd145..5f92cd2f61c1 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -3,8 +3,10 @@
3 * 3 *
4 * Copyright (c) 2003 Patrick Mochel 4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Open Source Development Lab 5 * Copyright (c) 2003 Open Source Development Lab
6 * Copyright (c) 2013 Greg Kroah-Hartman
7 * Copyright (c) 2013 The Linux Foundation
6 * 8 *
7 * This file is released undert the GPL v2. 9 * This file is released undert the GPL v2.
8 * 10 *
9 */ 11 */
10 12
@@ -19,8 +21,8 @@
19static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, 21static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
20 const struct attribute_group *grp) 22 const struct attribute_group *grp)
21{ 23{
22 struct attribute *const* attr; 24 struct attribute *const *attr;
23 struct bin_attribute *const* bin_attr; 25 struct bin_attribute *const *bin_attr;
24 26
25 if (grp->attrs) 27 if (grp->attrs)
26 for (attr = grp->attrs; *attr; attr++) 28 for (attr = grp->attrs; *attr; attr++)
@@ -33,8 +35,8 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
33static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, 35static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
34 const struct attribute_group *grp, int update) 36 const struct attribute_group *grp, int update)
35{ 37{
36 struct attribute *const* attr; 38 struct attribute *const *attr;
37 struct bin_attribute *const* bin_attr; 39 struct bin_attribute *const *bin_attr;
38 int error = 0, i; 40 int error = 0, i;
39 41
40 if (grp->attrs) { 42 if (grp->attrs) {
@@ -129,6 +131,41 @@ int sysfs_create_group(struct kobject *kobj,
129{ 131{
130 return internal_create_group(kobj, 0, grp); 132 return internal_create_group(kobj, 0, grp);
131} 133}
134EXPORT_SYMBOL_GPL(sysfs_create_group);
135
136/**
137 * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups
138 * @kobj: The kobject to create the group on
139 * @groups: The attribute groups to create, NULL terminated
140 *
141 * This function creates a bunch of attribute groups. If an error occurs when
142 * creating a group, all previously created groups will be removed, unwinding
143 * everything back to the original state when this function was called.
144 * It will explicitly warn and error if any of the attribute files being
145 * created already exist.
146 *
147 * Returns 0 on success or error code from sysfs_create_group on error.
148 */
149int sysfs_create_groups(struct kobject *kobj,
150 const struct attribute_group **groups)
151{
152 int error = 0;
153 int i;
154
155 if (!groups)
156 return 0;
157
158 for (i = 0; groups[i]; i++) {
159 error = sysfs_create_group(kobj, groups[i]);
160 if (error) {
161 while (--i >= 0)
162 sysfs_remove_group(kobj, groups[i]);
163 break;
164 }
165 }
166 return error;
167}
168EXPORT_SYMBOL_GPL(sysfs_create_groups);
132 169
133/** 170/**
134 * sysfs_update_group - given a directory kobject, update an attribute group 171 * sysfs_update_group - given a directory kobject, update an attribute group
@@ -152,11 +189,18 @@ int sysfs_update_group(struct kobject *kobj,
152{ 189{
153 return internal_create_group(kobj, 1, grp); 190 return internal_create_group(kobj, 1, grp);
154} 191}
192EXPORT_SYMBOL_GPL(sysfs_update_group);
155 193
156 194/**
157 195 * sysfs_remove_group: remove a group from a kobject
158void sysfs_remove_group(struct kobject * kobj, 196 * @kobj: kobject to remove the group from
159 const struct attribute_group * grp) 197 * @grp: group to remove
198 *
199 * This function removes a group of attributes from a kobject. The attributes
200 * previously have to have been created for this group, otherwise it will fail.
201 */
202void sysfs_remove_group(struct kobject *kobj,
203 const struct attribute_group *grp)
160{ 204{
161 struct sysfs_dirent *dir_sd = kobj->sd; 205 struct sysfs_dirent *dir_sd = kobj->sd;
162 struct sysfs_dirent *sd; 206 struct sysfs_dirent *sd;
@@ -164,8 +208,9 @@ void sysfs_remove_group(struct kobject * kobj,
164 if (grp->name) { 208 if (grp->name) {
165 sd = sysfs_get_dirent(dir_sd, NULL, grp->name); 209 sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
166 if (!sd) { 210 if (!sd) {
167 WARN(!sd, KERN_WARNING "sysfs group %p not found for " 211 WARN(!sd, KERN_WARNING
168 "kobject '%s'\n", grp, kobject_name(kobj)); 212 "sysfs group %p not found for kobject '%s'\n",
213 grp, kobject_name(kobj));
169 return; 214 return;
170 } 215 }
171 } else 216 } else
@@ -177,6 +222,27 @@ void sysfs_remove_group(struct kobject * kobj,
177 222
178 sysfs_put(sd); 223 sysfs_put(sd);
179} 224}
225EXPORT_SYMBOL_GPL(sysfs_remove_group);
226
227/**
228 * sysfs_remove_groups - remove a list of groups
229 *
230 * @kobj: The kobject for the groups to be removed from
231 * @groups: NULL terminated list of groups to be removed
232 *
233 * If groups is not NULL, remove the specified groups from the kobject.
234 */
235void sysfs_remove_groups(struct kobject *kobj,
236 const struct attribute_group **groups)
237{
238 int i;
239
240 if (!groups)
241 return;
242 for (i = 0; groups[i]; i++)
243 sysfs_remove_group(kobj, groups[i]);
244}
245EXPORT_SYMBOL_GPL(sysfs_remove_groups);
180 246
181/** 247/**
182 * sysfs_merge_group - merge files into a pre-existing attribute group. 248 * sysfs_merge_group - merge files into a pre-existing attribute group.
@@ -273,7 +339,3 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
273 } 339 }
274} 340}
275EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); 341EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group);
276
277EXPORT_SYMBOL_GPL(sysfs_create_group);
278EXPORT_SYMBOL_GPL(sysfs_update_group);
279EXPORT_SYMBOL_GPL(sysfs_remove_group);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 3e2837a633ed..963f910c8034 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -10,7 +10,7 @@
10 * Please see Documentation/filesystems/sysfs.txt for more information. 10 * Please see Documentation/filesystems/sysfs.txt for more information.
11 */ 11 */
12 12
13#undef DEBUG 13#undef DEBUG
14 14
15#include <linux/pagemap.h> 15#include <linux/pagemap.h>
16#include <linux/namei.h> 16#include <linux/namei.h>
@@ -36,7 +36,7 @@ static struct backing_dev_info sysfs_backing_dev_info = {
36 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, 36 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
37}; 37};
38 38
39static const struct inode_operations sysfs_inode_operations ={ 39static const struct inode_operations sysfs_inode_operations = {
40 .permission = sysfs_permission, 40 .permission = sysfs_permission,
41 .setattr = sysfs_setattr, 41 .setattr = sysfs_setattr,
42 .getattr = sysfs_getattr, 42 .getattr = sysfs_getattr,
@@ -67,7 +67,7 @@ static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
67 return attrs; 67 return attrs;
68} 68}
69 69
70int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr) 70int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr)
71{ 71{
72 struct sysfs_inode_attrs *sd_attrs; 72 struct sysfs_inode_attrs *sd_attrs;
73 struct iattr *iattrs; 73 struct iattr *iattrs;
@@ -128,7 +128,8 @@ out:
128 return error; 128 return error;
129} 129}
130 130
131static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *secdata_len) 131static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata,
132 u32 *secdata_len)
132{ 133{
133 struct sysfs_inode_attrs *iattrs; 134 struct sysfs_inode_attrs *iattrs;
134 void *old_secdata; 135 void *old_secdata;
@@ -186,13 +187,13 @@ out:
186 return error; 187 return error;
187} 188}
188 189
189static inline void set_default_inode_attr(struct inode * inode, umode_t mode) 190static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
190{ 191{
191 inode->i_mode = mode; 192 inode->i_mode = mode;
192 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 193 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
193} 194}
194 195
195static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) 196static inline void set_inode_attr(struct inode *inode, struct iattr *iattr)
196{ 197{
197 inode->i_uid = iattr->ia_uid; 198 inode->i_uid = iattr->ia_uid;
198 inode->i_gid = iattr->ia_gid; 199 inode->i_gid = iattr->ia_gid;
@@ -220,7 +221,8 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode)
220 set_nlink(inode, sd->s_dir.subdirs + 2); 221 set_nlink(inode, sd->s_dir.subdirs + 2);
221} 222}
222 223
223int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 224int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
225 struct kstat *stat)
224{ 226{
225 struct sysfs_dirent *sd = dentry->d_fsdata; 227 struct sysfs_dirent *sd = dentry->d_fsdata;
226 struct inode *inode = dentry->d_inode; 228 struct inode *inode = dentry->d_inode;
@@ -285,7 +287,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
285 * RETURNS: 287 * RETURNS:
286 * Pointer to allocated inode on success, NULL on failure. 288 * Pointer to allocated inode on success, NULL on failure.
287 */ 289 */
288struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd) 290struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
289{ 291{
290 struct inode *inode; 292 struct inode *inode;
291 293
@@ -312,7 +314,8 @@ void sysfs_evict_inode(struct inode *inode)
312 sysfs_put(sd); 314 sysfs_put(sd);
313} 315}
314 316
315int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name) 317int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
318 const char *name)
316{ 319{
317 struct sysfs_addrm_cxt acxt; 320 struct sysfs_addrm_cxt acxt;
318 struct sysfs_dirent *sd; 321 struct sysfs_dirent *sd;
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index afd83273e6ce..834ec2cdb7a3 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -64,7 +64,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
64 /* instantiate and link root dentry */ 64 /* instantiate and link root dentry */
65 root = d_make_root(inode); 65 root = d_make_root(inode);
66 if (!root) { 66 if (!root) {
67 pr_debug("%s: could not get root dentry!\n",__func__); 67 pr_debug("%s: could not get root dentry!\n", __func__);
68 return -ENOMEM; 68 return -ENOMEM;
69 } 69 }
70 root->d_fsdata = &sysfs_root; 70 root->d_fsdata = &sysfs_root;
@@ -112,8 +112,15 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
112 struct super_block *sb; 112 struct super_block *sb;
113 int error; 113 int error;
114 114
115 if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs) 115 if (!(flags & MS_KERNMOUNT)) {
116 return ERR_PTR(-EPERM); 116 if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
117 return ERR_PTR(-EPERM);
118
119 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) {
120 if (!kobj_ns_current_may_mount(type))
121 return ERR_PTR(-EPERM);
122 }
123 }
117 124
118 info = kzalloc(sizeof(*info), GFP_KERNEL); 125 info = kzalloc(sizeof(*info), GFP_KERNEL);
119 if (!info) 126 if (!info)
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 8c940df97a52..2dd4507d9edd 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -125,6 +125,7 @@ int sysfs_create_link(struct kobject *kobj, struct kobject *target,
125{ 125{
126 return sysfs_do_create_link(kobj, target, name, 1); 126 return sysfs_do_create_link(kobj, target, name, 1);
127} 127}
128EXPORT_SYMBOL_GPL(sysfs_create_link);
128 129
129/** 130/**
130 * sysfs_create_link_nowarn - create symlink between two objects. 131 * sysfs_create_link_nowarn - create symlink between two objects.
@@ -166,8 +167,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
166 * @kobj: object we're acting for. 167 * @kobj: object we're acting for.
167 * @name: name of the symlink to remove. 168 * @name: name of the symlink to remove.
168 */ 169 */
169 170void sysfs_remove_link(struct kobject *kobj, const char *name)
170void sysfs_remove_link(struct kobject * kobj, const char * name)
171{ 171{
172 struct sysfs_dirent *parent_sd = NULL; 172 struct sysfs_dirent *parent_sd = NULL;
173 173
@@ -178,6 +178,7 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)
178 178
179 sysfs_hash_and_remove(parent_sd, NULL, name); 179 sysfs_hash_and_remove(parent_sd, NULL, name);
180} 180}
181EXPORT_SYMBOL_GPL(sysfs_remove_link);
181 182
182/** 183/**
183 * sysfs_rename_link - rename symlink in object's directory. 184 * sysfs_rename_link - rename symlink in object's directory.
@@ -223,6 +224,7 @@ out:
223 sysfs_put(sd); 224 sysfs_put(sd);
224 return result; 225 return result;
225} 226}
227EXPORT_SYMBOL_GPL(sysfs_rename_link);
226 228
227static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, 229static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
228 struct sysfs_dirent *target_sd, char *path) 230 struct sysfs_dirent *target_sd, char *path)
@@ -276,7 +278,7 @@ static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
276 return 0; 278 return 0;
277} 279}
278 280
279static int sysfs_getlink(struct dentry *dentry, char * path) 281static int sysfs_getlink(struct dentry *dentry, char *path)
280{ 282{
281 struct sysfs_dirent *sd = dentry->d_fsdata; 283 struct sysfs_dirent *sd = dentry->d_fsdata;
282 struct sysfs_dirent *parent_sd = sd->s_parent; 284 struct sysfs_dirent *parent_sd = sd->s_parent;
@@ -295,7 +297,7 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
295 int error = -ENOMEM; 297 int error = -ENOMEM;
296 unsigned long page = get_zeroed_page(GFP_KERNEL); 298 unsigned long page = get_zeroed_page(GFP_KERNEL);
297 if (page) { 299 if (page) {
298 error = sysfs_getlink(dentry, (char *) page); 300 error = sysfs_getlink(dentry, (char *) page);
299 if (error < 0) 301 if (error < 0)
300 free_page((unsigned long)page); 302 free_page((unsigned long)page);
301 } 303 }
@@ -303,7 +305,8 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
303 return NULL; 305 return NULL;
304} 306}
305 307
306static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) 308static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd,
309 void *cookie)
307{ 310{
308 char *page = nd_get_link(nd); 311 char *page = nd_get_link(nd);
309 if (!IS_ERR(page)) 312 if (!IS_ERR(page))
@@ -319,8 +322,3 @@ const struct inode_operations sysfs_symlink_inode_operations = {
319 .getattr = sysfs_getattr, 322 .getattr = sysfs_getattr,
320 .permission = sysfs_permission, 323 .permission = sysfs_permission,
321}; 324};
322
323
324EXPORT_SYMBOL_GPL(sysfs_create_link);
325EXPORT_SYMBOL_GPL(sysfs_remove_link);
326EXPORT_SYMBOL_GPL(sysfs_rename_link);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index d1e4043eb0c3..b6deca3e301d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -78,7 +78,7 @@ struct sysfs_dirent {
78 }; 78 };
79 79
80 unsigned short s_flags; 80 unsigned short s_flags;
81 umode_t s_mode; 81 umode_t s_mode;
82 unsigned int s_ino; 82 unsigned int s_ino;
83 struct sysfs_inode_attrs *s_iattr; 83 struct sysfs_inode_attrs *s_iattr;
84}; 84};
@@ -123,9 +123,9 @@ do { \
123 key = &attr->skey; \ 123 key = &attr->skey; \
124 \ 124 \
125 lockdep_init_map(&sd->dep_map, "s_active", key, 0); \ 125 lockdep_init_map(&sd->dep_map, "s_active", key, 0); \
126} while(0) 126} while (0)
127#else 127#else
128#define sysfs_dirent_init_lockdep(sd) do {} while(0) 128#define sysfs_dirent_init_lockdep(sd) do {} while (0)
129#endif 129#endif
130 130
131/* 131/*
@@ -186,8 +186,8 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
186 struct sysfs_dirent **p_sd); 186 struct sysfs_dirent **p_sd);
187void sysfs_remove_subdir(struct sysfs_dirent *sd); 187void sysfs_remove_subdir(struct sysfs_dirent *sd);
188 188
189int sysfs_rename(struct sysfs_dirent *sd, 189int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
190 struct sysfs_dirent *new_parent_sd, const void *ns, const char *new_name); 190 const void *ns, const char *new_name);
191 191
192static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) 192static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
193{ 193{
@@ -214,10 +214,12 @@ void sysfs_evict_inode(struct inode *inode);
214int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); 214int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
215int sysfs_permission(struct inode *inode, int mask); 215int sysfs_permission(struct inode *inode, int mask);
216int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); 216int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
217int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); 217int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
218 struct kstat *stat);
218int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, 219int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
219 size_t size, int flags); 220 size_t size, int flags);
220int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name); 221int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
222 const char *name);
221int sysfs_inode_init(void); 223int sysfs_inode_init(void);
222 224
223/* 225/*