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