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