This source file includes following definitions.
- lookup_vfsmnt
- add_vfsmnt
- remove_vfsmnt
- register_filesystem
- unregister_filesystem
- fs_index
- fs_name
- fs_maxindex
- sys_sysfs
- get_filesystem_info
- get_filesystem_list
- get_fs_type
- __wait_on_super
- sync_supers
- get_super
- put_super
- sys_ustat
- read_super
- get_unnamed_dev
- put_unnamed_dev
- do_umount
- sys_umount
- do_mount
- do_remount_sb
- do_remount
- copy_mount_options
- sys_mount
- mount_root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <stdarg.h>
17
18 #include <linux/config.h>
19 #include <linux/sched.h>
20 #include <linux/kernel.h>
21 #include <linux/mount.h>
22 #include <linux/malloc.h>
23 #include <linux/major.h>
24 #include <linux/stat.h>
25 #include <linux/errno.h>
26 #include <linux/string.h>
27 #include <linux/locks.h>
28 #include <linux/mm.h>
29
30 #include <asm/system.h>
31 #include <asm/segment.h>
32 #include <asm/bitops.h>
33
34 #ifdef CONFIG_KERNELD
35 #include <linux/kerneld.h>
36 #endif
37
38 extern void wait_for_keypress(void);
39 extern struct file_operations * get_blkfops(unsigned int major);
40 extern void blkdev_release (struct inode *);
41
42 extern int root_mountflags;
43
44 static int do_remount_sb(struct super_block *sb, int flags, char * data);
45
46 #ifdef CONFIG_ROOT_NFS
47 extern int nfs_root_mount(struct super_block *sb);
48 #endif
49
50
51 kdev_t ROOT_DEV;
52
53 struct super_block super_blocks[NR_SUPER];
54 static struct file_system_type *file_systems = (struct file_system_type *) NULL;
55 static struct vfsmount *vfsmntlist = (struct vfsmount *) NULL,
56 *vfsmnttail = (struct vfsmount *) NULL,
57 *mru_vfsmnt = (struct vfsmount *) NULL;
58
59
60
61
62 struct vfsmount *lookup_vfsmnt(kdev_t dev)
63 {
64 struct vfsmount *lptr;
65
66 if (vfsmntlist == (struct vfsmount *)NULL)
67 return ((struct vfsmount *)NULL);
68
69 if (mru_vfsmnt != (struct vfsmount *)NULL &&
70 mru_vfsmnt->mnt_dev == dev)
71 return (mru_vfsmnt);
72
73 for (lptr = vfsmntlist;
74 lptr != (struct vfsmount *)NULL;
75 lptr = lptr->mnt_next)
76 if (lptr->mnt_dev == dev) {
77 mru_vfsmnt = lptr;
78 return (lptr);
79 }
80
81 return ((struct vfsmount *)NULL);
82
83 }
84
85 struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_name)
86 {
87 struct vfsmount *lptr;
88 char *tmp;
89
90 if ((lptr = (struct vfsmount *)
91 kmalloc(sizeof(struct vfsmount), GFP_KERNEL)) == (struct vfsmount *)NULL)
92 return ((struct vfsmount *)NULL);
93 memset(lptr, 0, sizeof(struct vfsmount));
94
95 lptr->mnt_dev = dev;
96 lptr->mnt_sem.count = 1;
97 if (dev_name && !getname(dev_name, &tmp)) {
98 if ((lptr->mnt_devname =
99 (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
100 strcpy(lptr->mnt_devname, tmp);
101 putname(tmp);
102 }
103 if (dir_name && !getname(dir_name, &tmp)) {
104 if ((lptr->mnt_dirname =
105 (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
106 strcpy(lptr->mnt_dirname, tmp);
107 putname(tmp);
108 }
109
110 if (vfsmntlist == (struct vfsmount *)NULL) {
111 vfsmntlist = vfsmnttail = lptr;
112 } else {
113 vfsmnttail->mnt_next = lptr;
114 vfsmnttail = lptr;
115 }
116 return (lptr);
117 }
118
119 void remove_vfsmnt(kdev_t dev)
120 {
121 struct vfsmount *lptr, *tofree;
122
123 if (vfsmntlist == (struct vfsmount *)NULL)
124 return;
125 lptr = vfsmntlist;
126 if (lptr->mnt_dev == dev) {
127 tofree = lptr;
128 vfsmntlist = lptr->mnt_next;
129 if (vfsmnttail->mnt_dev == dev)
130 vfsmnttail = vfsmntlist;
131 } else {
132 while (lptr->mnt_next != (struct vfsmount *)NULL) {
133 if (lptr->mnt_next->mnt_dev == dev)
134 break;
135 lptr = lptr->mnt_next;
136 }
137 tofree = lptr->mnt_next;
138 if (tofree == (struct vfsmount *)NULL)
139 return;
140 lptr->mnt_next = lptr->mnt_next->mnt_next;
141 if (vfsmnttail->mnt_dev == dev)
142 vfsmnttail = lptr;
143 }
144 kfree(tofree->mnt_devname);
145 kfree(tofree->mnt_dirname);
146 kfree_s(tofree, sizeof(struct vfsmount));
147 }
148
149 int register_filesystem(struct file_system_type * fs)
150 {
151 struct file_system_type ** tmp;
152
153 if (!fs)
154 return -EINVAL;
155 if (fs->next)
156 return -EBUSY;
157 tmp = &file_systems;
158 while (*tmp) {
159 if (strcmp((*tmp)->name, fs->name) == 0)
160 return -EBUSY;
161 tmp = &(*tmp)->next;
162 }
163 *tmp = fs;
164 return 0;
165 }
166
167 #ifdef CONFIG_MODULES
168 int unregister_filesystem(struct file_system_type * fs)
169 {
170 struct file_system_type ** tmp;
171
172 tmp = &file_systems;
173 while (*tmp) {
174 if (fs == *tmp) {
175 *tmp = fs->next;
176 fs->next = NULL;
177 return 0;
178 }
179 tmp = &(*tmp)->next;
180 }
181 return -EINVAL;
182 }
183 #endif
184
185 static int fs_index(const char * __name)
186 {
187 struct file_system_type * tmp;
188 char * name;
189 int err, index;
190
191 err = getname(__name, &name);
192 if (err)
193 return err;
194 index = 0;
195 for (tmp = file_systems ; tmp ; tmp = tmp->next) {
196 if (strcmp(tmp->name, name) == 0) {
197 putname(name);
198 return index;
199 }
200 index++;
201 }
202 putname(name);
203 return -EINVAL;
204 }
205
206 static int fs_name(unsigned int index, char * buf)
207 {
208 struct file_system_type * tmp;
209 int err, len;
210
211 tmp = file_systems;
212 while (tmp && index > 0) {
213 tmp = tmp->next;
214 index--;
215 }
216 if (!tmp)
217 return -EINVAL;
218 len = strlen(tmp->name) + 1;
219 err = verify_area(VERIFY_WRITE, buf, len);
220 if (err)
221 return err;
222 memcpy_tofs(buf, tmp->name, len);
223 return 0;
224 }
225
226 static int fs_maxindex(void)
227 {
228 struct file_system_type * tmp;
229 int index;
230
231 index = 0;
232 for (tmp = file_systems ; tmp ; tmp = tmp->next)
233 index++;
234 return index;
235 }
236
237
238
239
240 asmlinkage int sys_sysfs(int option, ...)
241 {
242 va_list args;
243 int retval = -EINVAL;
244 unsigned int index;
245
246 va_start(args, option);
247 switch (option) {
248 case 1:
249 retval = fs_index(va_arg(args, const char *));
250 break;
251
252 case 2:
253 index = va_arg(args, unsigned int);
254 retval = fs_name(index, va_arg(args, char *));
255 break;
256
257 case 3:
258 retval = fs_maxindex();
259 break;
260 }
261 va_end(args);
262 return retval;
263 }
264
265 int get_filesystem_info( char *buf )
266 {
267 struct vfsmount *tmp = vfsmntlist;
268 int len = 0;
269
270 while ( tmp && len < PAGE_SIZE - 80 )
271 {
272 len += sprintf( buf + len, "%s %s %s %s",
273 tmp->mnt_devname, tmp->mnt_dirname, tmp->mnt_sb->s_type->name,
274 tmp->mnt_flags & MS_RDONLY ? "ro" : "rw" );
275 len += sprintf( buf + len, " 0 0\n" );
276 tmp = tmp->mnt_next;
277 }
278
279 return len;
280 }
281
282 int get_filesystem_list(char * buf)
283 {
284 int len = 0;
285 struct file_system_type * tmp;
286
287 tmp = file_systems;
288 while (tmp && len < PAGE_SIZE - 80) {
289 len += sprintf(buf+len, "%s\t%s\n",
290 tmp->requires_dev ? "" : "nodev",
291 tmp->name);
292 tmp = tmp->next;
293 }
294 return len;
295 }
296
297 struct file_system_type *get_fs_type(const char *name)
298 {
299 struct file_system_type * fs = file_systems;
300
301 if (!name)
302 return fs;
303 for (fs = file_systems; fs && strcmp(fs->name, name); fs = fs->next)
304 ;
305 #ifdef CONFIG_KERNELD
306 if (!fs && (request_module(name) == 0)) {
307 for (fs = file_systems; fs && strcmp(fs->name, name); fs = fs->next)
308 ;
309 }
310 #endif
311
312 return fs;
313 }
314
315 void __wait_on_super(struct super_block * sb)
316 {
317 struct wait_queue wait = { current, NULL };
318
319 add_wait_queue(&sb->s_wait, &wait);
320 repeat:
321 current->state = TASK_UNINTERRUPTIBLE;
322 if (sb->s_lock) {
323 schedule();
324 goto repeat;
325 }
326 remove_wait_queue(&sb->s_wait, &wait);
327 current->state = TASK_RUNNING;
328 }
329
330 void sync_supers(kdev_t dev)
331 {
332 struct super_block * sb;
333
334 for (sb = super_blocks + 0 ; sb < super_blocks + NR_SUPER ; sb++) {
335 if (!sb->s_dev)
336 continue;
337 if (dev && sb->s_dev != dev)
338 continue;
339 wait_on_super(sb);
340 if (!sb->s_dev || !sb->s_dirt)
341 continue;
342 if (dev && (dev != sb->s_dev))
343 continue;
344 if (sb->s_op && sb->s_op->write_super)
345 sb->s_op->write_super(sb);
346 }
347 }
348
349 static struct super_block * get_super(kdev_t dev)
350 {
351 struct super_block * s;
352
353 if (!dev)
354 return NULL;
355 s = 0+super_blocks;
356 while (s < NR_SUPER+super_blocks)
357 if (s->s_dev == dev) {
358 wait_on_super(s);
359 if (s->s_dev == dev)
360 return s;
361 s = 0+super_blocks;
362 } else
363 s++;
364 return NULL;
365 }
366
367 void put_super(kdev_t dev)
368 {
369 struct super_block * sb;
370
371 if (dev == ROOT_DEV) {
372 printk("VFS: Root device %s: prepare for armageddon\n",
373 kdevname(dev));
374 return;
375 }
376 if (!(sb = get_super(dev)))
377 return;
378 if (sb->s_covered) {
379 printk("VFS: Mounted device %s - tssk, tssk\n",
380 kdevname(dev));
381 return;
382 }
383 if (sb->s_op && sb->s_op->put_super)
384 sb->s_op->put_super(sb);
385 }
386
387 asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf)
388 {
389 struct super_block *s;
390 struct ustat tmp;
391 struct statfs sbuf;
392 unsigned long old_fs;
393 int error;
394
395 s = get_super(to_kdev_t(dev));
396 if (s == NULL)
397 return -EINVAL;
398
399 if (!(s->s_op->statfs))
400 return -ENOSYS;
401
402 error = verify_area(VERIFY_WRITE,ubuf,sizeof(struct ustat));
403 if (error)
404 return error;
405
406 old_fs = get_fs();
407 set_fs(get_ds());
408 s->s_op->statfs(s,&sbuf,sizeof(struct statfs));
409 set_fs(old_fs);
410
411 memset(&tmp,0,sizeof(struct ustat));
412 tmp.f_tfree = sbuf.f_bfree;
413 tmp.f_tinode = sbuf.f_ffree;
414
415 memcpy_tofs(ubuf,&tmp,sizeof(struct ustat));
416 return 0;
417 }
418
419 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
420 void *data, int silent)
421 {
422 struct super_block * s;
423 struct file_system_type *type;
424
425 if (!dev)
426 return NULL;
427 check_disk_change(dev);
428 s = get_super(dev);
429 if (s)
430 return s;
431 if (!(type = get_fs_type(name))) {
432 printk("VFS: on device %s: get_fs_type(%s) failed\n",
433 kdevname(dev), name);
434 return NULL;
435 }
436 for (s = 0+super_blocks ;; s++) {
437 if (s >= NR_SUPER+super_blocks)
438 return NULL;
439 if (!(s->s_dev))
440 break;
441 }
442 s->s_dev = dev;
443 s->s_flags = flags;
444 if (!type->read_super(s,data, silent)) {
445 s->s_dev = 0;
446 return NULL;
447 }
448 s->s_dev = dev;
449 s->s_covered = NULL;
450 s->s_rd_only = 0;
451 s->s_dirt = 0;
452 s->s_type = type;
453 return s;
454 }
455
456
457
458
459
460
461 static unsigned int unnamed_dev_in_use[256/32] = { 0, };
462
463 kdev_t get_unnamed_dev(void)
464 {
465 int i;
466
467 for (i = 1; i < 256; i++) {
468 if (!set_bit(i,unnamed_dev_in_use))
469 return MKDEV(UNNAMED_MAJOR, i);
470 }
471 return 0;
472 }
473
474 void put_unnamed_dev(kdev_t dev)
475 {
476 if (!dev)
477 return;
478 if (MAJOR(dev) == UNNAMED_MAJOR &&
479 clear_bit(MINOR(dev), unnamed_dev_in_use))
480 return;
481 printk("VFS: put_unnamed_dev: freeing unused device %s\n",
482 kdevname(dev));
483 }
484
485 static int do_umount(kdev_t dev)
486 {
487 struct super_block * sb;
488 int retval;
489
490 if (dev==ROOT_DEV) {
491
492
493
494
495 if (!(sb=get_super(dev)))
496 return -ENOENT;
497 if (!(sb->s_flags & MS_RDONLY)) {
498
499
500
501
502
503
504 quota_off(dev, -1);
505 fsync_dev(dev);
506 retval = do_remount_sb(sb, MS_RDONLY, 0);
507 if (retval)
508 return retval;
509 }
510 return 0;
511 }
512 if (!(sb=get_super(dev)) || !(sb->s_covered))
513 return -ENOENT;
514 if (!sb->s_covered->i_mount)
515 printk("VFS: umount(%s): mounted inode has i_mount=NULL\n",
516 kdevname(dev));
517
518
519
520
521
522 quota_off(dev, -1);
523 if (!fs_may_umount(dev, sb->s_mounted))
524 return -EBUSY;
525 sb->s_covered->i_mount = NULL;
526 iput(sb->s_covered);
527 sb->s_covered = NULL;
528 iput(sb->s_mounted);
529 sb->s_mounted = NULL;
530 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
531 sb->s_op->write_super(sb);
532 put_super(dev);
533 remove_vfsmnt(dev);
534 return 0;
535 }
536
537
538
539
540
541
542
543
544
545
546
547
548 asmlinkage int sys_umount(char * name)
549 {
550 struct inode * inode;
551 kdev_t dev;
552 int retval;
553 struct inode dummy_inode;
554
555 if (!suser())
556 return -EPERM;
557 retval = namei(name, &inode);
558 if (retval) {
559 retval = lnamei(name, &inode);
560 if (retval)
561 return retval;
562 }
563 if (S_ISBLK(inode->i_mode)) {
564 dev = inode->i_rdev;
565 if (IS_NODEV(inode)) {
566 iput(inode);
567 return -EACCES;
568 }
569 } else {
570 if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
571 iput(inode);
572 return -EINVAL;
573 }
574 dev = inode->i_sb->s_dev;
575 iput(inode);
576 memset(&dummy_inode, 0, sizeof(dummy_inode));
577 dummy_inode.i_rdev = dev;
578 inode = &dummy_inode;
579 }
580 if (MAJOR(dev) >= MAX_BLKDEV) {
581 iput(inode);
582 return -ENXIO;
583 }
584 if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
585 blkdev_release (inode);
586 if (MAJOR(dev) == UNNAMED_MAJOR)
587 put_unnamed_dev(dev);
588 }
589 if (inode != &dummy_inode)
590 iput(inode);
591 if (retval)
592 return retval;
593 fsync_dev(dev);
594 return 0;
595 }
596
597
598
599
600
601
602
603
604
605
606
607 int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
608 {
609 struct inode * dir_i;
610 struct super_block * sb;
611 struct vfsmount *vfsmnt;
612 int error;
613
614 error = namei(dir_name, &dir_i);
615 if (error)
616 return error;
617 if (dir_i->i_count != 1 || dir_i->i_mount) {
618 iput(dir_i);
619 return -EBUSY;
620 }
621 if (!S_ISDIR(dir_i->i_mode)) {
622 iput(dir_i);
623 return -ENOTDIR;
624 }
625 if (!fs_may_mount(dev)) {
626 iput(dir_i);
627 return -EBUSY;
628 }
629 sb = read_super(dev,type,flags,data,0);
630 if (!sb) {
631 iput(dir_i);
632 return -EINVAL;
633 }
634 if (sb->s_covered) {
635 iput(dir_i);
636 return -EBUSY;
637 }
638 vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
639 if (vfsmnt) {
640 vfsmnt->mnt_sb = sb;
641 vfsmnt->mnt_flags = flags;
642 }
643 sb->s_covered = dir_i;
644 dir_i->i_mount = sb->s_mounted;
645 return 0;
646 }
647
648
649
650
651
652
653
654
655 static int do_remount_sb(struct super_block *sb, int flags, char *data)
656 {
657 int retval;
658
659 if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
660 return -EACCES;
661
662
663 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
664 if (!fs_may_remount_ro(sb->s_dev))
665 return -EBUSY;
666 if (sb->s_op && sb->s_op->remount_fs) {
667 retval = sb->s_op->remount_fs(sb, &flags, data);
668 if (retval)
669 return retval;
670 }
671 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
672 (flags & MS_RMT_MASK);
673 return 0;
674 }
675
676 static int do_remount(const char *dir,int flags,char *data)
677 {
678 struct inode *dir_i;
679 int retval;
680
681 retval = namei(dir, &dir_i);
682 if (retval)
683 return retval;
684 if (dir_i != dir_i->i_sb->s_mounted) {
685 iput(dir_i);
686 return -EINVAL;
687 }
688 retval = do_remount_sb(dir_i->i_sb, flags, data);
689 iput(dir_i);
690 return retval;
691 }
692
693 static int copy_mount_options (const void * data, unsigned long *where)
694 {
695 int i;
696 unsigned long page;
697 struct vm_area_struct * vma;
698
699 *where = 0;
700 if (!data)
701 return 0;
702
703 vma = find_vma(current, (unsigned long) data);
704 if (!vma || (unsigned long) data < vma->vm_start)
705 return -EFAULT;
706 i = vma->vm_end - (unsigned long) data;
707 if (PAGE_SIZE <= (unsigned long) i)
708 i = PAGE_SIZE-1;
709 if (!(page = __get_free_page(GFP_KERNEL))) {
710 return -ENOMEM;
711 }
712 memcpy_fromfs((void *) page,data,i);
713 *where = page;
714 return 0;
715 }
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
732 unsigned long new_flags, void * data)
733 {
734 struct file_system_type * fstype;
735 struct inode * inode;
736 struct file_operations * fops;
737 kdev_t dev;
738 int retval;
739 const char * t;
740 unsigned long flags = 0;
741 unsigned long page = 0;
742
743 if (!suser())
744 return -EPERM;
745 if ((new_flags &
746 (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
747 retval = copy_mount_options (data, &page);
748 if (retval < 0)
749 return retval;
750 retval = do_remount(dir_name,
751 new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
752 (char *) page);
753 free_page(page);
754 return retval;
755 }
756 retval = copy_mount_options (type, &page);
757 if (retval < 0)
758 return retval;
759 fstype = get_fs_type((char *) page);
760 free_page(page);
761 if (!fstype)
762 return -ENODEV;
763 t = fstype->name;
764 fops = NULL;
765 if (fstype->requires_dev) {
766 retval = namei(dev_name, &inode);
767 if (retval)
768 return retval;
769 if (!S_ISBLK(inode->i_mode)) {
770 iput(inode);
771 return -ENOTBLK;
772 }
773 if (IS_NODEV(inode)) {
774 iput(inode);
775 return -EACCES;
776 }
777 dev = inode->i_rdev;
778 if (MAJOR(dev) >= MAX_BLKDEV) {
779 iput(inode);
780 return -ENXIO;
781 }
782 fops = get_blkfops(MAJOR(dev));
783 if (!fops) {
784 iput(inode);
785 return -ENOTBLK;
786 }
787 if (fops->open) {
788 struct file dummy;
789 memset(&dummy, 0, sizeof(dummy));
790 dummy.f_inode = inode;
791 dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
792 retval = fops->open(inode, &dummy);
793 if (retval) {
794 iput(inode);
795 return retval;
796 }
797 }
798
799 } else {
800 if (!(dev = get_unnamed_dev()))
801 return -EMFILE;
802 inode = NULL;
803 }
804 page = 0;
805 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
806 flags = new_flags & ~MS_MGC_MSK;
807 retval = copy_mount_options(data, &page);
808 if (retval < 0) {
809 iput(inode);
810 return retval;
811 }
812 }
813 retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
814 free_page(page);
815 if (retval && fops && fops->release)
816 fops->release(inode, NULL);
817 iput(inode);
818 return retval;
819 }
820
821 void mount_root(void)
822 {
823 struct file_system_type * fs_type;
824 struct super_block * sb;
825 struct vfsmount *vfsmnt;
826 struct inode * inode, d_inode;
827 struct file filp;
828 int retval;
829
830 memset(super_blocks, 0, sizeof(super_blocks));
831 #ifdef CONFIG_ROOT_NFS
832 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
833 ROOT_DEV = 0;
834 if ((fs_type = get_fs_type("nfs"))) {
835 sb = &super_blocks[0];
836 sb->s_dev = get_unnamed_dev();
837 sb->s_flags = root_mountflags & ~MS_RDONLY;
838 if (nfs_root_mount(sb) >= 0) {
839 inode = sb->s_mounted;
840 inode->i_count += 3 ;
841 sb->s_covered = inode;
842 sb->s_rd_only = 0;
843 sb->s_dirt = 0;
844 sb->s_type = fs_type;
845 current->fs->pwd = inode;
846 current->fs->root = inode;
847 ROOT_DEV = sb->s_dev;
848 printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
849 return;
850 }
851 sb->s_dev = 0;
852 }
853 if (!ROOT_DEV) {
854 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
855 ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
856 }
857 }
858 #endif
859
860 #ifdef CONFIG_BLK_DEV_FD
861 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
862 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
863 wait_for_keypress();
864 }
865 #endif
866
867 memset(&filp, 0, sizeof(filp));
868 memset(&d_inode, 0, sizeof(d_inode));
869 d_inode.i_rdev = ROOT_DEV;
870 filp.f_inode = &d_inode;
871 if ( root_mountflags & MS_RDONLY)
872 filp.f_mode = 1;
873 else
874 filp.f_mode = 3;
875 retval = blkdev_open(&d_inode, &filp);
876 if(retval == -EROFS){
877 root_mountflags |= MS_RDONLY;
878 filp.f_mode = 1;
879 retval = blkdev_open(&d_inode, &filp);
880 }
881
882 for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
883 if(retval)
884 break;
885 if (!fs_type->requires_dev)
886 continue;
887 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
888 if (sb) {
889 inode = sb->s_mounted;
890 inode->i_count += 3 ;
891 sb->s_covered = inode;
892 sb->s_flags = root_mountflags;
893 current->fs->pwd = inode;
894 current->fs->root = inode;
895 printk ("VFS: Mounted root (%s filesystem)%s.\n",
896 fs_type->name,
897 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
898 vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
899 vfsmnt->mnt_sb = sb;
900 return;
901 }
902 }
903 panic("VFS: Unable to mount root fs on %s",
904 kdevname(ROOT_DEV));
905 }