This source file includes following definitions.
- get_fs_type
- __wait_on_super
- sync_supers
- get_super
- put_super
- read_super
- 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/minix_fs.h>
13 #include <linux/proc_fs.h>
14 #include <linux/ext_fs.h>
15 #include <linux/msdos_fs.h>
16 #include <linux/kernel.h>
17 #include <linux/stat.h>
18 #include <linux/errno.h>
19 #include <linux/locks.h>
20
21 #include <asm/system.h>
22 #include <asm/segment.h>
23
24 void wait_for_keypress(void);
25 void fcntl_init_locks(void);
26
27
28 #define set_bit(bitnr,addr) ({ \
29 register int __res __asm__("ax"); \
30 __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \
31 __res; })
32
33 struct super_block super_block[NR_SUPER];
34
35 dev_t ROOT_DEV = 0;
36
37
38
39 static struct file_system_type file_systems[] = {
40 {minix_read_super,"minix"},
41 {ext_read_super,"ext"},
42 {msdos_read_super,"msdos"},
43 {proc_read_super,"proc"},
44 {NULL,NULL}
45 };
46
47
48
49 struct file_system_type *get_fs_type(char *name)
50 {
51 int a;
52
53 for(a = 0 ; file_systems[a].read_super ; a++)
54 if (!strcmp(name,file_systems[a].name))
55 return(&file_systems[a]);
56 return(NULL);
57 }
58
59 void __wait_on_super(struct super_block * sb)
60 {
61 add_wait_queue(&sb->s_wait,¤t->wait);
62 repeat:
63 current->state = TASK_UNINTERRUPTIBLE;
64 if (sb->s_lock) {
65 schedule();
66 goto repeat;
67 }
68 remove_wait_queue(&sb->s_wait,¤t->wait);
69 current->state = TASK_RUNNING;
70 }
71
72 void sync_supers(dev_t dev)
73 {
74 struct super_block * sb;
75
76 for (sb = super_block + 0 ; sb < super_block + NR_SUPER ; sb++) {
77 if (!sb->s_dev)
78 continue;
79 wait_on_super(sb);
80 if (!sb->s_dev || !sb->s_dirt)
81 continue;
82 if (dev && (dev != sb->s_dev))
83 continue;
84 if (sb->s_op && sb->s_op->write_super)
85 sb->s_op->write_super(sb);
86 }
87 }
88
89 static struct super_block * get_super(dev_t dev)
90 {
91 struct super_block * s;
92
93 if (!dev)
94 return NULL;
95 s = 0+super_block;
96 while (s < NR_SUPER+super_block)
97 if (s->s_dev == dev) {
98 wait_on_super(s);
99 if (s->s_dev == dev)
100 return s;
101 s = 0+super_block;
102 } else
103 s++;
104 return NULL;
105 }
106
107 void put_super(dev_t dev)
108 {
109 struct super_block * sb;
110
111 if (dev == ROOT_DEV) {
112 printk("root diskette changed: prepare for armageddon\n\r");
113 return;
114 }
115 if (!(sb = get_super(dev)))
116 return;
117 if (sb->s_covered) {
118 printk("Mounted disk changed - tssk, tssk\n\r");
119 return;
120 }
121 if (sb->s_op && sb->s_op->put_super)
122 sb->s_op->put_super(sb);
123 }
124
125 static struct super_block * read_super(dev_t dev,char *name,int flags,void *data)
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 if (s = get_super(dev))
134 return s;
135 if (!(type = get_fs_type(name))) {
136 printk("get fs type failed %s\n",name);
137 return NULL;
138 }
139 for (s = 0+super_block ;; s++) {
140 if (s >= NR_SUPER+super_block)
141 return NULL;
142 if (!s->s_dev)
143 break;
144 }
145 s->s_dev = dev;
146 s->s_flags = flags;
147 if (!type->read_super(s,data)) {
148 s->s_dev = 0;
149 return NULL;
150 }
151 s->s_dev = dev;
152 s->s_covered = NULL;
153 s->s_rd_only = 0;
154 s->s_dirt = 0;
155 return s;
156 }
157
158 static int do_umount(dev_t dev)
159 {
160 struct super_block * sb;
161
162 if (dev==ROOT_DEV)
163 return -EBUSY;
164 if (!(sb=get_super(dev)) || !(sb->s_covered))
165 return -ENOENT;
166 if (!sb->s_covered->i_mount)
167 printk("Mounted inode has i_mount=0\n");
168 if (!fs_may_umount(dev, sb->s_mounted))
169 return -EBUSY;
170 sb->s_covered->i_mount=0;
171 iput(sb->s_covered);
172 sb->s_covered = NULL;
173 iput(sb->s_mounted);
174 sb->s_mounted = NULL;
175 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
176 sb->s_op->write_super (sb);
177 put_super(dev);
178 return 0;
179 }
180
181 int sys_umount(char * dev_name)
182 {
183 struct inode * inode;
184 int dev,retval;
185
186 if (!suser())
187 return -EPERM;
188 retval = namei(dev_name,&inode);
189 if (retval)
190 return retval;
191 dev = inode->i_rdev;
192 if (!S_ISBLK(inode->i_mode)) {
193 iput(inode);
194 return -ENOTBLK;
195 }
196 if (IS_NODEV(inode)) {
197 iput(inode);
198 return -EACCES;
199 }
200 if (MAJOR(dev) >= MAX_BLKDEV) {
201 iput(inode);
202 return -ENODEV;
203 }
204 retval = do_umount(dev);
205 if (!retval && blkdev_fops[MAJOR(dev)] && blkdev_fops[MAJOR(dev)]->release)
206 blkdev_fops[MAJOR(dev)]->release(inode,NULL);
207 iput(inode);
208 if (retval)
209 return retval;
210 sync_dev(dev);
211 return 0;
212 }
213
214
215
216
217
218
219
220
221
222
223 static int do_mount(dev_t dev, const char * dir, char * type, int flags, void * data)
224 {
225 struct inode * dir_i;
226 struct super_block * sb;
227 int error;
228
229 error = namei(dir,&dir_i);
230 if (error)
231 return error;
232 if (dir_i->i_count != 1 || dir_i->i_mount) {
233 iput(dir_i);
234 return -EBUSY;
235 }
236 if (!S_ISDIR(dir_i->i_mode)) {
237 iput(dir_i);
238 return -EPERM;
239 }
240 if (!fs_may_mount(dev)) {
241 iput(dir_i);
242 return -EBUSY;
243 }
244 sb = read_super(dev,type,flags,data);
245 if (!sb || sb->s_covered) {
246 iput(dir_i);
247 return -EBUSY;
248 }
249 sb->s_flags = flags;
250 sb->s_covered = dir_i;
251 dir_i->i_mount = 1;
252 return 0;
253 }
254
255
256
257
258
259
260
261
262
263
264
265
266
267 int sys_mount(char * dev_name, char * dir_name, char * type,
268 unsigned long new_flags, void *data)
269 {
270 struct inode * inode;
271 struct file_operations * fops;
272 int dev;
273 int retval;
274 char tmp[100],*t;
275 int i;
276 unsigned long flags = 0;
277 unsigned long page = 0;
278
279 if (!suser())
280 return -EPERM;
281 if (retval = namei(dev_name,&inode))
282 return retval;
283 dev = inode->i_rdev;
284 if (!S_ISBLK(inode->i_mode)) {
285 iput(inode);
286 return -ENOTBLK;
287 }
288 if (IS_NODEV(inode)) {
289 iput(inode);
290 return -EACCES;
291 }
292 if (MAJOR(dev) >= MAX_BLKDEV) {
293 iput(inode);
294 return -ENODEV;
295 }
296 fops = blkdev_fops[MAJOR(dev)];
297 if (fops && fops->open) {
298 if (retval = fops->open(inode,NULL)) {
299 iput(inode);
300 return retval;
301 }
302 }
303 if ((new_flags & 0xffff0000) == 0xC0ED0000) {
304 flags = new_flags & 0xffff;
305 if (data && (unsigned long) data < TASK_SIZE)
306 page = get_free_page(GFP_KERNEL);
307 }
308 if (page) {
309 i = TASK_SIZE - (unsigned long) data;
310 if (i < 0 || i > 4095)
311 i = 4095;
312 memcpy_fromfs((void *) page,data,i);
313 }
314 if (type) {
315 for (i = 0 ; i < 100 ; i++)
316 if (!(tmp[i] = get_fs_byte(type++)))
317 break;
318 t = tmp;
319 } else
320 t = "minix";
321 retval = do_mount(dev,dir_name,t,flags,(void *) page);
322 free_page(page);
323 if (retval && fops && fops->release)
324 fops->release(inode,NULL);
325 iput(inode);
326 return retval;
327 }
328
329 void mount_root(void)
330 {
331 int i;
332 struct file_system_type * fs_type = file_systems;
333 struct super_block * p;
334 struct inode * mi;
335
336 if (32 != sizeof (struct minix_inode))
337 panic("bad i-node size");
338 for(i=0;i<NR_FILE;i++)
339 file_table[i].f_count=0;
340 fcntl_init_locks();
341 if (MAJOR(ROOT_DEV) == 2) {
342 printk("Insert root floppy and press ENTER");
343 wait_for_keypress();
344 }
345 for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
346 p->s_dev = 0;
347 p->s_blocksize = 0;
348 p->s_lock = 0;
349 p->s_wait = NULL;
350 p->s_mounted = p->s_covered = NULL;
351 }
352 while (fs_type->read_super && fs_type->name) {
353 p = read_super(ROOT_DEV,fs_type->name,0,NULL);
354 if (p) {
355 mi = p->s_mounted;
356 mi->i_count += 3 ;
357 p->s_covered = mi;
358 p->s_flags = 0;
359 current->pwd = mi;
360 current->root = mi;
361 return;
362 }
363 fs_type++;
364 }
365 panic("Unable to mount root");
366 }