This source file includes following definitions.
- get_fs_type
- lock_super
- free_super
- wait_on_super
- 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
20 #include <asm/system.h>
21 #include <asm/segment.h>
22
23 int sync_dev(int dev);
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 int 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 lock_super(struct super_block * sb)
60 {
61 cli();
62 while (sb->s_lock)
63 sleep_on(&(sb->s_wait));
64 sb->s_lock = 1;
65 sti();
66 }
67
68 void free_super(struct super_block * sb)
69 {
70 sb->s_lock = 0;
71 wake_up(&(sb->s_wait));
72 }
73
74 void wait_on_super(struct super_block * sb)
75 {
76 cli();
77 while (sb->s_lock)
78 sleep_on(&(sb->s_wait));
79 sti();
80 }
81
82 struct super_block * get_super(int dev)
83 {
84 struct super_block * s;
85
86 if (!dev)
87 return NULL;
88 s = 0+super_block;
89 while (s < NR_SUPER+super_block)
90 if (s->s_dev == dev) {
91 wait_on_super(s);
92 if (s->s_dev == dev)
93 return s;
94 s = 0+super_block;
95 } else
96 s++;
97 return NULL;
98 }
99
100 void put_super(int dev)
101 {
102 struct super_block * sb;
103
104 if (dev == ROOT_DEV) {
105 printk("root diskette changed: prepare for armageddon\n\r");
106 return;
107 }
108 if (!(sb = get_super(dev)))
109 return;
110 if (sb->s_covered) {
111 printk("Mounted disk changed - tssk, tssk\n\r");
112 return;
113 }
114 if (sb->s_op && sb->s_op->put_super)
115 sb->s_op->put_super(sb);
116 }
117
118 static struct super_block * read_super(int dev,char *name,int flags,void *data)
119 {
120 struct super_block * s;
121 struct file_system_type *type;
122
123 if (!dev)
124 return NULL;
125 check_disk_change(dev);
126 if (s = get_super(dev))
127 return s;
128 if (!(type = get_fs_type(name))) {
129 printk("get fs type failed %s\n",name);
130 return NULL;
131 }
132 for (s = 0+super_block ;; s++) {
133 if (s >= NR_SUPER+super_block)
134 return NULL;
135 if (!s->s_dev)
136 break;
137 }
138 s->s_dev = dev;
139 s->s_flags = flags;
140 if (!type->read_super(s,data)) {
141 s->s_dev = 0;
142 return NULL;
143 }
144 s->s_dev = dev;
145 s->s_covered = NULL;
146 s->s_rd_only = 0;
147 s->s_dirt = 0;
148 return s;
149 }
150
151 static int do_umount(int dev)
152 {
153 struct super_block * sb;
154 struct inode * inode;
155
156 if (dev==ROOT_DEV)
157 return -EBUSY;
158 if (!(sb=get_super(dev)) || !(sb->s_covered))
159 return -ENOENT;
160 if (!sb->s_covered->i_mount)
161 printk("Mounted inode has i_mount=0\n");
162 for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
163 if (inode->i_dev==dev && inode->i_count)
164 if (inode == sb->s_mounted && inode->i_count == 1)
165 continue;
166 else
167 return -EBUSY;
168 sb->s_covered->i_mount=0;
169 iput(sb->s_covered);
170 sb->s_covered = NULL;
171 iput(sb->s_mounted);
172 sb->s_mounted = NULL;
173 if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
174 sb->s_op->write_super (sb);
175 put_super(dev);
176 return 0;
177 }
178
179 int sys_umount(char * dev_name)
180 {
181 struct inode * inode;
182 int dev,retval;
183
184 if (!suser())
185 return -EPERM;
186 retval = namei(dev_name,&inode);
187 if (retval)
188 return retval;
189 dev = inode->i_rdev;
190 if (!S_ISBLK(inode->i_mode)) {
191 iput(inode);
192 return -ENOTBLK;
193 }
194 retval = do_umount(dev);
195 if (!retval && MAJOR(dev) < MAX_BLKDEV &&
196 blkdev_fops[MAJOR(dev)]->release)
197 blkdev_fops[MAJOR(dev)]->release(inode,NULL);
198 iput(inode);
199 if (retval) return retval;
200 sync_dev(dev);
201 return 0;
202 }
203
204
205
206
207
208
209
210
211
212
213 static int do_mount(int dev, const char * dir, char * type, int flags, void * data)
214 {
215 struct inode * inode, * dir_i;
216 struct super_block * sb;
217 int error;
218
219 error = namei(dir,&dir_i);
220 if (error)
221 return error;
222 if (dir_i->i_count != 1 || dir_i->i_mount) {
223 iput(dir_i);
224 return -EBUSY;
225 }
226 if (!S_ISDIR(dir_i->i_mode)) {
227 iput(dir_i);
228 return -EPERM;
229 }
230 for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
231 if (inode->i_dev != dev)
232 continue;
233 if (inode->i_count || inode->i_dirt || inode->i_lock) {
234 iput(dir_i);
235 return -EBUSY;
236 }
237 inode->i_dev = 0;
238 }
239 sb = read_super(dev,type,flags,data);
240 if (!sb || sb->s_covered) {
241 iput(dir_i);
242 return -EBUSY;
243 }
244 sb->s_flags = flags;
245 sb->s_covered = dir_i;
246 dir_i->i_mount = 1;
247 return 0;
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262 int sys_mount(char * dev_name, char * dir_name, char * type,
263 unsigned long new_flags, void *data)
264 {
265 struct inode * inode;
266 int dev;
267 int retval;
268 char tmp[100],*t;
269 int i;
270 unsigned long flags = 0;
271 unsigned long page = 0;
272
273 if (!suser())
274 return -EPERM;
275 retval = namei(dev_name,&inode);
276 if (retval)
277 return retval;
278 dev = inode->i_rdev;
279 if (!S_ISBLK(inode->i_mode))
280 retval = -EPERM;
281 else if (IS_NODEV(inode))
282 retval = -EACCES;
283 if (!retval && blkdev_fops[MAJOR(dev)]->open)
284 retval = blkdev_fops[MAJOR(dev)]->open(inode,NULL);
285 if (retval) {
286 iput(inode);
287 return retval;
288 }
289 if ((new_flags & 0xffff0000) == 0xC0ED0000) {
290 flags = new_flags & 0xffff;
291 if (data && (unsigned long) data < TASK_SIZE)
292 page = get_free_page(GFP_KERNEL);
293 }
294 if (page) {
295 i = TASK_SIZE - (unsigned long) data;
296 if (i < 0 || i > 4095)
297 i = 4095;
298 memcpy_fromfs((void *) page,data,i);
299 }
300 if (type) {
301 for (i = 0 ; i < 100 ; i++)
302 if (!(tmp[i] = get_fs_byte(type++)))
303 break;
304 t = tmp;
305 } else
306 t = "minix";
307 retval = do_mount(dev,dir_name,t,flags,(void *) page);
308 free_page(page);
309 if (retval && blkdev_fops[MAJOR(dev)]->release)
310 blkdev_fops[MAJOR(dev)]->release(inode,NULL);
311 iput(inode);
312 return retval;
313 }
314
315 void mount_root(void)
316 {
317 int i;
318 struct file_system_type * fs_type = file_systems;
319 struct super_block * p;
320 struct inode * mi;
321
322 if (32 != sizeof (struct minix_inode))
323 panic("bad i-node size");
324 for(i=0;i<NR_FILE;i++)
325 file_table[i].f_count=0;
326 fcntl_init_locks();
327 if (MAJOR(ROOT_DEV) == 2) {
328 printk("Insert root floppy and press ENTER");
329 wait_for_keypress();
330 }
331 for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
332 p->s_dev = 0;
333 p->s_blocksize = 0;
334 p->s_lock = 0;
335 p->s_wait = NULL;
336 p->s_mounted = p->s_covered = NULL;
337 }
338 while (fs_type->read_super && fs_type->name) {
339 p = read_super(ROOT_DEV,fs_type->name,0,NULL);
340 if (p) {
341 mi = p->s_mounted;
342 mi->i_count += 3 ;
343 p->s_covered = mi;
344 p->s_flags = 0;
345 current->pwd = mi;
346 current->root = mi;
347 return;
348 }
349 fs_type++;
350 }
351 panic("Unable to mount root");
352 }