sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses
[safe/jmp/linux-2.6] / fs / sysfs / dir.c
1 /*
2  * dir.c - Operations for sysfs directories.
3  */
4
5 #undef DEBUG
6
7 #include <linux/fs.h>
8 #include <linux/mount.h>
9 #include <linux/module.h>
10 #include <linux/kobject.h>
11 #include <linux/namei.h>
12 #include <asm/semaphore.h>
13 #include "sysfs.h"
14
15 DECLARE_RWSEM(sysfs_rename_sem);
16
17 static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
18 {
19         struct sysfs_dirent * sd = dentry->d_fsdata;
20
21         if (sd) {
22                 BUG_ON(sd->s_dentry != dentry);
23                 sd->s_dentry = NULL;
24                 sysfs_put(sd);
25         }
26         iput(inode);
27 }
28
29 static struct dentry_operations sysfs_dentry_ops = {
30         .d_iput         = sysfs_d_iput,
31 };
32
33 static unsigned int sysfs_inode_counter;
34 ino_t sysfs_get_inum(void)
35 {
36         if (unlikely(sysfs_inode_counter < 3))
37                 sysfs_inode_counter = 3;
38         return sysfs_inode_counter++;
39 }
40
41 /*
42  * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
43  */
44 static struct sysfs_dirent * __sysfs_new_dirent(void * element)
45 {
46         struct sysfs_dirent * sd;
47
48         sd = kmem_cache_zalloc(sysfs_dir_cachep, GFP_KERNEL);
49         if (!sd)
50                 return NULL;
51
52         sd->s_ino = sysfs_get_inum();
53         atomic_set(&sd->s_count, 1);
54         atomic_set(&sd->s_event, 1);
55         INIT_LIST_HEAD(&sd->s_children);
56         INIT_LIST_HEAD(&sd->s_sibling);
57         sd->s_element = element;
58
59         return sd;
60 }
61
62 static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
63                               struct sysfs_dirent *sd)
64 {
65         if (sd)
66                 list_add(&sd->s_sibling, &parent_sd->s_children);
67 }
68
69 static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
70                                                 void * element)
71 {
72         struct sysfs_dirent *sd;
73         sd = __sysfs_new_dirent(element);
74         __sysfs_list_dirent(parent_sd, sd);
75         return sd;
76 }
77
78 /*
79  *
80  * Return -EEXIST if there is already a sysfs element with the same name for
81  * the same parent.
82  *
83  * called with parent inode's i_mutex held
84  */
85 int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
86                           const unsigned char *new)
87 {
88         struct sysfs_dirent * sd;
89
90         list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
91                 if (sd->s_element) {
92                         const unsigned char *existing = sysfs_get_name(sd);
93                         if (strcmp(existing, new))
94                                 continue;
95                         else
96                                 return -EEXIST;
97                 }
98         }
99
100         return 0;
101 }
102
103
104 static struct sysfs_dirent *
105 __sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
106 {
107         struct sysfs_dirent * sd;
108
109         sd = __sysfs_new_dirent(element);
110         if (!sd)
111                 goto out;
112
113         sd->s_mode = mode;
114         sd->s_type = type;
115         sd->s_dentry = dentry;
116         if (dentry) {
117                 dentry->d_fsdata = sysfs_get(sd);
118                 dentry->d_op = &sysfs_dentry_ops;
119         }
120
121 out:
122         return sd;
123 }
124
125 int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
126                         void * element, umode_t mode, int type)
127 {
128         struct sysfs_dirent *sd;
129
130         sd = __sysfs_make_dirent(dentry, element, mode, type);
131         __sysfs_list_dirent(parent_sd, sd);
132
133         return sd ? 0 : -ENOMEM;
134 }
135
136 static int init_dir(struct inode * inode)
137 {
138         inode->i_op = &sysfs_dir_inode_operations;
139         inode->i_fop = &sysfs_dir_operations;
140
141         /* directory inodes start off with i_nlink == 2 (for "." entry) */
142         inc_nlink(inode);
143         return 0;
144 }
145
146 static int init_file(struct inode * inode)
147 {
148         inode->i_size = PAGE_SIZE;
149         inode->i_fop = &sysfs_file_operations;
150         return 0;
151 }
152
153 static int init_symlink(struct inode * inode)
154 {
155         inode->i_op = &sysfs_symlink_inode_operations;
156         return 0;
157 }
158
159 static int create_dir(struct kobject * k, struct dentry * p,
160                       const char * n, struct dentry ** d)
161 {
162         int error;
163         umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
164
165         mutex_lock(&p->d_inode->i_mutex);
166         *d = lookup_one_len(n, p, strlen(n));
167         if (!IS_ERR(*d)) {
168                 if (sysfs_dirent_exist(p->d_fsdata, n))
169                         error = -EEXIST;
170                 else
171                         error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
172                                                                 SYSFS_DIR);
173                 if (!error) {
174                         error = sysfs_create(*d, mode, init_dir);
175                         if (!error) {
176                                 inc_nlink(p->d_inode);
177                                 (*d)->d_op = &sysfs_dentry_ops;
178                                 d_rehash(*d);
179                         }
180                 }
181                 if (error && (error != -EEXIST)) {
182                         struct sysfs_dirent *sd = (*d)->d_fsdata;
183                         if (sd) {
184                                 list_del_init(&sd->s_sibling);
185                                 sysfs_put(sd);
186                         }
187                         d_drop(*d);
188                 }
189                 dput(*d);
190         } else
191                 error = PTR_ERR(*d);
192         mutex_unlock(&p->d_inode->i_mutex);
193         return error;
194 }
195
196
197 int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
198 {
199         return create_dir(k,k->dentry,n,d);
200 }
201
202 /**
203  *      sysfs_create_dir - create a directory for an object.
204  *      @kobj:          object we're creating directory for. 
205  *      @shadow_parent: parent parent object.
206  */
207
208 int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
209 {
210         struct dentry * dentry = NULL;
211         struct dentry * parent;
212         int error = 0;
213
214         BUG_ON(!kobj);
215
216         if (shadow_parent)
217                 parent = shadow_parent;
218         else if (kobj->parent)
219                 parent = kobj->parent->dentry;
220         else if (sysfs_mount && sysfs_mount->mnt_sb)
221                 parent = sysfs_mount->mnt_sb->s_root;
222         else
223                 return -EFAULT;
224
225         error = create_dir(kobj,parent,kobject_name(kobj),&dentry);
226         if (!error)
227                 kobj->dentry = dentry;
228         return error;
229 }
230
231 /* attaches attribute's sysfs_dirent to the dentry corresponding to the
232  * attribute file
233  */
234 static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry)
235 {
236         struct attribute * attr = NULL;
237         struct bin_attribute * bin_attr = NULL;
238         int (* init) (struct inode *) = NULL;
239         int error = 0;
240
241         if (sd->s_type & SYSFS_KOBJ_BIN_ATTR) {
242                 bin_attr = sd->s_element;
243                 attr = &bin_attr->attr;
244         } else {
245                 attr = sd->s_element;
246                 init = init_file;
247         }
248
249         dentry->d_fsdata = sysfs_get(sd);
250         sd->s_dentry = dentry;
251         error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
252         if (error) {
253                 sysfs_put(sd);
254                 return error;
255         }
256
257         if (bin_attr) {
258                 dentry->d_inode->i_size = bin_attr->size;
259                 dentry->d_inode->i_fop = &bin_fops;
260         }
261         dentry->d_op = &sysfs_dentry_ops;
262         d_rehash(dentry);
263
264         return 0;
265 }
266
267 static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry)
268 {
269         int err = 0;
270
271         dentry->d_fsdata = sysfs_get(sd);
272         sd->s_dentry = dentry;
273         err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
274         if (!err) {
275                 dentry->d_op = &sysfs_dentry_ops;
276                 d_rehash(dentry);
277         } else
278                 sysfs_put(sd);
279
280         return err;
281 }
282
283 static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
284                                 struct nameidata *nd)
285 {
286         struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
287         struct sysfs_dirent * sd;
288         int err = 0;
289
290         list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
291                 if (sd->s_type & SYSFS_NOT_PINNED) {
292                         const unsigned char * name = sysfs_get_name(sd);
293
294                         if (strcmp(name, dentry->d_name.name))
295                                 continue;
296
297                         if (sd->s_type & SYSFS_KOBJ_LINK)
298                                 err = sysfs_attach_link(sd, dentry);
299                         else
300                                 err = sysfs_attach_attr(sd, dentry);
301                         break;
302                 }
303         }
304
305         return ERR_PTR(err);
306 }
307
308 const struct inode_operations sysfs_dir_inode_operations = {
309         .lookup         = sysfs_lookup,
310         .setattr        = sysfs_setattr,
311 };
312
313 static void remove_dir(struct dentry * d)
314 {
315         struct dentry * parent = dget(d->d_parent);
316         struct sysfs_dirent * sd;
317
318         mutex_lock(&parent->d_inode->i_mutex);
319         d_delete(d);
320         sd = d->d_fsdata;
321         list_del_init(&sd->s_sibling);
322         sysfs_put(sd);
323         if (d->d_inode)
324                 simple_rmdir(parent->d_inode,d);
325
326         pr_debug(" o %s removing done (%d)\n",d->d_name.name,
327                  atomic_read(&d->d_count));
328
329         mutex_unlock(&parent->d_inode->i_mutex);
330         dput(parent);
331 }
332
333 void sysfs_remove_subdir(struct dentry * d)
334 {
335         remove_dir(d);
336 }
337
338
339 static void __sysfs_remove_dir(struct dentry *dentry)
340 {
341         struct sysfs_dirent * parent_sd;
342         struct sysfs_dirent * sd, * tmp;
343
344         dget(dentry);
345         if (!dentry)
346                 return;
347
348         pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
349         mutex_lock(&dentry->d_inode->i_mutex);
350         parent_sd = dentry->d_fsdata;
351         list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
352                 if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
353                         continue;
354                 list_del_init(&sd->s_sibling);
355                 sysfs_drop_dentry(sd, dentry);
356                 sysfs_put(sd);
357         }
358         mutex_unlock(&dentry->d_inode->i_mutex);
359
360         remove_dir(dentry);
361         /**
362          * Drop reference from dget() on entrance.
363          */
364         dput(dentry);
365 }
366
367 /**
368  *      sysfs_remove_dir - remove an object's directory.
369  *      @kobj:  object.
370  *
371  *      The only thing special about this is that we remove any files in
372  *      the directory before we remove the directory, and we've inlined
373  *      what used to be sysfs_rmdir() below, instead of calling separately.
374  */
375
376 void sysfs_remove_dir(struct kobject * kobj)
377 {
378         __sysfs_remove_dir(kobj->dentry);
379         kobj->dentry = NULL;
380 }
381
382 int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
383                      const char *new_name)
384 {
385         int error = 0;
386         struct dentry * new_dentry;
387
388         if (!new_parent)
389                 return -EFAULT;
390
391         down_write(&sysfs_rename_sem);
392         mutex_lock(&new_parent->d_inode->i_mutex);
393
394         new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
395         if (!IS_ERR(new_dentry)) {
396                 /* By allowing two different directories with the
397                  * same d_parent we allow this routine to move
398                  * between different shadows of the same directory
399                  */
400                 if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
401                         return -EINVAL;
402                 else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
403                         error = -EINVAL;
404                 else if (new_dentry == kobj->dentry)
405                         error = -EINVAL;
406                 else if (!new_dentry->d_inode) {
407                         error = kobject_set_name(kobj, "%s", new_name);
408                         if (!error) {
409                                 struct sysfs_dirent *sd, *parent_sd;
410
411                                 d_add(new_dentry, NULL);
412                                 d_move(kobj->dentry, new_dentry);
413
414                                 sd = kobj->dentry->d_fsdata;
415                                 parent_sd = new_parent->d_fsdata;
416
417                                 list_del_init(&sd->s_sibling);
418                                 list_add(&sd->s_sibling, &parent_sd->s_children);
419                         }
420                         else
421                                 d_drop(new_dentry);
422                 } else
423                         error = -EEXIST;
424                 dput(new_dentry);
425         }
426         mutex_unlock(&new_parent->d_inode->i_mutex);
427         up_write(&sysfs_rename_sem);
428
429         return error;
430 }
431
432 int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
433 {
434         struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry;
435         struct sysfs_dirent *new_parent_sd, *sd;
436         int error;
437
438         old_parent_dentry = kobj->parent ?
439                 kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
440         new_parent_dentry = new_parent ?
441                 new_parent->dentry : sysfs_mount->mnt_sb->s_root;
442
443         if (old_parent_dentry->d_inode == new_parent_dentry->d_inode)
444                 return 0;       /* nothing to move */
445 again:
446         mutex_lock(&old_parent_dentry->d_inode->i_mutex);
447         if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) {
448                 mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
449                 goto again;
450         }
451
452         new_parent_sd = new_parent_dentry->d_fsdata;
453         sd = kobj->dentry->d_fsdata;
454
455         new_dentry = lookup_one_len(kobj->name, new_parent_dentry,
456                                     strlen(kobj->name));
457         if (IS_ERR(new_dentry)) {
458                 error = PTR_ERR(new_dentry);
459                 goto out;
460         } else
461                 error = 0;
462         d_add(new_dentry, NULL);
463         d_move(kobj->dentry, new_dentry);
464         dput(new_dentry);
465
466         /* Remove from old parent's list and insert into new parent's list. */
467         list_del_init(&sd->s_sibling);
468         list_add(&sd->s_sibling, &new_parent_sd->s_children);
469
470 out:
471         mutex_unlock(&new_parent_dentry->d_inode->i_mutex);
472         mutex_unlock(&old_parent_dentry->d_inode->i_mutex);
473
474         return error;
475 }
476
477 static int sysfs_dir_open(struct inode *inode, struct file *file)
478 {
479         struct dentry * dentry = file->f_path.dentry;
480         struct sysfs_dirent * parent_sd = dentry->d_fsdata;
481
482         mutex_lock(&dentry->d_inode->i_mutex);
483         file->private_data = sysfs_new_dirent(parent_sd, NULL);
484         mutex_unlock(&dentry->d_inode->i_mutex);
485
486         return file->private_data ? 0 : -ENOMEM;
487
488 }
489
490 static int sysfs_dir_close(struct inode *inode, struct file *file)
491 {
492         struct dentry * dentry = file->f_path.dentry;
493         struct sysfs_dirent * cursor = file->private_data;
494
495         mutex_lock(&dentry->d_inode->i_mutex);
496         list_del_init(&cursor->s_sibling);
497         mutex_unlock(&dentry->d_inode->i_mutex);
498
499         release_sysfs_dirent(cursor);
500
501         return 0;
502 }
503
504 /* Relationship between s_mode and the DT_xxx types */
505 static inline unsigned char dt_type(struct sysfs_dirent *sd)
506 {
507         return (sd->s_mode >> 12) & 15;
508 }
509
510 static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
511 {
512         struct dentry *dentry = filp->f_path.dentry;
513         struct sysfs_dirent * parent_sd = dentry->d_fsdata;
514         struct sysfs_dirent *cursor = filp->private_data;
515         struct list_head *p, *q = &cursor->s_sibling;
516         ino_t ino;
517         int i = filp->f_pos;
518
519         switch (i) {
520                 case 0:
521                         ino = parent_sd->s_ino;
522                         if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
523                                 break;
524                         filp->f_pos++;
525                         i++;
526                         /* fallthrough */
527                 case 1:
528                         ino = parent_ino(dentry);
529                         if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
530                                 break;
531                         filp->f_pos++;
532                         i++;
533                         /* fallthrough */
534                 default:
535                         if (filp->f_pos == 2)
536                                 list_move(q, &parent_sd->s_children);
537
538                         for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
539                                 struct sysfs_dirent *next;
540                                 const char * name;
541                                 int len;
542
543                                 next = list_entry(p, struct sysfs_dirent,
544                                                    s_sibling);
545                                 if (!next->s_element)
546                                         continue;
547
548                                 name = sysfs_get_name(next);
549                                 len = strlen(name);
550                                 ino = next->s_ino;
551
552                                 if (filldir(dirent, name, len, filp->f_pos, ino,
553                                                  dt_type(next)) < 0)
554                                         return 0;
555
556                                 list_move(q, p);
557                                 p = q;
558                                 filp->f_pos++;
559                         }
560         }
561         return 0;
562 }
563
564 static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
565 {
566         struct dentry * dentry = file->f_path.dentry;
567
568         mutex_lock(&dentry->d_inode->i_mutex);
569         switch (origin) {
570                 case 1:
571                         offset += file->f_pos;
572                 case 0:
573                         if (offset >= 0)
574                                 break;
575                 default:
576                         mutex_unlock(&file->f_path.dentry->d_inode->i_mutex);
577                         return -EINVAL;
578         }
579         if (offset != file->f_pos) {
580                 file->f_pos = offset;
581                 if (file->f_pos >= 2) {
582                         struct sysfs_dirent *sd = dentry->d_fsdata;
583                         struct sysfs_dirent *cursor = file->private_data;
584                         struct list_head *p;
585                         loff_t n = file->f_pos - 2;
586
587                         list_del(&cursor->s_sibling);
588                         p = sd->s_children.next;
589                         while (n && p != &sd->s_children) {
590                                 struct sysfs_dirent *next;
591                                 next = list_entry(p, struct sysfs_dirent,
592                                                    s_sibling);
593                                 if (next->s_element)
594                                         n--;
595                                 p = p->next;
596                         }
597                         list_add_tail(&cursor->s_sibling, p);
598                 }
599         }
600         mutex_unlock(&dentry->d_inode->i_mutex);
601         return offset;
602 }
603
604
605 /**
606  *      sysfs_make_shadowed_dir - Setup so a directory can be shadowed
607  *      @kobj:  object we're creating shadow of.
608  */
609
610 int sysfs_make_shadowed_dir(struct kobject *kobj,
611         void * (*follow_link)(struct dentry *, struct nameidata *))
612 {
613         struct inode *inode;
614         struct inode_operations *i_op;
615
616         inode = kobj->dentry->d_inode;
617         if (inode->i_op != &sysfs_dir_inode_operations)
618                 return -EINVAL;
619
620         i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
621         if (!i_op)
622                 return -ENOMEM;
623
624         memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
625         i_op->follow_link = follow_link;
626
627         /* Locking of inode->i_op?
628          * Since setting i_op is a single word write and they
629          * are atomic we should be ok here.
630          */
631         inode->i_op = i_op;
632         return 0;
633 }
634
635 /**
636  *      sysfs_create_shadow_dir - create a shadow directory for an object.
637  *      @kobj:  object we're creating directory for.
638  *
639  *      sysfs_make_shadowed_dir must already have been called on this
640  *      directory.
641  */
642
643 struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
644 {
645         struct sysfs_dirent *sd;
646         struct dentry *parent, *dir, *shadow;
647         struct inode *inode;
648
649         dir = kobj->dentry;
650         inode = dir->d_inode;
651         parent = dir->d_parent;
652         shadow = ERR_PTR(-EINVAL);
653         if (!sysfs_is_shadowed_inode(inode))
654                 goto out;
655
656         shadow = d_alloc(parent, &dir->d_name);
657         if (!shadow)
658                 goto nomem;
659
660         sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
661         if (!sd)
662                 goto nomem;
663
664         d_instantiate(shadow, igrab(inode));
665         inc_nlink(inode);
666         inc_nlink(parent->d_inode);
667         shadow->d_op = &sysfs_dentry_ops;
668
669         dget(shadow);           /* Extra count - pin the dentry in core */
670
671 out:
672         return shadow;
673 nomem:
674         dput(shadow);
675         shadow = ERR_PTR(-ENOMEM);
676         goto out;
677 }
678
679 /**
680  *      sysfs_remove_shadow_dir - remove an object's directory.
681  *      @shadow: dentry of shadow directory
682  *
683  *      The only thing special about this is that we remove any files in
684  *      the directory before we remove the directory, and we've inlined
685  *      what used to be sysfs_rmdir() below, instead of calling separately.
686  */
687
688 void sysfs_remove_shadow_dir(struct dentry *shadow)
689 {
690         __sysfs_remove_dir(shadow);
691 }
692
693 const struct file_operations sysfs_dir_operations = {
694         .open           = sysfs_dir_open,
695         .release        = sysfs_dir_close,
696         .llseek         = sysfs_dir_lseek,
697         .read           = generic_read_dir,
698         .readdir        = sysfs_readdir,
699 };