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