1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/config.h>
24#include <linux/slab.h>
25#include <linux/locks.h>
26#include <linux/smp_lock.h>
27#include <linux/devfs_fs_kernel.h>
28#include <linux/major.h>
29#include <linux/acct.h>
30
31#include <asm/uaccess.h>
32
33#include <linux/kmod.h>
34#define __NO_VERSION__
35#include <linux/module.h>
36
37LIST_HEAD(super_blocks);
38spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53static struct file_system_type *file_systems;
54static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
55
56
57static void get_filesystem(struct file_system_type *fs)
58{
59 if (fs->owner)
60 __MOD_INC_USE_COUNT(fs->owner);
61}
62
63static void put_filesystem(struct file_system_type *fs)
64{
65 if (fs->owner)
66 __MOD_DEC_USE_COUNT(fs->owner);
67}
68
69static struct file_system_type **find_filesystem(const char *name)
70{
71 struct file_system_type **p;
72 for (p=&file_systems; *p; p=&(*p)->next)
73 if (strcmp((*p)->name,name) == 0)
74 break;
75 return p;
76}
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91int register_filesystem(struct file_system_type * fs)
92{
93 int res = 0;
94 struct file_system_type ** p;
95
96 if (!fs)
97 return -EINVAL;
98 if (fs->next)
99 return -EBUSY;
100 INIT_LIST_HEAD(&fs->fs_supers);
101 write_lock(&file_systems_lock);
102 p = find_filesystem(fs->name);
103 if (*p)
104 res = -EBUSY;
105 else
106 *p = fs;
107 write_unlock(&file_systems_lock);
108 return res;
109}
110
111
112
113
114
115
116
117
118
119
120
121
122
123int unregister_filesystem(struct file_system_type * fs)
124{
125 struct file_system_type ** tmp;
126
127 write_lock(&file_systems_lock);
128 tmp = &file_systems;
129 while (*tmp) {
130 if (fs == *tmp) {
131 *tmp = fs->next;
132 fs->next = NULL;
133 write_unlock(&file_systems_lock);
134 return 0;
135 }
136 tmp = &(*tmp)->next;
137 }
138 write_unlock(&file_systems_lock);
139 return -EINVAL;
140}
141
142static int fs_index(const char * __name)
143{
144 struct file_system_type * tmp;
145 char * name;
146 int err, index;
147
148 name = getname(__name);
149 err = PTR_ERR(name);
150 if (IS_ERR(name))
151 return err;
152
153 err = -EINVAL;
154 read_lock(&file_systems_lock);
155 for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
156 if (strcmp(tmp->name,name) == 0) {
157 err = index;
158 break;
159 }
160 }
161 read_unlock(&file_systems_lock);
162 putname(name);
163 return err;
164}
165
166static int fs_name(unsigned int index, char * buf)
167{
168 struct file_system_type * tmp;
169 int len, res;
170
171 read_lock(&file_systems_lock);
172 for (tmp = file_systems; tmp; tmp = tmp->next, index--)
173 if (index <= 0 && try_inc_mod_count(tmp->owner))
174 break;
175 read_unlock(&file_systems_lock);
176 if (!tmp)
177 return -EINVAL;
178
179
180 len = strlen(tmp->name) + 1;
181 res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
182 put_filesystem(tmp);
183 return res;
184}
185
186static int fs_maxindex(void)
187{
188 struct file_system_type * tmp;
189 int index;
190
191 read_lock(&file_systems_lock);
192 for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
193 ;
194 read_unlock(&file_systems_lock);
195 return index;
196}
197
198
199
200
201asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2)
202{
203 int retval = -EINVAL;
204
205 switch (option) {
206 case 1:
207 retval = fs_index((const char *) arg1);
208 break;
209
210 case 2:
211 retval = fs_name(arg1, (char *) arg2);
212 break;
213
214 case 3:
215 retval = fs_maxindex();
216 break;
217 }
218 return retval;
219}
220
221int get_filesystem_list(char * buf)
222{
223 int len = 0;
224 struct file_system_type * tmp;
225
226 read_lock(&file_systems_lock);
227 tmp = file_systems;
228 while (tmp && len < PAGE_SIZE - 80) {
229 len += sprintf(buf+len, "%s\t%s\n",
230 (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
231 tmp->name);
232 tmp = tmp->next;
233 }
234 read_unlock(&file_systems_lock);
235 return len;
236}
237
238struct file_system_type *get_fs_type(const char *name)
239{
240 struct file_system_type *fs;
241
242 read_lock(&file_systems_lock);
243 fs = *(find_filesystem(name));
244 if (fs && !try_inc_mod_count(fs->owner))
245 fs = NULL;
246 read_unlock(&file_systems_lock);
247 if (!fs && (request_module(name) == 0)) {
248 read_lock(&file_systems_lock);
249 fs = *(find_filesystem(name));
250 if (fs && !try_inc_mod_count(fs->owner))
251 fs = NULL;
252 read_unlock(&file_systems_lock);
253 }
254 return fs;
255}
256
257
258
259
260
261
262
263static struct super_block *alloc_super(void)
264{
265 struct super_block *s = kmalloc(sizeof(struct super_block), GFP_USER);
266 if (s) {
267 memset(s, 0, sizeof(struct super_block));
268 INIT_LIST_HEAD(&s->s_dirty);
269 INIT_LIST_HEAD(&s->s_locked_inodes);
270 INIT_LIST_HEAD(&s->s_files);
271 INIT_LIST_HEAD(&s->s_instances);
272 init_rwsem(&s->s_umount);
273 sema_init(&s->s_lock, 1);
274 down_write(&s->s_umount);
275 s->s_count = S_BIAS;
276 atomic_set(&s->s_active, 1);
277 sema_init(&s->s_vfs_rename_sem,1);
278 sema_init(&s->s_nfsd_free_path_sem,1);
279 sema_init(&s->s_dquot.dqio_sem, 1);
280 sema_init(&s->s_dquot.dqoff_sem, 1);
281 s->s_maxbytes = MAX_NON_LFS;
282 }
283 return s;
284}
285
286
287
288
289
290
291
292static inline void destroy_super(struct super_block *s)
293{
294 kfree(s);
295}
296
297
298
299
300
301
302
303
304
305
306static inline int deactivate_super(struct super_block *s)
307{
308 if (!atomic_dec_and_lock(&s->s_active, &sb_lock))
309 return 0;
310 s->s_count -= S_BIAS-1;
311 spin_unlock(&sb_lock);
312 return 1;
313}
314
315
316
317
318
319
320
321
322static inline void put_super(struct super_block *s)
323{
324 spin_lock(&sb_lock);
325 if (!--s->s_count)
326 destroy_super(s);
327 spin_unlock(&sb_lock);
328}
329
330
331
332
333
334
335
336
337
338
339
340
341static int grab_super(struct super_block *s)
342{
343 s->s_count++;
344 spin_unlock(&sb_lock);
345 down_write(&s->s_umount);
346 if (s->s_root) {
347 spin_lock(&sb_lock);
348 if (s->s_count > S_BIAS) {
349 atomic_inc(&s->s_active);
350 s->s_count--;
351 spin_unlock(&sb_lock);
352 return 1;
353 }
354 spin_unlock(&sb_lock);
355 }
356 up_write(&s->s_umount);
357 put_super(s);
358 return 0;
359}
360
361
362
363
364
365
366
367
368
369static void insert_super(struct super_block *s, struct file_system_type *type)
370{
371 s->s_type = type;
372 list_add(&s->s_list, super_blocks.prev);
373 list_add(&s->s_instances, &type->fs_supers);
374 spin_unlock(&sb_lock);
375 get_filesystem(type);
376}
377
378static void put_anon_dev(kdev_t dev);
379
380
381
382
383
384
385
386
387
388
389
390
391
392static void remove_super(struct super_block *s)
393{
394 kdev_t dev = s->s_dev;
395 struct block_device *bdev = s->s_bdev;
396 struct file_system_type *fs = s->s_type;
397
398 spin_lock(&sb_lock);
399 list_del(&s->s_list);
400 list_del(&s->s_instances);
401 spin_unlock(&sb_lock);
402 up_write(&s->s_umount);
403 put_super(s);
404 put_filesystem(fs);
405 if (bdev)
406 blkdev_put(bdev, BDEV_FS);
407 else
408 put_anon_dev(dev);
409}
410
411struct vfsmount *alloc_vfsmnt(char *name);
412void free_vfsmnt(struct vfsmount *mnt);
413
414static inline struct super_block * find_super(kdev_t dev)
415{
416 struct list_head *p;
417
418 list_for_each(p, &super_blocks) {
419 struct super_block * s = sb_entry(p);
420 if (s->s_dev == dev) {
421 s->s_count++;
422 return s;
423 }
424 }
425 return NULL;
426}
427
428void drop_super(struct super_block *sb)
429{
430 up_read(&sb->s_umount);
431 put_super(sb);
432}
433
434static inline void write_super(struct super_block *sb)
435{
436 lock_super(sb);
437 if (sb->s_root && sb->s_dirt)
438 if (sb->s_op && sb->s_op->write_super)
439 sb->s_op->write_super(sb);
440 unlock_super(sb);
441}
442
443
444
445
446
447
448void sync_supers(kdev_t dev)
449{
450 struct super_block * sb;
451
452 if (dev) {
453 sb = get_super(dev);
454 if (sb) {
455 if (sb->s_dirt)
456 write_super(sb);
457 drop_super(sb);
458 }
459 return;
460 }
461restart:
462 spin_lock(&sb_lock);
463 sb = sb_entry(super_blocks.next);
464 while (sb != sb_entry(&super_blocks))
465 if (sb->s_dirt) {
466 sb->s_count++;
467 spin_unlock(&sb_lock);
468 down_read(&sb->s_umount);
469 write_super(sb);
470 drop_super(sb);
471 goto restart;
472 } else
473 sb = sb_entry(sb->s_list.next);
474 spin_unlock(&sb_lock);
475}
476
477
478
479
480
481
482
483
484
485struct super_block * get_super(kdev_t dev)
486{
487 struct super_block * s;
488
489 if (!dev)
490 return NULL;
491restart:
492 spin_lock(&sb_lock);
493 s = find_super(dev);
494 if (s) {
495 spin_unlock(&sb_lock);
496 down_read(&s->s_umount);
497 if (s->s_root)
498 return s;
499 drop_super(s);
500 goto restart;
501 }
502 spin_unlock(&sb_lock);
503 return NULL;
504}
505
506asmlinkage long sys_ustat(dev_t dev, struct ustat * ubuf)
507{
508 struct super_block *s;
509 struct ustat tmp;
510 struct statfs sbuf;
511 int err = -EINVAL;
512
513 s = get_super(to_kdev_t(dev));
514 if (s == NULL)
515 goto out;
516 err = vfs_statfs(s, &sbuf);
517 drop_super(s);
518 if (err)
519 goto out;
520
521 memset(&tmp,0,sizeof(struct ustat));
522 tmp.f_tfree = sbuf.f_bfree;
523 tmp.f_tinode = sbuf.f_ffree;
524
525 err = copy_to_user(ubuf,&tmp,sizeof(struct ustat)) ? -EFAULT : 0;
526out:
527 return err;
528}
529
530
531
532
533
534
535
536
537
538int do_remount_sb(struct super_block *sb, int flags, void *data)
539{
540 int retval;
541
542 if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
543 return -EACCES;
544
545 if (flags & MS_RDONLY)
546 acct_auto_close(sb->s_dev);
547 shrink_dcache_sb(sb);
548 fsync_super(sb);
549
550 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
551 if (!fs_may_remount_ro(sb))
552 return -EBUSY;
553 if (sb->s_op && sb->s_op->remount_fs) {
554 lock_super(sb);
555 retval = sb->s_op->remount_fs(sb, &flags, data);
556 unlock_super(sb);
557 if (retval)
558 return retval;
559 }
560 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
561 return 0;
562}
563
564
565
566
567
568
569enum {Max_anon = 256};
570static unsigned long unnamed_dev_in_use[Max_anon/(8*sizeof(unsigned long))];
571static spinlock_t unnamed_dev_lock = SPIN_LOCK_UNLOCKED;
572
573
574
575
576
577static void put_anon_dev(kdev_t dev)
578{
579 spin_lock(&unnamed_dev_lock);
580 clear_bit(MINOR(dev), unnamed_dev_in_use);
581 spin_unlock(&unnamed_dev_lock);
582}
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606struct super_block *get_anon_super(struct file_system_type *type,
607 int (*compare)(struct super_block *,void *), void *data)
608{
609 struct super_block *s = alloc_super();
610 kdev_t dev;
611 struct list_head *p;
612
613 if (!s)
614 return ERR_PTR(-ENOMEM);
615
616retry:
617 spin_lock(&sb_lock);
618 if (compare) list_for_each(p, &type->fs_supers) {
619 struct super_block *old;
620 old = list_entry(p, struct super_block, s_instances);
621 if (!compare(old, data))
622 continue;
623 if (!grab_super(old))
624 goto retry;
625 destroy_super(s);
626 return old;
627 }
628
629 spin_lock(&unnamed_dev_lock);
630 dev = find_first_zero_bit(unnamed_dev_in_use, Max_anon);
631 if (dev == Max_anon) {
632 spin_unlock(&unnamed_dev_lock);
633 spin_unlock(&sb_lock);
634 destroy_super(s);
635 return ERR_PTR(-EMFILE);
636 }
637 set_bit(dev, unnamed_dev_in_use);
638 spin_unlock(&unnamed_dev_lock);
639
640 s->s_dev = dev;
641 insert_super(s, type);
642 return s;
643}
644
645static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
646 int flags, char *dev_name, void * data)
647{
648 struct inode *inode;
649 struct block_device *bdev;
650 struct block_device_operations *bdops;
651 devfs_handle_t de;
652 struct super_block * s;
653 struct nameidata nd;
654 struct list_head *p;
655 kdev_t dev;
656 int error = 0;
657 mode_t mode = FMODE_READ;
658
659
660 if (!dev_name || !*dev_name)
661 return ERR_PTR(-EINVAL);
662 error = path_lookup(dev_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
663 if (error)
664 return ERR_PTR(error);
665 inode = nd.dentry->d_inode;
666 error = -ENOTBLK;
667 if (!S_ISBLK(inode->i_mode))
668 goto out;
669 error = -EACCES;
670 if (nd.mnt->mnt_flags & MNT_NODEV)
671 goto out;
672 bd_acquire(inode);
673 bdev = inode->i_bdev;
674 de = devfs_get_handle_from_inode (inode);
675 bdops = devfs_get_ops (de);
676 if (bdops) bdev->bd_op = bdops;
677
678 dev = to_kdev_t(bdev->bd_dev);
679 if (!(flags & MS_RDONLY))
680 mode |= FMODE_WRITE;
681 error = blkdev_get(bdev, mode, 0, BDEV_FS);
682 devfs_put_ops (de);
683 if (error)
684 goto out;
685 check_disk_change(dev);
686 error = -EACCES;
687 if (!(flags & MS_RDONLY) && is_read_only(dev))
688 goto out1;
689
690 error = -ENOMEM;
691 s = alloc_super();
692 if (!s)
693 goto out1;
694
695 error = -EBUSY;
696restart:
697 spin_lock(&sb_lock);
698
699 list_for_each(p, &super_blocks) {
700 struct super_block *old = sb_entry(p);
701 if (old->s_dev != dev)
702 continue;
703 if (old->s_type != fs_type ||
704 ((flags ^ old->s_flags) & MS_RDONLY)) {
705 spin_unlock(&sb_lock);
706 destroy_super(s);
707 goto out1;
708 }
709 if (!grab_super(old))
710 goto restart;
711 destroy_super(s);
712 blkdev_put(bdev, BDEV_FS);
713 path_release(&nd);
714 return old;
715 }
716 s->s_dev = dev;
717 s->s_bdev = bdev;
718 s->s_flags = flags;
719 insert_super(s, fs_type);
720 if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0))
721 goto Einval;
722 s->s_flags |= MS_ACTIVE;
723 path_release(&nd);
724 return s;
725
726Einval:
727 deactivate_super(s);
728 remove_super(s);
729 error = -EINVAL;
730 goto out;
731out1:
732 blkdev_put(bdev, BDEV_FS);
733out:
734 path_release(&nd);
735 return ERR_PTR(error);
736}
737
738static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
739 int flags, char *dev_name, void *data)
740{
741 struct super_block *s = get_anon_super(fs_type, NULL, NULL);
742
743 if (IS_ERR(s))
744 return s;
745
746 s->s_flags = flags;
747 if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
748 deactivate_super(s);
749 remove_super(s);
750 return ERR_PTR(-EINVAL);
751 }
752 s->s_flags |= MS_ACTIVE;
753 return s;
754}
755
756static int compare_single(struct super_block *s, void *p)
757{
758 return 1;
759}
760
761static struct super_block *get_sb_single(struct file_system_type *fs_type,
762 int flags, char *dev_name, void *data)
763{
764 struct super_block *s = get_anon_super(fs_type, compare_single, NULL);
765
766 if (IS_ERR(s))
767 return s;
768 if (!s->s_root) {
769 s->s_flags = flags;
770 if (!fs_type->read_super(s, data, flags & MS_VERBOSE ? 1 : 0)) {
771 deactivate_super(s);
772 remove_super(s);
773 return ERR_PTR(-EINVAL);
774 }
775 s->s_flags |= MS_ACTIVE;
776 }
777 do_remount_sb(s, flags, data);
778 return s;
779}
780
781struct vfsmount *
782do_kern_mount(const char *fstype, int flags, char *name, void *data)
783{
784 struct file_system_type *type = get_fs_type(fstype);
785 struct super_block *sb = ERR_PTR(-ENOMEM);
786 struct vfsmount *mnt;
787
788 if (!type)
789 return ERR_PTR(-ENODEV);
790
791 mnt = alloc_vfsmnt(name);
792 if (!mnt)
793 goto out;
794 if (type->fs_flags & FS_REQUIRES_DEV)
795 sb = get_sb_bdev(type, flags, name, data);
796 else if (type->fs_flags & FS_SINGLE)
797 sb = get_sb_single(type, flags, name, data);
798 else
799 sb = get_sb_nodev(type, flags, name, data);
800 if (IS_ERR(sb))
801 goto out_mnt;
802 if (type->fs_flags & FS_NOMOUNT)
803 sb->s_flags |= MS_NOUSER;
804 mnt->mnt_sb = sb;
805 mnt->mnt_root = dget(sb->s_root);
806 mnt->mnt_mountpoint = sb->s_root;
807 mnt->mnt_parent = mnt;
808 up_write(&sb->s_umount);
809 put_filesystem(type);
810 return mnt;
811out_mnt:
812 free_vfsmnt(mnt);
813out:
814 put_filesystem(type);
815 return (struct vfsmount *)sb;
816}
817
818void kill_super(struct super_block *sb)
819{
820 struct dentry *root = sb->s_root;
821 struct file_system_type *fs = sb->s_type;
822 struct super_operations *sop = sb->s_op;
823
824 if (!deactivate_super(sb))
825 return;
826
827 down_write(&sb->s_umount);
828 sb->s_root = NULL;
829
830 if (fs->fs_flags & FS_LITTER)
831 d_genocide(root);
832 shrink_dcache_parent(root);
833 dput(root);
834 fsync_super(sb);
835 lock_super(sb);
836 lock_kernel();
837 sb->s_flags &= ~MS_ACTIVE;
838 invalidate_inodes(sb);
839 if (sop) {
840 if (sop->write_super && sb->s_dirt)
841 sop->write_super(sb);
842 if (sop->put_super)
843 sop->put_super(sb);
844 }
845
846
847 if (invalidate_inodes(sb)) {
848 printk(KERN_ERR "VFS: Busy inodes after unmount. "
849 "Self-destruct in 5 seconds. Have a nice day...\n");
850 }
851
852 unlock_kernel();
853 unlock_super(sb);
854 remove_super(sb);
855}
856
857struct vfsmount *kern_mount(struct file_system_type *type)
858{
859 return do_kern_mount(type->name, 0, (char *)type->name, NULL);
860}
861