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 if (!(retval = do_umount(dev,0)) && dev != ROOT_DEV) {
586 blkdev_release (inode);
587 if (MAJOR(dev) == UNNAMED_MAJOR)
588 put_unnamed_dev(dev);
589 }
590 if (inode != &dummy_inode)
591 iput(inode);
592 if (retval)
593 return retval;
594 fsync_dev(dev);
595 return 0;
596 }
597
598
599
600
601
602
603
604
605
606
607
608 int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
609 {
610 struct inode * dir_i;
611 struct super_block * sb;
612 struct vfsmount *vfsmnt;
613 int error;
614
615 error = namei(dir_name, &dir_i);
616 if (error)
617 return error;
618 if (dir_i->i_count != 1 || dir_i->i_mount) {
619 iput(dir_i);
620 return -EBUSY;
621 }
622 if (!S_ISDIR(dir_i->i_mode)) {
623 iput(dir_i);
624 return -ENOTDIR;
625 }
626 if (!fs_may_mount(dev)) {
627 iput(dir_i);
628 return -EBUSY;
629 }
630 sb = read_super(dev,type,flags,data,0);
631 if (!sb) {
632 iput(dir_i);
633 return -EINVAL;
634 }
635 if (sb->s_covered) {
636 iput(dir_i);
637 return -EBUSY;
638 }
639 vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
640 if (vfsmnt) {
641 vfsmnt->mnt_sb = sb;
642 vfsmnt->mnt_flags = flags;
643 }
644 sb->s_covered = dir_i;
645 dir_i->i_mount = sb->s_mounted;
646 return 0;
647 }
648
649
650
651
652
653
654
655
656 static int do_remount_sb(struct super_block *sb, int flags, char *data)
657 {
658 int retval;
659
660 if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
661 return -EACCES;
662
663
664 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
665 if (!fs_may_remount_ro(sb->s_dev))
666 return -EBUSY;
667 if (sb->s_op && sb->s_op->remount_fs) {
668 retval = sb->s_op->remount_fs(sb, &flags, data);
669 if (retval)
670 return retval;
671 }
672 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
673 (flags & MS_RMT_MASK);
674 return 0;
675 }
676
677 static int do_remount(const char *dir,int flags,char *data)
678 {
679 struct inode *dir_i;
680 int retval;
681
682 retval = namei(dir, &dir_i);
683 if (retval)
684 return retval;
685 if (dir_i != dir_i->i_sb->s_mounted) {
686 iput(dir_i);
687 return -EINVAL;
688 }
689 retval = do_remount_sb(dir_i->i_sb, flags, data);
690 iput(dir_i);
691 return retval;
692 }
693
694 static int copy_mount_options (const void * data, unsigned long *where)
695 {
696 int i;
697 unsigned long page;
698 struct vm_area_struct * vma;
699
700 *where = 0;
701 if (!data)
702 return 0;
703
704 vma = find_vma(current, (unsigned long) data);
705 if (!vma || (unsigned long) data < vma->vm_start)
706 return -EFAULT;
707 i = vma->vm_end - (unsigned long) data;
708 if (PAGE_SIZE <= (unsigned long) i)
709 i = PAGE_SIZE-1;
710 if (!(page = __get_free_page(GFP_KERNEL))) {
711 return -ENOMEM;
712 }
713 memcpy_fromfs((void *) page,data,i);
714 *where = page;
715 return 0;
716 }
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
733 unsigned long new_flags, void * data)
734 {
735 struct file_system_type * fstype;
736 struct inode * inode;
737 struct file_operations * fops;
738 kdev_t dev;
739 int retval;
740 const char * t;
741 unsigned long flags = 0;
742 unsigned long page = 0;
743
744 if (!suser())
745 return -EPERM;
746 if ((new_flags &
747 (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
748 retval = copy_mount_options (data, &page);
749 if (retval < 0)
750 return retval;
751 retval = do_remount(dir_name,
752 new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
753 (char *) page);
754 free_page(page);
755 return retval;
756 }
757 retval = copy_mount_options (type, &page);
758 if (retval < 0)
759 return retval;
760 fstype = get_fs_type((char *) page);
761 free_page(page);
762 if (!fstype)
763 return -ENODEV;
764 t = fstype->name;
765 fops = NULL;
766 if (fstype->requires_dev) {
767 retval = namei(dev_name, &inode);
768 if (retval)
769 return retval;
770 if (!S_ISBLK(inode->i_mode)) {
771 iput(inode);
772 return -ENOTBLK;
773 }
774 if (IS_NODEV(inode)) {
775 iput(inode);
776 return -EACCES;
777 }
778 dev = inode->i_rdev;
779 if (MAJOR(dev) >= MAX_BLKDEV) {
780 iput(inode);
781 return -ENXIO;
782 }
783 fops = get_blkfops(MAJOR(dev));
784 if (!fops) {
785 iput(inode);
786 return -ENOTBLK;
787 }
788 if (fops->open) {
789 struct file dummy;
790 memset(&dummy, 0, sizeof(dummy));
791 dummy.f_inode = inode;
792 dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
793 retval = fops->open(inode, &dummy);
794 if (retval) {
795 iput(inode);
796 return retval;
797 }
798 }
799
800 } else {
801 if (!(dev = get_unnamed_dev()))
802 return -EMFILE;
803 inode = NULL;
804 }
805 page = 0;
806 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
807 flags = new_flags & ~MS_MGC_MSK;
808 retval = copy_mount_options(data, &page);
809 if (retval < 0) {
810 iput(inode);
811 return retval;
812 }
813 }
814 retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
815 free_page(page);
816 if (retval && fops && fops->release)
817 fops->release(inode, NULL);
818 iput(inode);
819 return retval;
820 }
821
822 static void do_mount_root(void)
823 {
824 struct file_system_type * fs_type;
825 struct super_block * sb;
826 struct vfsmount *vfsmnt;
827 struct inode * inode, d_inode;
828 struct file filp;
829 int retval;
830
831 #ifdef CONFIG_ROOT_NFS
832 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR)
833 if (nfs_root_init(nfs_root_name, nfs_root_addrs) < 0) {
834 printk(KERN_ERR "Root-NFS: Unable to contact NFS "
835 "server for root fs, using /dev/fd0 instead\n");
836 ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
837 }
838 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
839 ROOT_DEV = 0;
840 if ((fs_type = get_fs_type("nfs"))) {
841 sb = &super_blocks[0];
842 while (sb->s_dev) sb++;
843 sb->s_dev = get_unnamed_dev();
844 sb->s_flags = root_mountflags & ~MS_RDONLY;
845 if (nfs_root_mount(sb) >= 0) {
846 inode = sb->s_mounted;
847 inode->i_count += 3 ;
848 sb->s_covered = inode;
849 sb->s_rd_only = 0;
850 sb->s_dirt = 0;
851 sb->s_type = fs_type;
852 current->fs->pwd = inode;
853 current->fs->root = inode;
854 ROOT_DEV = sb->s_dev;
855 printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
856 return;
857 }
858 sb->s_dev = 0;
859 }
860 if (!ROOT_DEV) {
861 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
862 ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
863 }
864 }
865 #endif
866
867 #ifdef CONFIG_BLK_DEV_FD
868 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
869 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
870 wait_for_keypress();
871 }
872 #endif
873
874 memset(&filp, 0, sizeof(filp));
875 memset(&d_inode, 0, sizeof(d_inode));
876 d_inode.i_rdev = ROOT_DEV;
877 filp.f_inode = &d_inode;
878 if ( root_mountflags & MS_RDONLY)
879 filp.f_mode = 1;
880 else
881 filp.f_mode = 3;
882 retval = blkdev_open(&d_inode, &filp);
883 if (retval == -EROFS) {
884 root_mountflags |= MS_RDONLY;
885 filp.f_mode = 1;
886 retval = blkdev_open(&d_inode, &filp);
887 }
888 if (retval)
889
890
891
892
893 printk("VFS: Cannot open root device %s\n",
894 kdevname(ROOT_DEV));
895 else for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
896 if (!fs_type->requires_dev)
897 continue;
898 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
899 if (sb) {
900 inode = sb->s_mounted;
901 inode->i_count += 3 ;
902 sb->s_covered = inode;
903 sb->s_flags = root_mountflags;
904 current->fs->pwd = inode;
905 current->fs->root = inode;
906 printk ("VFS: Mounted root (%s filesystem)%s.\n",
907 fs_type->name,
908 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
909 vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
910 if (!vfsmnt)
911 panic("VFS: add_vfsmnt failed for root fs");
912 vfsmnt->mnt_sb = sb;
913 vfsmnt->mnt_flags = root_mountflags;
914 return;
915 }
916 }
917 panic("VFS: Unable to mount root fs on %s",
918 kdevname(ROOT_DEV));
919 }
920
921
922 void mount_root(void)
923 {
924 memset(super_blocks, 0, sizeof(super_blocks));
925 do_mount_root();
926 }
927
928
929 #ifdef CONFIG_BLK_DEV_INITRD
930
931 int change_root(kdev_t new_root_dev,const char *put_old)
932 {
933 kdev_t old_root_dev;
934 struct vfsmount *vfsmnt;
935 struct inode *old_root,*old_pwd,*inode;
936 unsigned long old_fs;
937 int error;
938
939 old_root = current->fs->root;
940 old_pwd = current->fs->pwd;
941 old_root_dev = ROOT_DEV;
942 ROOT_DEV = new_root_dev;
943 do_mount_root();
944 old_fs = get_fs();
945 set_fs(get_ds());
946 error = namei(put_old,&inode);
947 if (error) inode = NULL;
948 set_fs(old_fs);
949 if (!error && (inode->i_count != 1 || inode->i_mount)) error = -EBUSY;
950 if (!error && !S_ISDIR(inode->i_mode)) error = -ENOTDIR;
951 iput(old_root);
952 iput(old_pwd);
953 if (error) {
954 int umount_error;
955
956 if (inode) iput(inode);
957 printk(KERN_NOTICE "Trying to unmount old root ... ");
958 old_root->i_mount = old_root;
959
960 umount_error = do_umount(old_root_dev,1);
961 if (umount_error) printk(KERN_ERR "error %d\n",umount_error);
962 else {
963 printk(KERN_NOTICE "okay\n");
964 invalidate_buffers(old_root_dev);
965 }
966 return umount_error ? error : 0;
967 }
968 iput(old_root);
969 remove_vfsmnt(old_root_dev);
970 vfsmnt = add_vfsmnt(old_root_dev,"old_rootfs",put_old);
971 if (!vfsmnt) printk(KERN_CRIT "Trouble: add_vfsmnt failed\n");
972 else {
973 vfsmnt->mnt_sb = old_root->i_sb;
974 vfsmnt->mnt_sb->s_covered = inode;
975 vfsmnt->mnt_flags = vfsmnt->mnt_sb->s_flags;
976 }
977 inode->i_mount = old_root;
978 return 0;
979 }
980
981 #endif