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 s->s_type = type;
290 return s;
291 }
292
293
294
295
296
297
298 static char unnamed_dev_in_use[256/8] = { 0, };
299
300 static dev_t get_unnamed_dev(void)
301 {
302 int i;
303
304 for (i = 1; i < 256; i++) {
305 if (!set_bit(i,unnamed_dev_in_use))
306 return (UNNAMED_MAJOR << 8) | i;
307 }
308 return 0;
309 }
310
311 static void put_unnamed_dev(dev_t dev)
312 {
313 if (!dev)
314 return;
315 if (MAJOR(dev) == UNNAMED_MAJOR &&
316 clear_bit(MINOR(dev), unnamed_dev_in_use))
317 return;
318 printk("VFS: put_unnamed_dev: freeing unused device %d/%d\n",
319 MAJOR(dev), MINOR(dev));
320 }
321
322 static int do_umount(dev_t dev)
323 {
324 struct super_block * sb;
325 int retval;
326
327 if (dev==ROOT_DEV) {
328
329
330 if (!(sb=get_super(dev)))
331 return -ENOENT;
332 if (!(sb->s_flags & MS_RDONLY)) {
333 fsync_dev(dev);
334 retval = do_remount_sb(sb, MS_RDONLY, 0);
335 if (retval)
336 return retval;
337 }
338 return 0;
339 }
340 if (!(sb=get_super(dev)) || !(sb->s_covered))
341 return -ENOENT;
342 if (!sb->s_covered->i_mount)
343 printk("VFS: umount(%d/%d): mounted inode has i_mount=NULL\n",
344 MAJOR(dev), MINOR(dev));
345 if (!fs_may_umount(dev, sb->s_mounted))
346 return -EBUSY;
347 sb->s_covered->i_mount = NULL;
348 iput(sb->s_covered);
349 sb->s_covered = NULL;
350 iput(sb->s_mounted);
351 sb->s_mounted = NULL;
352 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
353 sb->s_op->write_super(sb);
354 put_super(dev);
355 return 0;
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369 asmlinkage int sys_umount(char * name)
370 {
371 struct inode * inode;
372 dev_t dev;
373 int retval;
374 struct inode dummy_inode;
375 struct file_operations * fops;
376
377 if (!suser())
378 return -EPERM;
379 retval = namei(name,&inode);
380 if (retval) {
381 retval = lnamei(name,&inode);
382 if (retval)
383 return retval;
384 }
385 if (S_ISBLK(inode->i_mode)) {
386 dev = inode->i_rdev;
387 if (IS_NODEV(inode)) {
388 iput(inode);
389 return -EACCES;
390 }
391 } else {
392 if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
393 iput(inode);
394 return -EINVAL;
395 }
396 dev = inode->i_sb->s_dev;
397 iput(inode);
398 memset(&dummy_inode, 0, sizeof(dummy_inode));
399 dummy_inode.i_rdev = dev;
400 inode = &dummy_inode;
401 }
402 if (MAJOR(dev) >= MAX_BLKDEV) {
403 iput(inode);
404 return -ENXIO;
405 }
406 if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
407 fops = get_blkfops(MAJOR(dev));
408 if (fops && fops->release)
409 fops->release(inode,NULL);
410 if (MAJOR(dev) == UNNAMED_MAJOR)
411 put_unnamed_dev(dev);
412 }
413 if (inode != &dummy_inode)
414 iput(inode);
415 if (retval)
416 return retval;
417 fsync_dev(dev);
418 return 0;
419 }
420
421
422
423
424
425
426
427
428
429
430 static int do_mount(dev_t dev, const char * dir, char * type, int flags, void * data)
431 {
432 struct inode * dir_i;
433 struct super_block * sb;
434 int error;
435
436 error = namei(dir,&dir_i);
437 if (error)
438 return error;
439 if (dir_i->i_count != 1 || dir_i->i_mount) {
440 iput(dir_i);
441 return -EBUSY;
442 }
443 if (!S_ISDIR(dir_i->i_mode)) {
444 iput(dir_i);
445 return -ENOTDIR;
446 }
447 if (!fs_may_mount(dev)) {
448 iput(dir_i);
449 return -EBUSY;
450 }
451 sb = read_super(dev,type,flags,data,0);
452 if (!sb) {
453 iput(dir_i);
454 return -EINVAL;
455 }
456 if (sb->s_covered) {
457 iput(dir_i);
458 return -EBUSY;
459 }
460 sb->s_covered = dir_i;
461 dir_i->i_mount = sb->s_mounted;
462 return 0;
463 }
464
465
466
467
468
469
470
471
472 static int do_remount_sb(struct super_block *sb, int flags, char *data)
473 {
474 int retval;
475
476 if (!(flags & MS_RDONLY ) && sb->s_dev && is_read_only(sb->s_dev))
477 return -EACCES;
478
479
480 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
481 if (!fs_may_remount_ro(sb->s_dev))
482 return -EBUSY;
483 if (sb->s_op && sb->s_op->remount_fs) {
484 retval = sb->s_op->remount_fs(sb, &flags, data);
485 if (retval)
486 return retval;
487 }
488 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
489 (flags & MS_RMT_MASK);
490 return 0;
491 }
492
493 static int do_remount(const char *dir,int flags,char *data)
494 {
495 struct inode *dir_i;
496 int retval;
497
498 retval = namei(dir,&dir_i);
499 if (retval)
500 return retval;
501 if (dir_i != dir_i->i_sb->s_mounted) {
502 iput(dir_i);
503 return -EINVAL;
504 }
505 retval = do_remount_sb(dir_i->i_sb, flags, data);
506 iput(dir_i);
507 return retval;
508 }
509
510 static int copy_mount_options (const void * data, unsigned long *where)
511 {
512 int i;
513 unsigned long page;
514 struct vm_area_struct * vma;
515
516 *where = 0;
517 if (!data)
518 return 0;
519
520 for (vma = current->mm->mmap ; ; ) {
521 if (!vma ||
522 (unsigned long) data < vma->vm_start) {
523 return -EFAULT;
524 }
525 if ((unsigned long) data < vma->vm_end)
526 break;
527 vma = vma->vm_next;
528 }
529 i = vma->vm_end - (unsigned long) data;
530 if (PAGE_SIZE <= (unsigned long) i)
531 i = PAGE_SIZE-1;
532 if (!(page = __get_free_page(GFP_KERNEL))) {
533 return -ENOMEM;
534 }
535 memcpy_fromfs((void *) page,data,i);
536 *where = page;
537 return 0;
538 }
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
555 unsigned long new_flags, void * data)
556 {
557 struct file_system_type * fstype;
558 struct inode * inode;
559 struct file_operations * fops;
560 dev_t dev;
561 int retval;
562 char * t;
563 unsigned long flags = 0;
564 unsigned long page = 0;
565
566 if (!suser())
567 return -EPERM;
568 if ((new_flags &
569 (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
570 retval = copy_mount_options (data, &page);
571 if (retval < 0)
572 return retval;
573 retval = do_remount(dir_name,
574 new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
575 (char *) page);
576 free_page(page);
577 return retval;
578 }
579 retval = copy_mount_options (type, &page);
580 if (retval < 0)
581 return retval;
582 fstype = get_fs_type((char *) page);
583 free_page(page);
584 if (!fstype)
585 return -ENODEV;
586 t = fstype->name;
587 fops = NULL;
588 if (fstype->requires_dev) {
589 retval = namei(dev_name,&inode);
590 if (retval)
591 return retval;
592 if (!S_ISBLK(inode->i_mode)) {
593 iput(inode);
594 return -ENOTBLK;
595 }
596 if (IS_NODEV(inode)) {
597 iput(inode);
598 return -EACCES;
599 }
600 dev = inode->i_rdev;
601 if (MAJOR(dev) >= MAX_BLKDEV) {
602 iput(inode);
603 return -ENXIO;
604 }
605 fops = get_blkfops(MAJOR(dev));
606 if (!fops) {
607 iput(inode);
608 return -ENOTBLK;
609 }
610 if (fops->open) {
611 struct file dummy;
612 memset(&dummy, 0, sizeof(dummy));
613 dummy.f_inode = inode;
614 dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
615 retval = fops->open(inode, &dummy);
616 if (retval) {
617 iput(inode);
618 return retval;
619 }
620 }
621
622 } else {
623 if (!(dev = get_unnamed_dev()))
624 return -EMFILE;
625 inode = NULL;
626 }
627 page = 0;
628 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
629 flags = new_flags & ~MS_MGC_MSK;
630 retval = copy_mount_options(data, &page);
631 if (retval < 0) {
632 iput(inode);
633 return retval;
634 }
635 }
636 retval = do_mount(dev,dir_name,t,flags,(void *) page);
637 free_page(page);
638 if (retval && fops && fops->release)
639 fops->release(inode, NULL);
640 iput(inode);
641 return retval;
642 }
643
644 void mount_root(void)
645 {
646 struct file_system_type * fs_type;
647 struct super_block * sb;
648 struct inode * inode, d_inode;
649 struct file filp;
650 int retval;
651
652 memset(super_blocks, 0, sizeof(super_blocks));
653 #ifdef CONFIG_BLK_DEV_FD
654 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
655 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
656 wait_for_keypress();
657 }
658 #endif
659
660 memset(&filp, 0, sizeof(filp));
661 memset(&d_inode, 0, sizeof(d_inode));
662 d_inode.i_rdev = ROOT_DEV;
663 filp.f_inode = &d_inode;
664 if ( root_mountflags & MS_RDONLY)
665 filp.f_mode = 1;
666 else
667 filp.f_mode = 3;
668 retval = blkdev_open(&d_inode, &filp);
669 if(retval == -EROFS){
670 root_mountflags |= MS_RDONLY;
671 filp.f_mode = 1;
672 retval = blkdev_open(&d_inode, &filp);
673 }
674
675 for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
676 if(retval)
677 break;
678 if (!fs_type->requires_dev)
679 continue;
680 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
681 if (sb) {
682 inode = sb->s_mounted;
683 inode->i_count += 3 ;
684 sb->s_covered = inode;
685 sb->s_flags = root_mountflags;
686 current->fs->pwd = inode;
687 current->fs->root = inode;
688 printk ("VFS: Mounted root (%s filesystem)%s.\n",
689 fs_type->name,
690 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
691 return;
692 }
693 }
694 panic("VFS: Unable to mount root fs on %02x:%02x",
695 MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
696 }