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