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