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
- 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);
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 retval = do_remount_sb(sb, MS_RDONLY);
214 if (retval)
215 return retval;
216 }
217 return 0;
218 }
219 if (!(sb=get_super(dev)) || !(sb->s_covered))
220 return -ENOENT;
221 if (!sb->s_covered->i_mount)
222 printk("VFS: umount(%d/%d): mounted inode has i_mount=NULL\n",
223 MAJOR(dev), MINOR(dev));
224 if (!fs_may_umount(dev, sb->s_mounted))
225 return -EBUSY;
226 sb->s_covered->i_mount = NULL;
227 iput(sb->s_covered);
228 sb->s_covered = NULL;
229 iput(sb->s_mounted);
230 sb->s_mounted = NULL;
231 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
232 sb->s_op->write_super(sb);
233 put_super(dev);
234 return 0;
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248 asmlinkage int sys_umount(char * name)
249 {
250 struct inode * inode;
251 dev_t dev;
252 int retval;
253 struct inode dummy_inode;
254 struct file_operations * fops;
255
256 if (!suser())
257 return -EPERM;
258 retval = namei(name,&inode);
259 if (retval) {
260 retval = lnamei(name,&inode);
261 if (retval)
262 return retval;
263 }
264 if (S_ISBLK(inode->i_mode)) {
265 dev = inode->i_rdev;
266 if (IS_NODEV(inode)) {
267 iput(inode);
268 return -EACCES;
269 }
270 } else {
271 if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) {
272 iput(inode);
273 return -EINVAL;
274 }
275 dev = inode->i_sb->s_dev;
276 iput(inode);
277 memset(&dummy_inode, 0, sizeof(dummy_inode));
278 dummy_inode.i_rdev = dev;
279 inode = &dummy_inode;
280 }
281 if (MAJOR(dev) >= MAX_BLKDEV) {
282 iput(inode);
283 return -ENXIO;
284 }
285 if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
286 fops = get_blkfops(MAJOR(dev));
287 if (fops && fops->release)
288 fops->release(inode,NULL);
289 if (MAJOR(dev) == UNNAMED_MAJOR)
290 put_unnamed_dev(dev);
291 }
292 if (inode != &dummy_inode)
293 iput(inode);
294 if (retval)
295 return retval;
296 fsync_dev(dev);
297 return 0;
298 }
299
300
301
302
303
304
305
306
307
308
309 static int do_mount(dev_t dev, const char * dir, char * type, int flags, void * data)
310 {
311 struct inode * dir_i;
312 struct super_block * sb;
313 int error;
314
315 error = namei(dir,&dir_i);
316 if (error)
317 return error;
318 if (dir_i->i_count != 1 || dir_i->i_mount) {
319 iput(dir_i);
320 return -EBUSY;
321 }
322 if (!S_ISDIR(dir_i->i_mode)) {
323 iput(dir_i);
324 return -EPERM;
325 }
326 if (!fs_may_mount(dev)) {
327 iput(dir_i);
328 return -EBUSY;
329 }
330 sb = read_super(dev,type,flags,data,0);
331 if (!sb || sb->s_covered) {
332 iput(dir_i);
333 return -EBUSY;
334 }
335 sb->s_covered = dir_i;
336 dir_i->i_mount = sb->s_mounted;
337 return 0;
338 }
339
340
341
342
343
344
345
346
347 static int do_remount_sb(struct super_block *sb, int flags)
348 {
349 int retval;
350
351
352 if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
353 if (!fs_may_remount_ro(sb->s_dev))
354 return -EBUSY;
355 if (sb->s_op && sb->s_op->remount_fs) {
356 retval = sb->s_op->remount_fs(sb, &flags);
357 if (retval)
358 return retval;
359 }
360 sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
361 (flags & MS_RMT_MASK);
362 return 0;
363 }
364
365 static int do_remount(const char *dir,int flags)
366 {
367 struct inode *dir_i;
368 int retval;
369
370 retval = namei(dir,&dir_i);
371 if (retval)
372 return retval;
373 if (dir_i != dir_i->i_sb->s_mounted) {
374 iput(dir_i);
375 return -EINVAL;
376 }
377 retval = do_remount_sb(dir_i->i_sb, flags);
378 iput(dir_i);
379 return retval;
380 }
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
396 unsigned long new_flags, void * data)
397 {
398 struct file_system_type * fstype;
399 struct inode * inode;
400 struct file_operations * fops;
401 dev_t dev;
402 int retval;
403 char tmp[100], * t;
404 int i;
405 unsigned long flags = 0;
406 unsigned long page = 0;
407
408 if (!suser())
409 return -EPERM;
410 if ((new_flags & (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
411 return do_remount(dir_name,new_flags & ~MS_MGC_MSK & ~MS_REMOUNT);
412 }
413 if (type) {
414 for (i = 0 ; i < 100 ; i++) {
415 if (TASK_SIZE <= (unsigned long) type)
416 return -EFAULT;
417 if (!(tmp[i] = get_fs_byte(type++)))
418 break;
419 }
420 t = tmp;
421 } else
422 t = NULL;
423 if (!(fstype = get_fs_type(t)))
424 return -ENODEV;
425 t = fstype->name;
426 if (fstype->requires_dev) {
427 retval = namei(dev_name,&inode);
428 if (retval)
429 return retval;
430 if (!S_ISBLK(inode->i_mode)) {
431 iput(inode);
432 return -ENOTBLK;
433 }
434 if (IS_NODEV(inode)) {
435 iput(inode);
436 return -EACCES;
437 }
438 dev = inode->i_rdev;
439 if (MAJOR(dev) >= MAX_BLKDEV) {
440 iput(inode);
441 return -ENXIO;
442 }
443 } else {
444 if (!(dev = get_unnamed_dev()))
445 return -EMFILE;
446 inode = NULL;
447 }
448 fops = get_blkfops(MAJOR(dev));
449 if (fops && fops->open) {
450 retval = fops->open(inode,NULL);
451 if (retval) {
452 iput(inode);
453 return retval;
454 }
455 }
456 if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
457 flags = new_flags & ~MS_MGC_MSK;
458 if (data) {
459 struct vm_area_struct * vma;
460
461 for (vma = current->mmap ; ; ) {
462 if (!vma || (unsigned long) data < vma->vm_start) {
463 iput(inode);
464 return -EFAULT;
465 }
466 if ((unsigned long) data < vma->vm_end)
467 break;
468 vma = vma->vm_next;
469 }
470 i = vma->vm_end - (unsigned long) data;
471 if (PAGE_SIZE <= (unsigned long) i)
472 i = PAGE_SIZE-1;
473 if (!(page = __get_free_page(GFP_KERNEL))) {
474 iput(inode);
475 return -ENOMEM;
476 }
477 memcpy_fromfs((void *) page,data,i);
478 }
479 }
480 retval = do_mount(dev,dir_name,t,flags,(void *) page);
481 free_page(page);
482 if (retval && fops && fops->release)
483 fops->release(inode,NULL);
484 iput(inode);
485 return retval;
486 }
487
488 void mount_root(void)
489 {
490 struct file_system_type * fs_type;
491 struct super_block * sb;
492 struct inode * inode;
493
494 memset(super_blocks, 0, sizeof(super_blocks));
495 fcntl_init_locks();
496 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
497 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
498 wait_for_keypress();
499 }
500 for (fs_type = file_systems; fs_type->read_super; fs_type++) {
501 if (!fs_type->requires_dev)
502 continue;
503 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
504 if (sb) {
505 inode = sb->s_mounted;
506 inode->i_count += 3 ;
507 sb->s_covered = inode;
508 sb->s_flags = root_mountflags;
509 current->pwd = inode;
510 current->root = inode;
511 printk ("VFS: Mounted root (%s filesystem)%s.\n",
512 fs_type->name,
513 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
514 return;
515 }
516 }
517 panic("VFS: Unable to mount root");
518 }