1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#undef DEBUG
28
29#include <linux/fs.h>
30#include <linux/mount.h>
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/err.h>
34
35#include <linux/configfs.h>
36#include "configfs_internal.h"
37
38DECLARE_RWSEM(configfs_rename_sem);
39
40
41
42
43
44
45
46
47
48
49
50
51DEFINE_SPINLOCK(configfs_dirent_lock);
52
53static void configfs_d_iput(struct dentry * dentry,
54 struct inode * inode)
55{
56 struct configfs_dirent *sd = dentry->d_fsdata;
57
58 if (sd) {
59 BUG_ON(sd->s_dentry != dentry);
60
61 spin_lock(&configfs_dirent_lock);
62 sd->s_dentry = NULL;
63 spin_unlock(&configfs_dirent_lock);
64 configfs_put(sd);
65 }
66 iput(inode);
67}
68
69
70
71
72
73static int configfs_d_delete(const struct dentry *dentry)
74{
75 return 1;
76}
77
78const struct dentry_operations configfs_dentry_ops = {
79 .d_iput = configfs_d_iput,
80
81 .d_delete = configfs_d_delete,
82};
83
84#ifdef CONFIG_LOCKDEP
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105static void configfs_init_dirent_depth(struct configfs_dirent *sd)
106{
107 sd->s_depth = -1;
108}
109
110static void configfs_set_dir_dirent_depth(struct configfs_dirent *parent_sd,
111 struct configfs_dirent *sd)
112{
113 int parent_depth = parent_sd->s_depth;
114
115 if (parent_depth >= 0)
116 sd->s_depth = parent_depth + 1;
117}
118
119static void
120configfs_adjust_dir_dirent_depth_before_populate(struct configfs_dirent *sd)
121{
122
123
124
125
126
127
128
129
130
131
132 if (sd->s_depth == -1)
133
134
135
136
137 sd->s_depth = 0;
138}
139
140static void
141configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
142{
143
144 sd->s_depth = -1;
145}
146
147#else
148
149static void configfs_init_dirent_depth(struct configfs_dirent *sd)
150{
151}
152
153static void configfs_set_dir_dirent_depth(struct configfs_dirent *parent_sd,
154 struct configfs_dirent *sd)
155{
156}
157
158static void
159configfs_adjust_dir_dirent_depth_before_populate(struct configfs_dirent *sd)
160{
161}
162
163static void
164configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
165{
166}
167
168#endif
169
170
171
172
173static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *parent_sd,
174 void *element, int type)
175{
176 struct configfs_dirent * sd;
177
178 sd = kmem_cache_zalloc(configfs_dir_cachep, GFP_KERNEL);
179 if (!sd)
180 return ERR_PTR(-ENOMEM);
181
182 atomic_set(&sd->s_count, 1);
183 INIT_LIST_HEAD(&sd->s_links);
184 INIT_LIST_HEAD(&sd->s_children);
185 sd->s_element = element;
186 sd->s_type = type;
187 configfs_init_dirent_depth(sd);
188 spin_lock(&configfs_dirent_lock);
189 if (parent_sd->s_type & CONFIGFS_USET_DROPPING) {
190 spin_unlock(&configfs_dirent_lock);
191 kmem_cache_free(configfs_dir_cachep, sd);
192 return ERR_PTR(-ENOENT);
193 }
194 list_add(&sd->s_sibling, &parent_sd->s_children);
195 spin_unlock(&configfs_dirent_lock);
196
197 return sd;
198}
199
200
201
202
203
204
205
206
207static int configfs_dirent_exists(struct configfs_dirent *parent_sd,
208 const unsigned char *new)
209{
210 struct configfs_dirent * sd;
211
212 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
213 if (sd->s_element) {
214 const unsigned char *existing = configfs_get_name(sd);
215 if (strcmp(existing, new))
216 continue;
217 else
218 return -EEXIST;
219 }
220 }
221
222 return 0;
223}
224
225
226int configfs_make_dirent(struct configfs_dirent * parent_sd,
227 struct dentry * dentry, void * element,
228 umode_t mode, int type)
229{
230 struct configfs_dirent * sd;
231
232 sd = configfs_new_dirent(parent_sd, element, type);
233 if (IS_ERR(sd))
234 return PTR_ERR(sd);
235
236 sd->s_mode = mode;
237 sd->s_dentry = dentry;
238 if (dentry)
239 dentry->d_fsdata = configfs_get(sd);
240
241 return 0;
242}
243
244static int init_dir(struct inode * inode)
245{
246 inode->i_op = &configfs_dir_inode_operations;
247 inode->i_fop = &configfs_dir_operations;
248
249
250 inc_nlink(inode);
251 return 0;
252}
253
254static int configfs_init_file(struct inode * inode)
255{
256 inode->i_size = PAGE_SIZE;
257 inode->i_fop = &configfs_file_operations;
258 return 0;
259}
260
261static int init_symlink(struct inode * inode)
262{
263 inode->i_op = &configfs_symlink_inode_operations;
264 return 0;
265}
266
267static int create_dir(struct config_item *k, struct dentry *d)
268{
269 int error;
270 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
271 struct dentry *p = d->d_parent;
272
273 BUG_ON(!k);
274
275 error = configfs_dirent_exists(p->d_fsdata, d->d_name.name);
276 if (!error)
277 error = configfs_make_dirent(p->d_fsdata, d, k, mode,
278 CONFIGFS_DIR | CONFIGFS_USET_CREATING);
279 if (!error) {
280 configfs_set_dir_dirent_depth(p->d_fsdata, d->d_fsdata);
281 error = configfs_create(d, mode, init_dir);
282 if (!error) {
283 inc_nlink(p->d_inode);
284 } else {
285 struct configfs_dirent *sd = d->d_fsdata;
286 if (sd) {
287 spin_lock(&configfs_dirent_lock);
288 list_del_init(&sd->s_sibling);
289 spin_unlock(&configfs_dirent_lock);
290 configfs_put(sd);
291 }
292 }
293 }
294 return error;
295}
296
297
298
299
300
301
302
303
304
305
306
307static int configfs_create_dir(struct config_item * item, struct dentry *dentry)
308{
309 int error = create_dir(item, dentry);
310 if (!error)
311 item->ci_dentry = dentry;
312 return error;
313}
314
315
316
317
318
319
320
321
322static void configfs_dir_set_ready(struct configfs_dirent *sd)
323{
324 struct configfs_dirent *child_sd;
325
326 sd->s_type &= ~CONFIGFS_USET_CREATING;
327 list_for_each_entry(child_sd, &sd->s_children, s_sibling)
328 if (child_sd->s_type & CONFIGFS_USET_CREATING)
329 configfs_dir_set_ready(child_sd);
330}
331
332
333
334
335
336
337
338
339
340
341
342int configfs_dirent_is_ready(struct configfs_dirent *sd)
343{
344 int ret;
345
346 spin_lock(&configfs_dirent_lock);
347 ret = !(sd->s_type & CONFIGFS_USET_CREATING);
348 spin_unlock(&configfs_dirent_lock);
349
350 return ret;
351}
352
353int configfs_create_link(struct configfs_symlink *sl,
354 struct dentry *parent,
355 struct dentry *dentry)
356{
357 int err = 0;
358 umode_t mode = S_IFLNK | S_IRWXUGO;
359
360 err = configfs_make_dirent(parent->d_fsdata, dentry, sl, mode,
361 CONFIGFS_ITEM_LINK);
362 if (!err) {
363 err = configfs_create(dentry, mode, init_symlink);
364 if (err) {
365 struct configfs_dirent *sd = dentry->d_fsdata;
366 if (sd) {
367 spin_lock(&configfs_dirent_lock);
368 list_del_init(&sd->s_sibling);
369 spin_unlock(&configfs_dirent_lock);
370 configfs_put(sd);
371 }
372 }
373 }
374 return err;
375}
376
377static void remove_dir(struct dentry * d)
378{
379 struct dentry * parent = dget(d->d_parent);
380 struct configfs_dirent * sd;
381
382 sd = d->d_fsdata;
383 spin_lock(&configfs_dirent_lock);
384 list_del_init(&sd->s_sibling);
385 spin_unlock(&configfs_dirent_lock);
386 configfs_put(sd);
387 if (d->d_inode)
388 simple_rmdir(parent->d_inode,d);
389
390 pr_debug(" o %s removing done (%d)\n",d->d_name.name, d_count(d));
391
392 dput(parent);
393}
394
395
396
397
398
399
400
401
402
403
404
405
406static void configfs_remove_dir(struct config_item * item)
407{
408 struct dentry * dentry = dget(item->ci_dentry);
409
410 if (!dentry)
411 return;
412
413 remove_dir(dentry);
414
415
416
417 dput(dentry);
418}
419
420
421
422
423
424static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * dentry)
425{
426 struct configfs_attribute * attr = sd->s_element;
427 int error;
428
429 dentry->d_fsdata = configfs_get(sd);
430 sd->s_dentry = dentry;
431 error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG,
432 configfs_init_file);
433 if (error) {
434 configfs_put(sd);
435 return error;
436 }
437
438 d_rehash(dentry);
439
440 return 0;
441}
442
443static struct dentry * configfs_lookup(struct inode *dir,
444 struct dentry *dentry,
445 unsigned int flags)
446{
447 struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
448 struct configfs_dirent * sd;
449 int found = 0;
450 int err;
451
452
453
454
455
456
457
458
459
460 err = -ENOENT;
461 if (!configfs_dirent_is_ready(parent_sd))
462 goto out;
463
464 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
465 if (sd->s_type & CONFIGFS_NOT_PINNED) {
466 const unsigned char * name = configfs_get_name(sd);
467
468 if (strcmp(name, dentry->d_name.name))
469 continue;
470
471 found = 1;
472 err = configfs_attach_attr(sd, dentry);
473 break;
474 }
475 }
476
477 if (!found) {
478
479
480
481
482 if (dentry->d_name.len > NAME_MAX)
483 return ERR_PTR(-ENAMETOOLONG);
484 d_add(dentry, NULL);
485 return NULL;
486 }
487
488out:
489 return ERR_PTR(err);
490}
491
492
493
494
495
496
497
498
499
500static int configfs_detach_prep(struct dentry *dentry, struct mutex **wait_mutex)
501{
502 struct configfs_dirent *parent_sd = dentry->d_fsdata;
503 struct configfs_dirent *sd;
504 int ret;
505
506
507 parent_sd->s_type |= CONFIGFS_USET_DROPPING;
508
509 ret = -EBUSY;
510 if (!list_empty(&parent_sd->s_links))
511 goto out;
512
513 ret = 0;
514 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
515 if (!sd->s_element ||
516 (sd->s_type & CONFIGFS_NOT_PINNED))
517 continue;
518 if (sd->s_type & CONFIGFS_USET_DEFAULT) {
519
520 if (sd->s_type & CONFIGFS_USET_IN_MKDIR) {
521 if (wait_mutex)
522 *wait_mutex = &sd->s_dentry->d_inode->i_mutex;
523 return -EAGAIN;
524 }
525
526
527
528
529
530 ret = configfs_detach_prep(sd->s_dentry, wait_mutex);
531 if (!ret)
532 continue;
533 } else
534 ret = -ENOTEMPTY;
535
536 break;
537 }
538
539out:
540 return ret;
541}
542
543
544
545
546
547static void configfs_detach_rollback(struct dentry *dentry)
548{
549 struct configfs_dirent *parent_sd = dentry->d_fsdata;
550 struct configfs_dirent *sd;
551
552 parent_sd->s_type &= ~CONFIGFS_USET_DROPPING;
553
554 list_for_each_entry(sd, &parent_sd->s_children, s_sibling)
555 if (sd->s_type & CONFIGFS_USET_DEFAULT)
556 configfs_detach_rollback(sd->s_dentry);
557}
558
559static void detach_attrs(struct config_item * item)
560{
561 struct dentry * dentry = dget(item->ci_dentry);
562 struct configfs_dirent * parent_sd;
563 struct configfs_dirent * sd, * tmp;
564
565 if (!dentry)
566 return;
567
568 pr_debug("configfs %s: dropping attrs for dir\n",
569 dentry->d_name.name);
570
571 parent_sd = dentry->d_fsdata;
572 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
573 if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED))
574 continue;
575 spin_lock(&configfs_dirent_lock);
576 list_del_init(&sd->s_sibling);
577 spin_unlock(&configfs_dirent_lock);
578 configfs_drop_dentry(sd, dentry);
579 configfs_put(sd);
580 }
581
582
583
584
585 dput(dentry);
586}
587
588static int populate_attrs(struct config_item *item)
589{
590 struct config_item_type *t = item->ci_type;
591 struct configfs_attribute *attr;
592 int error = 0;
593 int i;
594
595 if (!t)
596 return -EINVAL;
597 if (t->ct_attrs) {
598 for (i = 0; (attr = t->ct_attrs[i]) != NULL; i++) {
599 if ((error = configfs_create_file(item, attr)))
600 break;
601 }
602 }
603
604 if (error)
605 detach_attrs(item);
606
607 return error;
608}
609
610static int configfs_attach_group(struct config_item *parent_item,
611 struct config_item *item,
612 struct dentry *dentry);
613static void configfs_detach_group(struct config_item *item);
614
615static void detach_groups(struct config_group *group)
616{
617 struct dentry * dentry = dget(group->cg_item.ci_dentry);
618 struct dentry *child;
619 struct configfs_dirent *parent_sd;
620 struct configfs_dirent *sd, *tmp;
621
622 if (!dentry)
623 return;
624
625 parent_sd = dentry->d_fsdata;
626 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
627 if (!sd->s_element ||
628 !(sd->s_type & CONFIGFS_USET_DEFAULT))
629 continue;
630
631 child = sd->s_dentry;
632
633 mutex_lock(&child->d_inode->i_mutex);
634
635 configfs_detach_group(sd->s_element);
636 child->d_inode->i_flags |= S_DEAD;
637 dont_mount(child);
638
639 mutex_unlock(&child->d_inode->i_mutex);
640
641 d_delete(child);
642 dput(child);
643 }
644
645
646
647
648 dput(dentry);
649}
650
651
652
653
654
655
656
657
658
659static int create_default_group(struct config_group *parent_group,
660 struct config_group *group)
661{
662 int ret;
663 struct configfs_dirent *sd;
664
665 struct dentry *child, *parent = parent_group->cg_item.ci_dentry;
666
667 if (!group->cg_item.ci_name)
668 group->cg_item.ci_name = group->cg_item.ci_namebuf;
669
670 ret = -ENOMEM;
671 child = d_alloc_name(parent, group->cg_item.ci_name);
672 if (child) {
673 d_add(child, NULL);
674
675 ret = configfs_attach_group(&parent_group->cg_item,
676 &group->cg_item, child);
677 if (!ret) {
678 sd = child->d_fsdata;
679 sd->s_type |= CONFIGFS_USET_DEFAULT;
680 } else {
681 BUG_ON(child->d_inode);
682 d_drop(child);
683 dput(child);
684 }
685 }
686
687 return ret;
688}
689
690static int populate_groups(struct config_group *group)
691{
692 struct config_group *new_group;
693 int ret = 0;
694 int i;
695
696 if (group->default_groups) {
697 for (i = 0; group->default_groups[i]; i++) {
698 new_group = group->default_groups[i];
699
700 ret = create_default_group(group, new_group);
701 if (ret) {
702 detach_groups(group);
703 break;
704 }
705 }
706 }
707
708 return ret;
709}
710
711
712
713
714
715
716static void unlink_obj(struct config_item *item)
717{
718 struct config_group *group;
719
720 group = item->ci_group;
721 if (group) {
722 list_del_init(&item->ci_entry);
723
724 item->ci_group = NULL;
725 item->ci_parent = NULL;
726
727
728 config_item_put(item);
729
730
731 config_group_put(group);
732 }
733}
734
735static void link_obj(struct config_item *parent_item, struct config_item *item)
736{
737
738
739
740
741 item->ci_parent = parent_item;
742
743
744
745
746
747 item->ci_group = config_group_get(to_config_group(parent_item));
748 list_add_tail(&item->ci_entry, &item->ci_group->cg_children);
749
750
751
752
753
754 config_item_get(item);
755}
756
757static void unlink_group(struct config_group *group)
758{
759 int i;
760 struct config_group *new_group;
761
762 if (group->default_groups) {
763 for (i = 0; group->default_groups[i]; i++) {
764 new_group = group->default_groups[i];
765 unlink_group(new_group);
766 }
767 }
768
769 group->cg_subsys = NULL;
770 unlink_obj(&group->cg_item);
771}
772
773static void link_group(struct config_group *parent_group, struct config_group *group)
774{
775 int i;
776 struct config_group *new_group;
777 struct configfs_subsystem *subsys = NULL;
778
779 link_obj(&parent_group->cg_item, &group->cg_item);
780
781 if (parent_group->cg_subsys)
782 subsys = parent_group->cg_subsys;
783 else if (configfs_is_root(&parent_group->cg_item))
784 subsys = to_configfs_subsystem(group);
785 else
786 BUG();
787 group->cg_subsys = subsys;
788
789 if (group->default_groups) {
790 for (i = 0; group->default_groups[i]; i++) {
791 new_group = group->default_groups[i];
792 link_group(group, new_group);
793 }
794 }
795}
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812static int configfs_attach_item(struct config_item *parent_item,
813 struct config_item *item,
814 struct dentry *dentry)
815{
816 int ret;
817
818 ret = configfs_create_dir(item, dentry);
819 if (!ret) {
820 ret = populate_attrs(item);
821 if (ret) {
822
823
824
825
826
827 mutex_lock(&dentry->d_inode->i_mutex);
828 configfs_remove_dir(item);
829 dentry->d_inode->i_flags |= S_DEAD;
830 dont_mount(dentry);
831 mutex_unlock(&dentry->d_inode->i_mutex);
832 d_delete(dentry);
833 }
834 }
835
836 return ret;
837}
838
839
840static void configfs_detach_item(struct config_item *item)
841{
842 detach_attrs(item);
843 configfs_remove_dir(item);
844}
845
846static int configfs_attach_group(struct config_item *parent_item,
847 struct config_item *item,
848 struct dentry *dentry)
849{
850 int ret;
851 struct configfs_dirent *sd;
852
853 ret = configfs_attach_item(parent_item, item, dentry);
854 if (!ret) {
855 sd = dentry->d_fsdata;
856 sd->s_type |= CONFIGFS_USET_DIR;
857
858
859
860
861
862
863
864
865
866
867 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
868 configfs_adjust_dir_dirent_depth_before_populate(sd);
869 ret = populate_groups(to_config_group(item));
870 if (ret) {
871 configfs_detach_item(item);
872 dentry->d_inode->i_flags |= S_DEAD;
873 dont_mount(dentry);
874 }
875 configfs_adjust_dir_dirent_depth_after_populate(sd);
876 mutex_unlock(&dentry->d_inode->i_mutex);
877 if (ret)
878 d_delete(dentry);
879 }
880
881 return ret;
882}
883
884
885static void configfs_detach_group(struct config_item *item)
886{
887 detach_groups(to_config_group(item));
888 configfs_detach_item(item);
889}
890
891
892
893
894
895
896
897
898
899
900static void client_disconnect_notify(struct config_item *parent_item,
901 struct config_item *item)
902{
903 struct config_item_type *type;
904
905 type = parent_item->ci_type;
906 BUG_ON(!type);
907
908 if (type->ct_group_ops && type->ct_group_ops->disconnect_notify)
909 type->ct_group_ops->disconnect_notify(to_config_group(parent_item),
910 item);
911}
912
913
914
915
916
917
918
919static void client_drop_item(struct config_item *parent_item,
920 struct config_item *item)
921{
922 struct config_item_type *type;
923
924 type = parent_item->ci_type;
925 BUG_ON(!type);
926
927
928
929
930
931 if (type->ct_group_ops && type->ct_group_ops->drop_item)
932 type->ct_group_ops->drop_item(to_config_group(parent_item),
933 item);
934 else
935 config_item_put(item);
936}
937
938#ifdef DEBUG
939static void configfs_dump_one(struct configfs_dirent *sd, int level)
940{
941 printk(KERN_INFO "%*s\"%s\":\n", level, " ", configfs_get_name(sd));
942
943#define type_print(_type) if (sd->s_type & _type) printk(KERN_INFO "%*s %s\n", level, " ", #_type);
944 type_print(CONFIGFS_ROOT);
945 type_print(CONFIGFS_DIR);
946 type_print(CONFIGFS_ITEM_ATTR);
947 type_print(CONFIGFS_ITEM_LINK);
948 type_print(CONFIGFS_USET_DIR);
949 type_print(CONFIGFS_USET_DEFAULT);
950 type_print(CONFIGFS_USET_DROPPING);
951#undef type_print
952}
953
954static int configfs_dump(struct configfs_dirent *sd, int level)
955{
956 struct configfs_dirent *child_sd;
957 int ret = 0;
958
959 configfs_dump_one(sd, level);
960
961 if (!(sd->s_type & (CONFIGFS_DIR|CONFIGFS_ROOT)))
962 return 0;
963
964 list_for_each_entry(child_sd, &sd->s_children, s_sibling) {
965 ret = configfs_dump(child_sd, level + 2);
966 if (ret)
967 break;
968 }
969
970 return ret;
971}
972#endif
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033static int configfs_depend_prep(struct dentry *origin,
1034 struct config_item *target)
1035{
1036 struct configfs_dirent *child_sd, *sd;
1037 int ret = 0;
1038
1039 BUG_ON(!origin || !origin->d_fsdata);
1040 sd = origin->d_fsdata;
1041
1042 if (sd->s_element == target)
1043 goto out;
1044
1045 list_for_each_entry(child_sd, &sd->s_children, s_sibling) {
1046 if ((child_sd->s_type & CONFIGFS_DIR) &&
1047 !(child_sd->s_type & CONFIGFS_USET_DROPPING) &&
1048 !(child_sd->s_type & CONFIGFS_USET_CREATING)) {
1049 ret = configfs_depend_prep(child_sd->s_dentry,
1050 target);
1051 if (!ret)
1052 goto out;
1053 }
1054 }
1055
1056
1057 ret = -ENOENT;
1058
1059out:
1060 return ret;
1061}
1062
1063int configfs_depend_item(struct configfs_subsystem *subsys,
1064 struct config_item *target)
1065{
1066 int ret;
1067 struct configfs_dirent *p, *root_sd, *subsys_sd = NULL;
1068 struct config_item *s_item = &subsys->su_group.cg_item;
1069 struct dentry *root;
1070
1071
1072
1073
1074
1075 root = configfs_pin_fs();
1076 if (IS_ERR(root))
1077 return PTR_ERR(root);
1078
1079
1080
1081
1082
1083
1084 mutex_lock(&root->d_inode->i_mutex);
1085
1086 root_sd = root->d_fsdata;
1087
1088 list_for_each_entry(p, &root_sd->s_children, s_sibling) {
1089 if (p->s_type & CONFIGFS_DIR) {
1090 if (p->s_element == s_item) {
1091 subsys_sd = p;
1092 break;
1093 }
1094 }
1095 }
1096
1097 if (!subsys_sd) {
1098 ret = -ENOENT;
1099 goto out_unlock_fs;
1100 }
1101
1102
1103
1104 spin_lock(&configfs_dirent_lock);
1105
1106 ret = configfs_depend_prep(subsys_sd->s_dentry, target);
1107 if (ret)
1108 goto out_unlock_dirent_lock;
1109
1110
1111
1112
1113
1114 p = target->ci_dentry->d_fsdata;
1115 p->s_dependent_count += 1;
1116
1117out_unlock_dirent_lock:
1118 spin_unlock(&configfs_dirent_lock);
1119out_unlock_fs:
1120 mutex_unlock(&root->d_inode->i_mutex);
1121
1122
1123
1124
1125
1126 configfs_release_fs();
1127
1128 return ret;
1129}
1130EXPORT_SYMBOL(configfs_depend_item);
1131
1132
1133
1134
1135
1136
1137void configfs_undepend_item(struct configfs_subsystem *subsys,
1138 struct config_item *target)
1139{
1140 struct configfs_dirent *sd;
1141
1142
1143
1144
1145
1146 spin_lock(&configfs_dirent_lock);
1147
1148 sd = target->ci_dentry->d_fsdata;
1149 BUG_ON(sd->s_dependent_count < 1);
1150
1151 sd->s_dependent_count -= 1;
1152
1153
1154
1155
1156
1157 spin_unlock(&configfs_dirent_lock);
1158}
1159EXPORT_SYMBOL(configfs_undepend_item);
1160
1161static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1162{
1163 int ret = 0;
1164 int module_got = 0;
1165 struct config_group *group = NULL;
1166 struct config_item *item = NULL;
1167 struct config_item *parent_item;
1168 struct configfs_subsystem *subsys;
1169 struct configfs_dirent *sd;
1170 struct config_item_type *type;
1171 struct module *subsys_owner = NULL, *new_item_owner = NULL;
1172 char *name;
1173
1174 sd = dentry->d_parent->d_fsdata;
1175
1176
1177
1178
1179
1180 if (!configfs_dirent_is_ready(sd)) {
1181 ret = -ENOENT;
1182 goto out;
1183 }
1184
1185 if (!(sd->s_type & CONFIGFS_USET_DIR)) {
1186 ret = -EPERM;
1187 goto out;
1188 }
1189
1190
1191 parent_item = configfs_get_config_item(dentry->d_parent);
1192 type = parent_item->ci_type;
1193 subsys = to_config_group(parent_item)->cg_subsys;
1194 BUG_ON(!subsys);
1195
1196 if (!type || !type->ct_group_ops ||
1197 (!type->ct_group_ops->make_group &&
1198 !type->ct_group_ops->make_item)) {
1199 ret = -EPERM;
1200 goto out_put;
1201 }
1202
1203
1204
1205
1206
1207
1208 if (!subsys->su_group.cg_item.ci_type) {
1209 ret = -EINVAL;
1210 goto out_put;
1211 }
1212 subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1213 if (!try_module_get(subsys_owner)) {
1214 ret = -EINVAL;
1215 goto out_put;
1216 }
1217
1218 name = kmalloc(dentry->d_name.len + 1, GFP_KERNEL);
1219 if (!name) {
1220 ret = -ENOMEM;
1221 goto out_subsys_put;
1222 }
1223
1224 snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);
1225
1226 mutex_lock(&subsys->su_mutex);
1227 if (type->ct_group_ops->make_group) {
1228 group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
1229 if (!group)
1230 group = ERR_PTR(-ENOMEM);
1231 if (!IS_ERR(group)) {
1232 link_group(to_config_group(parent_item), group);
1233 item = &group->cg_item;
1234 } else
1235 ret = PTR_ERR(group);
1236 } else {
1237 item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
1238 if (!item)
1239 item = ERR_PTR(-ENOMEM);
1240 if (!IS_ERR(item))
1241 link_obj(parent_item, item);
1242 else
1243 ret = PTR_ERR(item);
1244 }
1245 mutex_unlock(&subsys->su_mutex);
1246
1247 kfree(name);
1248 if (ret) {
1249
1250
1251
1252
1253 goto out_subsys_put;
1254 }
1255
1256
1257
1258
1259
1260
1261 type = item->ci_type;
1262 if (!type) {
1263 ret = -EINVAL;
1264 goto out_unlink;
1265 }
1266
1267 new_item_owner = type->ct_owner;
1268 if (!try_module_get(new_item_owner)) {
1269 ret = -EINVAL;
1270 goto out_unlink;
1271 }
1272
1273
1274
1275
1276
1277
1278 module_got = 1;
1279
1280
1281
1282
1283
1284
1285
1286 spin_lock(&configfs_dirent_lock);
1287
1288 sd->s_type |= CONFIGFS_USET_IN_MKDIR;
1289 spin_unlock(&configfs_dirent_lock);
1290
1291 if (group)
1292 ret = configfs_attach_group(parent_item, item, dentry);
1293 else
1294 ret = configfs_attach_item(parent_item, item, dentry);
1295
1296 spin_lock(&configfs_dirent_lock);
1297 sd->s_type &= ~CONFIGFS_USET_IN_MKDIR;
1298 if (!ret)
1299 configfs_dir_set_ready(dentry->d_fsdata);
1300 spin_unlock(&configfs_dirent_lock);
1301
1302out_unlink:
1303 if (ret) {
1304
1305 mutex_lock(&subsys->su_mutex);
1306
1307 client_disconnect_notify(parent_item, item);
1308 if (group)
1309 unlink_group(group);
1310 else
1311 unlink_obj(item);
1312 client_drop_item(parent_item, item);
1313
1314 mutex_unlock(&subsys->su_mutex);
1315
1316 if (module_got)
1317 module_put(new_item_owner);
1318 }
1319
1320out_subsys_put:
1321 if (ret)
1322 module_put(subsys_owner);
1323
1324out_put:
1325
1326
1327
1328
1329
1330 config_item_put(parent_item);
1331
1332out:
1333 return ret;
1334}
1335
1336static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
1337{
1338 struct config_item *parent_item;
1339 struct config_item *item;
1340 struct configfs_subsystem *subsys;
1341 struct configfs_dirent *sd;
1342 struct module *subsys_owner = NULL, *dead_item_owner = NULL;
1343 int ret;
1344
1345 sd = dentry->d_fsdata;
1346 if (sd->s_type & CONFIGFS_USET_DEFAULT)
1347 return -EPERM;
1348
1349
1350 parent_item = configfs_get_config_item(dentry->d_parent);
1351 subsys = to_config_group(parent_item)->cg_subsys;
1352 BUG_ON(!subsys);
1353
1354 if (!parent_item->ci_type) {
1355 config_item_put(parent_item);
1356 return -EINVAL;
1357 }
1358
1359
1360 BUG_ON(!subsys->su_group.cg_item.ci_type);
1361 subsys_owner = subsys->su_group.cg_item.ci_type->ct_owner;
1362
1363
1364
1365
1366
1367 do {
1368 struct mutex *wait_mutex;
1369
1370 mutex_lock(&configfs_symlink_mutex);
1371 spin_lock(&configfs_dirent_lock);
1372
1373
1374
1375
1376
1377 ret = sd->s_dependent_count ? -EBUSY : 0;
1378 if (!ret) {
1379 ret = configfs_detach_prep(dentry, &wait_mutex);
1380 if (ret)
1381 configfs_detach_rollback(dentry);
1382 }
1383 spin_unlock(&configfs_dirent_lock);
1384 mutex_unlock(&configfs_symlink_mutex);
1385
1386 if (ret) {
1387 if (ret != -EAGAIN) {
1388 config_item_put(parent_item);
1389 return ret;
1390 }
1391
1392
1393 mutex_lock(wait_mutex);
1394 mutex_unlock(wait_mutex);
1395 }
1396 } while (ret == -EAGAIN);
1397
1398
1399 item = configfs_get_config_item(dentry);
1400
1401
1402 config_item_put(parent_item);
1403
1404 if (item->ci_type)
1405 dead_item_owner = item->ci_type->ct_owner;
1406
1407 if (sd->s_type & CONFIGFS_USET_DIR) {
1408 configfs_detach_group(item);
1409
1410 mutex_lock(&subsys->su_mutex);
1411 client_disconnect_notify(parent_item, item);
1412 unlink_group(to_config_group(item));
1413 } else {
1414 configfs_detach_item(item);
1415
1416 mutex_lock(&subsys->su_mutex);
1417 client_disconnect_notify(parent_item, item);
1418 unlink_obj(item);
1419 }
1420
1421 client_drop_item(parent_item, item);
1422 mutex_unlock(&subsys->su_mutex);
1423
1424
1425 config_item_put(item);
1426
1427 module_put(dead_item_owner);
1428 module_put(subsys_owner);
1429
1430 return 0;
1431}
1432
1433const struct inode_operations configfs_dir_inode_operations = {
1434 .mkdir = configfs_mkdir,
1435 .rmdir = configfs_rmdir,
1436 .symlink = configfs_symlink,
1437 .unlink = configfs_unlink,
1438 .lookup = configfs_lookup,
1439 .setattr = configfs_setattr,
1440};
1441
1442const struct inode_operations configfs_root_inode_operations = {
1443 .lookup = configfs_lookup,
1444 .setattr = configfs_setattr,
1445};
1446
1447#if 0
1448int configfs_rename_dir(struct config_item * item, const char *new_name)
1449{
1450 int error = 0;
1451 struct dentry * new_dentry, * parent;
1452
1453 if (!strcmp(config_item_name(item), new_name))
1454 return -EINVAL;
1455
1456 if (!item->parent)
1457 return -EINVAL;
1458
1459 down_write(&configfs_rename_sem);
1460 parent = item->parent->dentry;
1461
1462 mutex_lock(&parent->d_inode->i_mutex);
1463
1464 new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
1465 if (!IS_ERR(new_dentry)) {
1466 if (!new_dentry->d_inode) {
1467 error = config_item_set_name(item, "%s", new_name);
1468 if (!error) {
1469 d_add(new_dentry, NULL);
1470 d_move(item->dentry, new_dentry);
1471 }
1472 else
1473 d_delete(new_dentry);
1474 } else
1475 error = -EEXIST;
1476 dput(new_dentry);
1477 }
1478 mutex_unlock(&parent->d_inode->i_mutex);
1479 up_write(&configfs_rename_sem);
1480
1481 return error;
1482}
1483#endif
1484
1485static int configfs_dir_open(struct inode *inode, struct file *file)
1486{
1487 struct dentry * dentry = file->f_path.dentry;
1488 struct configfs_dirent * parent_sd = dentry->d_fsdata;
1489 int err;
1490
1491 mutex_lock(&dentry->d_inode->i_mutex);
1492
1493
1494
1495
1496 err = -ENOENT;
1497 if (configfs_dirent_is_ready(parent_sd)) {
1498 file->private_data = configfs_new_dirent(parent_sd, NULL, 0);
1499 if (IS_ERR(file->private_data))
1500 err = PTR_ERR(file->private_data);
1501 else
1502 err = 0;
1503 }
1504 mutex_unlock(&dentry->d_inode->i_mutex);
1505
1506 return err;
1507}
1508
1509static int configfs_dir_close(struct inode *inode, struct file *file)
1510{
1511 struct dentry * dentry = file->f_path.dentry;
1512 struct configfs_dirent * cursor = file->private_data;
1513
1514 mutex_lock(&dentry->d_inode->i_mutex);
1515 spin_lock(&configfs_dirent_lock);
1516 list_del_init(&cursor->s_sibling);
1517 spin_unlock(&configfs_dirent_lock);
1518 mutex_unlock(&dentry->d_inode->i_mutex);
1519
1520 release_configfs_dirent(cursor);
1521
1522 return 0;
1523}
1524
1525
1526static inline unsigned char dt_type(struct configfs_dirent *sd)
1527{
1528 return (sd->s_mode >> 12) & 15;
1529}
1530
1531static int configfs_readdir(struct file *file, struct dir_context *ctx)
1532{
1533 struct dentry *dentry = file->f_path.dentry;
1534 struct super_block *sb = dentry->d_sb;
1535 struct configfs_dirent * parent_sd = dentry->d_fsdata;
1536 struct configfs_dirent *cursor = file->private_data;
1537 struct list_head *p, *q = &cursor->s_sibling;
1538 ino_t ino = 0;
1539
1540 if (!dir_emit_dots(file, ctx))
1541 return 0;
1542 if (ctx->pos == 2) {
1543 spin_lock(&configfs_dirent_lock);
1544 list_move(q, &parent_sd->s_children);
1545 spin_unlock(&configfs_dirent_lock);
1546 }
1547 for (p = q->next; p != &parent_sd->s_children; p = p->next) {
1548 struct configfs_dirent *next;
1549 const char *name;
1550 int len;
1551 struct inode *inode = NULL;
1552
1553 next = list_entry(p, struct configfs_dirent, s_sibling);
1554 if (!next->s_element)
1555 continue;
1556
1557 name = configfs_get_name(next);
1558 len = strlen(name);
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573 spin_lock(&configfs_dirent_lock);
1574 dentry = next->s_dentry;
1575 if (dentry)
1576 inode = dentry->d_inode;
1577 if (inode)
1578 ino = inode->i_ino;
1579 spin_unlock(&configfs_dirent_lock);
1580 if (!inode)
1581 ino = iunique(sb, 2);
1582
1583 if (!dir_emit(ctx, name, len, ino, dt_type(next)))
1584 return 0;
1585
1586 spin_lock(&configfs_dirent_lock);
1587 list_move(q, p);
1588 spin_unlock(&configfs_dirent_lock);
1589 p = q;
1590 ctx->pos++;
1591 }
1592 return 0;
1593}
1594
1595static loff_t configfs_dir_lseek(struct file *file, loff_t offset, int whence)
1596{
1597 struct dentry * dentry = file->f_path.dentry;
1598
1599 mutex_lock(&dentry->d_inode->i_mutex);
1600 switch (whence) {
1601 case 1:
1602 offset += file->f_pos;
1603 case 0:
1604 if (offset >= 0)
1605 break;
1606 default:
1607 mutex_unlock(&file_inode(file)->i_mutex);
1608 return -EINVAL;
1609 }
1610 if (offset != file->f_pos) {
1611 file->f_pos = offset;
1612 if (file->f_pos >= 2) {
1613 struct configfs_dirent *sd = dentry->d_fsdata;
1614 struct configfs_dirent *cursor = file->private_data;
1615 struct list_head *p;
1616 loff_t n = file->f_pos - 2;
1617
1618 spin_lock(&configfs_dirent_lock);
1619 list_del(&cursor->s_sibling);
1620 p = sd->s_children.next;
1621 while (n && p != &sd->s_children) {
1622 struct configfs_dirent *next;
1623 next = list_entry(p, struct configfs_dirent,
1624 s_sibling);
1625 if (next->s_element)
1626 n--;
1627 p = p->next;
1628 }
1629 list_add_tail(&cursor->s_sibling, p);
1630 spin_unlock(&configfs_dirent_lock);
1631 }
1632 }
1633 mutex_unlock(&dentry->d_inode->i_mutex);
1634 return offset;
1635}
1636
1637const struct file_operations configfs_dir_operations = {
1638 .open = configfs_dir_open,
1639 .release = configfs_dir_close,
1640 .llseek = configfs_dir_lseek,
1641 .read = generic_read_dir,
1642 .iterate = configfs_readdir,
1643};
1644
1645int configfs_register_subsystem(struct configfs_subsystem *subsys)
1646{
1647 int err;
1648 struct config_group *group = &subsys->su_group;
1649 struct dentry *dentry;
1650 struct dentry *root;
1651 struct configfs_dirent *sd;
1652
1653 root = configfs_pin_fs();
1654 if (IS_ERR(root))
1655 return PTR_ERR(root);
1656
1657 if (!group->cg_item.ci_name)
1658 group->cg_item.ci_name = group->cg_item.ci_namebuf;
1659
1660 sd = root->d_fsdata;
1661 link_group(to_config_group(sd->s_element), group);
1662
1663 mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
1664
1665 err = -ENOMEM;
1666 dentry = d_alloc_name(root, group->cg_item.ci_name);
1667 if (dentry) {
1668 d_add(dentry, NULL);
1669
1670 err = configfs_attach_group(sd->s_element, &group->cg_item,
1671 dentry);
1672 if (err) {
1673 BUG_ON(dentry->d_inode);
1674 d_drop(dentry);
1675 dput(dentry);
1676 } else {
1677 spin_lock(&configfs_dirent_lock);
1678 configfs_dir_set_ready(dentry->d_fsdata);
1679 spin_unlock(&configfs_dirent_lock);
1680 }
1681 }
1682
1683 mutex_unlock(&root->d_inode->i_mutex);
1684
1685 if (err) {
1686 unlink_group(group);
1687 configfs_release_fs();
1688 }
1689
1690 return err;
1691}
1692
1693void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
1694{
1695 struct config_group *group = &subsys->su_group;
1696 struct dentry *dentry = group->cg_item.ci_dentry;
1697 struct dentry *root = dentry->d_sb->s_root;
1698
1699 if (dentry->d_parent != root) {
1700 printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n");
1701 return;
1702 }
1703
1704 mutex_lock_nested(&root->d_inode->i_mutex,
1705 I_MUTEX_PARENT);
1706 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
1707 mutex_lock(&configfs_symlink_mutex);
1708 spin_lock(&configfs_dirent_lock);
1709 if (configfs_detach_prep(dentry, NULL)) {
1710 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");
1711 }
1712 spin_unlock(&configfs_dirent_lock);
1713 mutex_unlock(&configfs_symlink_mutex);
1714 configfs_detach_group(&group->cg_item);
1715 dentry->d_inode->i_flags |= S_DEAD;
1716 dont_mount(dentry);
1717 mutex_unlock(&dentry->d_inode->i_mutex);
1718
1719 d_delete(dentry);
1720
1721 mutex_unlock(&root->d_inode->i_mutex);
1722
1723 dput(dentry);
1724
1725 unlink_group(group);
1726 configfs_release_fs();
1727}
1728
1729EXPORT_SYMBOL(configfs_register_subsystem);
1730EXPORT_SYMBOL(configfs_unregister_subsystem);
1731