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