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