diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/block_dev.c | 8 | ||||
-rw-r--r-- | fs/char_dev.c | 6 | ||||
-rw-r--r-- | fs/coda/psdev.c | 8 | ||||
-rw-r--r-- | fs/configfs/mount.c | 13 | ||||
-rw-r--r-- | fs/debugfs/inode.c | 13 | ||||
-rw-r--r-- | fs/dlm/lockspace.c | 50 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 129 | ||||
-rw-r--r-- | fs/fuse/inode.c | 26 | ||||
-rw-r--r-- | fs/gfs2/locking/dlm/sysfs.c | 38 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 29 | ||||
-rw-r--r-- | fs/namespace.c | 11 | ||||
-rw-r--r-- | fs/ocfs2/cluster/masklog.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/cluster/sys.c | 83 | ||||
-rw-r--r-- | fs/partitions/check.c | 327 | ||||
-rw-r--r-- | fs/sysfs/dir.c | 2 | ||||
-rw-r--r-- | fs/sysfs/file.c | 67 | ||||
-rw-r--r-- | fs/sysfs/symlink.c | 88 |
17 files changed, 287 insertions, 615 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index 993f78c55221..e48a630ae266 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -738,9 +738,9 @@ EXPORT_SYMBOL(bd_release); | |||
738 | static struct kobject *bdev_get_kobj(struct block_device *bdev) | 738 | static struct kobject *bdev_get_kobj(struct block_device *bdev) |
739 | { | 739 | { |
740 | if (bdev->bd_contains != bdev) | 740 | if (bdev->bd_contains != bdev) |
741 | return kobject_get(&bdev->bd_part->kobj); | 741 | return kobject_get(&bdev->bd_part->dev.kobj); |
742 | else | 742 | else |
743 | return kobject_get(&bdev->bd_disk->kobj); | 743 | return kobject_get(&bdev->bd_disk->dev.kobj); |
744 | } | 744 | } |
745 | 745 | ||
746 | static struct kobject *bdev_get_holder(struct block_device *bdev) | 746 | static struct kobject *bdev_get_holder(struct block_device *bdev) |
@@ -1176,7 +1176,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) | |||
1176 | ret = -ENXIO; | 1176 | ret = -ENXIO; |
1177 | goto out_first; | 1177 | goto out_first; |
1178 | } | 1178 | } |
1179 | kobject_get(&p->kobj); | 1179 | kobject_get(&p->dev.kobj); |
1180 | bdev->bd_part = p; | 1180 | bdev->bd_part = p; |
1181 | bd_set_size(bdev, (loff_t) p->nr_sects << 9); | 1181 | bd_set_size(bdev, (loff_t) p->nr_sects << 9); |
1182 | } | 1182 | } |
@@ -1299,7 +1299,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part) | |||
1299 | module_put(owner); | 1299 | module_put(owner); |
1300 | 1300 | ||
1301 | if (bdev->bd_contains != bdev) { | 1301 | if (bdev->bd_contains != bdev) { |
1302 | kobject_put(&bdev->bd_part->kobj); | 1302 | kobject_put(&bdev->bd_part->dev.kobj); |
1303 | bdev->bd_part = NULL; | 1303 | bdev->bd_part = NULL; |
1304 | } | 1304 | } |
1305 | bdev->bd_disk = NULL; | 1305 | bdev->bd_disk = NULL; |
diff --git a/fs/char_dev.c b/fs/char_dev.c index c3bfa76765c4..2c7a8b5b4598 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -510,9 +510,8 @@ struct cdev *cdev_alloc(void) | |||
510 | { | 510 | { |
511 | struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); | 511 | struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); |
512 | if (p) { | 512 | if (p) { |
513 | p->kobj.ktype = &ktype_cdev_dynamic; | ||
514 | INIT_LIST_HEAD(&p->list); | 513 | INIT_LIST_HEAD(&p->list); |
515 | kobject_init(&p->kobj); | 514 | kobject_init(&p->kobj, &ktype_cdev_dynamic); |
516 | } | 515 | } |
517 | return p; | 516 | return p; |
518 | } | 517 | } |
@@ -529,8 +528,7 @@ void cdev_init(struct cdev *cdev, const struct file_operations *fops) | |||
529 | { | 528 | { |
530 | memset(cdev, 0, sizeof *cdev); | 529 | memset(cdev, 0, sizeof *cdev); |
531 | INIT_LIST_HEAD(&cdev->list); | 530 | INIT_LIST_HEAD(&cdev->list); |
532 | cdev->kobj.ktype = &ktype_cdev_default; | 531 | kobject_init(&cdev->kobj, &ktype_cdev_default); |
533 | kobject_init(&cdev->kobj); | ||
534 | cdev->ops = fops; | 532 | cdev->ops = fops; |
535 | } | 533 | } |
536 | 534 | ||
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index dcc6aead70f5..e3eb3556622b 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -362,8 +362,8 @@ static int init_coda_psdev(void) | |||
362 | goto out_chrdev; | 362 | goto out_chrdev; |
363 | } | 363 | } |
364 | for (i = 0; i < MAX_CODADEVS; i++) | 364 | for (i = 0; i < MAX_CODADEVS; i++) |
365 | class_device_create(coda_psdev_class, NULL, | 365 | device_create(coda_psdev_class, NULL, |
366 | MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i); | 366 | MKDEV(CODA_PSDEV_MAJOR,i), "cfs%d", i); |
367 | coda_sysctl_init(); | 367 | coda_sysctl_init(); |
368 | goto out; | 368 | goto out; |
369 | 369 | ||
@@ -405,7 +405,7 @@ static int __init init_coda(void) | |||
405 | return 0; | 405 | return 0; |
406 | out: | 406 | out: |
407 | for (i = 0; i < MAX_CODADEVS; i++) | 407 | for (i = 0; i < MAX_CODADEVS; i++) |
408 | class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); | 408 | device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); |
409 | class_destroy(coda_psdev_class); | 409 | class_destroy(coda_psdev_class); |
410 | unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); | 410 | unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); |
411 | coda_sysctl_clean(); | 411 | coda_sysctl_clean(); |
@@ -424,7 +424,7 @@ static void __exit exit_coda(void) | |||
424 | printk("coda: failed to unregister filesystem\n"); | 424 | printk("coda: failed to unregister filesystem\n"); |
425 | } | 425 | } |
426 | for (i = 0; i < MAX_CODADEVS; i++) | 426 | for (i = 0; i < MAX_CODADEVS; i++) |
427 | class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); | 427 | device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); |
428 | class_destroy(coda_psdev_class); | 428 | class_destroy(coda_psdev_class); |
429 | unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); | 429 | unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); |
430 | coda_sysctl_clean(); | 430 | coda_sysctl_clean(); |
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 3bf0278ea843..de3b31d0a37d 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
@@ -128,7 +128,7 @@ void configfs_release_fs(void) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | 130 | ||
131 | static decl_subsys(config, NULL, NULL); | 131 | static struct kobject *config_kobj; |
132 | 132 | ||
133 | static int __init configfs_init(void) | 133 | static int __init configfs_init(void) |
134 | { | 134 | { |
@@ -140,9 +140,8 @@ static int __init configfs_init(void) | |||
140 | if (!configfs_dir_cachep) | 140 | if (!configfs_dir_cachep) |
141 | goto out; | 141 | goto out; |
142 | 142 | ||
143 | kobj_set_kset_s(&config_subsys, kernel_subsys); | 143 | config_kobj = kobject_create_and_add("config", kernel_kobj); |
144 | err = subsystem_register(&config_subsys); | 144 | if (!config_kobj) { |
145 | if (err) { | ||
146 | kmem_cache_destroy(configfs_dir_cachep); | 145 | kmem_cache_destroy(configfs_dir_cachep); |
147 | configfs_dir_cachep = NULL; | 146 | configfs_dir_cachep = NULL; |
148 | goto out; | 147 | goto out; |
@@ -151,7 +150,7 @@ static int __init configfs_init(void) | |||
151 | err = register_filesystem(&configfs_fs_type); | 150 | err = register_filesystem(&configfs_fs_type); |
152 | if (err) { | 151 | if (err) { |
153 | printk(KERN_ERR "configfs: Unable to register filesystem!\n"); | 152 | printk(KERN_ERR "configfs: Unable to register filesystem!\n"); |
154 | subsystem_unregister(&config_subsys); | 153 | kobject_put(config_kobj); |
155 | kmem_cache_destroy(configfs_dir_cachep); | 154 | kmem_cache_destroy(configfs_dir_cachep); |
156 | configfs_dir_cachep = NULL; | 155 | configfs_dir_cachep = NULL; |
157 | goto out; | 156 | goto out; |
@@ -160,7 +159,7 @@ static int __init configfs_init(void) | |||
160 | err = configfs_inode_init(); | 159 | err = configfs_inode_init(); |
161 | if (err) { | 160 | if (err) { |
162 | unregister_filesystem(&configfs_fs_type); | 161 | unregister_filesystem(&configfs_fs_type); |
163 | subsystem_unregister(&config_subsys); | 162 | kobject_put(config_kobj); |
164 | kmem_cache_destroy(configfs_dir_cachep); | 163 | kmem_cache_destroy(configfs_dir_cachep); |
165 | configfs_dir_cachep = NULL; | 164 | configfs_dir_cachep = NULL; |
166 | } | 165 | } |
@@ -171,7 +170,7 @@ out: | |||
171 | static void __exit configfs_exit(void) | 170 | static void __exit configfs_exit(void) |
172 | { | 171 | { |
173 | unregister_filesystem(&configfs_fs_type); | 172 | unregister_filesystem(&configfs_fs_type); |
174 | subsystem_unregister(&config_subsys); | 173 | kobject_put(config_kobj); |
175 | kmem_cache_destroy(configfs_dir_cachep); | 174 | kmem_cache_destroy(configfs_dir_cachep); |
176 | configfs_dir_cachep = NULL; | 175 | configfs_dir_cachep = NULL; |
177 | configfs_inode_exit(); | 176 | configfs_inode_exit(); |
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 6a713b33992f..d26e2826ba5b 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -426,20 +426,19 @@ exit: | |||
426 | } | 426 | } |
427 | EXPORT_SYMBOL_GPL(debugfs_rename); | 427 | EXPORT_SYMBOL_GPL(debugfs_rename); |
428 | 428 | ||
429 | static decl_subsys(debug, NULL, NULL); | 429 | static struct kobject *debug_kobj; |
430 | 430 | ||
431 | static int __init debugfs_init(void) | 431 | static int __init debugfs_init(void) |
432 | { | 432 | { |
433 | int retval; | 433 | int retval; |
434 | 434 | ||
435 | kobj_set_kset_s(&debug_subsys, kernel_subsys); | 435 | debug_kobj = kobject_create_and_add("debug", kernel_kobj); |
436 | retval = subsystem_register(&debug_subsys); | 436 | if (!debug_kobj) |
437 | if (retval) | 437 | return -EINVAL; |
438 | return retval; | ||
439 | 438 | ||
440 | retval = register_filesystem(&debug_fs_type); | 439 | retval = register_filesystem(&debug_fs_type); |
441 | if (retval) | 440 | if (retval) |
442 | subsystem_unregister(&debug_subsys); | 441 | kobject_put(debug_kobj); |
443 | return retval; | 442 | return retval; |
444 | } | 443 | } |
445 | 444 | ||
@@ -447,7 +446,7 @@ static void __exit debugfs_exit(void) | |||
447 | { | 446 | { |
448 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | 447 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); |
449 | unregister_filesystem(&debug_fs_type); | 448 | unregister_filesystem(&debug_fs_type); |
450 | subsystem_unregister(&debug_subsys); | 449 | kobject_put(debug_kobj); |
451 | } | 450 | } |
452 | 451 | ||
453 | core_initcall(debugfs_init); | 452 | core_initcall(debugfs_init); |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 6353a8384520..5c108c49cb8c 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -166,26 +166,7 @@ static struct kobj_type dlm_ktype = { | |||
166 | .release = lockspace_kobj_release, | 166 | .release = lockspace_kobj_release, |
167 | }; | 167 | }; |
168 | 168 | ||
169 | static struct kset dlm_kset = { | 169 | static struct kset *dlm_kset; |
170 | .ktype = &dlm_ktype, | ||
171 | }; | ||
172 | |||
173 | static int kobject_setup(struct dlm_ls *ls) | ||
174 | { | ||
175 | char lsname[DLM_LOCKSPACE_LEN]; | ||
176 | int error; | ||
177 | |||
178 | memset(lsname, 0, DLM_LOCKSPACE_LEN); | ||
179 | snprintf(lsname, DLM_LOCKSPACE_LEN, "%s", ls->ls_name); | ||
180 | |||
181 | error = kobject_set_name(&ls->ls_kobj, "%s", lsname); | ||
182 | if (error) | ||
183 | return error; | ||
184 | |||
185 | ls->ls_kobj.kset = &dlm_kset; | ||
186 | ls->ls_kobj.ktype = &dlm_ktype; | ||
187 | return 0; | ||
188 | } | ||
189 | 170 | ||
190 | static int do_uevent(struct dlm_ls *ls, int in) | 171 | static int do_uevent(struct dlm_ls *ls, int in) |
191 | { | 172 | { |
@@ -220,24 +201,22 @@ static int do_uevent(struct dlm_ls *ls, int in) | |||
220 | 201 | ||
221 | int dlm_lockspace_init(void) | 202 | int dlm_lockspace_init(void) |
222 | { | 203 | { |
223 | int error; | ||
224 | |||
225 | ls_count = 0; | 204 | ls_count = 0; |
226 | mutex_init(&ls_lock); | 205 | mutex_init(&ls_lock); |
227 | INIT_LIST_HEAD(&lslist); | 206 | INIT_LIST_HEAD(&lslist); |
228 | spin_lock_init(&lslist_lock); | 207 | spin_lock_init(&lslist_lock); |
229 | 208 | ||
230 | kobject_set_name(&dlm_kset.kobj, "dlm"); | 209 | dlm_kset = kset_create_and_add("dlm", NULL, kernel_kobj); |
231 | kobj_set_kset_s(&dlm_kset, kernel_subsys); | 210 | if (!dlm_kset) { |
232 | error = kset_register(&dlm_kset); | 211 | printk(KERN_WARNING "%s: can not create kset\n", __FUNCTION__); |
233 | if (error) | 212 | return -ENOMEM; |
234 | printk("dlm_lockspace_init: cannot register kset %d\n", error); | 213 | } |
235 | return error; | 214 | return 0; |
236 | } | 215 | } |
237 | 216 | ||
238 | void dlm_lockspace_exit(void) | 217 | void dlm_lockspace_exit(void) |
239 | { | 218 | { |
240 | kset_unregister(&dlm_kset); | 219 | kset_unregister(dlm_kset); |
241 | } | 220 | } |
242 | 221 | ||
243 | static int dlm_scand(void *data) | 222 | static int dlm_scand(void *data) |
@@ -549,13 +528,12 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
549 | goto out_delist; | 528 | goto out_delist; |
550 | } | 529 | } |
551 | 530 | ||
552 | error = kobject_setup(ls); | 531 | ls->ls_kobj.kset = dlm_kset; |
553 | if (error) | 532 | error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL, |
554 | goto out_stop; | 533 | "%s", ls->ls_name); |
555 | |||
556 | error = kobject_register(&ls->ls_kobj); | ||
557 | if (error) | 534 | if (error) |
558 | goto out_stop; | 535 | goto out_stop; |
536 | kobject_uevent(&ls->ls_kobj, KOBJ_ADD); | ||
559 | 537 | ||
560 | /* let kobject handle freeing of ls if there's an error */ | 538 | /* let kobject handle freeing of ls if there's an error */ |
561 | do_unreg = 1; | 539 | do_unreg = 1; |
@@ -601,7 +579,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
601 | kfree(ls->ls_rsbtbl); | 579 | kfree(ls->ls_rsbtbl); |
602 | out_lsfree: | 580 | out_lsfree: |
603 | if (do_unreg) | 581 | if (do_unreg) |
604 | kobject_unregister(&ls->ls_kobj); | 582 | kobject_put(&ls->ls_kobj); |
605 | else | 583 | else |
606 | kfree(ls); | 584 | kfree(ls); |
607 | out: | 585 | out: |
@@ -750,7 +728,7 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
750 | dlm_clear_members(ls); | 728 | dlm_clear_members(ls); |
751 | dlm_clear_members_gone(ls); | 729 | dlm_clear_members_gone(ls); |
752 | kfree(ls->ls_node_array); | 730 | kfree(ls->ls_node_array); |
753 | kobject_unregister(&ls->ls_kobj); | 731 | kobject_put(&ls->ls_kobj); |
754 | /* The ls structure will be freed when the kobject is done with */ | 732 | /* The ls structure will be freed when the kobject is done with */ |
755 | 733 | ||
756 | mutex_lock(&ls_lock); | 734 | mutex_lock(&ls_lock); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index e5580bcb923a..0249aa4ae181 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -734,127 +734,40 @@ static int ecryptfs_init_kmem_caches(void) | |||
734 | return 0; | 734 | return 0; |
735 | } | 735 | } |
736 | 736 | ||
737 | struct ecryptfs_obj { | 737 | static struct kobject *ecryptfs_kobj; |
738 | char *name; | ||
739 | struct list_head slot_list; | ||
740 | struct kobject kobj; | ||
741 | }; | ||
742 | |||
743 | struct ecryptfs_attribute { | ||
744 | struct attribute attr; | ||
745 | ssize_t(*show) (struct ecryptfs_obj *, char *); | ||
746 | ssize_t(*store) (struct ecryptfs_obj *, const char *, size_t); | ||
747 | }; | ||
748 | 738 | ||
749 | static ssize_t | 739 | static ssize_t version_show(struct kobject *kobj, |
750 | ecryptfs_attr_store(struct kobject *kobj, | 740 | struct kobj_attribute *attr, char *buff) |
751 | struct attribute *attr, const char *buf, size_t len) | ||
752 | { | 741 | { |
753 | struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj, | 742 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); |
754 | kobj); | ||
755 | struct ecryptfs_attribute *attribute = | ||
756 | container_of(attr, struct ecryptfs_attribute, attr); | ||
757 | |||
758 | return (attribute->store ? attribute->store(obj, buf, len) : 0); | ||
759 | } | 743 | } |
760 | 744 | ||
761 | static ssize_t | 745 | static struct kobj_attribute version_attr = __ATTR_RO(version); |
762 | ecryptfs_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) | ||
763 | { | ||
764 | struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj, | ||
765 | kobj); | ||
766 | struct ecryptfs_attribute *attribute = | ||
767 | container_of(attr, struct ecryptfs_attribute, attr); | ||
768 | |||
769 | return (attribute->show ? attribute->show(obj, buf) : 0); | ||
770 | } | ||
771 | 746 | ||
772 | static struct sysfs_ops ecryptfs_sysfs_ops = { | 747 | static struct attribute *attributes[] = { |
773 | .show = ecryptfs_attr_show, | 748 | &version_attr.attr, |
774 | .store = ecryptfs_attr_store | 749 | NULL, |
775 | }; | 750 | }; |
776 | 751 | ||
777 | static struct kobj_type ecryptfs_ktype = { | 752 | static struct attribute_group attr_group = { |
778 | .sysfs_ops = &ecryptfs_sysfs_ops | 753 | .attrs = attributes, |
779 | }; | 754 | }; |
780 | 755 | ||
781 | static decl_subsys(ecryptfs, &ecryptfs_ktype, NULL); | ||
782 | |||
783 | static ssize_t version_show(struct ecryptfs_obj *obj, char *buff) | ||
784 | { | ||
785 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); | ||
786 | } | ||
787 | |||
788 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); | ||
789 | |||
790 | static struct ecryptfs_version_str_map_elem { | ||
791 | u32 flag; | ||
792 | char *str; | ||
793 | } ecryptfs_version_str_map[] = { | ||
794 | {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"}, | ||
795 | {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, | ||
796 | {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, | ||
797 | {ECRYPTFS_VERSIONING_POLICY, "policy"}, | ||
798 | {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"}, | ||
799 | {ECRYPTFS_VERSIONING_MULTKEY, "multiple keys per file"} | ||
800 | }; | ||
801 | |||
802 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) | ||
803 | { | ||
804 | int i; | ||
805 | int remaining = PAGE_SIZE; | ||
806 | int total_written = 0; | ||
807 | |||
808 | buff[0] = '\0'; | ||
809 | for (i = 0; i < ARRAY_SIZE(ecryptfs_version_str_map); i++) { | ||
810 | int entry_size; | ||
811 | |||
812 | if (!(ECRYPTFS_VERSIONING_MASK | ||
813 | & ecryptfs_version_str_map[i].flag)) | ||
814 | continue; | ||
815 | entry_size = strlen(ecryptfs_version_str_map[i].str); | ||
816 | if ((entry_size + 2) > remaining) | ||
817 | goto out; | ||
818 | memcpy(buff, ecryptfs_version_str_map[i].str, entry_size); | ||
819 | buff[entry_size++] = '\n'; | ||
820 | buff[entry_size] = '\0'; | ||
821 | buff += entry_size; | ||
822 | total_written += entry_size; | ||
823 | remaining -= entry_size; | ||
824 | } | ||
825 | out: | ||
826 | return total_written; | ||
827 | } | ||
828 | |||
829 | static struct ecryptfs_attribute sysfs_attr_version_str = __ATTR_RO(version_str); | ||
830 | |||
831 | static int do_sysfs_registration(void) | 756 | static int do_sysfs_registration(void) |
832 | { | 757 | { |
833 | int rc; | 758 | int rc; |
834 | 759 | ||
835 | rc = subsystem_register(&ecryptfs_subsys); | 760 | ecryptfs_kobj = kobject_create_and_add("ecryptfs", fs_kobj); |
836 | if (rc) { | 761 | if (!ecryptfs_kobj) { |
837 | printk(KERN_ERR | 762 | printk(KERN_ERR "Unable to create ecryptfs kset\n"); |
838 | "Unable to register ecryptfs sysfs subsystem\n"); | 763 | rc = -ENOMEM; |
839 | goto out; | ||
840 | } | ||
841 | rc = sysfs_create_file(&ecryptfs_subsys.kobj, | ||
842 | &sysfs_attr_version.attr); | ||
843 | if (rc) { | ||
844 | printk(KERN_ERR | ||
845 | "Unable to create ecryptfs version attribute\n"); | ||
846 | subsystem_unregister(&ecryptfs_subsys); | ||
847 | goto out; | 764 | goto out; |
848 | } | 765 | } |
849 | rc = sysfs_create_file(&ecryptfs_subsys.kobj, | 766 | rc = sysfs_create_group(ecryptfs_kobj, &attr_group); |
850 | &sysfs_attr_version_str.attr); | ||
851 | if (rc) { | 767 | if (rc) { |
852 | printk(KERN_ERR | 768 | printk(KERN_ERR |
853 | "Unable to create ecryptfs version_str attribute\n"); | 769 | "Unable to create ecryptfs version attributes\n"); |
854 | sysfs_remove_file(&ecryptfs_subsys.kobj, | 770 | kobject_put(ecryptfs_kobj); |
855 | &sysfs_attr_version.attr); | ||
856 | subsystem_unregister(&ecryptfs_subsys); | ||
857 | goto out; | ||
858 | } | 771 | } |
859 | out: | 772 | out: |
860 | return rc; | 773 | return rc; |
@@ -862,11 +775,8 @@ out: | |||
862 | 775 | ||
863 | static void do_sysfs_unregistration(void) | 776 | static void do_sysfs_unregistration(void) |
864 | { | 777 | { |
865 | sysfs_remove_file(&ecryptfs_subsys.kobj, | 778 | sysfs_remove_group(ecryptfs_kobj, &attr_group); |
866 | &sysfs_attr_version.attr); | 779 | kobject_put(ecryptfs_kobj); |
867 | sysfs_remove_file(&ecryptfs_subsys.kobj, | ||
868 | &sysfs_attr_version_str.attr); | ||
869 | subsystem_unregister(&ecryptfs_subsys); | ||
870 | } | 780 | } |
871 | 781 | ||
872 | static int __init ecryptfs_init(void) | 782 | static int __init ecryptfs_init(void) |
@@ -894,7 +804,6 @@ static int __init ecryptfs_init(void) | |||
894 | printk(KERN_ERR "Failed to register filesystem\n"); | 804 | printk(KERN_ERR "Failed to register filesystem\n"); |
895 | goto out_free_kmem_caches; | 805 | goto out_free_kmem_caches; |
896 | } | 806 | } |
897 | kobj_set_kset_s(&ecryptfs_subsys, fs_subsys); | ||
898 | rc = do_sysfs_registration(); | 807 | rc = do_sysfs_registration(); |
899 | if (rc) { | 808 | if (rc) { |
900 | printk(KERN_ERR "sysfs registration failed\n"); | 809 | printk(KERN_ERR "sysfs registration failed\n"); |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 84f9f7dfdf5b..e5e80d1a4687 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -744,9 +744,6 @@ static inline void unregister_fuseblk(void) | |||
744 | } | 744 | } |
745 | #endif | 745 | #endif |
746 | 746 | ||
747 | static decl_subsys(fuse, NULL, NULL); | ||
748 | static decl_subsys(connections, NULL, NULL); | ||
749 | |||
750 | static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo) | 747 | static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo) |
751 | { | 748 | { |
752 | struct inode * inode = foo; | 749 | struct inode * inode = foo; |
@@ -791,32 +788,37 @@ static void fuse_fs_cleanup(void) | |||
791 | kmem_cache_destroy(fuse_inode_cachep); | 788 | kmem_cache_destroy(fuse_inode_cachep); |
792 | } | 789 | } |
793 | 790 | ||
791 | static struct kobject *fuse_kobj; | ||
792 | static struct kobject *connections_kobj; | ||
793 | |||
794 | static int fuse_sysfs_init(void) | 794 | static int fuse_sysfs_init(void) |
795 | { | 795 | { |
796 | int err; | 796 | int err; |
797 | 797 | ||
798 | kobj_set_kset_s(&fuse_subsys, fs_subsys); | 798 | fuse_kobj = kobject_create_and_add("fuse", fs_kobj); |
799 | err = subsystem_register(&fuse_subsys); | 799 | if (!fuse_kobj) { |
800 | if (err) | 800 | err = -ENOMEM; |
801 | goto out_err; | 801 | goto out_err; |
802 | } | ||
802 | 803 | ||
803 | kobj_set_kset_s(&connections_subsys, fuse_subsys); | 804 | connections_kobj = kobject_create_and_add("connections", fuse_kobj); |
804 | err = subsystem_register(&connections_subsys); | 805 | if (!connections_kobj) { |
805 | if (err) | 806 | err = -ENOMEM; |
806 | goto out_fuse_unregister; | 807 | goto out_fuse_unregister; |
808 | } | ||
807 | 809 | ||
808 | return 0; | 810 | return 0; |
809 | 811 | ||
810 | out_fuse_unregister: | 812 | out_fuse_unregister: |
811 | subsystem_unregister(&fuse_subsys); | 813 | kobject_put(fuse_kobj); |
812 | out_err: | 814 | out_err: |
813 | return err; | 815 | return err; |
814 | } | 816 | } |
815 | 817 | ||
816 | static void fuse_sysfs_cleanup(void) | 818 | static void fuse_sysfs_cleanup(void) |
817 | { | 819 | { |
818 | subsystem_unregister(&connections_subsys); | 820 | kobject_put(connections_kobj); |
819 | subsystem_unregister(&fuse_subsys); | 821 | kobject_put(fuse_kobj); |
820 | } | 822 | } |
821 | 823 | ||
822 | static int __init fuse_init(void) | 824 | static int __init fuse_init(void) |
diff --git a/fs/gfs2/locking/dlm/sysfs.c b/fs/gfs2/locking/dlm/sysfs.c index ae9e6a25fe2b..a87b09839761 100644 --- a/fs/gfs2/locking/dlm/sysfs.c +++ b/fs/gfs2/locking/dlm/sysfs.c | |||
@@ -189,51 +189,39 @@ static struct kobj_type gdlm_ktype = { | |||
189 | .sysfs_ops = &gdlm_attr_ops, | 189 | .sysfs_ops = &gdlm_attr_ops, |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static struct kset gdlm_kset = { | 192 | static struct kset *gdlm_kset; |
193 | .ktype = &gdlm_ktype, | ||
194 | }; | ||
195 | 193 | ||
196 | int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj) | 194 | int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj) |
197 | { | 195 | { |
198 | int error; | 196 | int error; |
199 | 197 | ||
200 | error = kobject_set_name(&ls->kobj, "%s", "lock_module"); | 198 | ls->kobj.kset = gdlm_kset; |
201 | if (error) { | 199 | error = kobject_init_and_add(&ls->kobj, &gdlm_ktype, fskobj, |
202 | log_error("can't set kobj name %d", error); | 200 | "lock_module"); |
203 | return error; | ||
204 | } | ||
205 | |||
206 | ls->kobj.kset = &gdlm_kset; | ||
207 | ls->kobj.ktype = &gdlm_ktype; | ||
208 | ls->kobj.parent = fskobj; | ||
209 | |||
210 | error = kobject_register(&ls->kobj); | ||
211 | if (error) | 201 | if (error) |
212 | log_error("can't register kobj %d", error); | 202 | log_error("can't register kobj %d", error); |
203 | kobject_uevent(&ls->kobj, KOBJ_ADD); | ||
213 | 204 | ||
214 | return error; | 205 | return error; |
215 | } | 206 | } |
216 | 207 | ||
217 | void gdlm_kobject_release(struct gdlm_ls *ls) | 208 | void gdlm_kobject_release(struct gdlm_ls *ls) |
218 | { | 209 | { |
219 | kobject_unregister(&ls->kobj); | 210 | kobject_put(&ls->kobj); |
220 | } | 211 | } |
221 | 212 | ||
222 | int gdlm_sysfs_init(void) | 213 | int gdlm_sysfs_init(void) |
223 | { | 214 | { |
224 | int error; | 215 | gdlm_kset = kset_create_and_add("lock_dlm", NULL, kernel_kobj); |
225 | 216 | if (!gdlm_kset) { | |
226 | kobject_set_name(&gdlm_kset.kobj, "lock_dlm"); | 217 | printk(KERN_WARNING "%s: can not create kset\n", __FUNCTION__); |
227 | kobj_set_kset_s(&gdlm_kset, kernel_subsys); | 218 | return -ENOMEM; |
228 | error = kset_register(&gdlm_kset); | 219 | } |
229 | if (error) | 220 | return 0; |
230 | printk("lock_dlm: cannot register kset %d\n", error); | ||
231 | |||
232 | return error; | ||
233 | } | 221 | } |
234 | 222 | ||
235 | void gdlm_sysfs_exit(void) | 223 | void gdlm_sysfs_exit(void) |
236 | { | 224 | { |
237 | kset_unregister(&gdlm_kset); | 225 | kset_unregister(gdlm_kset); |
238 | } | 226 | } |
239 | 227 | ||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 06e0b7768d97..3a3176b846f3 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -221,9 +221,7 @@ static struct kobj_type gfs2_ktype = { | |||
221 | .sysfs_ops = &gfs2_attr_ops, | 221 | .sysfs_ops = &gfs2_attr_ops, |
222 | }; | 222 | }; |
223 | 223 | ||
224 | static struct kset gfs2_kset = { | 224 | static struct kset *gfs2_kset; |
225 | .ktype = &gfs2_ktype, | ||
226 | }; | ||
227 | 225 | ||
228 | /* | 226 | /* |
229 | * display struct lm_lockstruct fields | 227 | * display struct lm_lockstruct fields |
@@ -495,14 +493,9 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
495 | { | 493 | { |
496 | int error; | 494 | int error; |
497 | 495 | ||
498 | sdp->sd_kobj.kset = &gfs2_kset; | 496 | sdp->sd_kobj.kset = gfs2_kset; |
499 | sdp->sd_kobj.ktype = &gfs2_ktype; | 497 | error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, |
500 | 498 | "%s", sdp->sd_table_name); | |
501 | error = kobject_set_name(&sdp->sd_kobj, "%s", sdp->sd_table_name); | ||
502 | if (error) | ||
503 | goto fail; | ||
504 | |||
505 | error = kobject_register(&sdp->sd_kobj); | ||
506 | if (error) | 499 | if (error) |
507 | goto fail; | 500 | goto fail; |
508 | 501 | ||
@@ -522,6 +515,7 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
522 | if (error) | 515 | if (error) |
523 | goto fail_args; | 516 | goto fail_args; |
524 | 517 | ||
518 | kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); | ||
525 | return 0; | 519 | return 0; |
526 | 520 | ||
527 | fail_args: | 521 | fail_args: |
@@ -531,7 +525,7 @@ fail_counters: | |||
531 | fail_lockstruct: | 525 | fail_lockstruct: |
532 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 526 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
533 | fail_reg: | 527 | fail_reg: |
534 | kobject_unregister(&sdp->sd_kobj); | 528 | kobject_put(&sdp->sd_kobj); |
535 | fail: | 529 | fail: |
536 | fs_err(sdp, "error %d adding sysfs files", error); | 530 | fs_err(sdp, "error %d adding sysfs files", error); |
537 | return error; | 531 | return error; |
@@ -543,21 +537,22 @@ void gfs2_sys_fs_del(struct gfs2_sbd *sdp) | |||
543 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 537 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
544 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); | 538 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); |
545 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 539 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
546 | kobject_unregister(&sdp->sd_kobj); | 540 | kobject_put(&sdp->sd_kobj); |
547 | } | 541 | } |
548 | 542 | ||
549 | int gfs2_sys_init(void) | 543 | int gfs2_sys_init(void) |
550 | { | 544 | { |
551 | gfs2_sys_margs = NULL; | 545 | gfs2_sys_margs = NULL; |
552 | spin_lock_init(&gfs2_sys_margs_lock); | 546 | spin_lock_init(&gfs2_sys_margs_lock); |
553 | kobject_set_name(&gfs2_kset.kobj, "gfs2"); | 547 | gfs2_kset = kset_create_and_add("gfs2", NULL, fs_kobj); |
554 | kobj_set_kset_s(&gfs2_kset, fs_subsys); | 548 | if (!gfs2_kset) |
555 | return kset_register(&gfs2_kset); | 549 | return -ENOMEM; |
550 | return 0; | ||
556 | } | 551 | } |
557 | 552 | ||
558 | void gfs2_sys_uninit(void) | 553 | void gfs2_sys_uninit(void) |
559 | { | 554 | { |
560 | kfree(gfs2_sys_margs); | 555 | kfree(gfs2_sys_margs); |
561 | kset_unregister(&gfs2_kset); | 556 | kset_unregister(gfs2_kset); |
562 | } | 557 | } |
563 | 558 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 06083885b21e..61bf376e29e8 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -41,8 +41,8 @@ static struct kmem_cache *mnt_cache __read_mostly; | |||
41 | static struct rw_semaphore namespace_sem; | 41 | static struct rw_semaphore namespace_sem; |
42 | 42 | ||
43 | /* /sys/fs */ | 43 | /* /sys/fs */ |
44 | decl_subsys(fs, NULL, NULL); | 44 | struct kobject *fs_kobj; |
45 | EXPORT_SYMBOL_GPL(fs_subsys); | 45 | EXPORT_SYMBOL_GPL(fs_kobj); |
46 | 46 | ||
47 | static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) | 47 | static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) |
48 | { | 48 | { |
@@ -1861,10 +1861,9 @@ void __init mnt_init(void) | |||
1861 | if (err) | 1861 | if (err) |
1862 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", | 1862 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", |
1863 | __FUNCTION__, err); | 1863 | __FUNCTION__, err); |
1864 | err = subsystem_register(&fs_subsys); | 1864 | fs_kobj = kobject_create_and_add("fs", NULL); |
1865 | if (err) | 1865 | if (!fs_kobj) |
1866 | printk(KERN_WARNING "%s: subsystem_register error: %d\n", | 1866 | printk(KERN_WARNING "%s: kobj create error\n", __FUNCTION__); |
1867 | __FUNCTION__, err); | ||
1868 | init_rootfs(); | 1867 | init_rootfs(); |
1869 | init_mount_tree(); | 1868 | init_mount_tree(); |
1870 | } | 1869 | } |
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index a4882c8df945..23c732f27529 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c | |||
@@ -146,7 +146,7 @@ static struct kset mlog_kset = { | |||
146 | .kobj = {.ktype = &mlog_ktype}, | 146 | .kobj = {.ktype = &mlog_ktype}, |
147 | }; | 147 | }; |
148 | 148 | ||
149 | int mlog_sys_init(struct kset *o2cb_subsys) | 149 | int mlog_sys_init(struct kset *o2cb_kset) |
150 | { | 150 | { |
151 | int i = 0; | 151 | int i = 0; |
152 | 152 | ||
@@ -157,7 +157,7 @@ int mlog_sys_init(struct kset *o2cb_subsys) | |||
157 | mlog_attr_ptrs[i] = NULL; | 157 | mlog_attr_ptrs[i] = NULL; |
158 | 158 | ||
159 | kobject_set_name(&mlog_kset.kobj, "logmask"); | 159 | kobject_set_name(&mlog_kset.kobj, "logmask"); |
160 | kobj_set_kset_s(&mlog_kset, *o2cb_subsys); | 160 | mlog_kset.kobj.kset = o2cb_kset; |
161 | return kset_register(&mlog_kset); | 161 | return kset_register(&mlog_kset); |
162 | } | 162 | } |
163 | 163 | ||
diff --git a/fs/ocfs2/cluster/sys.c b/fs/ocfs2/cluster/sys.c index 64f6f378fd09..a4b07730b2e1 100644 --- a/fs/ocfs2/cluster/sys.c +++ b/fs/ocfs2/cluster/sys.c | |||
@@ -28,96 +28,55 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/kobject.h> | 29 | #include <linux/kobject.h> |
30 | #include <linux/sysfs.h> | 30 | #include <linux/sysfs.h> |
31 | #include <linux/fs.h> | ||
31 | 32 | ||
32 | #include "ocfs2_nodemanager.h" | 33 | #include "ocfs2_nodemanager.h" |
33 | #include "masklog.h" | 34 | #include "masklog.h" |
34 | #include "sys.h" | 35 | #include "sys.h" |
35 | 36 | ||
36 | struct o2cb_attribute { | ||
37 | struct attribute attr; | ||
38 | ssize_t (*show)(char *buf); | ||
39 | ssize_t (*store)(const char *buf, size_t count); | ||
40 | }; | ||
41 | |||
42 | #define O2CB_ATTR(_name, _mode, _show, _store) \ | ||
43 | struct o2cb_attribute o2cb_attr_##_name = __ATTR(_name, _mode, _show, _store) | ||
44 | |||
45 | #define to_o2cb_attr(_attr) container_of(_attr, struct o2cb_attribute, attr) | ||
46 | 37 | ||
47 | static ssize_t o2cb_interface_revision_show(char *buf) | 38 | static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr, |
39 | char *buf) | ||
48 | { | 40 | { |
49 | return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION); | 41 | return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION); |
50 | } | 42 | } |
51 | 43 | static struct kobj_attribute attr_version = | |
52 | static O2CB_ATTR(interface_revision, S_IFREG | S_IRUGO, o2cb_interface_revision_show, NULL); | 44 | __ATTR(interface_revision, S_IFREG | S_IRUGO, version_show, NULL); |
53 | 45 | ||
54 | static struct attribute *o2cb_attrs[] = { | 46 | static struct attribute *o2cb_attrs[] = { |
55 | &o2cb_attr_interface_revision.attr, | 47 | &attr_version.attr, |
56 | NULL, | 48 | NULL, |
57 | }; | 49 | }; |
58 | 50 | ||
59 | static ssize_t | 51 | static struct attribute_group o2cb_attr_group = { |
60 | o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer); | 52 | .attrs = o2cb_attrs, |
61 | static ssize_t | ||
62 | o2cb_store(struct kobject * kobj, struct attribute * attr, | ||
63 | const char * buffer, size_t count); | ||
64 | static struct sysfs_ops o2cb_sysfs_ops = { | ||
65 | .show = o2cb_show, | ||
66 | .store = o2cb_store, | ||
67 | }; | 53 | }; |
68 | 54 | ||
69 | static struct kobj_type o2cb_subsys_type = { | 55 | static struct kset *o2cb_kset; |
70 | .default_attrs = o2cb_attrs, | ||
71 | .sysfs_ops = &o2cb_sysfs_ops, | ||
72 | }; | ||
73 | |||
74 | /* gives us o2cb_subsys */ | ||
75 | static decl_subsys(o2cb, NULL, NULL); | ||
76 | |||
77 | static ssize_t | ||
78 | o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer) | ||
79 | { | ||
80 | struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); | ||
81 | struct kset *sbs = to_kset(kobj); | ||
82 | |||
83 | BUG_ON(sbs != &o2cb_subsys); | ||
84 | |||
85 | if (o2cb_attr->show) | ||
86 | return o2cb_attr->show(buffer); | ||
87 | return -EIO; | ||
88 | } | ||
89 | |||
90 | static ssize_t | ||
91 | o2cb_store(struct kobject * kobj, struct attribute * attr, | ||
92 | const char * buffer, size_t count) | ||
93 | { | ||
94 | struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); | ||
95 | struct kset *sbs = to_kset(kobj); | ||
96 | |||
97 | BUG_ON(sbs != &o2cb_subsys); | ||
98 | |||
99 | if (o2cb_attr->store) | ||
100 | return o2cb_attr->store(buffer, count); | ||
101 | return -EIO; | ||
102 | } | ||
103 | 56 | ||
104 | void o2cb_sys_shutdown(void) | 57 | void o2cb_sys_shutdown(void) |
105 | { | 58 | { |
106 | mlog_sys_shutdown(); | 59 | mlog_sys_shutdown(); |
107 | subsystem_unregister(&o2cb_subsys); | 60 | kset_unregister(o2cb_kset); |
108 | } | 61 | } |
109 | 62 | ||
110 | int o2cb_sys_init(void) | 63 | int o2cb_sys_init(void) |
111 | { | 64 | { |
112 | int ret; | 65 | int ret; |
113 | 66 | ||
114 | o2cb_subsys.kobj.ktype = &o2cb_subsys_type; | 67 | o2cb_kset = kset_create_and_add("o2cb", NULL, fs_kobj); |
115 | ret = subsystem_register(&o2cb_subsys); | 68 | if (!o2cb_kset) |
69 | return -ENOMEM; | ||
70 | |||
71 | ret = sysfs_create_group(&o2cb_kset->kobj, &o2cb_attr_group); | ||
116 | if (ret) | 72 | if (ret) |
117 | return ret; | 73 | goto error; |
118 | 74 | ||
119 | ret = mlog_sys_init(&o2cb_subsys); | 75 | ret = mlog_sys_init(o2cb_kset); |
120 | if (ret) | 76 | if (ret) |
121 | subsystem_unregister(&o2cb_subsys); | 77 | goto error; |
78 | return 0; | ||
79 | error: | ||
80 | kset_unregister(o2cb_kset); | ||
122 | return ret; | 81 | return ret; |
123 | } | 82 | } |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 722e12e5acc7..739da701ae7b 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -195,96 +195,45 @@ check_partition(struct gendisk *hd, struct block_device *bdev) | |||
195 | return ERR_PTR(res); | 195 | return ERR_PTR(res); |
196 | } | 196 | } |
197 | 197 | ||
198 | /* | 198 | static ssize_t part_start_show(struct device *dev, |
199 | * sysfs bindings for partitions | 199 | struct device_attribute *attr, char *buf) |
200 | */ | ||
201 | |||
202 | struct part_attribute { | ||
203 | struct attribute attr; | ||
204 | ssize_t (*show)(struct hd_struct *,char *); | ||
205 | ssize_t (*store)(struct hd_struct *,const char *, size_t); | ||
206 | }; | ||
207 | |||
208 | static ssize_t | ||
209 | part_attr_show(struct kobject * kobj, struct attribute * attr, char * page) | ||
210 | { | 200 | { |
211 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); | 201 | struct hd_struct *p = dev_to_part(dev); |
212 | struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); | ||
213 | ssize_t ret = 0; | ||
214 | if (part_attr->show) | ||
215 | ret = part_attr->show(p, page); | ||
216 | return ret; | ||
217 | } | ||
218 | static ssize_t | ||
219 | part_attr_store(struct kobject * kobj, struct attribute * attr, | ||
220 | const char *page, size_t count) | ||
221 | { | ||
222 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); | ||
223 | struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr); | ||
224 | ssize_t ret = 0; | ||
225 | 202 | ||
226 | if (part_attr->store) | 203 | return sprintf(buf, "%llu\n",(unsigned long long)p->start_sect); |
227 | ret = part_attr->store(p, page, count); | ||
228 | return ret; | ||
229 | } | 204 | } |
230 | 205 | ||
231 | static struct sysfs_ops part_sysfs_ops = { | 206 | static ssize_t part_size_show(struct device *dev, |
232 | .show = part_attr_show, | 207 | struct device_attribute *attr, char *buf) |
233 | .store = part_attr_store, | ||
234 | }; | ||
235 | |||
236 | static ssize_t part_uevent_store(struct hd_struct * p, | ||
237 | const char *page, size_t count) | ||
238 | { | 208 | { |
239 | kobject_uevent(&p->kobj, KOBJ_ADD); | 209 | struct hd_struct *p = dev_to_part(dev); |
240 | return count; | 210 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); |
241 | } | 211 | } |
242 | static ssize_t part_dev_read(struct hd_struct * p, char *page) | 212 | |
243 | { | 213 | static ssize_t part_stat_show(struct device *dev, |
244 | struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); | 214 | struct device_attribute *attr, char *buf) |
245 | dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno); | ||
246 | return print_dev_t(page, dev); | ||
247 | } | ||
248 | static ssize_t part_start_read(struct hd_struct * p, char *page) | ||
249 | { | ||
250 | return sprintf(page, "%llu\n",(unsigned long long)p->start_sect); | ||
251 | } | ||
252 | static ssize_t part_size_read(struct hd_struct * p, char *page) | ||
253 | { | ||
254 | return sprintf(page, "%llu\n",(unsigned long long)p->nr_sects); | ||
255 | } | ||
256 | static ssize_t part_stat_read(struct hd_struct * p, char *page) | ||
257 | { | 215 | { |
258 | return sprintf(page, "%8u %8llu %8u %8llu\n", | 216 | struct hd_struct *p = dev_to_part(dev); |
217 | |||
218 | return sprintf(buf, "%8u %8llu %8u %8llu\n", | ||
259 | p->ios[0], (unsigned long long)p->sectors[0], | 219 | p->ios[0], (unsigned long long)p->sectors[0], |
260 | p->ios[1], (unsigned long long)p->sectors[1]); | 220 | p->ios[1], (unsigned long long)p->sectors[1]); |
261 | } | 221 | } |
262 | static struct part_attribute part_attr_uevent = { | ||
263 | .attr = {.name = "uevent", .mode = S_IWUSR }, | ||
264 | .store = part_uevent_store | ||
265 | }; | ||
266 | static struct part_attribute part_attr_dev = { | ||
267 | .attr = {.name = "dev", .mode = S_IRUGO }, | ||
268 | .show = part_dev_read | ||
269 | }; | ||
270 | static struct part_attribute part_attr_start = { | ||
271 | .attr = {.name = "start", .mode = S_IRUGO }, | ||
272 | .show = part_start_read | ||
273 | }; | ||
274 | static struct part_attribute part_attr_size = { | ||
275 | .attr = {.name = "size", .mode = S_IRUGO }, | ||
276 | .show = part_size_read | ||
277 | }; | ||
278 | static struct part_attribute part_attr_stat = { | ||
279 | .attr = {.name = "stat", .mode = S_IRUGO }, | ||
280 | .show = part_stat_read | ||
281 | }; | ||
282 | 222 | ||
283 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 223 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
224 | static ssize_t part_fail_show(struct device *dev, | ||
225 | struct device_attribute *attr, char *buf) | ||
226 | { | ||
227 | struct hd_struct *p = dev_to_part(dev); | ||
284 | 228 | ||
285 | static ssize_t part_fail_store(struct hd_struct * p, | 229 | return sprintf(buf, "%d\n", p->make_it_fail); |
230 | } | ||
231 | |||
232 | static ssize_t part_fail_store(struct device *dev, | ||
233 | struct device_attribute *attr, | ||
286 | const char *buf, size_t count) | 234 | const char *buf, size_t count) |
287 | { | 235 | { |
236 | struct hd_struct *p = dev_to_part(dev); | ||
288 | int i; | 237 | int i; |
289 | 238 | ||
290 | if (count > 0 && sscanf(buf, "%d", &i) > 0) | 239 | if (count > 0 && sscanf(buf, "%d", &i) > 0) |
@@ -292,50 +241,53 @@ static ssize_t part_fail_store(struct hd_struct * p, | |||
292 | 241 | ||
293 | return count; | 242 | return count; |
294 | } | 243 | } |
295 | static ssize_t part_fail_read(struct hd_struct * p, char *page) | 244 | #endif |
296 | { | ||
297 | return sprintf(page, "%d\n", p->make_it_fail); | ||
298 | } | ||
299 | static struct part_attribute part_attr_fail = { | ||
300 | .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR }, | ||
301 | .store = part_fail_store, | ||
302 | .show = part_fail_read | ||
303 | }; | ||
304 | 245 | ||
246 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | ||
247 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | ||
248 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | ||
249 | #ifdef CONFIG_FAIL_MAKE_REQUEST | ||
250 | static struct device_attribute dev_attr_fail = | ||
251 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | ||
305 | #endif | 252 | #endif |
306 | 253 | ||
307 | static struct attribute * default_attrs[] = { | 254 | static struct attribute *part_attrs[] = { |
308 | &part_attr_uevent.attr, | 255 | &dev_attr_start.attr, |
309 | &part_attr_dev.attr, | 256 | &dev_attr_size.attr, |
310 | &part_attr_start.attr, | 257 | &dev_attr_stat.attr, |
311 | &part_attr_size.attr, | ||
312 | &part_attr_stat.attr, | ||
313 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 258 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
314 | &part_attr_fail.attr, | 259 | &dev_attr_fail.attr, |
315 | #endif | 260 | #endif |
316 | NULL, | 261 | NULL |
317 | }; | 262 | }; |
318 | 263 | ||
319 | extern struct kset block_subsys; | 264 | static struct attribute_group part_attr_group = { |
265 | .attrs = part_attrs, | ||
266 | }; | ||
320 | 267 | ||
321 | static void part_release(struct kobject *kobj) | 268 | static struct attribute_group *part_attr_groups[] = { |
269 | &part_attr_group, | ||
270 | NULL | ||
271 | }; | ||
272 | |||
273 | static void part_release(struct device *dev) | ||
322 | { | 274 | { |
323 | struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); | 275 | struct hd_struct *p = dev_to_part(dev); |
324 | kfree(p); | 276 | kfree(p); |
325 | } | 277 | } |
326 | 278 | ||
327 | struct kobj_type ktype_part = { | 279 | struct device_type part_type = { |
280 | .name = "partition", | ||
281 | .groups = part_attr_groups, | ||
328 | .release = part_release, | 282 | .release = part_release, |
329 | .default_attrs = default_attrs, | ||
330 | .sysfs_ops = &part_sysfs_ops, | ||
331 | }; | 283 | }; |
332 | 284 | ||
333 | static inline void partition_sysfs_add_subdir(struct hd_struct *p) | 285 | static inline void partition_sysfs_add_subdir(struct hd_struct *p) |
334 | { | 286 | { |
335 | struct kobject *k; | 287 | struct kobject *k; |
336 | 288 | ||
337 | k = kobject_get(&p->kobj); | 289 | k = kobject_get(&p->dev.kobj); |
338 | p->holder_dir = kobject_add_dir(k, "holders"); | 290 | p->holder_dir = kobject_create_and_add("holders", k); |
339 | kobject_put(k); | 291 | kobject_put(k); |
340 | } | 292 | } |
341 | 293 | ||
@@ -343,15 +295,16 @@ static inline void disk_sysfs_add_subdirs(struct gendisk *disk) | |||
343 | { | 295 | { |
344 | struct kobject *k; | 296 | struct kobject *k; |
345 | 297 | ||
346 | k = kobject_get(&disk->kobj); | 298 | k = kobject_get(&disk->dev.kobj); |
347 | disk->holder_dir = kobject_add_dir(k, "holders"); | 299 | disk->holder_dir = kobject_create_and_add("holders", k); |
348 | disk->slave_dir = kobject_add_dir(k, "slaves"); | 300 | disk->slave_dir = kobject_create_and_add("slaves", k); |
349 | kobject_put(k); | 301 | kobject_put(k); |
350 | } | 302 | } |
351 | 303 | ||
352 | void delete_partition(struct gendisk *disk, int part) | 304 | void delete_partition(struct gendisk *disk, int part) |
353 | { | 305 | { |
354 | struct hd_struct *p = disk->part[part-1]; | 306 | struct hd_struct *p = disk->part[part-1]; |
307 | |||
355 | if (!p) | 308 | if (!p) |
356 | return; | 309 | return; |
357 | if (!p->nr_sects) | 310 | if (!p->nr_sects) |
@@ -361,113 +314,55 @@ void delete_partition(struct gendisk *disk, int part) | |||
361 | p->nr_sects = 0; | 314 | p->nr_sects = 0; |
362 | p->ios[0] = p->ios[1] = 0; | 315 | p->ios[0] = p->ios[1] = 0; |
363 | p->sectors[0] = p->sectors[1] = 0; | 316 | p->sectors[0] = p->sectors[1] = 0; |
364 | sysfs_remove_link(&p->kobj, "subsystem"); | 317 | kobject_put(p->holder_dir); |
365 | kobject_unregister(p->holder_dir); | 318 | device_del(&p->dev); |
366 | kobject_uevent(&p->kobj, KOBJ_REMOVE); | 319 | put_device(&p->dev); |
367 | kobject_del(&p->kobj); | ||
368 | kobject_put(&p->kobj); | ||
369 | } | 320 | } |
370 | 321 | ||
371 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags) | 322 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags) |
372 | { | 323 | { |
373 | struct hd_struct *p; | 324 | struct hd_struct *p; |
325 | int err; | ||
374 | 326 | ||
375 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 327 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
376 | if (!p) | 328 | if (!p) |
377 | return; | 329 | return; |
378 | 330 | ||
379 | p->start_sect = start; | 331 | p->start_sect = start; |
380 | p->nr_sects = len; | 332 | p->nr_sects = len; |
381 | p->partno = part; | 333 | p->partno = part; |
382 | p->policy = disk->policy; | 334 | p->policy = disk->policy; |
383 | 335 | ||
384 | if (isdigit(disk->kobj.k_name[strlen(disk->kobj.k_name)-1])) | 336 | if (isdigit(disk->dev.bus_id[strlen(disk->dev.bus_id)-1])) |
385 | kobject_set_name(&p->kobj, "%sp%d", | 337 | snprintf(p->dev.bus_id, BUS_ID_SIZE, |
386 | kobject_name(&disk->kobj), part); | 338 | "%sp%d", disk->dev.bus_id, part); |
387 | else | 339 | else |
388 | kobject_set_name(&p->kobj, "%s%d", | 340 | snprintf(p->dev.bus_id, BUS_ID_SIZE, |
389 | kobject_name(&disk->kobj),part); | 341 | "%s%d", disk->dev.bus_id, part); |
390 | p->kobj.parent = &disk->kobj; | 342 | |
391 | p->kobj.ktype = &ktype_part; | 343 | device_initialize(&p->dev); |
392 | kobject_init(&p->kobj); | 344 | p->dev.devt = MKDEV(disk->major, disk->first_minor + part); |
393 | kobject_add(&p->kobj); | 345 | p->dev.class = &block_class; |
394 | if (!disk->part_uevent_suppress) | 346 | p->dev.type = &part_type; |
395 | kobject_uevent(&p->kobj, KOBJ_ADD); | 347 | p->dev.parent = &disk->dev; |
396 | sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem"); | 348 | disk->part[part-1] = p; |
349 | |||
350 | /* delay uevent until 'holders' subdir is created */ | ||
351 | p->dev.uevent_suppress = 1; | ||
352 | device_add(&p->dev); | ||
353 | partition_sysfs_add_subdir(p); | ||
354 | p->dev.uevent_suppress = 0; | ||
397 | if (flags & ADDPART_FLAG_WHOLEDISK) { | 355 | if (flags & ADDPART_FLAG_WHOLEDISK) { |
398 | static struct attribute addpartattr = { | 356 | static struct attribute addpartattr = { |
399 | .name = "whole_disk", | 357 | .name = "whole_disk", |
400 | .mode = S_IRUSR | S_IRGRP | S_IROTH, | 358 | .mode = S_IRUSR | S_IRGRP | S_IROTH, |
401 | }; | 359 | }; |
402 | 360 | err = sysfs_create_file(&p->dev.kobj, &addpartattr); | |
403 | sysfs_create_file(&p->kobj, &addpartattr); | ||
404 | } | 361 | } |
405 | partition_sysfs_add_subdir(p); | ||
406 | disk->part[part-1] = p; | ||
407 | } | ||
408 | 362 | ||
409 | static char *make_block_name(struct gendisk *disk) | 363 | /* suppress uevent if the disk supresses it */ |
410 | { | 364 | if (!disk->dev.uevent_suppress) |
411 | char *name; | 365 | kobject_uevent(&p->dev.kobj, KOBJ_ADD); |
412 | static char *block_str = "block:"; | ||
413 | int size; | ||
414 | char *s; | ||
415 | |||
416 | size = strlen(block_str) + strlen(disk->disk_name) + 1; | ||
417 | name = kmalloc(size, GFP_KERNEL); | ||
418 | if (!name) | ||
419 | return NULL; | ||
420 | strcpy(name, block_str); | ||
421 | strcat(name, disk->disk_name); | ||
422 | /* ewww... some of these buggers have / in name... */ | ||
423 | s = strchr(name, '/'); | ||
424 | if (s) | ||
425 | *s = '!'; | ||
426 | return name; | ||
427 | } | ||
428 | |||
429 | static int disk_sysfs_symlinks(struct gendisk *disk) | ||
430 | { | ||
431 | struct device *target = get_device(disk->driverfs_dev); | ||
432 | int err; | ||
433 | char *disk_name = NULL; | ||
434 | |||
435 | if (target) { | ||
436 | disk_name = make_block_name(disk); | ||
437 | if (!disk_name) { | ||
438 | err = -ENOMEM; | ||
439 | goto err_out; | ||
440 | } | ||
441 | |||
442 | err = sysfs_create_link(&disk->kobj, &target->kobj, "device"); | ||
443 | if (err) | ||
444 | goto err_out_disk_name; | ||
445 | |||
446 | err = sysfs_create_link(&target->kobj, &disk->kobj, disk_name); | ||
447 | if (err) | ||
448 | goto err_out_dev_link; | ||
449 | } | ||
450 | |||
451 | err = sysfs_create_link(&disk->kobj, &block_subsys.kobj, | ||
452 | "subsystem"); | ||
453 | if (err) | ||
454 | goto err_out_disk_name_lnk; | ||
455 | |||
456 | kfree(disk_name); | ||
457 | |||
458 | return 0; | ||
459 | |||
460 | err_out_disk_name_lnk: | ||
461 | if (target) { | ||
462 | sysfs_remove_link(&target->kobj, disk_name); | ||
463 | err_out_dev_link: | ||
464 | sysfs_remove_link(&disk->kobj, "device"); | ||
465 | err_out_disk_name: | ||
466 | kfree(disk_name); | ||
467 | err_out: | ||
468 | put_device(target); | ||
469 | } | ||
470 | return err; | ||
471 | } | 366 | } |
472 | 367 | ||
473 | /* Not exported, helper to add_disk(). */ | 368 | /* Not exported, helper to add_disk(). */ |
@@ -479,19 +374,29 @@ void register_disk(struct gendisk *disk) | |||
479 | struct hd_struct *p; | 374 | struct hd_struct *p; |
480 | int err; | 375 | int err; |
481 | 376 | ||
482 | kobject_set_name(&disk->kobj, "%s", disk->disk_name); | 377 | disk->dev.parent = disk->driverfs_dev; |
483 | /* ewww... some of these buggers have / in name... */ | 378 | disk->dev.devt = MKDEV(disk->major, disk->first_minor); |
484 | s = strchr(disk->kobj.k_name, '/'); | 379 | |
380 | strlcpy(disk->dev.bus_id, disk->disk_name, KOBJ_NAME_LEN); | ||
381 | /* ewww... some of these buggers have / in the name... */ | ||
382 | s = strchr(disk->dev.bus_id, '/'); | ||
485 | if (s) | 383 | if (s) |
486 | *s = '!'; | 384 | *s = '!'; |
487 | if ((err = kobject_add(&disk->kobj))) | 385 | |
386 | /* delay uevents, until we scanned partition table */ | ||
387 | disk->dev.uevent_suppress = 1; | ||
388 | |||
389 | if (device_add(&disk->dev)) | ||
488 | return; | 390 | return; |
489 | err = disk_sysfs_symlinks(disk); | 391 | #ifndef CONFIG_SYSFS_DEPRECATED |
392 | err = sysfs_create_link(block_depr, &disk->dev.kobj, | ||
393 | kobject_name(&disk->dev.kobj)); | ||
490 | if (err) { | 394 | if (err) { |
491 | kobject_del(&disk->kobj); | 395 | device_del(&disk->dev); |
492 | return; | 396 | return; |
493 | } | 397 | } |
494 | disk_sysfs_add_subdirs(disk); | 398 | #endif |
399 | disk_sysfs_add_subdirs(disk); | ||
495 | 400 | ||
496 | /* No minors to use for partitions */ | 401 | /* No minors to use for partitions */ |
497 | if (disk->minors == 1) | 402 | if (disk->minors == 1) |
@@ -505,25 +410,23 @@ void register_disk(struct gendisk *disk) | |||
505 | if (!bdev) | 410 | if (!bdev) |
506 | goto exit; | 411 | goto exit; |
507 | 412 | ||
508 | /* scan partition table, but suppress uevents */ | ||
509 | bdev->bd_invalidated = 1; | 413 | bdev->bd_invalidated = 1; |
510 | disk->part_uevent_suppress = 1; | ||
511 | err = blkdev_get(bdev, FMODE_READ, 0); | 414 | err = blkdev_get(bdev, FMODE_READ, 0); |
512 | disk->part_uevent_suppress = 0; | ||
513 | if (err < 0) | 415 | if (err < 0) |
514 | goto exit; | 416 | goto exit; |
515 | blkdev_put(bdev); | 417 | blkdev_put(bdev); |
516 | 418 | ||
517 | exit: | 419 | exit: |
518 | /* announce disk after possible partitions are already created */ | 420 | /* announce disk after possible partitions are created */ |
519 | kobject_uevent(&disk->kobj, KOBJ_ADD); | 421 | disk->dev.uevent_suppress = 0; |
422 | kobject_uevent(&disk->dev.kobj, KOBJ_ADD); | ||
520 | 423 | ||
521 | /* announce possible partitions */ | 424 | /* announce possible partitions */ |
522 | for (i = 1; i < disk->minors; i++) { | 425 | for (i = 1; i < disk->minors; i++) { |
523 | p = disk->part[i-1]; | 426 | p = disk->part[i-1]; |
524 | if (!p || !p->nr_sects) | 427 | if (!p || !p->nr_sects) |
525 | continue; | 428 | continue; |
526 | kobject_uevent(&p->kobj, KOBJ_ADD); | 429 | kobject_uevent(&p->dev.kobj, KOBJ_ADD); |
527 | } | 430 | } |
528 | } | 431 | } |
529 | 432 | ||
@@ -602,19 +505,11 @@ void del_gendisk(struct gendisk *disk) | |||
602 | disk_stat_set_all(disk, 0); | 505 | disk_stat_set_all(disk, 0); |
603 | disk->stamp = 0; | 506 | disk->stamp = 0; |
604 | 507 | ||
605 | kobject_uevent(&disk->kobj, KOBJ_REMOVE); | 508 | kobject_put(disk->holder_dir); |
606 | kobject_unregister(disk->holder_dir); | 509 | kobject_put(disk->slave_dir); |
607 | kobject_unregister(disk->slave_dir); | 510 | disk->driverfs_dev = NULL; |
608 | if (disk->driverfs_dev) { | 511 | #ifndef CONFIG_SYSFS_DEPRECATED |
609 | char *disk_name = make_block_name(disk); | 512 | sysfs_remove_link(block_depr, disk->dev.bus_id); |
610 | sysfs_remove_link(&disk->kobj, "device"); | 513 | #endif |
611 | if (disk_name) { | 514 | device_del(&disk->dev); |
612 | sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name); | ||
613 | kfree(disk_name); | ||
614 | } | ||
615 | put_device(disk->driverfs_dev); | ||
616 | disk->driverfs_dev = NULL; | ||
617 | } | ||
618 | sysfs_remove_link(&disk->kobj, "subsystem"); | ||
619 | kobject_del(&disk->kobj); | ||
620 | } | 515 | } |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f281cc6584b0..4948d9bc405d 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -440,7 +440,7 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
440 | /** | 440 | /** |
441 | * sysfs_remove_one - remove sysfs_dirent from parent | 441 | * sysfs_remove_one - remove sysfs_dirent from parent |
442 | * @acxt: addrm context to use | 442 | * @acxt: addrm context to use |
443 | * @sd: sysfs_dirent to be added | 443 | * @sd: sysfs_dirent to be removed |
444 | * | 444 | * |
445 | * Mark @sd removed and drop nlink of parent inode if @sd is a | 445 | * Mark @sd removed and drop nlink of parent inode if @sd is a |
446 | * directory. @sd is unlinked from the children list. | 446 | * directory. @sd is unlinked from the children list. |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 4045bdcc4b33..8acf82bba44c 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -20,43 +20,6 @@ | |||
20 | 20 | ||
21 | #include "sysfs.h" | 21 | #include "sysfs.h" |
22 | 22 | ||
23 | #define to_sattr(a) container_of(a,struct subsys_attribute, attr) | ||
24 | |||
25 | /* | ||
26 | * Subsystem file operations. | ||
27 | * These operations allow subsystems to have files that can be | ||
28 | * read/written. | ||
29 | */ | ||
30 | static ssize_t | ||
31 | subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page) | ||
32 | { | ||
33 | struct kset *kset = to_kset(kobj); | ||
34 | struct subsys_attribute * sattr = to_sattr(attr); | ||
35 | ssize_t ret = -EIO; | ||
36 | |||
37 | if (sattr->show) | ||
38 | ret = sattr->show(kset, page); | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | static ssize_t | ||
43 | subsys_attr_store(struct kobject * kobj, struct attribute * attr, | ||
44 | const char * page, size_t count) | ||
45 | { | ||
46 | struct kset *kset = to_kset(kobj); | ||
47 | struct subsys_attribute * sattr = to_sattr(attr); | ||
48 | ssize_t ret = -EIO; | ||
49 | |||
50 | if (sattr->store) | ||
51 | ret = sattr->store(kset, page, count); | ||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | static struct sysfs_ops subsys_sysfs_ops = { | ||
56 | .show = subsys_attr_show, | ||
57 | .store = subsys_attr_store, | ||
58 | }; | ||
59 | |||
60 | /* | 23 | /* |
61 | * There's one sysfs_buffer for each open file and one | 24 | * There's one sysfs_buffer for each open file and one |
62 | * sysfs_open_dirent for each sysfs_dirent with one or more open | 25 | * sysfs_open_dirent for each sysfs_dirent with one or more open |
@@ -66,7 +29,7 @@ static struct sysfs_ops subsys_sysfs_ops = { | |||
66 | * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open | 29 | * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open |
67 | * is protected by sysfs_open_dirent_lock. | 30 | * is protected by sysfs_open_dirent_lock. |
68 | */ | 31 | */ |
69 | static spinlock_t sysfs_open_dirent_lock = SPIN_LOCK_UNLOCKED; | 32 | static DEFINE_SPINLOCK(sysfs_open_dirent_lock); |
70 | 33 | ||
71 | struct sysfs_open_dirent { | 34 | struct sysfs_open_dirent { |
72 | atomic_t refcnt; | 35 | atomic_t refcnt; |
@@ -354,31 +317,23 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
354 | { | 317 | { |
355 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 318 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
356 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 319 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
357 | struct sysfs_buffer * buffer; | 320 | struct sysfs_buffer *buffer; |
358 | struct sysfs_ops * ops = NULL; | 321 | struct sysfs_ops *ops; |
359 | int error; | 322 | int error = -EACCES; |
360 | 323 | ||
361 | /* need attr_sd for attr and ops, its parent for kobj */ | 324 | /* need attr_sd for attr and ops, its parent for kobj */ |
362 | if (!sysfs_get_active_two(attr_sd)) | 325 | if (!sysfs_get_active_two(attr_sd)) |
363 | return -ENODEV; | 326 | return -ENODEV; |
364 | 327 | ||
365 | /* if the kobject has no ktype, then we assume that it is a subsystem | 328 | /* every kobject with an attribute needs a ktype assigned */ |
366 | * itself, and use ops for it. | 329 | if (kobj->ktype && kobj->ktype->sysfs_ops) |
367 | */ | ||
368 | if (kobj->kset && kobj->kset->ktype) | ||
369 | ops = kobj->kset->ktype->sysfs_ops; | ||
370 | else if (kobj->ktype) | ||
371 | ops = kobj->ktype->sysfs_ops; | 330 | ops = kobj->ktype->sysfs_ops; |
372 | else | 331 | else { |
373 | ops = &subsys_sysfs_ops; | 332 | printk(KERN_ERR "missing sysfs attribute operations for " |
374 | 333 | "kobject: %s\n", kobject_name(kobj)); | |
375 | error = -EACCES; | 334 | WARN_ON(1); |
376 | |||
377 | /* No sysfs operations, either from having no subsystem, | ||
378 | * or the subsystem have no operations. | ||
379 | */ | ||
380 | if (!ops) | ||
381 | goto err_out; | 335 | goto err_out; |
336 | } | ||
382 | 337 | ||
383 | /* File needs write support. | 338 | /* File needs write support. |
384 | * The inode's perms must say it's ok, | 339 | * The inode's perms must say it's ok, |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 3eac20c63c41..5f66c4466151 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -19,39 +19,6 @@ | |||
19 | 19 | ||
20 | #include "sysfs.h" | 20 | #include "sysfs.h" |
21 | 21 | ||
22 | static int object_depth(struct sysfs_dirent *sd) | ||
23 | { | ||
24 | int depth = 0; | ||
25 | |||
26 | for (; sd->s_parent; sd = sd->s_parent) | ||
27 | depth++; | ||
28 | |||
29 | return depth; | ||
30 | } | ||
31 | |||
32 | static int object_path_length(struct sysfs_dirent * sd) | ||
33 | { | ||
34 | int length = 1; | ||
35 | |||
36 | for (; sd->s_parent; sd = sd->s_parent) | ||
37 | length += strlen(sd->s_name) + 1; | ||
38 | |||
39 | return length; | ||
40 | } | ||
41 | |||
42 | static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length) | ||
43 | { | ||
44 | --length; | ||
45 | for (; sd->s_parent; sd = sd->s_parent) { | ||
46 | int cur = strlen(sd->s_name); | ||
47 | |||
48 | /* back up enough to print this bus id with '/' */ | ||
49 | length -= cur; | ||
50 | strncpy(buffer + length, sd->s_name, cur); | ||
51 | *(buffer + --length) = '/'; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | /** | 22 | /** |
56 | * sysfs_create_link - create symlink between two objects. | 23 | * sysfs_create_link - create symlink between two objects. |
57 | * @kobj: object whose directory we're creating the link in. | 24 | * @kobj: object whose directory we're creating the link in. |
@@ -112,7 +79,6 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
112 | return error; | 79 | return error; |
113 | } | 80 | } |
114 | 81 | ||
115 | |||
116 | /** | 82 | /** |
117 | * sysfs_remove_link - remove symlink in object's directory. | 83 | * sysfs_remove_link - remove symlink in object's directory. |
118 | * @kobj: object we're acting for. | 84 | * @kobj: object we're acting for. |
@@ -124,24 +90,54 @@ void sysfs_remove_link(struct kobject * kobj, const char * name) | |||
124 | sysfs_hash_and_remove(kobj->sd, name); | 90 | sysfs_hash_and_remove(kobj->sd, name); |
125 | } | 91 | } |
126 | 92 | ||
127 | static int sysfs_get_target_path(struct sysfs_dirent * parent_sd, | 93 | static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, |
128 | struct sysfs_dirent * target_sd, char *path) | 94 | struct sysfs_dirent *target_sd, char *path) |
129 | { | 95 | { |
130 | char * s; | 96 | struct sysfs_dirent *base, *sd; |
131 | int depth, size; | 97 | char *s = path; |
98 | int len = 0; | ||
99 | |||
100 | /* go up to the root, stop at the base */ | ||
101 | base = parent_sd; | ||
102 | while (base->s_parent) { | ||
103 | sd = target_sd->s_parent; | ||
104 | while (sd->s_parent && base != sd) | ||
105 | sd = sd->s_parent; | ||
106 | |||
107 | if (base == sd) | ||
108 | break; | ||
109 | |||
110 | strcpy(s, "../"); | ||
111 | s += 3; | ||
112 | base = base->s_parent; | ||
113 | } | ||
114 | |||
115 | /* determine end of target string for reverse fillup */ | ||
116 | sd = target_sd; | ||
117 | while (sd->s_parent && sd != base) { | ||
118 | len += strlen(sd->s_name) + 1; | ||
119 | sd = sd->s_parent; | ||
120 | } | ||
132 | 121 | ||
133 | depth = object_depth(parent_sd); | 122 | /* check limits */ |
134 | size = object_path_length(target_sd) + depth * 3 - 1; | 123 | if (len < 2) |
135 | if (size > PATH_MAX) | 124 | return -EINVAL; |
125 | len--; | ||
126 | if ((s - path) + len > PATH_MAX) | ||
136 | return -ENAMETOOLONG; | 127 | return -ENAMETOOLONG; |
137 | 128 | ||
138 | pr_debug("%s: depth = %d, size = %d\n", __FUNCTION__, depth, size); | 129 | /* reverse fillup of target string from target to base */ |
130 | sd = target_sd; | ||
131 | while (sd->s_parent && sd != base) { | ||
132 | int slen = strlen(sd->s_name); | ||
139 | 133 | ||
140 | for (s = path; depth--; s += 3) | 134 | len -= slen; |
141 | strcpy(s,"../"); | 135 | strncpy(s + len, sd->s_name, slen); |
136 | if (len) | ||
137 | s[--len] = '/'; | ||
142 | 138 | ||
143 | fill_object_path(target_sd, path, size); | 139 | sd = sd->s_parent; |
144 | pr_debug("%s: path = '%s'\n", __FUNCTION__, path); | 140 | } |
145 | 141 | ||
146 | return 0; | 142 | return 0; |
147 | } | 143 | } |