This source file includes following definitions.
- minix_put_inode
- minix_put_super
- minix_read_super
- minix_statfs
- block_bmap
- minix_bmap
- inode_getblk
- block_getblk
- minix_getblk
- minix_bread
- minix_read_inode
- minix_update_inode
- minix_write_inode
- minix_sync_inode
1
2
3
4
5
6
7 #include <linux/sched.h>
8 #include <linux/minix_fs.h>
9 #include <linux/kernel.h>
10 #include <linux/mm.h>
11 #include <linux/string.h>
12 #include <linux/stat.h>
13 #include <linux/locks.h>
14
15 #include <asm/system.h>
16 #include <asm/segment.h>
17 #include <asm/bitops.h>
18
19 void minix_put_inode(struct inode *inode)
20 {
21 if (inode->i_nlink)
22 return;
23 inode->i_size = 0;
24 minix_truncate(inode);
25 minix_free_inode(inode);
26 }
27
28 void minix_put_super(struct super_block *sb)
29 {
30 int i;
31
32 lock_super(sb);
33 sb->s_dev = 0;
34 for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
35 brelse(sb->u.minix_sb.s_imap[i]);
36 for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
37 brelse(sb->u.minix_sb.s_zmap[i]);
38 unlock_super(sb);
39 return;
40 }
41
42 static struct super_operations minix_sops = {
43 minix_read_inode,
44 NULL,
45 minix_write_inode,
46 minix_put_inode,
47 minix_put_super,
48 NULL,
49 minix_statfs,
50 NULL
51 };
52
53 struct super_block *minix_read_super(struct super_block *s,void *data,
54 int silent)
55 {
56 struct buffer_head *bh;
57 struct minix_super_block *ms;
58 int i,dev=s->s_dev,block;
59
60 if (32 != sizeof (struct minix_inode))
61 panic("bad i-node size");
62 lock_super(s);
63 if (!(bh = bread(dev,1,BLOCK_SIZE))) {
64 s->s_dev=0;
65 unlock_super(s);
66 printk("MINIX-fs: unable to read superblock\n");
67 return NULL;
68 }
69 ms = (struct minix_super_block *) bh->b_data;
70 s->s_blocksize = 1024;
71 s->s_blocksize_bits = 10;
72 s->u.minix_sb.s_ninodes = ms->s_ninodes;
73 s->u.minix_sb.s_nzones = ms->s_nzones;
74 s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
75 s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
76 s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
77 s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
78 s->u.minix_sb.s_max_size = ms->s_max_size;
79 s->s_magic = ms->s_magic;
80 brelse(bh);
81 if (s->s_magic == MINIX_SUPER_MAGIC) {
82 s->u.minix_sb.s_dirsize = 16;
83 s->u.minix_sb.s_namelen = 14;
84 } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
85 s->u.minix_sb.s_dirsize = 32;
86 s->u.minix_sb.s_namelen = 30;
87 } else {
88 s->s_dev = 0;
89 unlock_super(s);
90 if (!silent)
91 printk("VFS: Can't find a minix filesystem on dev 0x%04x.\n",
92 dev);
93 return NULL;
94 }
95 for (i=0;i < MINIX_I_MAP_SLOTS;i++)
96 s->u.minix_sb.s_imap[i] = NULL;
97 for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
98 s->u.minix_sb.s_zmap[i] = NULL;
99 block=2;
100 for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
101 if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
102 block++;
103 else
104 break;
105 for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
106 if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
107 block++;
108 else
109 break;
110 if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
111 for(i=0;i<MINIX_I_MAP_SLOTS;i++)
112 brelse(s->u.minix_sb.s_imap[i]);
113 for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
114 brelse(s->u.minix_sb.s_zmap[i]);
115 s->s_dev=0;
116 unlock_super(s);
117 printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
118 return NULL;
119 }
120 set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
121 set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
122
123 s->s_dev = dev;
124 s->s_op = &minix_sops;
125 s->s_mounted = iget(s,MINIX_ROOT_INO);
126 unlock_super(s);
127 if (!s->s_mounted) {
128 s->s_dev = 0;
129 printk("MINIX-fs: get root inode failed\n");
130 return NULL;
131 }
132 return s;
133 }
134
135 void minix_statfs(struct super_block *sb, struct statfs *buf)
136 {
137 long tmp;
138
139 put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
140 put_fs_long(1024, &buf->f_bsize);
141 tmp = sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone;
142 tmp <<= sb->u.minix_sb.s_log_zone_size;
143 put_fs_long(tmp, &buf->f_blocks);
144 tmp = minix_count_free_blocks(sb);
145 put_fs_long(tmp, &buf->f_bfree);
146 put_fs_long(tmp, &buf->f_bavail);
147 put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
148 put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
149 put_fs_long(sb->u.minix_sb.s_namelen, &buf->f_namelen);
150
151 }
152
153 #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
154
155 static int block_bmap(struct buffer_head * bh, int nr)
156 {
157 int tmp;
158
159 if (!bh)
160 return 0;
161 tmp = ((unsigned short *) bh->b_data)[nr];
162 brelse(bh);
163 return tmp;
164 }
165
166 int minix_bmap(struct inode * inode,int block)
167 {
168 int i;
169
170 if (block<0) {
171 printk("minix_bmap: block<0");
172 return 0;
173 }
174 if (block >= 7+512+512*512) {
175 printk("minix_bmap: block>big");
176 return 0;
177 }
178 if (block < 7)
179 return inode_bmap(inode,block);
180 block -= 7;
181 if (block < 512) {
182 i = inode_bmap(inode,7);
183 if (!i)
184 return 0;
185 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
186 }
187 block -= 512;
188 i = inode_bmap(inode,8);
189 if (!i)
190 return 0;
191 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
192 if (!i)
193 return 0;
194 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
195 }
196
197 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
198 {
199 int tmp;
200 unsigned short *p;
201 struct buffer_head * result;
202
203 p = inode->u.minix_i.i_data + nr;
204 repeat:
205 tmp = *p;
206 if (tmp) {
207 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
208 if (tmp == *p)
209 return result;
210 brelse(result);
211 goto repeat;
212 }
213 if (!create)
214 return NULL;
215 tmp = minix_new_block(inode->i_sb);
216 if (!tmp)
217 return NULL;
218 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
219 if (*p) {
220 minix_free_block(inode->i_sb,tmp);
221 brelse(result);
222 goto repeat;
223 }
224 *p = tmp;
225 inode->i_ctime = CURRENT_TIME;
226 inode->i_dirt = 1;
227 return result;
228 }
229
230 static struct buffer_head * block_getblk(struct inode * inode,
231 struct buffer_head * bh, int nr, int create)
232 {
233 int tmp;
234 unsigned short *p;
235 struct buffer_head * result;
236
237 if (!bh)
238 return NULL;
239 if (!bh->b_uptodate) {
240 ll_rw_block(READ, 1, &bh);
241 wait_on_buffer(bh);
242 if (!bh->b_uptodate) {
243 brelse(bh);
244 return NULL;
245 }
246 }
247 p = nr + (unsigned short *) bh->b_data;
248 repeat:
249 tmp = *p;
250 if (tmp) {
251 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
252 if (tmp == *p) {
253 brelse(bh);
254 return result;
255 }
256 brelse(result);
257 goto repeat;
258 }
259 if (!create) {
260 brelse(bh);
261 return NULL;
262 }
263 tmp = minix_new_block(inode->i_sb);
264 if (!tmp) {
265 brelse(bh);
266 return NULL;
267 }
268 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
269 if (*p) {
270 minix_free_block(inode->i_sb,tmp);
271 brelse(result);
272 goto repeat;
273 }
274 *p = tmp;
275 bh->b_dirt = 1;
276 brelse(bh);
277 return result;
278 }
279
280 struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
281 {
282 struct buffer_head * bh;
283
284 if (block<0) {
285 printk("minix_getblk: block<0");
286 return NULL;
287 }
288 if (block >= 7+512+512*512) {
289 printk("minix_getblk: block>big");
290 return NULL;
291 }
292 if (block < 7)
293 return inode_getblk(inode,block,create);
294 block -= 7;
295 if (block < 512) {
296 bh = inode_getblk(inode,7,create);
297 return block_getblk(inode, bh, block, create);
298 }
299 block -= 512;
300 bh = inode_getblk(inode,8,create);
301 bh = block_getblk(inode, bh, block>>9, create);
302 return block_getblk(inode, bh, block & 511, create);
303 }
304
305 struct buffer_head * minix_bread(struct inode * inode, int block, int create)
306 {
307 struct buffer_head * bh;
308
309 bh = minix_getblk(inode,block,create);
310 if (!bh || bh->b_uptodate)
311 return bh;
312 ll_rw_block(READ, 1, &bh);
313 wait_on_buffer(bh);
314 if (bh->b_uptodate)
315 return bh;
316 brelse(bh);
317 return NULL;
318 }
319
320 void minix_read_inode(struct inode * inode)
321 {
322 struct buffer_head * bh;
323 struct minix_inode * raw_inode;
324 int block, ino;
325
326 ino = inode->i_ino;
327 inode->i_op = NULL;
328 inode->i_mode = 0;
329 if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
330 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
331 inode->i_dev, ino);
332 return;
333 }
334 block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
335 inode->i_sb->u.minix_sb.s_zmap_blocks +
336 (ino-1)/MINIX_INODES_PER_BLOCK;
337 if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
338 printk("Major problem: unable to read inode from dev 0x%04x\n",
339 inode->i_dev);
340 return;
341 }
342 raw_inode = ((struct minix_inode *) bh->b_data) +
343 (ino-1)%MINIX_INODES_PER_BLOCK;
344 inode->i_mode = raw_inode->i_mode;
345 inode->i_uid = raw_inode->i_uid;
346 inode->i_gid = raw_inode->i_gid;
347 inode->i_nlink = raw_inode->i_nlinks;
348 inode->i_size = raw_inode->i_size;
349 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
350 inode->i_blocks = inode->i_blksize = 0;
351 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
352 inode->i_rdev = raw_inode->i_zone[0];
353 else for (block = 0; block < 9; block++)
354 inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
355 brelse(bh);
356 if (S_ISREG(inode->i_mode))
357 inode->i_op = &minix_file_inode_operations;
358 else if (S_ISDIR(inode->i_mode))
359 inode->i_op = &minix_dir_inode_operations;
360 else if (S_ISLNK(inode->i_mode))
361 inode->i_op = &minix_symlink_inode_operations;
362 else if (S_ISCHR(inode->i_mode))
363 inode->i_op = &chrdev_inode_operations;
364 else if (S_ISBLK(inode->i_mode))
365 inode->i_op = &blkdev_inode_operations;
366 else if (S_ISFIFO(inode->i_mode))
367 init_fifo(inode);
368 }
369
370 static struct buffer_head * minix_update_inode(struct inode * inode)
371 {
372 struct buffer_head * bh;
373 struct minix_inode * raw_inode;
374 int ino, block;
375
376 ino = inode->i_ino;
377 if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
378 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
379 inode->i_dev, ino);
380 inode->i_dirt = 0;
381 return 0;
382 }
383 block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
384 (ino-1)/MINIX_INODES_PER_BLOCK;
385 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
386 printk("unable to read i-node block\n");
387 inode->i_dirt = 0;
388 return 0;
389 }
390 raw_inode = ((struct minix_inode *)bh->b_data) +
391 (ino-1)%MINIX_INODES_PER_BLOCK;
392 raw_inode->i_mode = inode->i_mode;
393 raw_inode->i_uid = inode->i_uid;
394 raw_inode->i_gid = inode->i_gid;
395 raw_inode->i_nlinks = inode->i_nlink;
396 raw_inode->i_size = inode->i_size;
397 raw_inode->i_time = inode->i_mtime;
398 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
399 raw_inode->i_zone[0] = inode->i_rdev;
400 else for (block = 0; block < 9; block++)
401 raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
402 inode->i_dirt=0;
403 bh->b_dirt=1;
404 return bh;
405 }
406
407 void minix_write_inode(struct inode * inode)
408 {
409 struct buffer_head *bh;
410 bh = minix_update_inode(inode);
411 brelse(bh);
412 }
413
414 int minix_sync_inode(struct inode * inode)
415 {
416 int err = 0;
417 struct buffer_head *bh;
418
419 bh = minix_update_inode(inode);
420 if (bh && bh->b_dirt)
421 {
422 ll_rw_block(WRITE, 1, &bh);
423 wait_on_buffer(bh);
424 if (bh->b_req && !bh->b_uptodate)
425 {
426 printk ("IO error syncing minix inode [%04x:%08lx]\n",
427 inode->i_dev, inode->i_ino);
428 err = -1;
429 }
430 }
431 else if (!bh)
432 err = -1;
433 brelse (bh);
434 return err;
435 }