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