Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6] / fs / configfs / dir.c
1 /* -*- mode: c; c-basic-offset: 8; -*-
2  * vim: noexpandtab sw=8 ts=8 sts=0:
3  *
4  * dir.c - Operations for configfs directories.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 021110-1307, USA.
20  *
21  * Based on sysfs:
22  *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
23  *
24  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
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
37 DECLARE_RWSEM(configfs_rename_sem);
38
39 static 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  * We _must_ delete our dentries on last dput, as the chain-to-parent
54  * behavior is required to clear the parents of default_groups.
55  */
56 static int configfs_d_delete(struct dentry *dentry)
57 {
58         return 1;
59 }
60
61 static struct dentry_operations configfs_dentry_ops = {
62         .d_iput         = configfs_d_iput,
63         /* simple_delete_dentry() isn't exported */
64         .d_delete       = configfs_d_delete,
65 };
66
67 /*
68  * Allocates a new configfs_dirent and links it to the parent configfs_dirent
69  */
70 static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * parent_sd,
71                                                 void * element)
72 {
73         struct configfs_dirent * sd;
74
75         sd = kmalloc(sizeof(*sd), GFP_KERNEL);
76         if (!sd)
77                 return NULL;
78
79         memset(sd, 0, sizeof(*sd));
80         atomic_set(&sd->s_count, 1);
81         INIT_LIST_HEAD(&sd->s_links);
82         INIT_LIST_HEAD(&sd->s_children);
83         list_add(&sd->s_sibling, &parent_sd->s_children);
84         sd->s_element = element;
85
86         return sd;
87 }
88
89 int configfs_make_dirent(struct configfs_dirent * parent_sd,
90                          struct dentry * dentry, void * element,
91                          umode_t mode, int type)
92 {
93         struct configfs_dirent * sd;
94
95         sd = configfs_new_dirent(parent_sd, element);
96         if (!sd)
97                 return -ENOMEM;
98
99         sd->s_mode = mode;
100         sd->s_type = type;
101         sd->s_dentry = dentry;
102         if (dentry) {
103                 dentry->d_fsdata = configfs_get(sd);
104                 dentry->d_op = &configfs_dentry_ops;
105         }
106
107         return 0;
108 }
109
110 static int init_dir(struct inode * inode)
111 {
112         inode->i_op = &configfs_dir_inode_operations;
113         inode->i_fop = &configfs_dir_operations;
114
115         /* directory inodes start off with i_nlink == 2 (for "." entry) */
116         inode->i_nlink++;
117         return 0;
118 }
119
120 static int init_file(struct inode * inode)
121 {
122         inode->i_size = PAGE_SIZE;
123         inode->i_fop = &configfs_file_operations;
124         return 0;
125 }
126
127 static int init_symlink(struct inode * inode)
128 {
129         inode->i_op = &configfs_symlink_inode_operations;
130         return 0;
131 }
132
133 static int create_dir(struct config_item * k, struct dentry * p,
134                       struct dentry * d)
135 {
136         int error;
137         umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
138
139         error = configfs_create(d, mode, init_dir);
140         if (!error) {
141                 error = configfs_make_dirent(p->d_fsdata, d, k, mode,
142                                            CONFIGFS_DIR);
143                 if (!error) {
144                         p->d_inode->i_nlink++;
145                         (d)->d_op = &configfs_dentry_ops;
146                 }
147         }
148         return error;
149 }
150
151
152 /**
153  *      configfs_create_dir - create a directory for an config_item.
154  *      @item:          config_itemwe're creating directory for.
155  *      @dentry:        config_item's dentry.
156  */
157
158 static int configfs_create_dir(struct config_item * item, struct dentry *dentry)
159 {
160         struct dentry * parent;
161         int error = 0;
162
163         BUG_ON(!item);
164
165         if (item->ci_parent)
166                 parent = item->ci_parent->ci_dentry;
167         else if (configfs_mount && configfs_mount->mnt_sb)
168                 parent = configfs_mount->mnt_sb->s_root;
169         else
170                 return -EFAULT;
171
172         error = create_dir(item,parent,dentry);
173         if (!error)
174                 item->ci_dentry = dentry;
175         return error;
176 }
177
178 int configfs_create_link(struct configfs_symlink *sl,
179                          struct dentry *parent,
180                          struct dentry *dentry)
181 {
182         int err = 0;
183         umode_t mode = S_IFLNK | S_IRWXUGO;
184
185         err = configfs_create(dentry, mode, init_symlink);
186         if (!err) {
187                 err = configfs_make_dirent(parent->d_fsdata, dentry, sl,
188                                          mode, CONFIGFS_ITEM_LINK);
189                 if (!err)
190                         dentry->d_op = &configfs_dentry_ops;
191         }
192         return err;
193 }
194
195 static void remove_dir(struct dentry * d)
196 {
197         struct dentry * parent = dget(d->d_parent);
198         struct configfs_dirent * sd;
199
200         sd = d->d_fsdata;
201         list_del_init(&sd->s_sibling);
202         configfs_put(sd);
203         if (d->d_inode)
204                 simple_rmdir(parent->d_inode,d);
205
206         pr_debug(" o %s removing done (%d)\n",d->d_name.name,
207                  atomic_read(&d->d_count));
208
209         dput(parent);
210 }
211
212 /**
213  * configfs_remove_dir - remove an config_item's directory.
214  * @item:       config_item we're removing.
215  *
216  * The only thing special about this is that we remove any files in
217  * the directory before we remove the directory, and we've inlined
218  * what used to be configfs_rmdir() below, instead of calling separately.
219  */
220
221 static void configfs_remove_dir(struct config_item * item)
222 {
223         struct dentry * dentry = dget(item->ci_dentry);
224
225         if (!dentry)
226                 return;
227
228         remove_dir(dentry);
229         /**
230          * Drop reference from dget() on entrance.
231          */
232         dput(dentry);
233 }
234
235
236 /* attaches attribute's configfs_dirent to the dentry corresponding to the
237  * attribute file
238  */
239 static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * dentry)
240 {
241         struct configfs_attribute * attr = sd->s_element;
242         int error;
243
244         error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file);
245         if (error)
246                 return error;
247
248         dentry->d_op = &configfs_dentry_ops;
249         dentry->d_fsdata = configfs_get(sd);
250         sd->s_dentry = dentry;
251         d_rehash(dentry);
252
253         return 0;
254 }
255
256 static struct dentry * configfs_lookup(struct inode *dir,
257                                        struct dentry *dentry,
258                                        struct nameidata *nd)
259 {
260         struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
261         struct configfs_dirent * sd;
262         int found = 0;
263         int err = 0;
264
265         list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
266                 if (sd->s_type & CONFIGFS_NOT_PINNED) {
267                         const unsigned char * name = configfs_get_name(sd);
268
269                         if (strcmp(name, dentry->d_name.name))
270                                 continue;
271
272                         found = 1;
273                         err = configfs_attach_attr(sd, dentry);
274                         break;
275                 }
276         }
277
278         if (!found) {
279                 /*
280                  * If it doesn't exist and it isn't a NOT_PINNED item,
281                  * it must be negative.
282                  */
283                 return simple_lookup(dir, dentry, nd);
284         }
285
286         return ERR_PTR(err);
287 }
288
289 /*
290  * Only subdirectories count here.  Files (CONFIGFS_NOT_PINNED) are
291  * attributes and are removed by rmdir().  We recurse, taking i_sem
292  * on all children that are candidates for default detach.  If the
293  * result is clean, then configfs_detach_group() will handle dropping
294  * i_sem.  If there is an error, the caller will clean up the i_sem
295  * holders via configfs_detach_rollback().
296  */
297 static int configfs_detach_prep(struct dentry *dentry)
298 {
299         struct configfs_dirent *parent_sd = dentry->d_fsdata;
300         struct configfs_dirent *sd;
301         int ret;
302
303         ret = -EBUSY;
304         if (!list_empty(&parent_sd->s_links))
305                 goto out;
306
307         ret = 0;
308         list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
309                 if (sd->s_type & CONFIGFS_NOT_PINNED)
310                         continue;
311                 if (sd->s_type & CONFIGFS_USET_DEFAULT) {
312                         down(&sd->s_dentry->d_inode->i_sem);
313                         /* Mark that we've taken i_sem */
314                         sd->s_type |= CONFIGFS_USET_DROPPING;
315
316                         ret = configfs_detach_prep(sd->s_dentry);
317                         if (!ret)
318                                 continue;
319                 } else
320                         ret = -ENOTEMPTY;
321
322                 break;
323         }
324
325 out:
326         return ret;
327 }
328
329 /*
330  * Walk the tree, dropping i_sem wherever CONFIGFS_USET_DROPPING is
331  * set.
332  */
333 static void configfs_detach_rollback(struct dentry *dentry)
334 {
335         struct configfs_dirent *parent_sd = dentry->d_fsdata;
336         struct configfs_dirent *sd;
337
338         list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
339                 if (sd->s_type & CONFIGFS_USET_DEFAULT) {
340                         configfs_detach_rollback(sd->s_dentry);
341
342                         if (sd->s_type & CONFIGFS_USET_DROPPING) {
343                                 sd->s_type &= ~CONFIGFS_USET_DROPPING;
344                                 up(&sd->s_dentry->d_inode->i_sem);
345                         }
346                 }
347         }
348 }
349
350 static void detach_attrs(struct config_item * item)
351 {
352         struct dentry * dentry = dget(item->ci_dentry);
353         struct configfs_dirent * parent_sd;
354         struct configfs_dirent * sd, * tmp;
355
356         if (!dentry)
357                 return;
358
359         pr_debug("configfs %s: dropping attrs for  dir\n",
360                  dentry->d_name.name);
361
362         parent_sd = dentry->d_fsdata;
363         list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
364                 if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED))
365                         continue;
366                 list_del_init(&sd->s_sibling);
367                 configfs_drop_dentry(sd, dentry);
368                 configfs_put(sd);
369         }
370
371         /**
372          * Drop reference from dget() on entrance.
373          */
374         dput(dentry);
375 }
376
377 static int populate_attrs(struct config_item *item)
378 {
379         struct config_item_type *t = item->ci_type;
380         struct configfs_attribute *attr;
381         int error = 0;
382         int i;
383
384         if (!t)
385                 return -EINVAL;
386         if (t->ct_attrs) {
387                 for (i = 0; (attr = t->ct_attrs[i]) != NULL; i++) {
388                         if ((error = configfs_create_file(item, attr)))
389                                 break;
390                 }
391         }
392
393         if (error)
394                 detach_attrs(item);
395
396         return error;
397 }
398
399 static int configfs_attach_group(struct config_item *parent_item,
400                                  struct config_item *item,
401                                  struct dentry *dentry);
402 static void configfs_detach_group(struct config_item *item);
403
404 static void detach_groups(struct config_group *group)
405 {
406         struct dentry * dentry = dget(group->cg_item.ci_dentry);
407         struct dentry *child;
408         struct configfs_dirent *parent_sd;
409         struct configfs_dirent *sd, *tmp;
410
411         if (!dentry)
412                 return;
413
414         parent_sd = dentry->d_fsdata;
415         list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
416                 if (!sd->s_element ||
417                     !(sd->s_type & CONFIGFS_USET_DEFAULT))
418                         continue;
419
420                 child = sd->s_dentry;
421
422                 configfs_detach_group(sd->s_element);
423                 child->d_inode->i_flags |= S_DEAD;
424
425                 /*
426                  * From rmdir/unregister, a configfs_detach_prep() pass
427                  * has taken our i_sem for us.  Drop it.
428                  * From mkdir/register cleanup, there is no sem held.
429                  */
430                 if (sd->s_type & CONFIGFS_USET_DROPPING)
431                         up(&child->d_inode->i_sem);
432
433                 d_delete(child);
434                 dput(child);
435         }
436
437         /**
438          * Drop reference from dget() on entrance.
439          */
440         dput(dentry);
441 }
442
443 /*
444  * This fakes mkdir(2) on a default_groups[] entry.  It
445  * creates a dentry, attachs it, and then does fixup
446  * on the sd->s_type.
447  *
448  * We could, perhaps, tweak our parent's ->mkdir for a minute and
449  * try using vfs_mkdir.  Just a thought.
450  */
451 static int create_default_group(struct config_group *parent_group,
452                                 struct config_group *group)
453 {
454         int ret;
455         struct qstr name;
456         struct configfs_dirent *sd;
457         /* We trust the caller holds a reference to parent */
458         struct dentry *child, *parent = parent_group->cg_item.ci_dentry;
459
460         if (!group->cg_item.ci_name)
461                 group->cg_item.ci_name = group->cg_item.ci_namebuf;
462         name.name = group->cg_item.ci_name;
463         name.len = strlen(name.name);
464         name.hash = full_name_hash(name.name, name.len);
465
466         ret = -ENOMEM;
467         child = d_alloc(parent, &name);
468         if (child) {
469                 d_add(child, NULL);
470
471                 ret = configfs_attach_group(&parent_group->cg_item,
472                                             &group->cg_item, child);
473                 if (!ret) {
474                         sd = child->d_fsdata;
475                         sd->s_type |= CONFIGFS_USET_DEFAULT;
476                 } else {
477                         d_delete(child);
478                         dput(child);
479                 }
480         }
481
482         return ret;
483 }
484
485 static int populate_groups(struct config_group *group)
486 {
487         struct config_group *new_group;
488         struct dentry *dentry = group->cg_item.ci_dentry;
489         int ret = 0;
490         int i;
491
492         if (group && group->default_groups) {
493                 /* FYI, we're faking mkdir here
494                  * I'm not sure we need this semaphore, as we're called
495                  * from our parent's mkdir.  That holds our parent's
496                  * i_sem, so afaik lookup cannot continue through our
497                  * parent to find us, let alone mess with our tree.
498                  * That said, taking our i_sem is closer to mkdir
499                  * emulation, and shouldn't hurt. */
500                 down(&dentry->d_inode->i_sem);
501
502                 for (i = 0; group->default_groups[i]; i++) {
503                         new_group = group->default_groups[i];
504
505                         ret = create_default_group(group, new_group);
506                         if (ret)
507                                 break;
508                 }
509
510                 up(&dentry->d_inode->i_sem);
511         }
512
513         if (ret)
514                 detach_groups(group);
515
516         return ret;
517 }
518
519 /*
520  * All of link_obj/unlink_obj/link_group/unlink_group require that
521  * subsys->su_sem is held.
522  */
523
524 static void unlink_obj(struct config_item *item)
525 {
526         struct config_group *group;
527
528         group = item->ci_group;
529         if (group) {
530                 list_del_init(&item->ci_entry);
531
532                 item->ci_group = NULL;
533                 item->ci_parent = NULL;
534                 config_item_put(item);
535
536                 config_group_put(group);
537         }
538 }
539
540 static void link_obj(struct config_item *parent_item, struct config_item *item)
541 {
542         /* Parent seems redundant with group, but it makes certain
543          * traversals much nicer. */
544         item->ci_parent = parent_item;
545         item->ci_group = config_group_get(to_config_group(parent_item));
546         list_add_tail(&item->ci_entry, &item->ci_group->cg_children);
547
548         config_item_get(item);
549 }
550
551 static void unlink_group(struct config_group *group)
552 {
553         int i;
554         struct config_group *new_group;
555
556         if (group->default_groups) {
557                 for (i = 0; group->default_groups[i]; i++) {
558                         new_group = group->default_groups[i];
559                         unlink_group(new_group);
560                 }
561         }
562
563         group->cg_subsys = NULL;
564         unlink_obj(&group->cg_item);
565 }
566
567 static void link_group(struct config_group *parent_group, struct config_group *group)
568 {
569         int i;
570         struct config_group *new_group;
571         struct configfs_subsystem *subsys = NULL; /* gcc is a turd */
572
573         link_obj(&parent_group->cg_item, &group->cg_item);
574
575         if (parent_group->cg_subsys)
576                 subsys = parent_group->cg_subsys;
577         else if (configfs_is_root(&parent_group->cg_item))
578                 subsys = to_configfs_subsystem(group);
579         else
580                 BUG();
581         group->cg_subsys = subsys;
582
583         if (group->default_groups) {
584                 for (i = 0; group->default_groups[i]; i++) {
585                         new_group = group->default_groups[i];
586                         link_group(group, new_group);
587                 }
588         }
589 }
590
591 /*
592  * The goal is that configfs_attach_item() (and
593  * configfs_attach_group()) can be called from either the VFS or this
594  * module.  That is, they assume that the items have been created,
595  * the dentry allocated, and the dcache is all ready to go.
596  *
597  * If they fail, they must clean up after themselves as if they
598  * had never been called.  The caller (VFS or local function) will
599  * handle cleaning up the dcache bits.
600  *
601  * configfs_detach_group() and configfs_detach_item() behave similarly on
602  * the way out.  They assume that the proper semaphores are held, they
603  * clean up the configfs items, and they expect their callers will
604  * handle the dcache bits.
605  */
606 static int configfs_attach_item(struct config_item *parent_item,
607                                 struct config_item *item,
608                                 struct dentry *dentry)
609 {
610         int ret;
611
612         ret = configfs_create_dir(item, dentry);
613         if (!ret) {
614                 ret = populate_attrs(item);
615                 if (ret) {
616                         configfs_remove_dir(item);
617                         d_delete(dentry);
618                 }
619         }
620
621         return ret;
622 }
623
624 static void configfs_detach_item(struct config_item *item)
625 {
626         detach_attrs(item);
627         configfs_remove_dir(item);
628 }
629
630 static int configfs_attach_group(struct config_item *parent_item,
631                                  struct config_item *item,
632                                  struct dentry *dentry)
633 {
634         int ret;
635         struct configfs_dirent *sd;
636
637         ret = configfs_attach_item(parent_item, item, dentry);
638         if (!ret) {
639                 sd = dentry->d_fsdata;
640                 sd->s_type |= CONFIGFS_USET_DIR;
641
642                 ret = populate_groups(to_config_group(item));
643                 if (ret) {
644                         configfs_detach_item(item);
645                         d_delete(dentry);
646                 }
647         }
648
649         return ret;
650 }
651
652 static void configfs_detach_group(struct config_item *item)
653 {
654         detach_groups(to_config_group(item));
655         configfs_detach_item(item);
656 }
657
658 /*
659  * Drop the initial reference from make_item()/make_group()
660  * This function assumes that reference is held on item
661  * and that item holds a valid reference to the parent.  Also, it
662  * assumes the caller has validated ci_type.
663  */
664 static void client_drop_item(struct config_item *parent_item,
665                              struct config_item *item)
666 {
667         struct config_item_type *type;
668
669         type = parent_item->ci_type;
670         BUG_ON(!type);
671
672         if (type->ct_group_ops && type->ct_group_ops->drop_item)
673                 type->ct_group_ops->drop_item(to_config_group(parent_item),
674                                                 item);
675         else
676                 config_item_put(item);
677 }
678
679
680 static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
681 {
682         int ret;
683         struct config_group *group;
684         struct config_item *item;
685         struct config_item *parent_item;
686         struct configfs_subsystem *subsys;
687         struct configfs_dirent *sd;
688         struct config_item_type *type;
689         struct module *owner;
690         char *name;
691
692         if (dentry->d_parent == configfs_sb->s_root)
693                 return -EPERM;
694
695         sd = dentry->d_parent->d_fsdata;
696         if (!(sd->s_type & CONFIGFS_USET_DIR))
697                 return -EPERM;
698
699         parent_item = configfs_get_config_item(dentry->d_parent);
700         type = parent_item->ci_type;
701         subsys = to_config_group(parent_item)->cg_subsys;
702         BUG_ON(!subsys);
703
704         if (!type || !type->ct_group_ops ||
705             (!type->ct_group_ops->make_group &&
706              !type->ct_group_ops->make_item)) {
707                 config_item_put(parent_item);
708                 return -EPERM;  /* What lack-of-mkdir returns */
709         }
710
711         name = kmalloc(dentry->d_name.len + 1, GFP_KERNEL);
712         if (!name) {
713                 config_item_put(parent_item);
714                 return -ENOMEM;
715         }
716         snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);
717
718         down(&subsys->su_sem);
719         group = NULL;
720         item = NULL;
721         if (type->ct_group_ops->make_group) {
722                 group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
723                 if (group) {
724                         link_group(to_config_group(parent_item), group);
725                         item = &group->cg_item;
726                 }
727         } else {
728                 item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
729                 if (item)
730                         link_obj(parent_item, item);
731         }
732         up(&subsys->su_sem);
733
734         kfree(name);
735         if (!item) {
736                 config_item_put(parent_item);
737                 return -ENOMEM;
738         }
739
740         ret = -EINVAL;
741         type = item->ci_type;
742         if (type) {
743                 owner = type->ct_owner;
744                 if (try_module_get(owner)) {
745                         if (group) {
746                                 ret = configfs_attach_group(parent_item,
747                                                             item,
748                                                             dentry);
749                         } else {
750                                 ret = configfs_attach_item(parent_item,
751                                                            item,
752                                                            dentry);
753                         }
754
755                         if (ret) {
756                                 down(&subsys->su_sem);
757                                 if (group)
758                                         unlink_group(group);
759                                 else
760                                         unlink_obj(item);
761                                 client_drop_item(parent_item, item);
762                                 up(&subsys->su_sem);
763
764                                 config_item_put(parent_item);
765                                 module_put(owner);
766                         }
767                 }
768         }
769
770         return ret;
771 }
772
773 static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
774 {
775         struct config_item *parent_item;
776         struct config_item *item;
777         struct configfs_subsystem *subsys;
778         struct configfs_dirent *sd;
779         struct module *owner = NULL;
780         int ret;
781
782         if (dentry->d_parent == configfs_sb->s_root)
783                 return -EPERM;
784
785         sd = dentry->d_fsdata;
786         if (sd->s_type & CONFIGFS_USET_DEFAULT)
787                 return -EPERM;
788
789         parent_item = configfs_get_config_item(dentry->d_parent);
790         subsys = to_config_group(parent_item)->cg_subsys;
791         BUG_ON(!subsys);
792
793         if (!parent_item->ci_type) {
794                 config_item_put(parent_item);
795                 return -EINVAL;
796         }
797
798         ret = configfs_detach_prep(dentry);
799         if (ret) {
800                 configfs_detach_rollback(dentry);
801                 config_item_put(parent_item);
802                 return ret;
803         }
804
805         item = configfs_get_config_item(dentry);
806
807         /* Drop reference from above, item already holds one. */
808         config_item_put(parent_item);
809
810         if (item->ci_type)
811                 owner = item->ci_type->ct_owner;
812
813         if (sd->s_type & CONFIGFS_USET_DIR) {
814                 configfs_detach_group(item);
815
816                 down(&subsys->su_sem);
817                 unlink_group(to_config_group(item));
818         } else {
819                 configfs_detach_item(item);
820
821                 down(&subsys->su_sem);
822                 unlink_obj(item);
823         }
824
825         client_drop_item(parent_item, item);
826         up(&subsys->su_sem);
827
828         /* Drop our reference from above */
829         config_item_put(item);
830
831         module_put(owner);
832
833         return 0;
834 }
835
836 struct inode_operations configfs_dir_inode_operations = {
837         .mkdir          = configfs_mkdir,
838         .rmdir          = configfs_rmdir,
839         .symlink        = configfs_symlink,
840         .unlink         = configfs_unlink,
841         .lookup         = configfs_lookup,
842 };
843
844 #if 0
845 int configfs_rename_dir(struct config_item * item, const char *new_name)
846 {
847         int error = 0;
848         struct dentry * new_dentry, * parent;
849
850         if (!strcmp(config_item_name(item), new_name))
851                 return -EINVAL;
852
853         if (!item->parent)
854                 return -EINVAL;
855
856         down_write(&configfs_rename_sem);
857         parent = item->parent->dentry;
858
859         down(&parent->d_inode->i_sem);
860
861         new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
862         if (!IS_ERR(new_dentry)) {
863                 if (!new_dentry->d_inode) {
864                         error = config_item_set_name(item, "%s", new_name);
865                         if (!error) {
866                                 d_add(new_dentry, NULL);
867                                 d_move(item->dentry, new_dentry);
868                         }
869                         else
870                                 d_delete(new_dentry);
871                 } else
872                         error = -EEXIST;
873                 dput(new_dentry);
874         }
875         up(&parent->d_inode->i_sem);
876         up_write(&configfs_rename_sem);
877
878         return error;
879 }
880 #endif
881
882 static int configfs_dir_open(struct inode *inode, struct file *file)
883 {
884         struct dentry * dentry = file->f_dentry;
885         struct configfs_dirent * parent_sd = dentry->d_fsdata;
886
887         down(&dentry->d_inode->i_sem);
888         file->private_data = configfs_new_dirent(parent_sd, NULL);
889         up(&dentry->d_inode->i_sem);
890
891         return file->private_data ? 0 : -ENOMEM;
892
893 }
894
895 static int configfs_dir_close(struct inode *inode, struct file *file)
896 {
897         struct dentry * dentry = file->f_dentry;
898         struct configfs_dirent * cursor = file->private_data;
899
900         down(&dentry->d_inode->i_sem);
901         list_del_init(&cursor->s_sibling);
902         up(&dentry->d_inode->i_sem);
903
904         release_configfs_dirent(cursor);
905
906         return 0;
907 }
908
909 /* Relationship between s_mode and the DT_xxx types */
910 static inline unsigned char dt_type(struct configfs_dirent *sd)
911 {
912         return (sd->s_mode >> 12) & 15;
913 }
914
915 static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
916 {
917         struct dentry *dentry = filp->f_dentry;
918         struct configfs_dirent * parent_sd = dentry->d_fsdata;
919         struct configfs_dirent *cursor = filp->private_data;
920         struct list_head *p, *q = &cursor->s_sibling;
921         ino_t ino;
922         int i = filp->f_pos;
923
924         switch (i) {
925                 case 0:
926                         ino = dentry->d_inode->i_ino;
927                         if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
928                                 break;
929                         filp->f_pos++;
930                         i++;
931                         /* fallthrough */
932                 case 1:
933                         ino = parent_ino(dentry);
934                         if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
935                                 break;
936                         filp->f_pos++;
937                         i++;
938                         /* fallthrough */
939                 default:
940                         if (filp->f_pos == 2) {
941                                 list_del(q);
942                                 list_add(q, &parent_sd->s_children);
943                         }
944                         for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
945                                 struct configfs_dirent *next;
946                                 const char * name;
947                                 int len;
948
949                                 next = list_entry(p, struct configfs_dirent,
950                                                    s_sibling);
951                                 if (!next->s_element)
952                                         continue;
953
954                                 name = configfs_get_name(next);
955                                 len = strlen(name);
956                                 if (next->s_dentry)
957                                         ino = next->s_dentry->d_inode->i_ino;
958                                 else
959                                         ino = iunique(configfs_sb, 2);
960
961                                 if (filldir(dirent, name, len, filp->f_pos, ino,
962                                                  dt_type(next)) < 0)
963                                         return 0;
964
965                                 list_del(q);
966                                 list_add(q, p);
967                                 p = q;
968                                 filp->f_pos++;
969                         }
970         }
971         return 0;
972 }
973
974 static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
975 {
976         struct dentry * dentry = file->f_dentry;
977
978         down(&dentry->d_inode->i_sem);
979         switch (origin) {
980                 case 1:
981                         offset += file->f_pos;
982                 case 0:
983                         if (offset >= 0)
984                                 break;
985                 default:
986                         up(&file->f_dentry->d_inode->i_sem);
987                         return -EINVAL;
988         }
989         if (offset != file->f_pos) {
990                 file->f_pos = offset;
991                 if (file->f_pos >= 2) {
992                         struct configfs_dirent *sd = dentry->d_fsdata;
993                         struct configfs_dirent *cursor = file->private_data;
994                         struct list_head *p;
995                         loff_t n = file->f_pos - 2;
996
997                         list_del(&cursor->s_sibling);
998                         p = sd->s_children.next;
999                         while (n && p != &sd->s_children) {
1000                                 struct configfs_dirent *next;
1001                                 next = list_entry(p, struct configfs_dirent,
1002                                                    s_sibling);
1003                                 if (next->s_element)
1004                                         n--;
1005                                 p = p->next;
1006                         }
1007                         list_add_tail(&cursor->s_sibling, p);
1008                 }
1009         }
1010         up(&dentry->d_inode->i_sem);
1011         return offset;
1012 }
1013
1014 struct file_operations configfs_dir_operations = {
1015         .open           = configfs_dir_open,
1016         .release        = configfs_dir_close,
1017         .llseek         = configfs_dir_lseek,
1018         .read           = generic_read_dir,
1019         .readdir        = configfs_readdir,
1020 };
1021
1022 int configfs_register_subsystem(struct configfs_subsystem *subsys)
1023 {
1024         int err;
1025         struct config_group *group = &subsys->su_group;
1026         struct qstr name;
1027         struct dentry *dentry;
1028         struct configfs_dirent *sd;
1029
1030         err = configfs_pin_fs();
1031         if (err)
1032                 return err;
1033
1034         if (!group->cg_item.ci_name)
1035                 group->cg_item.ci_name = group->cg_item.ci_namebuf;
1036
1037         sd = configfs_sb->s_root->d_fsdata;
1038         link_group(to_config_group(sd->s_element), group);
1039
1040         down(&configfs_sb->s_root->d_inode->i_sem);
1041
1042         name.name = group->cg_item.ci_name;
1043         name.len = strlen(name.name);
1044         name.hash = full_name_hash(name.name, name.len);
1045
1046         err = -ENOMEM;
1047         dentry = d_alloc(configfs_sb->s_root, &name);
1048         if (!dentry)
1049                 goto out_release;
1050
1051         d_add(dentry, NULL);
1052
1053         err = configfs_attach_group(sd->s_element, &group->cg_item,
1054                                     dentry);
1055         if (!err)
1056                 dentry = NULL;
1057         else
1058                 d_delete(dentry);
1059
1060         up(&configfs_sb->s_root->d_inode->i_sem);
1061
1062         if (dentry) {
1063             dput(dentry);
1064 out_release:
1065             unlink_group(group);
1066             configfs_release_fs();
1067         }
1068
1069         return err;
1070 }
1071
1072 void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
1073 {
1074         struct config_group *group = &subsys->su_group;
1075         struct dentry *dentry = group->cg_item.ci_dentry;
1076
1077         if (dentry->d_parent != configfs_sb->s_root) {
1078                 printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n");
1079                 return;
1080         }
1081
1082         down(&configfs_sb->s_root->d_inode->i_sem);
1083         down(&dentry->d_inode->i_sem);
1084         if (configfs_detach_prep(dentry)) {
1085                 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");
1086         }
1087         configfs_detach_group(&group->cg_item);
1088         dentry->d_inode->i_flags |= S_DEAD;
1089         up(&dentry->d_inode->i_sem);
1090
1091         d_delete(dentry);
1092
1093         up(&configfs_sb->s_root->d_inode->i_sem);
1094
1095         dput(dentry);
1096
1097         unlink_group(group);
1098         configfs_release_fs();
1099 }
1100
1101 EXPORT_SYMBOL(configfs_register_subsystem);
1102 EXPORT_SYMBOL(configfs_unregister_subsystem);