This source file includes following definitions.
- register_filesystem
- unregister_filesystem
- fs_index
- fs_name
- fs_maxindex
- sys_sysfs
- 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
- mount_root
1
2
3
4
5
6
7
8
9
10
11
12 #include <stdarg.h>
13
14 #include <linux/config.h>
15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/major.h>
18 #include <linux/stat.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
21 #include <linux/locks.h>
22 #include <linux/mm.h>
23
24 #include <asm/system.h>
25 #include <asm/segment.h>
26 #include <asm/bitops.h>
27
28 extern struct file_operations * get_blkfops(unsigned int);
29 extern struct file_operations * get_chrfops(unsigned int);
30
31 extern void wait_for_keypress(void);
32
33 extern int root_mountflags;
34
35 struct super_block super_blocks[NR_SUPER];
36
37 static int do_remount_sb(struct super_block *sb, int flags, char * data);
38
39 #ifdef CONFIG_ROOT_NFS
40 extern int nfs_root_mount(struct super_block *sb);
41 #endif
42
43
44 kdev_t ROOT_DEV;
45
46 static struct file_system_type * file_systems = NULL;
47
48 int register_filesystem(struct file_system_type * fs)
49 {
50 struct file_system_type ** tmp;
51
52 if (!fs)
53 return -EINVAL;
54 if (fs->next)
55 return -EBUSY;
56 tmp = &file_systems;
57 while (*tmp) {
58 if (strcmp((*tmp)->name, fs->name) == 0)
59 return -EBUSY;
60 tmp = &(*tmp)->next;
61 }
62 *tmp = fs;
63 return 0;
64 }
65
66 int unregister_filesystem(struct file_system_type * fs)
67 {
68 struct file_system_type ** tmp;
69
70 tmp = &file_systems;
71 while (*tmp) {
72 if (fs == *tmp) {
73 *tmp = fs->next;
74 fs->next = NULL;
75 return 0;
76 }
77 tmp = &(*tmp)->next;
78 }
79 return -EINVAL;
80 }
81
82 static int fs_index(const char * __name)
83 {
84 struct file_system_type * tmp;
85 char * name;
86 int err, index;
87
88 err = getname(__name, &name);
89 if (err)
90 return err;
91 index = 0;
92 for (tmp = file_systems ; tmp ; tmp = tmp->next) {
93 if (strcmp(tmp->name, name) == 0) {
94 putname(name);
95 return index;
96 }
97 index++;
98 }
99 putname(name);
100 return -EINVAL;
101 }
102
103 static int fs_name(unsigned int index, char * buf)
104 {
105 struct file_system_type * tmp;
106 int err, len;
107
108 tmp = file_systems;
109 while (tmp && index > 0) {
110 tmp = tmp->next;
111 index--;
112 }
113 if (!tmp)
114 return -EINVAL;
115 len = strlen(tmp->name) + 1;
116 err = verify_area(VERIFY_WRITE, buf, len);
117 if (err)
118 return err;
119 memcpy_tofs(buf, tmp->name, len);
120 return 0;
121 }
122
123 static int fs_maxindex(void)
124 {
125 struct file_system_type * tmp;
126 int index;
127
128 index = 0;
129 for (tmp = file_systems ; tmp ; tmp = tmp->next)
130 index++;
131 return index;
132 }
133
134
135
136
137 asmlinkage int sys_sysfs(int option, ...)
138 {
139 va_list args;
140 int retval = -EINVAL;
141 unsigned int index;
142
143 va_start(args, option);
144 switch (option) {
145 case 1:
146 retval = fs_index(va_arg(args, const char *));
147 break;
148
149 case 2:
150 index = va_arg(args, unsigned int);
151 retval = fs_name(index, va_arg(args, char *));
152 break;
153
154 case 3:
155 retval = fs_maxindex();
156 break;
157 }
158 va_end(args);
159 return retval;
160 }
161
162 int get_filesystem_list(char * buf)
163 {
164 int len = 0;
165 struct file_system_type * tmp;
166
167 tmp = file_systems;
168 while (tmp && len < PAGE_SIZE - 80) {
169 len += sprintf(buf+len, "%s\t%s\n",
170 tmp->requires_dev ? "" : "nodev",
171 tmp->name);
172 tmp = tmp->next;
173 }
174 return len;
175 }
176
177 struct file_system_type *get_fs_type(const char *name)
178 {
179 struct file_system_type * fs = file_systems;
180
181 if (!name)
182 return fs;
183 while (fs) {
184 if (!strcmp(name,fs->name))
185 break;
186 fs = fs->next;
187 }
188 return fs;
189 }
190
191 void __wait_on_super(struct super_block * sb)
192 {
193 struct wait_queue wait = { current, NULL };
194
195 add_wait_queue(&sb->s_wait, &wait);
196 repeat:
197 current->state = TASK_UNINTERRUPTIBLE;
198 if (sb->s_lock) {
199 schedule();
200 goto repeat;
201 }
202 remove_wait_queue(&sb->s_wait, &wait);
203 current->state = TASK_RUNNING;
204 }
205
206 void sync_supers(kdev_t dev)
207 {
208 struct super_block * sb;
209
210 for (sb = super_blocks + 0 ; sb < super_blocks + NR_SUPER ; sb++) {
211 if (!sb->s_dev)
212 continue;
213 if (dev && sb->s_dev != dev)
214 continue;
215 wait_on_super(sb);
216 if (!sb->s_dev || !sb->s_dirt)
217 continue;
218 if (dev && (dev != sb->s_dev))
219 continue;
220 if (sb->s_op && sb->s_op->write_super)
221 sb->s_op->write_super(sb);
222 }
223 }
224
225 static struct super_block * get_super(kdev_t dev)
226 {
227 struct super_block * s;
228
229 if (!dev)
230 return NULL;
231 s = 0+super_blocks;
232 while (s < NR_SUPER+super_blocks)
233 if (s->s_dev == dev) {
234 wait_on_super(s);
235 if (s->s_dev == dev)
236 return s;
237 s = 0+super_blocks;
238 } else
239 s++;
240 return NULL;
241 }
242
243 void put_super(kdev_t dev)
244 {
245 struct super_block * sb;
246
247 if (dev == ROOT_DEV) {
248 printk("VFS: Root device %s: prepare for armageddon\n",
249 kdevname(dev));
250 return;
251 }
252 if (!(sb = get_super(dev)))
253 return;
254 if (sb->s_covered) {
255 printk("VFS: Mounted device %s - tssk, tssk\n",
256 kdevname(dev));
257 return;
258 }
259 if (sb->s_op && sb->s_op->put_super)
260 sb->s_op->put_super(sb);
261 }
262
263 asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf)
264 {
265 struct super_block *s;
266 struct ustat tmp;
267 struct statfs sbuf;
268 unsigned long old_fs;
269 int error;
270
271 s = get_super(to_kdev_t(dev));
272 if (s == NULL)
273 return -EINVAL;
274
275 if (!(s->s_op->statfs))
276 return -ENOSYS;
277
278 error = verify_area(VERIFY_WRITE,ubuf,sizeof(struct ustat));
279 if (error)
280 return error;
281
282 old_fs = get_fs();
283 set_fs(get_ds());
284 s->s_op->statfs(s,&sbuf,sizeof(struct statfs));
285 set_fs(old_fs);
286
287 memset(&tmp,0,sizeof(struct ustat));
288 tmp.f_tfree = sbuf.f_bfree;
289 tmp.f_tinode = sbuf.f_ffree;
290
291 memcpy_tofs(ubuf,&tmp,sizeof(struct ustat));
292 return 0;
293 }
294
295 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
296 void *data, int silent)
297 {
298 struct super_block * s;
299 struct file_system_type *type;
300
301 if (!dev)
302 return NULL;
303 check_disk_change(dev);
304 s = get_super(dev);
305 if (s)
306 return s;
307 if (!(type = get_fs_type(name))) {
308 printk("VFS: on device %s: get_fs_type(%s) failed\n",
309 kdevname(dev), name);
310 return NULL;
311 }
312 for (s = 0+super_blocks ;; s++) {
313 if (s >= NR_SUPER+super_blocks)
314 return NULL;
315 if (!(s->s_dev))
316 break;
317 }
318 s->s_dev = dev;
319 s->s_flags = flags;
320 if (!type->read_super(s,data, silent)) {
321 s->s_dev = 0;
322 return NULL;
323 }
324 s->s_dev = dev;
325 s->s_covered = NULL;
326 s->s_rd_only = 0;
327 s->s_dirt = 0;
328 s->s_type = type;
329 return s;
330 }
331
332
333
334
335
336
337 static char unnamed_dev_in_use[256/8] = { 0, };
338
339 kdev_t get_unnamed_dev(void)
340 {
341 int i;
342
343 for (i = 1; i < 256; i++) {
344 if (!set_bit(i,unnamed_dev_in_use))
345 return MKDEV(UNNAMED_MAJOR, i);
346 }
347 return 0;
348 }
349
350 void put_unnamed_dev(kdev_t dev)
351 {
352 if (!dev)
353 return;
354 if (MAJOR(dev) == UNNAMED_MAJOR &&
355 clear_bit(MINOR(dev), unnamed_dev_in_use))
356 return;
357 printk("VFS: put_unnamed_dev: freeing unused device %s\n",
358 kdevname(dev));
359 }
360
361 static int do_umount(kdev_t dev)
362 {
363 struct super_block * sb;
364 int retval;
365
366 if (dev==ROOT_DEV) {
367
368
369 if (!(sb=get_super(dev)))
370 return -ENOENT;
371 if (!(sb->s_flags & MS_RDONLY)) {
372 fsync_dev(dev);
373 retval = do_remount_sb(sb, MS_RDONLY, 0);
374 if (retval)
375 return retval;
376 }
377 return 0;
378 }
379 if (!(sb=get_super(dev)) || !(sb->s_covered))
380 return -ENOENT;
381 if (!sb->s_covered->i_mount)
382 printk("VFS: umount(%s): mounted inode has i_mount=NULL\n",
383 kdevname(dev));
384 if (!fs_may_umount(dev, sb->s_mounted))
385 return -EBUSY;
386 sb->s_covered->i_mount = NULL;
387 iput(sb->s_covered);
388 sb->s_covered = NULL;
389 iput(sb->s_mounted);
390 sb->s_mounted = NULL;
391 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
392 sb->s_op->write_super(sb);
393 put_super(dev);
394 return 0;
395 }
396
397
398
399
400
401
402
403
404
405
406
407
408 asmlinkage int sys_umount(char * name)
409 {
410 struct inode * inode;
411 kdev_t dev;
412 int retval;
413 struct inode dummy_inode;
414 struct file_operations * fops;
415
416 if (!suser())
417 return -EPERM;
418 retval = namei(name,&inode);
419 if (retval) {
420 retval = lnamei(name,&inode);
421 if (retval)
422 return retval;
423 }
424 if (S_ISBLK(inode->i_mode)) {
425 dev = inode->i_rdev;
426 if (IS_NODEV(inode)) {
427 iput(inode);
428 return -EACCES;
429 }
430 } else {
431 if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
432 iput(inode);
433 return -EINVAL;
434 }
435 dev = inode->i_sb->s_dev;
436 iput(inode);
437 memset(&dummy_inode, 0, sizeof(dummy_inode));
438 dummy_inode.i_rdev = dev;
439 inode = &dummy_inode;
440 }
441 if (MAJOR(dev) >= MAX_BLKDEV) {
442 iput(inode);
443 return -ENXIO;
444 }
445 if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
446 fops = get_blkfops(MAJOR(dev));
447 if (fops && fops->release)
448 fops->release(inode,NULL);
449 if (MAJOR(dev) == UNNAMED_MAJOR)
450 put_unnamed_dev(dev);
451 }
452 if (inode != &dummy_inode)
453 iput(inode);
454 if (retval)
455 return retval;
456 fsync_dev(dev);
457 return 0;
458 }
459
460
461
462
463
464
465
466
467
468
469 int do_mount(kdev_t dev, const char * dir, const char * type, int flags, void * data)
470 {
471 struct inode * dir_i;
472 struct super_block * sb;
473 int error;
474
475 error = namei(dir,&dir_i);
476 if (error)
477 return error;
478 if (dir_i->i_count != 1 || dir_i->i_mount) {
479 iput(dir_i);
480 return -EBUSY;
481 }
482 if (!S_ISDIR(dir_i->i_mode)) {
483 iput(dir_i);
484 return -ENOTDIR;
485 }
486 if (!fs_may_mount(dev)) {
487 iput(dir_i);
488 return -EBUSY;
489 }
490 sb = read_super(dev,type,flags,data,0);
491 if (!sb) {
492 iput(dir_i);
493 return -EINVAL;
494 }
495 if (sb->s_covered) {
496 iput(dir_i);
497 return -EBUSY;
498 }
499 sb->s_covered = dir_i;
500 dir_i->i_mount = sb->s_mounted;
501 return 0;
502 }
503
504
505
506
507
508
509
510
511 static int do_remount_sb(struct super_block *sb, int flags, char *data)
512 {
513 int retval;
514
515 if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
516 return -EACCES;
517
518
519 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
520 if (!fs_may_remount_ro(sb->s_dev))
521 return -EBUSY;
522 if (sb->s_op && sb->s_op->remount_fs) {
523 retval = sb->s_op->remount_fs(sb, &flags, data);
524 if (retval)
525 return retval;
526 }
527 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
528 (flags & MS_RMT_MASK);
529 return 0;
530 }
531
532 static int do_remount(const char *dir,int flags,char *data)
533 {
534 struct inode *dir_i;
535 int retval;
536
537 retval = namei(dir,&dir_i);
538 if (retval)
539 return retval;
540 if (dir_i != dir_i->i_sb->s_mounted) {
541 iput(dir_i);
542 return -EINVAL;
543 }
544 retval = do_remount_sb(dir_i->i_sb, flags, data);
545 iput(dir_i);
546 return retval;
547 }
548
549 static int copy_mount_options (const void * data, unsigned long *where)
550 {
551 int i;
552 unsigned long page;
553 struct vm_area_struct * vma;
554
555 *where = 0;
556 if (!data)
557 return 0;
558
559 vma = find_vma(current, (unsigned long) data);
560 if (!vma || (unsigned long) data < vma->vm_start)
561 return -EFAULT;
562 i = vma->vm_end - (unsigned long) data;
563 if (PAGE_SIZE <= (unsigned long) i)
564 i = PAGE_SIZE-1;
565 if (!(page = __get_free_page(GFP_KERNEL))) {
566 return -ENOMEM;
567 }
568 memcpy_fromfs((void *) page,data,i);
569 *where = page;
570 return 0;
571 }
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
588 unsigned long new_flags, void * data)
589 {
590 struct file_system_type * fstype;
591 struct inode * inode;
592 struct file_operations * fops;
593 kdev_t dev;
594 int retval;
595 const char * t;
596 unsigned long flags = 0;
597 unsigned long page = 0;
598
599 if (!suser())
600 return -EPERM;
601 if ((new_flags &
602 (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
603 retval = copy_mount_options (data, &page);
604 if (retval < 0)
605 return retval;
606 retval = do_remount(dir_name,
607 new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
608 (char *) page);
609 free_page(page);
610 return retval;
611 }
612 retval = copy_mount_options (type, &page);
613 if (retval < 0)
614 return retval;
615 fstype = get_fs_type((char *) page);
616 free_page(page);
617 if (!fstype)
618 return -ENODEV;
619 t = fstype->name;
620 fops = NULL;
621 if (fstype->requires_dev) {
622 retval = namei(dev_name,&inode);
623 if (retval)
624 return retval;
625 if (!S_ISBLK(inode->i_mode)) {
626 iput(inode);
627 return -ENOTBLK;
628 }
629 if (IS_NODEV(inode)) {
630 iput(inode);
631 return -EACCES;
632 }
633 dev = inode->i_rdev;
634 if (MAJOR(dev) >= MAX_BLKDEV) {
635 iput(inode);
636 return -ENXIO;
637 }
638 fops = get_blkfops(MAJOR(dev));
639 if (!fops) {
640 iput(inode);
641 return -ENOTBLK;
642 }
643 if (fops->open) {
644 struct file dummy;
645 memset(&dummy, 0, sizeof(dummy));
646 dummy.f_inode = inode;
647 dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
648 retval = fops->open(inode, &dummy);
649 if (retval) {
650 iput(inode);
651 return retval;
652 }
653 }
654
655 } else {
656 if (!(dev = get_unnamed_dev()))
657 return -EMFILE;
658 inode = NULL;
659 }
660 page = 0;
661 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
662 flags = new_flags & ~MS_MGC_MSK;
663 retval = copy_mount_options(data, &page);
664 if (retval < 0) {
665 iput(inode);
666 return retval;
667 }
668 }
669 retval = do_mount(dev,dir_name,t,flags,(void *) page);
670 free_page(page);
671 if (retval && fops && fops->release)
672 fops->release(inode, NULL);
673 iput(inode);
674 return retval;
675 }
676
677 void mount_root(void)
678 {
679 struct file_system_type * fs_type;
680 struct super_block * sb;
681 struct inode * inode, d_inode;
682 struct file filp;
683 int retval;
684
685 memset(super_blocks, 0, sizeof(super_blocks));
686 #ifdef CONFIG_ROOT_NFS
687 if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
688 ROOT_DEV = 0;
689 if ((fs_type = get_fs_type("nfs"))) {
690 sb = &super_blocks[0];
691 sb->s_dev = get_unnamed_dev();
692 sb->s_flags = root_mountflags & ~MS_RDONLY;
693 if (nfs_root_mount(sb) >= 0) {
694 inode = sb->s_mounted;
695 inode->i_count += 3 ;
696 sb->s_covered = inode;
697 sb->s_rd_only = 0;
698 sb->s_dirt = 0;
699 sb->s_type = fs_type;
700 current->fs->pwd = inode;
701 current->fs->root = inode;
702 ROOT_DEV = sb->s_dev;
703 printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
704 return;
705 }
706 sb->s_dev = 0;
707 }
708 if (!ROOT_DEV) {
709 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
710 ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
711 }
712 }
713 #endif
714
715 #ifdef CONFIG_BLK_DEV_FD
716 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
717 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
718 wait_for_keypress();
719 }
720 #endif
721
722 memset(&filp, 0, sizeof(filp));
723 memset(&d_inode, 0, sizeof(d_inode));
724 d_inode.i_rdev = ROOT_DEV;
725 filp.f_inode = &d_inode;
726 if ( root_mountflags & MS_RDONLY)
727 filp.f_mode = 1;
728 else
729 filp.f_mode = 3;
730 retval = blkdev_open(&d_inode, &filp);
731 if(retval == -EROFS){
732 root_mountflags |= MS_RDONLY;
733 filp.f_mode = 1;
734 retval = blkdev_open(&d_inode, &filp);
735 }
736
737 for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
738 if(retval)
739 break;
740 if (!fs_type->requires_dev)
741 continue;
742 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
743 if (sb) {
744 inode = sb->s_mounted;
745 inode->i_count += 3 ;
746 sb->s_covered = inode;
747 sb->s_flags = root_mountflags;
748 current->fs->pwd = inode;
749 current->fs->root = inode;
750 printk ("VFS: Mounted root (%s filesystem)%s.\n",
751 fs_type->name,
752 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
753 return;
754 }
755 }
756 panic("VFS: Unable to mount root fs on %s",
757 kdevname(ROOT_DEV));
758 }