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