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