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