This source file includes following definitions.
- 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 <linux/config.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/major.h>
14 #include <linux/stat.h>
15 #include <linux/errno.h>
16 #include <linux/string.h>
17 #include <linux/locks.h>
18
19 #include <asm/system.h>
20 #include <asm/segment.h>
21
22
23
24
25
26
27
28 extern struct file_system_type file_systems[];
29 extern struct file_operations * get_blkfops(unsigned int);
30 extern struct file_operations * get_chrfops(unsigned int);
31
32 extern void wait_for_keypress(void);
33 extern void fcntl_init_locks(void);
34
35 extern int root_mountflags;
36
37 struct super_block super_blocks[NR_SUPER];
38
39 static int do_remount_sb(struct super_block *sb, int flags, char * data);
40
41
42 dev_t ROOT_DEV = 0;
43
44 struct file_system_type *get_fs_type(char *name)
45 {
46 int a;
47
48 if (!name)
49 return &file_systems[0];
50 for(a = 0 ; file_systems[a].read_super ; a++)
51 if (!strcmp(name,file_systems[a].name))
52 return(&file_systems[a]);
53 return NULL;
54 }
55
56 void __wait_on_super(struct super_block * sb)
57 {
58 struct wait_queue wait = { current, NULL };
59
60 add_wait_queue(&sb->s_wait, &wait);
61 repeat:
62 current->state = TASK_UNINTERRUPTIBLE;
63 if (sb->s_lock) {
64 schedule();
65 goto repeat;
66 }
67 remove_wait_queue(&sb->s_wait, &wait);
68 current->state = TASK_RUNNING;
69 }
70
71 void sync_supers(dev_t dev)
72 {
73 struct super_block * sb;
74
75 for (sb = super_blocks + 0 ; sb < super_blocks + NR_SUPER ; sb++) {
76 if (!sb->s_dev)
77 continue;
78 if (dev && sb->s_dev != dev)
79 continue;
80 wait_on_super(sb);
81 if (!sb->s_dev || !sb->s_dirt)
82 continue;
83 if (dev && (dev != sb->s_dev))
84 continue;
85 if (sb->s_op && sb->s_op->write_super)
86 sb->s_op->write_super(sb);
87 }
88 }
89
90 static struct super_block * get_super(dev_t dev)
91 {
92 struct super_block * s;
93
94 if (!dev)
95 return NULL;
96 s = 0+super_blocks;
97 while (s < NR_SUPER+super_blocks)
98 if (s->s_dev == dev) {
99 wait_on_super(s);
100 if (s->s_dev == dev)
101 return s;
102 s = 0+super_blocks;
103 } else
104 s++;
105 return NULL;
106 }
107
108 void put_super(dev_t dev)
109 {
110 struct super_block * sb;
111
112 if (dev == ROOT_DEV) {
113 printk("VFS: Root device %d/%d: prepare for armageddon\n",
114 MAJOR(dev), MINOR(dev));
115 return;
116 }
117 if (!(sb = get_super(dev)))
118 return;
119 if (sb->s_covered) {
120 printk("VFS: Mounted device %d/%d - tssk, tssk\n",
121 MAJOR(dev), MINOR(dev));
122 return;
123 }
124 if (sb->s_op && sb->s_op->put_super)
125 sb->s_op->put_super(sb);
126 }
127
128 static struct super_block * read_super(dev_t dev,char *name,int flags,
129 void *data, int silent)
130 {
131 struct super_block * s;
132 struct file_system_type *type;
133
134 if (!dev)
135 return NULL;
136 check_disk_change(dev);
137 s = get_super(dev);
138 if (s)
139 return s;
140 if (!(type = get_fs_type(name))) {
141 printk("VFS: on device %d/%d: get_fs_type(%s) failed\n",
142 MAJOR(dev), MINOR(dev), name);
143 return NULL;
144 }
145 for (s = 0+super_blocks ;; s++) {
146 if (s >= NR_SUPER+super_blocks)
147 return NULL;
148 if (!s->s_dev)
149 break;
150 }
151 s->s_dev = dev;
152 s->s_flags = flags;
153 if (!type->read_super(s,data, silent)) {
154 s->s_dev = 0;
155 return NULL;
156 }
157 s->s_dev = dev;
158 s->s_covered = NULL;
159 s->s_rd_only = 0;
160 s->s_dirt = 0;
161 return s;
162 }
163
164
165
166
167
168
169 static char unnamed_dev_in_use[256];
170
171 static dev_t get_unnamed_dev(void)
172 {
173 static int first_use = 0;
174 int i;
175
176 if (first_use == 0) {
177 first_use = 1;
178 memset(unnamed_dev_in_use, 0, sizeof(unnamed_dev_in_use));
179 unnamed_dev_in_use[0] = 1;
180 }
181 for (i = 0; i < sizeof unnamed_dev_in_use/sizeof unnamed_dev_in_use[0]; i++) {
182 if (!unnamed_dev_in_use[i]) {
183 unnamed_dev_in_use[i] = 1;
184 return (UNNAMED_MAJOR << 8) | i;
185 }
186 }
187 return 0;
188 }
189
190 static void put_unnamed_dev(dev_t dev)
191 {
192 if (!dev)
193 return;
194 if (!unnamed_dev_in_use[dev]) {
195 printk("VFS: put_unnamed_dev: freeing unused device %d/%d\n",
196 MAJOR(dev), MINOR(dev));
197 return;
198 }
199 unnamed_dev_in_use[dev] = 0;
200 }
201
202 static int do_umount(dev_t dev)
203 {
204 struct super_block * sb;
205 int retval;
206
207 if (dev==ROOT_DEV) {
208
209
210 if (!(sb=get_super(dev)))
211 return -ENOENT;
212 if (!(sb->s_flags & MS_RDONLY)) {
213 fsync_dev(dev);
214 retval = do_remount_sb(sb, MS_RDONLY, 0);
215 if (retval)
216 return retval;
217 }
218 return 0;
219 }
220 if (!(sb=get_super(dev)) || !(sb->s_covered))
221 return -ENOENT;
222 if (!sb->s_covered->i_mount)
223 printk("VFS: umount(%d/%d): mounted inode has i_mount=NULL\n",
224 MAJOR(dev), MINOR(dev));
225 if (!fs_may_umount(dev, sb->s_mounted))
226 return -EBUSY;
227 sb->s_covered->i_mount = NULL;
228 iput(sb->s_covered);
229 sb->s_covered = NULL;
230 iput(sb->s_mounted);
231 sb->s_mounted = NULL;
232 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
233 sb->s_op->write_super(sb);
234 put_super(dev);
235 return 0;
236 }
237
238
239
240
241
242
243
244
245
246
247
248
249 asmlinkage int sys_umount(char * name)
250 {
251 struct inode * inode;
252 dev_t dev;
253 int retval;
254 struct inode dummy_inode;
255 struct file_operations * fops;
256
257 if (!suser())
258 return -EPERM;
259 retval = namei(name,&inode);
260 if (retval) {
261 retval = lnamei(name,&inode);
262 if (retval)
263 return retval;
264 }
265 if (S_ISBLK(inode->i_mode)) {
266 dev = inode->i_rdev;
267 if (IS_NODEV(inode)) {
268 iput(inode);
269 return -EACCES;
270 }
271 } else {
272 if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) {
273 iput(inode);
274 return -EINVAL;
275 }
276 dev = inode->i_sb->s_dev;
277 iput(inode);
278 memset(&dummy_inode, 0, sizeof(dummy_inode));
279 dummy_inode.i_rdev = dev;
280 inode = &dummy_inode;
281 }
282 if (MAJOR(dev) >= MAX_BLKDEV) {
283 iput(inode);
284 return -ENXIO;
285 }
286 if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
287 fops = get_blkfops(MAJOR(dev));
288 if (fops && fops->release)
289 fops->release(inode,NULL);
290 if (MAJOR(dev) == UNNAMED_MAJOR)
291 put_unnamed_dev(dev);
292 }
293 if (inode != &dummy_inode)
294 iput(inode);
295 if (retval)
296 return retval;
297 fsync_dev(dev);
298 return 0;
299 }
300
301
302
303
304
305
306
307
308
309
310 static int do_mount(dev_t dev, const char * dir, char * type, int flags, void * data)
311 {
312 struct inode * dir_i;
313 struct super_block * sb;
314 int error;
315
316 error = namei(dir,&dir_i);
317 if (error)
318 return error;
319 if (dir_i->i_count != 1 || dir_i->i_mount) {
320 iput(dir_i);
321 return -EBUSY;
322 }
323 if (!S_ISDIR(dir_i->i_mode)) {
324 iput(dir_i);
325 return -EPERM;
326 }
327 if (!fs_may_mount(dev)) {
328 iput(dir_i);
329 return -EBUSY;
330 }
331 sb = read_super(dev,type,flags,data,0);
332 if (!sb || sb->s_covered) {
333 iput(dir_i);
334 return -EBUSY;
335 }
336 sb->s_covered = dir_i;
337 dir_i->i_mount = sb->s_mounted;
338 return 0;
339 }
340
341
342
343
344
345
346
347
348 static int do_remount_sb(struct super_block *sb, int flags, char *data)
349 {
350 int retval;
351
352
353 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
354 if (!fs_may_remount_ro(sb->s_dev))
355 return -EBUSY;
356 if (sb->s_op && sb->s_op->remount_fs) {
357 retval = sb->s_op->remount_fs(sb, &flags, data);
358 if (retval)
359 return retval;
360 }
361 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
362 (flags & MS_RMT_MASK);
363 return 0;
364 }
365
366 static int do_remount(const char *dir,int flags,char *data)
367 {
368 struct inode *dir_i;
369 int retval;
370
371 retval = namei(dir,&dir_i);
372 if (retval)
373 return retval;
374 if (dir_i != dir_i->i_sb->s_mounted) {
375 iput(dir_i);
376 return -EINVAL;
377 }
378 retval = do_remount_sb(dir_i->i_sb, flags, data);
379 iput(dir_i);
380 return retval;
381 }
382
383 static int copy_mount_options (const void * data, unsigned long *where)
384 {
385 int i;
386 unsigned long page;
387 struct vm_area_struct * vma;
388
389 *where = 0;
390 if (!data)
391 return 0;
392
393 for (vma = current->mmap ; ; ) {
394 if (!vma ||
395 (unsigned long) data < vma->vm_start) {
396 return -EFAULT;
397 }
398 if ((unsigned long) data < vma->vm_end)
399 break;
400 vma = vma->vm_next;
401 }
402 i = vma->vm_end - (unsigned long) data;
403 if (PAGE_SIZE <= (unsigned long) i)
404 i = PAGE_SIZE-1;
405 if (!(page = __get_free_page(GFP_KERNEL))) {
406 return -ENOMEM;
407 }
408 memcpy_fromfs((void *) page,data,i);
409 *where = page;
410 return 0;
411 }
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
428 unsigned long new_flags, void * data)
429 {
430 struct file_system_type * fstype;
431 struct inode * inode;
432 struct file_operations * fops;
433 dev_t dev;
434 int retval;
435 char * t;
436 unsigned long flags = 0;
437 unsigned long page = 0;
438
439 if (!suser())
440 return -EPERM;
441 if ((new_flags &
442 (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
443 retval = copy_mount_options (data, &page);
444 if (retval < 0)
445 return retval;
446 retval = do_remount(dir_name,
447 new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
448 (char *) page);
449 free_page(page);
450 return retval;
451 }
452 retval = copy_mount_options (type, &page);
453 if (retval < 0)
454 return retval;
455 fstype = get_fs_type((char *) page);
456 free_page(page);
457 if (!fstype)
458 return -ENODEV;
459 t = fstype->name;
460 if (fstype->requires_dev) {
461 retval = namei(dev_name,&inode);
462 if (retval)
463 return retval;
464 if (!S_ISBLK(inode->i_mode)) {
465 iput(inode);
466 return -ENOTBLK;
467 }
468 if (IS_NODEV(inode)) {
469 iput(inode);
470 return -EACCES;
471 }
472 dev = inode->i_rdev;
473 if (MAJOR(dev) >= MAX_BLKDEV) {
474 iput(inode);
475 return -ENXIO;
476 }
477 } else {
478 if (!(dev = get_unnamed_dev()))
479 return -EMFILE;
480 inode = NULL;
481 }
482 fops = get_blkfops(MAJOR(dev));
483 if (fops && fops->open) {
484 retval = fops->open(inode,NULL);
485 if (retval) {
486 iput(inode);
487 return retval;
488 }
489 }
490 page = 0;
491 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
492 flags = new_flags & ~MS_MGC_MSK;
493 retval = copy_mount_options(data, &page);
494 if (retval < 0) {
495 iput(inode);
496 return retval;
497 }
498 }
499 retval = do_mount(dev,dir_name,t,flags,(void *) page);
500 free_page(page);
501 if (retval && fops && fops->release)
502 fops->release(inode,NULL);
503 iput(inode);
504 return retval;
505 }
506
507 void mount_root(void)
508 {
509 struct file_system_type * fs_type;
510 struct super_block * sb;
511 struct inode * inode;
512
513 memset(super_blocks, 0, sizeof(super_blocks));
514 fcntl_init_locks();
515 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
516 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
517 wait_for_keypress();
518 }
519 for (fs_type = file_systems; fs_type->read_super; fs_type++) {
520 if (!fs_type->requires_dev)
521 continue;
522 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
523 if (sb) {
524 inode = sb->s_mounted;
525 inode->i_count += 3 ;
526 sb->s_covered = inode;
527 sb->s_flags = root_mountflags;
528 current->pwd = inode;
529 current->root = inode;
530 printk ("VFS: Mounted root (%s filesystem)%s.\n",
531 fs_type->name,
532 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
533 return;
534 }
535 }
536 panic("VFS: Unable to mount root");
537 }