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