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