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