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