This source file includes following definitions.
- get_fs_type
- lock_super
- free_super
- wait_on_super
- get_super
- put_super
- read_super
- sys_umount
- 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/kernel.h>
14 #include <asm/system.h>
15 #include <asm/segment.h>
16
17 #include <errno.h>
18 #include <sys/stat.h>
19
20 int sync_dev(int dev);
21 void wait_for_keypress(void);
22
23
24 #define set_bit(bitnr,addr) ({ \
25 register int __res __asm__("ax"); \
26 __asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \
27 __res; })
28
29 struct super_block super_block[NR_SUPER];
30
31 int ROOT_DEV = 0;
32
33
34
35 static struct file_system_type file_systems[] = {
36 {minix_read_super,"minix"},
37 {NULL,NULL}
38 };
39
40
41
42 struct file_system_type *get_fs_type(char *name)
43 {
44 int a;
45
46 for(a = 0 ; file_systems[a].read_super ; a++)
47 if (!strcmp(name,file_systems[a].name))
48 return(&file_systems[a]);
49 return(NULL);
50 }
51
52 void lock_super(struct super_block * sb)
53 {
54 cli();
55 while (sb->s_lock)
56 sleep_on(&(sb->s_wait));
57 sb->s_lock = 1;
58 sti();
59 }
60
61 void free_super(struct super_block * sb)
62 {
63 cli();
64 sb->s_lock = 0;
65 wake_up(&(sb->s_wait));
66 sti();
67 }
68
69 void wait_on_super(struct super_block * sb)
70 {
71 cli();
72 while (sb->s_lock)
73 sleep_on(&(sb->s_wait));
74 sti();
75 }
76
77 struct super_block * get_super(int dev)
78 {
79 struct super_block * s;
80
81 if (!dev)
82 return NULL;
83 s = 0+super_block;
84 while (s < NR_SUPER+super_block)
85 if (s->s_dev == dev) {
86 wait_on_super(s);
87 if (s->s_dev == dev)
88 return s;
89 s = 0+super_block;
90 } else
91 s++;
92 return NULL;
93 }
94
95 void put_super(int dev)
96 {
97 struct super_block * sb;
98
99 if (dev == ROOT_DEV) {
100 printk("root diskette changed: prepare for armageddon\n\r");
101 return;
102 }
103 if (!(sb = get_super(dev)))
104 return;
105 if (sb->s_covered) {
106 printk("Mounted disk changed - tssk, tssk\n\r");
107 return;
108 }
109 if (sb->s_op && sb->s_op->put_super)
110 sb->s_op->put_super(sb);
111 }
112
113 static struct super_block * read_super(int dev,char *name,void *data)
114 {
115 struct super_block * s;
116 struct file_system_type *type;
117
118 if (!dev)
119 return NULL;
120 check_disk_change(dev);
121 if (s = get_super(dev))
122 return s;
123 if (!(type=get_fs_type(name))) {
124 printk("get fs type failed %s\n",name);
125 return NULL;
126 }
127 for (s = 0+super_block ;; s++) {
128 if (s >= NR_SUPER+super_block)
129 return NULL;
130 if (!s->s_dev)
131 break;
132 }
133 s->s_dev = dev;
134 if (!type->read_super(s,data))
135 return(NULL);
136 s->s_dev = dev;
137 s->s_covered = NULL;
138 s->s_time = 0;
139 s->s_rd_only = 0;
140 s->s_dirt = 0;
141 return(s);
142 }
143
144 int sys_umount(char * dev_name)
145 {
146 struct inode * inode;
147 struct super_block * sb;
148 int dev;
149
150 if (!suser())
151 return -EPERM;
152 if (!(inode = namei(dev_name)))
153 return -ENOENT;
154 dev = inode->i_rdev;
155 if (!S_ISBLK(inode->i_mode)) {
156 iput(inode);
157 return -ENOTBLK;
158 }
159 iput(inode);
160 if (dev==ROOT_DEV)
161 return -EBUSY;
162 if (!(sb=get_super(dev)) || !(sb->s_covered))
163 return -ENOENT;
164 if (!sb->s_covered->i_mount)
165 printk("Mounted inode has i_mount=0\n");
166 for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
167 if (inode->i_dev==dev && inode->i_count)
168 if (inode == sb->s_mounted && inode->i_count == 1)
169 continue;
170 else
171 return -EBUSY;
172 sb->s_covered->i_mount=0;
173 iput(sb->s_covered);
174 sb->s_covered = NULL;
175 iput(sb->s_mounted);
176 sb->s_mounted = NULL;
177 put_super(dev);
178 sync_dev(dev);
179 return 0;
180 }
181
182 int sys_mount(char * dev_name, char * dir_name, char * type, int rw_flag)
183 {
184 struct inode * dev_i, * dir_i;
185 struct super_block * sb;
186 int dev;
187 char tmp[100],*t;
188 int i;
189
190 if (!suser())
191 return -EPERM;
192 if (!(dev_i = namei(dev_name)))
193 return -ENOENT;
194 dev = dev_i->i_rdev;
195 if (!S_ISBLK(dev_i->i_mode)) {
196 iput(dev_i);
197 return -EPERM;
198 }
199 iput(dev_i);
200 if (!(dir_i=namei(dir_name)))
201 return -ENOENT;
202 if (dir_i->i_count != 1 || dir_i->i_ino == MINIX_ROOT_INO) {
203 iput(dir_i);
204 return -EBUSY;
205 }
206 if (!S_ISDIR(dir_i->i_mode)) {
207 iput(dir_i);
208 return -EPERM;
209 }
210 if (dir_i->i_mount) {
211 iput(dir_i);
212 return -EPERM;
213 }
214 if (type) {
215 i = 0;
216 while (i < 100 && (tmp[i] = get_fs_byte(type++)))
217 i++;
218 t = tmp;
219 } else
220 t = "minix";
221 if (!(sb = read_super(dev,t,NULL))) {
222 iput(dir_i);
223 return -EBUSY;
224 }
225 if (sb->s_covered) {
226 iput(dir_i);
227 return -EBUSY;
228 }
229 sb->s_covered = dir_i;
230 dir_i->i_mount = 1;
231 dir_i->i_dirt = 1;
232 return 0;
233 }
234
235 void mount_root(void)
236 {
237 int i,free;
238 struct super_block * p;
239 struct inode * mi;
240
241 if (32 != sizeof (struct minix_inode))
242 panic("bad i-node size");
243 for(i=0;i<NR_FILE;i++)
244 file_table[i].f_count=0;
245 if (MAJOR(ROOT_DEV) == 2) {
246 printk("Insert root floppy and press ENTER");
247 wait_for_keypress();
248 }
249 for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
250 p->s_dev = 0;
251 p->s_lock = 0;
252 p->s_wait = NULL;
253 }
254 if (!(p=read_super(ROOT_DEV,"minix",NULL)))
255 panic("Unable to mount root");
256
257
258
259
260 mi=p->s_mounted;
261 mi->i_count += 3 ;
262 p->s_mounted = p->s_covered = mi;
263 current->pwd = mi;
264 current->root = mi;
265 free=0;
266 i=p->s_nzones;
267 while (-- i >= 0)
268 if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
269 free++;
270 printk("%d/%d free blocks\n\r",free,p->s_nzones);
271 free=0;
272 i=p->s_ninodes+1;
273 while (-- i >= 0)
274 if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
275 free++;
276 printk("%d/%d free inodes\n\r",free,p->s_ninodes);
277 }