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