diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:37:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:37:15 -0400 |
commit | 542a086ac72fb193cbc1b996963a572269e57743 (patch) | |
tree | b137c08037cca4ffc8a156a891a01113b3b8edce /fs | |
parent | 1d1fdd95df681f0c065d90ffaafa215a0e8825e2 (diff) | |
parent | 1eeeef153c02f5856ec109fa532eb5f31c39f85c (diff) |
Merge tag 'driver-core-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core patches from Greg KH:
"Here's the big driver core pull request for 3.12-rc1.
Lots of tiny changes here fixing up the way sysfs attributes are
created, to try to make drivers simpler, and fix a whole class race
conditions with creations of device attributes after the device was
announced to userspace.
All the various pieces are acked by the different subsystem
maintainers"
* tag 'driver-core-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (119 commits)
firmware loader: fix pending_fw_head list corruption
drivers/base/memory.c: introduce help macro to_memory_block
dynamic debug: line queries failing due to uninitialized local variable
sysfs: sysfs_create_groups returns a value.
debugfs: provide debugfs_create_x64() when disabled
rbd: convert bus code to use bus_groups
firmware: dcdbas: use binary attribute groups
sysfs: add sysfs_create/remove_groups for when SYSFS is not enabled
driver core: add #include <linux/sysfs.h> to core files.
HID: convert bus code to use dev_groups
Input: serio: convert bus code to use drv_groups
Input: gameport: convert bus code to use drv_groups
driver core: firmware: use __ATTR_RW()
driver core: core: use DEVICE_ATTR_RO
driver core: bus: use DRIVER_ATTR_WO()
driver core: create write-only attribute macros for devices and drivers
sysfs: create __ATTR_WO()
driver-core: platform: convert bus code to use dev_groups
workqueue: convert bus code to use dev_groups
MEI: convert bus code to use dev_groups
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/cuse.c | 13 | ||||
-rw-r--r-- | fs/sysfs/bin.c | 13 | ||||
-rw-r--r-- | fs/sysfs/dir.c | 41 | ||||
-rw-r--r-- | fs/sysfs/file.c | 82 | ||||
-rw-r--r-- | fs/sysfs/group.c | 92 | ||||
-rw-r--r-- | fs/sysfs/inode.c | 21 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 2 | ||||
-rw-r--r-- | fs/sysfs/symlink.c | 18 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 18 |
9 files changed, 180 insertions, 120 deletions
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index aef34b1e635e..adbfd66b380f 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c | |||
@@ -568,6 +568,7 @@ static ssize_t cuse_class_waiting_show(struct device *dev, | |||
568 | 568 | ||
569 | return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting)); | 569 | return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting)); |
570 | } | 570 | } |
571 | static DEVICE_ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL); | ||
571 | 572 | ||
572 | static ssize_t cuse_class_abort_store(struct device *dev, | 573 | static ssize_t cuse_class_abort_store(struct device *dev, |
573 | struct device_attribute *attr, | 574 | struct device_attribute *attr, |
@@ -578,12 +579,14 @@ static ssize_t cuse_class_abort_store(struct device *dev, | |||
578 | fuse_abort_conn(&cc->fc); | 579 | fuse_abort_conn(&cc->fc); |
579 | return count; | 580 | return count; |
580 | } | 581 | } |
582 | static DEVICE_ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store); | ||
581 | 583 | ||
582 | static struct device_attribute cuse_class_dev_attrs[] = { | 584 | static struct attribute *cuse_class_dev_attrs[] = { |
583 | __ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL), | 585 | &dev_attr_waiting.attr, |
584 | __ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store), | 586 | &dev_attr_abort.attr, |
585 | { } | 587 | NULL, |
586 | }; | 588 | }; |
589 | ATTRIBUTE_GROUPS(cuse_class_dev); | ||
587 | 590 | ||
588 | static struct miscdevice cuse_miscdev = { | 591 | static struct miscdevice cuse_miscdev = { |
589 | .minor = MISC_DYNAMIC_MINOR, | 592 | .minor = MISC_DYNAMIC_MINOR, |
@@ -609,7 +612,7 @@ static int __init cuse_init(void) | |||
609 | if (IS_ERR(cuse_class)) | 612 | if (IS_ERR(cuse_class)) |
610 | return PTR_ERR(cuse_class); | 613 | return PTR_ERR(cuse_class); |
611 | 614 | ||
612 | cuse_class->dev_attrs = cuse_class_dev_attrs; | 615 | cuse_class->dev_groups = cuse_class_dev_groups; |
613 | 616 | ||
614 | rc = misc_register(&cuse_miscdev); | 617 | rc = misc_register(&cuse_miscdev); |
615 | if (rc) { | 618 | if (rc) { |
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 | ||
394 | static int open(struct inode * inode, struct file * file) | 393 | static 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 | ||
438 | static int release(struct inode * inode, struct file * file) | 437 | static 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 | |||
485 | int sysfs_create_bin_file(struct kobject *kobj, | 483 | int 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 | 490 | EXPORT_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 | |||
500 | void sysfs_remove_bin_file(struct kobject *kobj, | 497 | void 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 | |||
506 | EXPORT_SYMBOL_GPL(sysfs_create_bin_file); | ||
507 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); | 502 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index e068e744dbdd..99ec5b40e977 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 | ||
261 | void release_sysfs_dirent(struct sysfs_dirent * sd) | 261 | void release_sysfs_dirent(struct sysfs_dirent *sd) |
262 | { | 262 | { |
263 | struct sysfs_dirent *parent_sd; | 263 | struct sysfs_dirent *parent_sd; |
264 | 264 | ||
@@ -451,7 +451,7 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
451 | 451 | ||
452 | if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { | 452 | if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { |
453 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", | 453 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", |
454 | sysfs_ns_type(acxt->parent_sd)? "required": "invalid", | 454 | sysfs_ns_type(acxt->parent_sd) ? "required" : "invalid", |
455 | acxt->parent_sd->s_name, sd->s_name); | 455 | acxt->parent_sd->s_name, sd->s_name); |
456 | return -EINVAL; | 456 | return -EINVAL; |
457 | } | 457 | } |
@@ -619,7 +619,7 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, | |||
619 | 619 | ||
620 | if (!!sysfs_ns_type(parent_sd) != !!ns) { | 620 | if (!!sysfs_ns_type(parent_sd) != !!ns) { |
621 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", | 621 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", |
622 | sysfs_ns_type(parent_sd)? "required": "invalid", | 622 | sysfs_ns_type(parent_sd) ? "required" : "invalid", |
623 | parent_sd->s_name, name); | 623 | parent_sd->s_name, name); |
624 | return NULL; | 624 | return NULL; |
625 | } | 625 | } |
@@ -674,7 +674,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, | 674 | enum kobj_ns_type type, const void *ns, const char *name, |
675 | struct sysfs_dirent **p_sd) | 675 | struct sysfs_dirent **p_sd) |
676 | { | 676 | { |
677 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 677 | umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; |
678 | struct sysfs_addrm_cxt acxt; | 678 | struct sysfs_addrm_cxt acxt; |
679 | struct sysfs_dirent *sd; | 679 | struct sysfs_dirent *sd; |
680 | int rc; | 680 | int rc; |
@@ -735,9 +735,9 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj) | |||
735 | 735 | ||
736 | /** | 736 | /** |
737 | * sysfs_create_dir - create a directory for an object. | 737 | * sysfs_create_dir - create a directory for an object. |
738 | * @kobj: object we're creating directory for. | 738 | * @kobj: object we're creating directory for. |
739 | */ | 739 | */ |
740 | int sysfs_create_dir(struct kobject * kobj) | 740 | int sysfs_create_dir(struct kobject *kobj) |
741 | { | 741 | { |
742 | enum kobj_ns_type type; | 742 | enum kobj_ns_type type; |
743 | struct sysfs_dirent *parent_sd, *sd; | 743 | struct sysfs_dirent *parent_sd, *sd; |
@@ -764,8 +764,8 @@ int sysfs_create_dir(struct kobject * kobj) | |||
764 | return error; | 764 | return error; |
765 | } | 765 | } |
766 | 766 | ||
767 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | 767 | static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, |
768 | unsigned int flags) | 768 | unsigned int flags) |
769 | { | 769 | { |
770 | struct dentry *ret = NULL; | 770 | struct dentry *ret = NULL; |
771 | struct dentry *parent = dentry->d_parent; | 771 | struct dentry *parent = dentry->d_parent; |
@@ -857,7 +857,7 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd) | |||
857 | * what used to be sysfs_rmdir() below, instead of calling separately. | 857 | * what used to be sysfs_rmdir() below, instead of calling separately. |
858 | */ | 858 | */ |
859 | 859 | ||
860 | void sysfs_remove_dir(struct kobject * kobj) | 860 | void sysfs_remove_dir(struct kobject *kobj) |
861 | { | 861 | { |
862 | struct sysfs_dirent *sd = kobj->sd; | 862 | struct sysfs_dirent *sd = kobj->sd; |
863 | 863 | ||
@@ -896,7 +896,9 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
896 | sd->s_name = new_name; | 896 | sd->s_name = new_name; |
897 | } | 897 | } |
898 | 898 | ||
899 | /* Move to the appropriate place in the appropriate directories rbtree. */ | 899 | /* |
900 | * Move to the appropriate place in the appropriate directories rbtree. | ||
901 | */ | ||
900 | sysfs_unlink_sibling(sd); | 902 | sysfs_unlink_sibling(sd); |
901 | sysfs_get(new_parent_sd); | 903 | sysfs_get(new_parent_sd); |
902 | sysfs_put(sd->s_parent); | 904 | sysfs_put(sd->s_parent); |
@@ -988,20 +990,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) | 990 | struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) |
989 | { | 991 | { |
990 | pos = sysfs_dir_pos(ns, parent_sd, ino, pos); | 992 | pos = sysfs_dir_pos(ns, parent_sd, ino, pos); |
991 | if (pos) do { | 993 | if (pos) |
992 | struct rb_node *node = rb_next(&pos->s_rb); | 994 | do { |
993 | if (!node) | 995 | struct rb_node *node = rb_next(&pos->s_rb); |
994 | pos = NULL; | 996 | if (!node) |
995 | else | 997 | pos = NULL; |
996 | pos = to_sysfs_dirent(node); | 998 | else |
997 | } while (pos && pos->s_ns != ns); | 999 | pos = to_sysfs_dirent(node); |
1000 | } while (pos && pos->s_ns != ns); | ||
998 | return pos; | 1001 | return pos; |
999 | } | 1002 | } |
1000 | 1003 | ||
1001 | static int sysfs_readdir(struct file *file, struct dir_context *ctx) | 1004 | static int sysfs_readdir(struct file *file, struct dir_context *ctx) |
1002 | { | 1005 | { |
1003 | struct dentry *dentry = file->f_path.dentry; | 1006 | struct dentry *dentry = file->f_path.dentry; |
1004 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | 1007 | struct sysfs_dirent *parent_sd = dentry->d_fsdata; |
1005 | struct sysfs_dirent *pos = file->private_data; | 1008 | struct sysfs_dirent *pos = file->private_data; |
1006 | enum kobj_ns_type type; | 1009 | enum kobj_ns_type type; |
1007 | const void *ns; | 1010 | 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 { | |||
45 | struct sysfs_buffer { | 45 | struct 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 | */ |
67 | static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) | 67 | static 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 | |||
127 | static ssize_t | 127 | static ssize_t |
128 | sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 128 | sysfs_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 | 157 | static int fill_write_buffer(struct sysfs_buffer *buffer, | |
158 | static int | 158 | const char __user *buf, size_t count) |
159 | fill_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 | 188 | static int flush_write_buffer(struct dentry *dentry, | |
190 | static int | 189 | struct sysfs_buffer *buffer, size_t count) |
191 | flush_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 | 224 | static ssize_t sysfs_write_file(struct file *file, const char __user *buf, | |
227 | static ssize_t | 225 | size_t count, loff_t *ppos) |
228 | sysfs_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 | */ |
421 | static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | 419 | static 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); |
519 | out: | 517 | out: |
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 | 571 | int sysfs_create_file(struct kobject *kobj, const struct attribute *attr) | |
573 | int 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 | } |
578 | EXPORT_SYMBOL_GPL(sysfs_create_file); | ||
580 | 579 | ||
581 | int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) | 580 | int 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 | } |
592 | EXPORT_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 | } |
655 | EXPORT_SYMBOL_GPL(sysfs_chmod_file); | 655 | EXPORT_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 | 664 | void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr) | |
666 | void 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 | } |
673 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | ||
675 | 674 | ||
676 | void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) | 675 | void 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 | } |
681 | EXPORT_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 | } |
795 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | 795 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); |
796 | |||
797 | |||
798 | EXPORT_SYMBOL_GPL(sysfs_create_file); | ||
799 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | ||
800 | EXPORT_SYMBOL_GPL(sysfs_remove_files); | ||
801 | EXPORT_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 @@ | |||
19 | static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 21 | static 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, | |||
33 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 35 | static 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 | } |
134 | EXPORT_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 | */ | ||
149 | int 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 | } | ||
168 | EXPORT_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 | } |
192 | EXPORT_SYMBOL_GPL(sysfs_update_group); | ||
155 | 193 | ||
156 | 194 | /** | |
157 | 195 | * sysfs_remove_group: remove a group from a kobject | |
158 | void 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 | */ | ||
202 | void 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 | } |
225 | EXPORT_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 | */ | ||
235 | void 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 | } | ||
245 | EXPORT_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 | } |
275 | EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); | 341 | EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); |
276 | |||
277 | EXPORT_SYMBOL_GPL(sysfs_create_group); | ||
278 | EXPORT_SYMBOL_GPL(sysfs_update_group); | ||
279 | EXPORT_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 | ||
39 | static const struct inode_operations sysfs_inode_operations ={ | 39 | static 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 | ||
70 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr) | 70 | int 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 | ||
131 | static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *secdata_len) | 131 | static 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 | ||
189 | static inline void set_default_inode_attr(struct inode * inode, umode_t mode) | 190 | static 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 | ||
195 | static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) | 196 | static 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 | ||
223 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 224 | int 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 | */ |
288 | struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd) | 290 | struct 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 | ||
315 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name) | 317 | int 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..fd7ce7a39f91 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; |
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 | } |
128 | EXPORT_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 | 170 | void sysfs_remove_link(struct kobject *kobj, const char *name) | |
170 | void 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 | } |
181 | EXPORT_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 | } |
227 | EXPORT_SYMBOL_GPL(sysfs_rename_link); | ||
226 | 228 | ||
227 | static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, | 229 | static 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 | ||
279 | static int sysfs_getlink(struct dentry *dentry, char * path) | 281 | static 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 | ||
306 | static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) | 308 | static 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 | |||
324 | EXPORT_SYMBOL_GPL(sysfs_create_link); | ||
325 | EXPORT_SYMBOL_GPL(sysfs_remove_link); | ||
326 | EXPORT_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); |
187 | void sysfs_remove_subdir(struct sysfs_dirent *sd); | 187 | void sysfs_remove_subdir(struct sysfs_dirent *sd); |
188 | 188 | ||
189 | int sysfs_rename(struct sysfs_dirent *sd, | 189 | int 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 | ||
192 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) | 192 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) |
193 | { | 193 | { |
@@ -214,10 +214,12 @@ void sysfs_evict_inode(struct inode *inode); | |||
214 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); | 214 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); |
215 | int sysfs_permission(struct inode *inode, int mask); | 215 | int sysfs_permission(struct inode *inode, int mask); |
216 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | 216 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); |
217 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); | 217 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
218 | struct kstat *stat); | ||
218 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 219 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
219 | size_t size, int flags); | 220 | size_t size, int flags); |
220 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name); | 221 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, |
222 | const char *name); | ||
221 | int sysfs_inode_init(void); | 223 | int sysfs_inode_init(void); |
222 | 224 | ||
223 | /* | 225 | /* |