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_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_list(char * buf)
266 {
267 int len = 0;
268 struct file_system_type * tmp;
269
270 tmp = file_systems;
271 while (tmp && len < PAGE_SIZE - 80) {
272 len += sprintf(buf+len, "%s\t%s\n",
273 tmp->requires_dev ? "" : "nodev",
274 tmp->name);
275 tmp = tmp->next;
276 }
277 return len;
278 }
279
280 struct file_system_type *get_fs_type(const char *name)
281 {
282 struct file_system_type * fs = file_systems;
283
284 if (!name)
285 return fs;
286 for (fs = file_systems; fs && strcmp(fs->name, name); fs = fs->next)
287 ;
288 #ifdef CONFIG_KERNELD
289 if (!fs && (request_module(name) == 0)) {
290 for (fs = file_systems; fs && strcmp(fs->name, name); fs = fs->next)
291 ;
292 }
293 #endif
294
295 return fs;
296 }
297
298 void __wait_on_super(struct super_block * sb)
299 {
300 struct wait_queue wait = { current, NULL };
301
302 add_wait_queue(&sb->s_wait, &wait);
303 repeat:
304 current->state = TASK_UNINTERRUPTIBLE;
305 if (sb->s_lock) {
306 schedule();
307 goto repeat;
308 }
309 remove_wait_queue(&sb->s_wait, &wait);
310 current->state = TASK_RUNNING;
311 }
312
313 void sync_supers(kdev_t dev)
314 {
315 struct super_block * sb;
316
317 for (sb = super_blocks + 0 ; sb < super_blocks + NR_SUPER ; sb++) {
318 if (!sb->s_dev)
319 continue;
320 if (dev && sb->s_dev != dev)
321 continue;
322 wait_on_super(sb);
323 if (!sb->s_dev || !sb->s_dirt)
324 continue;
325 if (dev && (dev != sb->s_dev))
326 continue;
327 if (sb->s_op && sb->s_op->write_super)
328 sb->s_op->write_super(sb);
329 }
330 }
331
332 static struct super_block * get_super(kdev_t dev)
333 {
334 struct super_block * s;
335
336 if (!dev)
337 return NULL;
338 s = 0+super_blocks;
339 while (s < NR_SUPER+super_blocks)
340 if (s->s_dev == dev) {
341 wait_on_super(s);
342 if (s->s_dev == dev)
343 return s;
344 s = 0+super_blocks;
345 } else
346 s++;
347 return NULL;
348 }
349
350 void put_super(kdev_t dev)
351 {
352 struct super_block * sb;
353
354 if (dev == ROOT_DEV) {
355 printk("VFS: Root device %s: prepare for armageddon\n",
356 kdevname(dev));
357 return;
358 }
359 if (!(sb = get_super(dev)))
360 return;
361 if (sb->s_covered) {
362 printk("VFS: Mounted device %s - tssk, tssk\n",
363 kdevname(dev));
364 return;
365 }
366 if (sb->s_op && sb->s_op->put_super)
367 sb->s_op->put_super(sb);
368 }
369
370 asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf)
371 {
372 struct super_block *s;
373 struct ustat tmp;
374 struct statfs sbuf;
375 unsigned long old_fs;
376 int error;
377
378 s = get_super(to_kdev_t(dev));
379 if (s == NULL)
380 return -EINVAL;
381
382 if (!(s->s_op->statfs))
383 return -ENOSYS;
384
385 error = verify_area(VERIFY_WRITE,ubuf,sizeof(struct ustat));
386 if (error)
387 return error;
388
389 old_fs = get_fs();
390 set_fs(get_ds());
391 s->s_op->statfs(s,&sbuf,sizeof(struct statfs));
392 set_fs(old_fs);
393
394 memset(&tmp,0,sizeof(struct ustat));
395 tmp.f_tfree = sbuf.f_bfree;
396 tmp.f_tinode = sbuf.f_ffree;
397
398 memcpy_tofs(ubuf,&tmp,sizeof(struct ustat));
399 return 0;
400 }
401
402 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
403 void *data, int silent)
404 {
405 struct super_block * s;
406 struct file_system_type *type;
407
408 if (!dev)
409 return NULL;
410 check_disk_change(dev);
411 s = get_super(dev);
412 if (s)
413 return s;
414 if (!(type = get_fs_type(name))) {
415 printk("VFS: on device %s: get_fs_type(%s) failed\n",
416 kdevname(dev), name);
417 return NULL;
418 }
419 for (s = 0+super_blocks ;; s++) {
420 if (s >= NR_SUPER+super_blocks)
421 return NULL;
422 if (!(s->s_dev))
423 break;
424 }
425 s->s_dev = dev;
426 s->s_flags = flags;
427 if (!type->read_super(s,data, silent)) {
428 s->s_dev = 0;
429 return NULL;
430 }
431 s->s_dev = dev;
432 s->s_covered = NULL;
433 s->s_rd_only = 0;
434 s->s_dirt = 0;
435 s->s_type = type;
436 return s;
437 }
438
439
440
441
442
443
444 static char unnamed_dev_in_use[256/8] = { 0, };
445
446 kdev_t get_unnamed_dev(void)
447 {
448 int i;
449
450 for (i = 1; i < 256; i++) {
451 if (!set_bit(i,unnamed_dev_in_use))
452 return MKDEV(UNNAMED_MAJOR, i);
453 }
454 return 0;
455 }
456
457 void put_unnamed_dev(kdev_t dev)
458 {
459 if (!dev)
460 return;
461 if (MAJOR(dev) == UNNAMED_MAJOR &&
462 clear_bit(MINOR(dev), unnamed_dev_in_use))
463 return;
464 printk("VFS: put_unnamed_dev: freeing unused device %s\n",
465 kdevname(dev));
466 }
467
468 static int do_umount(kdev_t dev)
469 {
470 struct super_block * sb;
471 int retval;
472
473 if (dev==ROOT_DEV) {
474
475
476
477
478 if (!(sb=get_super(dev)))
479 return -ENOENT;
480 if (!(sb->s_flags & MS_RDONLY)) {
481
482
483
484
485
486
487 quota_off(dev, -1);
488 fsync_dev(dev);
489 retval = do_remount_sb(sb, MS_RDONLY, 0);
490 if (retval)
491 return retval;
492 }
493 return 0;
494 }
495 if (!(sb=get_super(dev)) || !(sb->s_covered))
496 return -ENOENT;
497 if (!sb->s_covered->i_mount)
498 printk("VFS: umount(%s): mounted inode has i_mount=NULL\n",
499 kdevname(dev));
500
501
502
503
504
505 quota_off(dev, -1);
506 if (!fs_may_umount(dev, sb->s_mounted))
507 return -EBUSY;
508 sb->s_covered->i_mount = NULL;
509 iput(sb->s_covered);
510 sb->s_covered = NULL;
511 iput(sb->s_mounted);
512 sb->s_mounted = NULL;
513 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
514 sb->s_op->write_super(sb);
515 put_super(dev);
516 remove_vfsmnt(dev);
517 return 0;
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531 asmlinkage int sys_umount(char * name)
532 {
533 struct inode * inode;
534 kdev_t dev;
535 int retval;
536 struct inode dummy_inode;
537
538 if (!suser())
539 return -EPERM;
540 retval = namei(name, &inode);
541 if (retval) {
542 retval = lnamei(name, &inode);
543 if (retval)
544 return retval;
545 }
546 if (S_ISBLK(inode->i_mode)) {
547 dev = inode->i_rdev;
548 if (IS_NODEV(inode)) {
549 iput(inode);
550 return -EACCES;
551 }
552 } else {
553 if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
554 iput(inode);
555 return -EINVAL;
556 }
557 dev = inode->i_sb->s_dev;
558 iput(inode);
559 memset(&dummy_inode, 0, sizeof(dummy_inode));
560 dummy_inode.i_rdev = dev;
561 inode = &dummy_inode;
562 }
563 if (MAJOR(dev) >= MAX_BLKDEV) {
564 iput(inode);
565 return -ENXIO;
566 }
567 if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
568 blkdev_release (inode);
569 if (MAJOR(dev) == UNNAMED_MAJOR)
570 put_unnamed_dev(dev);
571 }
572 if (inode != &dummy_inode)
573 iput(inode);
574 if (retval)
575 return retval;
576 fsync_dev(dev);
577 return 0;
578 }
579
580
581
582
583
584
585
586
587
588
589
590 int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
591 {
592 struct inode * dir_i;
593 struct super_block * sb;
594 struct vfsmount *vfsmnt;
595 int error;
596
597 error = namei(dir_name, &dir_i);
598 if (error)
599 return error;
600 if (dir_i->i_count != 1 || dir_i->i_mount) {
601 iput(dir_i);
602 return -EBUSY;
603 }
604 if (!S_ISDIR(dir_i->i_mode)) {
605 iput(dir_i);
606 return -ENOTDIR;
607 }
608 if (!fs_may_mount(dev)) {
609 iput(dir_i);
610 return -EBUSY;
611 }
612 sb = read_super(dev,type,flags,data,0);
613 if (!sb) {
614 iput(dir_i);
615 return -EINVAL;
616 }
617 if (sb->s_covered) {
618 iput(dir_i);
619 return -EBUSY;
620 }
621 vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
622 vfsmnt->mnt_sb = sb;
623 sb->s_covered = dir_i;
624 dir_i->i_mount = sb->s_mounted;
625 return 0;
626 }
627
628
629
630
631
632
633
634
635 static int do_remount_sb(struct super_block *sb, int flags, char *data)
636 {
637 int retval;
638
639 if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
640 return -EACCES;
641
642
643 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
644 if (!fs_may_remount_ro(sb->s_dev))
645 return -EBUSY;
646 if (sb->s_op && sb->s_op->remount_fs) {
647 retval = sb->s_op->remount_fs(sb, &flags, data);
648 if (retval)
649 return retval;
650 }
651 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
652 (flags & MS_RMT_MASK);
653 return 0;
654 }
655
656 static int do_remount(const char *dir,int flags,char *data)
657 {
658 struct inode *dir_i;
659 int retval;
660
661 retval = namei(dir, &dir_i);
662 if (retval)
663 return retval;
664 if (dir_i != dir_i->i_sb->s_mounted) {
665 iput(dir_i);
666 return -EINVAL;
667 }
668 retval = do_remount_sb(dir_i->i_sb, flags, data);
669 iput(dir_i);
670 return retval;
671 }
672
673 static int copy_mount_options (const void * data, unsigned long *where)
674 {
675 int i;
676 unsigned long page;
677 struct vm_area_struct * vma;
678
679 *where = 0;
680 if (!data)
681 return 0;
682
683 vma = find_vma(current, (unsigned long) data);
684 if (!vma || (unsigned long) data < vma->vm_start)
685 return -EFAULT;
686 i = vma->vm_end - (unsigned long) data;
687 if (PAGE_SIZE <= (unsigned long) i)
688 i = PAGE_SIZE-1;
689 if (!(page = __get_free_page(GFP_KERNEL))) {
690 return -ENOMEM;
691 }
692 memcpy_fromfs((void *) page,data,i);
693 *where = page;
694 return 0;
695 }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
712 unsigned long new_flags, void * data)
713 {
714 struct file_system_type * fstype;
715 struct inode * inode;
716 struct file_operations * fops;
717 kdev_t dev;
718 int retval;
719 const char * t;
720 unsigned long flags = 0;
721 unsigned long page = 0;
722
723 if (!suser())
724 return -EPERM;
725 if ((new_flags &
726 (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
727 retval = copy_mount_options (data, &page);
728 if (retval < 0)
729 return retval;
730 retval = do_remount(dir_name,
731 new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
732 (char *) page);
733 free_page(page);
734 return retval;
735 }
736 retval = copy_mount_options (type, &page);
737 if (retval < 0)
738 return retval;
739 fstype = get_fs_type((char *) page);
740 free_page(page);
741 if (!fstype)
742 return -ENODEV;
743 t = fstype->name;
744 fops = NULL;
745 if (fstype->requires_dev) {
746 retval = namei(dev_name, &inode);
747 if (retval)
748 return retval;
749 if (!S_ISBLK(inode->i_mode)) {
750 iput(inode);
751 return -ENOTBLK;
752 }
753 if (IS_NODEV(inode)) {
754 iput(inode);
755 return -EACCES;
756 }
757 dev = inode->i_rdev;
758 if (MAJOR(dev) >= MAX_BLKDEV) {
759 iput(inode);
760 return -ENXIO;
761 }
762 fops = get_blkfops(MAJOR(dev));
763 if (!fops) {
764 iput(inode);
765 return -ENOTBLK;
766 }
767 if (fops->open) {
768 struct file dummy;
769 memset(&dummy, 0, sizeof(dummy));
770 dummy.f_inode = inode;
771 dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
772 retval = fops->open(inode, &dummy);
773 if (retval) {
774 iput(inode);
775 return retval;
776 }
777 }
778
779 } else {
780 if (!(dev = get_unnamed_dev()))
781 return -EMFILE;
782 inode = NULL;
783 }
784 page = 0;
785 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
786 flags = new_flags & ~MS_MGC_MSK;
787 retval = copy_mount_options(data, &page);
788 if (retval < 0) {
789 iput(inode);
790 return retval;
791 }
792 }
793 retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
794 free_page(page);
795 if (retval && fops && fops->release)
796 fops->release(inode, NULL);
797 iput(inode);
798 return retval;
799 }
800
801 void mount_root(void)
802 {
803 struct file_system_type * fs_type;
804 struct super_block * sb;
805 struct vfsmount *vfsmnt;
806 struct inode * inode, d_inode;
807 struct file filp;
808 int retval;
809
810 memset(super_blocks, 0, sizeof(super_blocks));
811 #ifdef CONFIG_ROOT_NFS
812 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
813 ROOT_DEV = 0;
814 if ((fs_type = get_fs_type("nfs"))) {
815 sb = &super_blocks[0];
816 sb->s_dev = get_unnamed_dev();
817 sb->s_flags = root_mountflags & ~MS_RDONLY;
818 if (nfs_root_mount(sb) >= 0) {
819 inode = sb->s_mounted;
820 inode->i_count += 3 ;
821 sb->s_covered = inode;
822 sb->s_rd_only = 0;
823 sb->s_dirt = 0;
824 sb->s_type = fs_type;
825 current->fs->pwd = inode;
826 current->fs->root = inode;
827 ROOT_DEV = sb->s_dev;
828 printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
829 return;
830 }
831 sb->s_dev = 0;
832 }
833 if (!ROOT_DEV) {
834 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
835 ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
836 }
837 }
838 #endif
839
840 #ifdef CONFIG_BLK_DEV_FD
841 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
842 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
843 wait_for_keypress();
844 }
845 #endif
846
847 memset(&filp, 0, sizeof(filp));
848 memset(&d_inode, 0, sizeof(d_inode));
849 d_inode.i_rdev = ROOT_DEV;
850 filp.f_inode = &d_inode;
851 if ( root_mountflags & MS_RDONLY)
852 filp.f_mode = 1;
853 else
854 filp.f_mode = 3;
855 retval = blkdev_open(&d_inode, &filp);
856 if(retval == -EROFS){
857 root_mountflags |= MS_RDONLY;
858 filp.f_mode = 1;
859 retval = blkdev_open(&d_inode, &filp);
860 }
861
862 for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
863 if(retval)
864 break;
865 if (!fs_type->requires_dev)
866 continue;
867 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
868 if (sb) {
869 inode = sb->s_mounted;
870 inode->i_count += 3 ;
871 sb->s_covered = inode;
872 sb->s_flags = root_mountflags;
873 current->fs->pwd = inode;
874 current->fs->root = inode;
875 printk ("VFS: Mounted root (%s filesystem)%s.\n",
876 fs_type->name,
877 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
878 vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
879 vfsmnt->mnt_sb = sb;
880 return;
881 }
882 }
883 panic("VFS: Unable to mount root fs on %s",
884 kdevname(ROOT_DEV));
885 }