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, int bufsiz)
228 {
229 struct statfs tmp;
230
231 tmp.f_type = MINIX_SUPER_MAGIC;
232 tmp.f_bsize = 1024;
233 tmp.f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
234 tmp.f_bfree = minix_count_free_blocks(sb);
235 tmp.f_bavail = tmp.f_bfree;
236 tmp.f_files = sb->u.minix_sb.s_ninodes;
237 tmp.f_ffree = minix_count_free_inodes(sb);
238 tmp.f_namelen = sb->u.minix_sb.s_namelen;
239 memcpy_tofs(buf, &tmp, bufsiz);
240 }
241
242 #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
243
244 static int block_bmap(struct buffer_head * bh, int nr)
245 {
246 int tmp;
247
248 if (!bh)
249 return 0;
250 tmp = ((unsigned short *) bh->b_data)[nr];
251 brelse(bh);
252 return tmp;
253 }
254
255 int minix_bmap(struct inode * inode,int block)
256 {
257 int i;
258
259 if (block<0) {
260 printk("minix_bmap: block<0");
261 return 0;
262 }
263 if (block >= 7+512+512*512) {
264 printk("minix_bmap: block>big");
265 return 0;
266 }
267 if (block < 7)
268 return inode_bmap(inode,block);
269 block -= 7;
270 if (block < 512) {
271 i = inode_bmap(inode,7);
272 if (!i)
273 return 0;
274 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
275 }
276 block -= 512;
277 i = inode_bmap(inode,8);
278 if (!i)
279 return 0;
280 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
281 if (!i)
282 return 0;
283 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
284 }
285
286 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
287 {
288 int tmp;
289 unsigned short *p;
290 struct buffer_head * result;
291
292 p = inode->u.minix_i.i_data + nr;
293 repeat:
294 tmp = *p;
295 if (tmp) {
296 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
297 if (tmp == *p)
298 return result;
299 brelse(result);
300 goto repeat;
301 }
302 if (!create)
303 return NULL;
304 tmp = minix_new_block(inode->i_sb);
305 if (!tmp)
306 return NULL;
307 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
308 if (*p) {
309 minix_free_block(inode->i_sb,tmp);
310 brelse(result);
311 goto repeat;
312 }
313 *p = tmp;
314 inode->i_ctime = CURRENT_TIME;
315 inode->i_dirt = 1;
316 return result;
317 }
318
319 static struct buffer_head * block_getblk(struct inode * inode,
320 struct buffer_head * bh, int nr, int create)
321 {
322 int tmp;
323 unsigned short *p;
324 struct buffer_head * result;
325
326 if (!bh)
327 return NULL;
328 if (!bh->b_uptodate) {
329 ll_rw_block(READ, 1, &bh);
330 wait_on_buffer(bh);
331 if (!bh->b_uptodate) {
332 brelse(bh);
333 return NULL;
334 }
335 }
336 p = nr + (unsigned short *) bh->b_data;
337 repeat:
338 tmp = *p;
339 if (tmp) {
340 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
341 if (tmp == *p) {
342 brelse(bh);
343 return result;
344 }
345 brelse(result);
346 goto repeat;
347 }
348 if (!create) {
349 brelse(bh);
350 return NULL;
351 }
352 tmp = minix_new_block(inode->i_sb);
353 if (!tmp) {
354 brelse(bh);
355 return NULL;
356 }
357 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
358 if (*p) {
359 minix_free_block(inode->i_sb,tmp);
360 brelse(result);
361 goto repeat;
362 }
363 *p = tmp;
364 mark_buffer_dirty(bh, 1);
365 brelse(bh);
366 return result;
367 }
368
369 struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
370 {
371 struct buffer_head * bh;
372
373 if (block<0) {
374 printk("minix_getblk: block<0");
375 return NULL;
376 }
377 if (block >= 7+512+512*512) {
378 printk("minix_getblk: block>big");
379 return NULL;
380 }
381 if (block < 7)
382 return inode_getblk(inode,block,create);
383 block -= 7;
384 if (block < 512) {
385 bh = inode_getblk(inode,7,create);
386 return block_getblk(inode, bh, block, create);
387 }
388 block -= 512;
389 bh = inode_getblk(inode,8,create);
390 bh = block_getblk(inode, bh, block>>9, create);
391 return block_getblk(inode, bh, block & 511, create);
392 }
393
394 struct buffer_head * minix_bread(struct inode * inode, int block, int create)
395 {
396 struct buffer_head * bh;
397
398 bh = minix_getblk(inode,block,create);
399 if (!bh || bh->b_uptodate)
400 return bh;
401 ll_rw_block(READ, 1, &bh);
402 wait_on_buffer(bh);
403 if (bh->b_uptodate)
404 return bh;
405 brelse(bh);
406 return NULL;
407 }
408
409 void minix_read_inode(struct inode * inode)
410 {
411 struct buffer_head * bh;
412 struct minix_inode * raw_inode;
413 int block, ino;
414
415 ino = inode->i_ino;
416 inode->i_op = NULL;
417 inode->i_mode = 0;
418 if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
419 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
420 inode->i_dev, ino);
421 return;
422 }
423 block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
424 inode->i_sb->u.minix_sb.s_zmap_blocks +
425 (ino-1)/MINIX_INODES_PER_BLOCK;
426 if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
427 printk("Major problem: unable to read inode from dev 0x%04x\n",
428 inode->i_dev);
429 return;
430 }
431 raw_inode = ((struct minix_inode *) bh->b_data) +
432 (ino-1)%MINIX_INODES_PER_BLOCK;
433 inode->i_mode = raw_inode->i_mode;
434 inode->i_uid = raw_inode->i_uid;
435 inode->i_gid = raw_inode->i_gid;
436 inode->i_nlink = raw_inode->i_nlinks;
437 inode->i_size = raw_inode->i_size;
438 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
439 inode->i_blocks = inode->i_blksize = 0;
440 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
441 inode->i_rdev = raw_inode->i_zone[0];
442 else for (block = 0; block < 9; block++)
443 inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
444 brelse(bh);
445 if (S_ISREG(inode->i_mode))
446 inode->i_op = &minix_file_inode_operations;
447 else if (S_ISDIR(inode->i_mode))
448 inode->i_op = &minix_dir_inode_operations;
449 else if (S_ISLNK(inode->i_mode))
450 inode->i_op = &minix_symlink_inode_operations;
451 else if (S_ISCHR(inode->i_mode))
452 inode->i_op = &chrdev_inode_operations;
453 else if (S_ISBLK(inode->i_mode))
454 inode->i_op = &blkdev_inode_operations;
455 else if (S_ISFIFO(inode->i_mode))
456 init_fifo(inode);
457 }
458
459 static struct buffer_head * minix_update_inode(struct inode * inode)
460 {
461 struct buffer_head * bh;
462 struct minix_inode * raw_inode;
463 int ino, block;
464
465 ino = inode->i_ino;
466 if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
467 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
468 inode->i_dev, ino);
469 inode->i_dirt = 0;
470 return 0;
471 }
472 block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
473 (ino-1)/MINIX_INODES_PER_BLOCK;
474 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
475 printk("unable to read i-node block\n");
476 inode->i_dirt = 0;
477 return 0;
478 }
479 raw_inode = ((struct minix_inode *)bh->b_data) +
480 (ino-1)%MINIX_INODES_PER_BLOCK;
481 raw_inode->i_mode = inode->i_mode;
482 raw_inode->i_uid = inode->i_uid;
483 raw_inode->i_gid = inode->i_gid;
484 raw_inode->i_nlinks = inode->i_nlink;
485 raw_inode->i_size = inode->i_size;
486 raw_inode->i_time = inode->i_mtime;
487 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
488 raw_inode->i_zone[0] = inode->i_rdev;
489 else for (block = 0; block < 9; block++)
490 raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
491 inode->i_dirt=0;
492 mark_buffer_dirty(bh, 1);
493 return bh;
494 }
495
496 void minix_write_inode(struct inode * inode)
497 {
498 struct buffer_head *bh;
499 bh = minix_update_inode(inode);
500 brelse(bh);
501 }
502
503 int minix_sync_inode(struct inode * inode)
504 {
505 int err = 0;
506 struct buffer_head *bh;
507
508 bh = minix_update_inode(inode);
509 if (bh && bh->b_dirt)
510 {
511 ll_rw_block(WRITE, 1, &bh);
512 wait_on_buffer(bh);
513 if (bh->b_req && !bh->b_uptodate)
514 {
515 printk ("IO error syncing minix inode [%04x:%08lx]\n",
516 inode->i_dev, inode->i_ino);
517 err = -1;
518 }
519 }
520 else if (!bh)
521 err = -1;
522 brelse (bh);
523 return err;
524 }
525
526 #ifdef MODULE
527
528 char kernel_version[] = UTS_RELEASE;
529
530 static struct file_system_type minix_fs_type = {
531 minix_read_super, "minix", 1, NULL
532 };
533
534 int init_module(void)
535 {
536 register_filesystem(&minix_fs_type);
537 return 0;
538 }
539
540 void cleanup_module(void)
541 {
542 unregister_filesystem(&minix_fs_type);
543 }
544
545 #endif
546