This source file includes following definitions.
- sysv_put_inode
- detected_bs512
- detected_bs1024
- detect_xenix
- detected_xenix
- detect_sysv4
- detected_sysv4
- detect_sysv2
- detected_sysv2
- detect_coherent
- detected_coherent
- sysv_read_super
- sysv_write_super
- sysv_put_super
- sysv_statfs
- inode_bmap
- block_bmap
- sysv_bmap
- inode_getblk
- block_getblk
- sysv_getblk
- sysv_file_bread
- read3byte
- write3byte
- coh_read3byte
- coh_write3byte
- sysv_read_inode
- sysv_notify_change
- sysv_update_inode
- sysv_write_inode
- sysv_sync_inode
- init_sysv_fs
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <linux/module.h>
24
25 #include <linux/sched.h>
26 #include <linux/kernel.h>
27 #include <linux/fs.h>
28 #include <linux/sysv_fs.h>
29 #include <linux/stat.h>
30 #include <linux/string.h>
31 #include <linux/locks.h>
32
33 #include <asm/segment.h>
34
35 void sysv_put_inode(struct inode *inode)
36 {
37 if (inode->i_nlink)
38 return;
39 inode->i_size = 0;
40 sysv_truncate(inode);
41 sysv_free_inode(inode);
42 }
43
44
45 static struct super_operations sysv_sops = {
46 sysv_read_inode,
47 sysv_notify_change,
48 sysv_write_inode,
49 sysv_put_inode,
50 sysv_put_super,
51 sysv_write_super,
52 sysv_statfs,
53 NULL
54 };
55
56
57
58
59
60
61
62
63
64
65 static void detected_bs512 (struct super_block *sb)
66 {
67 sb->sv_block_size = 512;
68 sb->sv_block_size_1 = 512-1;
69 sb->sv_block_size_bits = 9;
70 sb->sv_block_size_ratio = 2;
71 sb->sv_block_size_ratio_bits = 1;
72 sb->sv_inodes_per_block = 512/64;
73 sb->sv_inodes_per_block_1 = 512/64-1;
74 sb->sv_inodes_per_block_bits = 9-6;
75 sb->sv_toobig_block = 10 +
76 (sb->sv_ind_per_block = 512/4) +
77 (sb->sv_ind_per_block_2 = (512/4)*(512/4)) +
78 (sb->sv_ind_per_block_3 = (512/4)*(512/4)*(512/4));
79 sb->sv_ind_per_block_1 = 512/4-1;
80 sb->sv_ind_per_block_2_1 = (512/4)*(512/4)-1;
81 sb->sv_ind_per_block_2_bits = 2 *
82 (sb->sv_ind_per_block_bits = 9-2);
83 sb->sv_ind_per_block_block_size_1 = (512/4)*512-1;
84 sb->sv_ind_per_block_block_size_bits = (9-2)+9;
85 sb->sv_ind_per_block_2_block_size_1 = (512/4)*(512/4)*512-1;
86 sb->sv_ind_per_block_2_block_size_bits = (9-2)+(9-2)+9;
87 sb->sv_ind0_size = 10 * 512;
88 sb->sv_ind1_size = (10 + (512/4))* 512;
89 sb->sv_ind2_size = (10 + (512/4) + (512/4)*(512/4)) * 512;
90 }
91
92 static void detected_bs1024 (struct super_block *sb)
93 {
94 sb->sv_block_size = 1024;
95 sb->sv_block_size_1 = 1024-1;
96 sb->sv_block_size_bits = 10;
97 sb->sv_block_size_ratio = 1;
98 sb->sv_block_size_ratio_bits = 0;
99 sb->sv_inodes_per_block = 1024/64;
100 sb->sv_inodes_per_block_1 = 1024/64-1;
101 sb->sv_inodes_per_block_bits = 10-6;
102 sb->sv_toobig_block = 10 +
103 (sb->sv_ind_per_block = 1024/4) +
104 (sb->sv_ind_per_block_2 = (1024/4)*(1024/4)) +
105 (sb->sv_ind_per_block_3 = (1024/4)*(1024/4)*(1024/4));
106 sb->sv_ind_per_block_1 = 1024/4-1;
107 sb->sv_ind_per_block_2_1 = (1024/4)*(1024/4)-1;
108 sb->sv_ind_per_block_2_bits = 2 *
109 (sb->sv_ind_per_block_bits = 10-2);
110 sb->sv_ind_per_block_block_size_1 = (1024/4)*1024-1;
111 sb->sv_ind_per_block_block_size_bits = (10-2)+10;
112 sb->sv_ind_per_block_2_block_size_1 = (1024/4)*(1024/4)*1024-1;
113 sb->sv_ind_per_block_2_block_size_bits = (10-2)+(10-2)+10;
114 sb->sv_ind0_size = 10 * 1024;
115 sb->sv_ind1_size = (10 + (1024/4))* 1024;
116 sb->sv_ind2_size = (10 + (1024/4) + (1024/4)*(1024/4)) * 1024;
117 }
118
119 static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
120 {
121 struct xenix_super_block * sbd;
122
123 sbd = (struct xenix_super_block *) bh->b_data;
124 if (sbd->s_magic != 0x2b5544)
125 return NULL;
126 switch (sbd->s_type) {
127 case 1: detected_bs512(sb); break;
128 case 2: detected_bs1024(sb); break;
129 default: return NULL;
130 }
131 sb->sv_type = FSTYPE_XENIX;
132 return "Xenix";
133 }
134 static struct super_block * detected_xenix (struct super_block *sb, struct buffer_head *bh1, struct buffer_head *bh2)
135 {
136 struct xenix_super_block * sbd1;
137 struct xenix_super_block * sbd2;
138
139 if (sb->sv_block_size == BLOCK_SIZE)
140
141 sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
142 else {
143
144 sbd1 = (struct xenix_super_block *) bh1->b_data;
145 sbd2 = (struct xenix_super_block *) (bh2->b_data - BLOCK_SIZE/2);
146
147 if (sbd2->s_magic != 0x2b5544)
148 return NULL;
149 }
150
151 sb->sv_convert = 0;
152 sb->sv_kludge_symlinks = 1;
153 sb->sv_truncate = 1;
154 sb->sv_link_max = XENIX_LINK_MAX;
155 sb->sv_fic_size = XENIX_NICINOD;
156 sb->sv_flc_size = XENIX_NICFREE;
157 sb->sv_bh1 = bh1;
158 sb->sv_bh2 = bh2;
159 sb->sv_sbd1 = (char *) sbd1;
160 sb->sv_sbd2 = (char *) sbd2;
161 sb->sv_sb_fic_count = &sbd1->s_ninode;
162 sb->sv_sb_fic_inodes = &sbd1->s_inode[0];
163 sb->sv_sb_total_free_inodes = &sbd2->s_tinode;
164 sb->sv_sb_flc_count = &sbd1->s_nfree;
165 sb->sv_sb_flc_blocks = &sbd1->s_free[0];
166 sb->sv_sb_total_free_blocks = &sbd2->s_tfree;
167 sb->sv_sb_time = &sbd2->s_time;
168 sb->sv_block_base = 0;
169 sb->sv_firstinodezone = 2;
170 sb->sv_firstdatazone = sbd1->s_isize;
171 sb->sv_nzones = sbd1->s_fsize;
172 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
173 return sb;
174 }
175
176 static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
177 {
178 struct sysv4_super_block * sbd;
179
180 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
181 if (sbd->s_magic != 0xfd187e20)
182 return NULL;
183 if (sbd->s_time < 315532800)
184 return NULL;
185 switch (sbd->s_type) {
186 case 1: detected_bs512(sb); break;
187 case 2: detected_bs1024(sb); break;
188 default: return NULL;
189 }
190 sb->sv_type = FSTYPE_SYSV4;
191 return "SystemV";
192 }
193 static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh)
194 {
195 struct sysv4_super_block * sbd;
196
197 if (sb->sv_block_size == BLOCK_SIZE)
198 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
199 else {
200 sbd = (struct sysv4_super_block *) bh->b_data;
201
202 if (sbd->s_magic != 0xfd187e20)
203 return NULL;
204 if (sbd->s_time < 315532800)
205 return NULL;
206 }
207
208 sb->sv_convert = 0;
209 sb->sv_kludge_symlinks = 0;
210 sb->sv_truncate = 1;
211 sb->sv_link_max = SYSV_LINK_MAX;
212 sb->sv_fic_size = SYSV_NICINOD;
213 sb->sv_flc_size = SYSV_NICFREE;
214 sb->sv_bh1 = bh;
215 sb->sv_bh2 = bh;
216 sb->sv_sbd1 = (char *) sbd;
217 sb->sv_sbd2 = (char *) sbd;
218 sb->sv_sb_fic_count = &sbd->s_ninode;
219 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
220 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
221 sb->sv_sb_flc_count = &sbd->s_nfree;
222 sb->sv_sb_flc_blocks = &sbd->s_free[0];
223 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
224 sb->sv_sb_time = &sbd->s_time;
225 sb->sv_sb_state = &sbd->s_state;
226 sb->sv_block_base = 0;
227 sb->sv_firstinodezone = 2;
228 sb->sv_firstdatazone = sbd->s_isize;
229 sb->sv_nzones = sbd->s_fsize;
230 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
231 return sb;
232 }
233
234 static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh)
235 {
236 struct sysv2_super_block * sbd;
237
238 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
239 if (sbd->s_magic != 0xfd187e20)
240 return NULL;
241 if (sbd->s_time < 315532800)
242 return NULL;
243 switch (sbd->s_type) {
244 case 1: detected_bs512(sb); break;
245 case 2: detected_bs1024(sb); break;
246 default: return NULL;
247 }
248 sb->sv_type = FSTYPE_SYSV2;
249 return "SystemV Release 2";
250 }
251 static struct super_block * detected_sysv2 (struct super_block *sb, struct buffer_head *bh)
252 {
253 struct sysv2_super_block * sbd;
254
255 if (sb->sv_block_size == BLOCK_SIZE)
256 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
257 else {
258 sbd = (struct sysv2_super_block *) bh->b_data;
259
260 if (sbd->s_magic != 0xfd187e20)
261 return NULL;
262 if (sbd->s_time < 315532800)
263 return NULL;
264 }
265
266 sb->sv_convert = 0;
267 sb->sv_kludge_symlinks = 0;
268 sb->sv_truncate = 1;
269 sb->sv_link_max = SYSV_LINK_MAX;
270 sb->sv_fic_size = SYSV_NICINOD;
271 sb->sv_flc_size = SYSV_NICFREE;
272 sb->sv_bh1 = bh;
273 sb->sv_bh2 = bh;
274 sb->sv_sbd1 = (char *) sbd;
275 sb->sv_sbd2 = (char *) sbd;
276 sb->sv_sb_fic_count = &sbd->s_ninode;
277 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
278 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
279 sb->sv_sb_flc_count = &sbd->s_nfree;
280 sb->sv_sb_flc_blocks = &sbd->s_free[0];
281 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
282 sb->sv_sb_time = &sbd->s_time;
283 sb->sv_sb_state = &sbd->s_state;
284 sb->sv_block_base = 0;
285 sb->sv_firstinodezone = 2;
286 sb->sv_firstdatazone = sbd->s_isize;
287 sb->sv_nzones = sbd->s_fsize;
288 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
289 return sb;
290 }
291
292 static const char* detect_coherent (struct super_block *sb, struct buffer_head *bh)
293 {
294 struct coh_super_block * sbd;
295
296 sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);
297 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
298 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
299 return NULL;
300 detected_bs512(sb);
301 sb->sv_type = FSTYPE_COH;
302 return "Coherent";
303 }
304 static struct super_block * detected_coherent (struct super_block *sb, struct buffer_head *bh)
305 {
306 struct coh_super_block * sbd;
307
308 sbd = (struct coh_super_block *) bh->b_data;
309
310 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
311 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
312 return NULL;
313
314 sb->sv_convert = 1;
315 sb->sv_kludge_symlinks = 1;
316 sb->sv_truncate = 1;
317 sb->sv_link_max = COH_LINK_MAX;
318 sb->sv_fic_size = COH_NICINOD;
319 sb->sv_flc_size = COH_NICFREE;
320 sb->sv_bh1 = bh;
321 sb->sv_bh2 = bh;
322 sb->sv_sbd1 = (char *) sbd;
323 sb->sv_sbd2 = (char *) sbd;
324 sb->sv_sb_fic_count = &sbd->s_ninode;
325 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
326 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
327 sb->sv_sb_flc_count = &sbd->s_nfree;
328 sb->sv_sb_flc_blocks = &sbd->s_free[0];
329 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
330 sb->sv_sb_time = &sbd->s_time;
331 sb->sv_block_base = 0;
332 sb->sv_firstinodezone = 2;
333 sb->sv_firstdatazone = sbd->s_isize;
334 sb->sv_nzones = from_coh_ulong(sbd->s_fsize);
335 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
336 return sb;
337 }
338
339 struct super_block *sysv_read_super(struct super_block *sb,void *data,
340 int silent)
341 {
342 struct buffer_head *bh;
343 const char *found;
344 kdev_t dev = sb->s_dev;
345
346 if (1024 != sizeof (struct xenix_super_block))
347 panic("Xenix FS: bad super-block size");
348 if ((512 != sizeof (struct sysv4_super_block))
349 || (512 != sizeof (struct sysv2_super_block)))
350 panic("SystemV FS: bad super-block size");
351 if (500 != sizeof (struct coh_super_block))
352 panic("Coherent FS: bad super-block size");
353 if (64 != sizeof (struct sysv_inode))
354 panic("sysv fs: bad i-node size");
355 MOD_INC_USE_COUNT;
356 lock_super(sb);
357 set_blocksize(dev,BLOCK_SIZE);
358
359
360 if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
361 if ((found = detect_xenix(sb,bh)) != NULL)
362 goto ok;
363 brelse(bh);
364 }
365 if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {
366
367 if ((found = detect_sysv4(sb,bh)) != NULL)
368 goto ok;
369 if ((found = detect_sysv2(sb,bh)) != NULL)
370 goto ok;
371
372 if ((found = detect_coherent(sb,bh)) != NULL)
373 goto ok;
374 brelse(bh);
375 }
376
377
378 { static int offsets[] = { 9, 15, 18, };
379 int i;
380 for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
381 if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
382
383 if ((found = detect_sysv4(sb,bh)) != NULL) {
384 sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
385 goto ok;
386 }
387 if ((found = detect_sysv2(sb,bh)) != NULL) {
388 sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
389 goto ok;
390 }
391 brelse(bh);
392 }
393 }
394 sb->s_dev = 0;
395 unlock_super(sb);
396 if (!silent)
397 printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
398 "%s\n", kdevname(dev));
399 failed:
400 MOD_DEC_USE_COUNT;
401 return NULL;
402
403 ok:
404 if (sb->sv_block_size == BLOCK_SIZE) {
405 switch (sb->sv_type) {
406 case FSTYPE_XENIX:
407 if (!detected_xenix(sb,bh,bh))
408 goto bad_superblock;
409 break;
410 case FSTYPE_SYSV4:
411 if (!detected_sysv4(sb,bh))
412 goto bad_superblock;
413 break;
414 case FSTYPE_SYSV2:
415 if (!detected_sysv2(sb,bh))
416 goto bad_superblock;
417 break;
418 default:
419 bad_superblock:
420 brelse(bh);
421 sb->s_dev = 0;
422 unlock_super(sb);
423 printk("SysV FS: cannot read superblock in 1024 byte mode\n");
424 goto failed;
425 }
426 } else {
427
428
429 struct buffer_head *bh1, *bh2;
430 unsigned long blocknr = bh->b_blocknr << sb->sv_block_size_ratio_bits;
431
432 brelse(bh);
433 set_blocksize(dev,sb->sv_block_size);
434 bh1 = NULL; bh2 = NULL;
435 switch (sb->sv_type) {
436 case FSTYPE_XENIX:
437 if ((bh1 = bread(dev, blocknr, sb->sv_block_size)) == NULL)
438 goto bad_superblock2;
439 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
440 goto bad_superblock2;
441 if (!detected_xenix(sb,bh1,bh2))
442 goto bad_superblock2;
443 break;
444 case FSTYPE_SYSV4:
445 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
446 goto bad_superblock2;
447 if (!detected_sysv4(sb,bh2))
448 goto bad_superblock2;
449 break;
450 case FSTYPE_SYSV2:
451 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
452 goto bad_superblock2;
453 if (!detected_sysv2(sb,bh2))
454 goto bad_superblock2;
455 break;
456 case FSTYPE_COH:
457 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
458 goto bad_superblock2;
459 if (!detected_coherent(sb,bh2))
460 goto bad_superblock2;
461 break;
462 default:
463 bad_superblock2:
464 brelse(bh1);
465 brelse(bh2);
466 set_blocksize(sb->s_dev,BLOCK_SIZE);
467 sb->s_dev = 0;
468 unlock_super(sb);
469 printk("SysV FS: cannot read superblock in 512 byte mode\n");
470 goto failed;
471 }
472 }
473 sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
474 if (!silent)
475 printk("VFS: Found a %s FS (block size = %d) on device %s\n",
476 found, sb->sv_block_size, kdevname(dev));
477 sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;
478
479 sb->s_blocksize = sb->sv_block_size;
480 sb->s_blocksize_bits = sb->sv_block_size_bits;
481
482 sb->s_dev = dev;
483 sb->s_op = &sysv_sops;
484 sb->s_mounted = iget(sb,SYSV_ROOT_INO);
485 unlock_super(sb);
486 if (!sb->s_mounted) {
487 printk("SysV FS: get root inode failed\n");
488 sysv_put_super(sb);
489 return NULL;
490 }
491 sb->s_dirt = 1;
492
493
494 return sb;
495 }
496
497
498 void sysv_write_super (struct super_block *sb)
499 {
500 lock_super(sb);
501 if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {
502
503
504
505 unsigned long time = CURRENT_TIME;
506 unsigned long old_time = *sb->sv_sb_time;
507 if (sb->sv_convert)
508 old_time = from_coh_ulong(old_time);
509 if (sb->sv_type == FSTYPE_SYSV4)
510 if (*sb->sv_sb_state == 0x7c269d38 - old_time)
511 *sb->sv_sb_state = 0x7c269d38 - time;
512 if (sb->sv_convert)
513 time = to_coh_ulong(time);
514 *sb->sv_sb_time = time;
515 mark_buffer_dirty(sb->sv_bh2, 1);
516 }
517 sb->s_dirt = 0;
518 unlock_super(sb);
519 }
520
521 void sysv_put_super(struct super_block *sb)
522 {
523
524 lock_super(sb);
525 brelse(sb->sv_bh1);
526 if (sb->sv_bh1 != sb->sv_bh2) brelse(sb->sv_bh2);
527
528 if (sb->s_blocksize != BLOCK_SIZE)
529 set_blocksize(sb->s_dev,BLOCK_SIZE);
530 sb->s_dev = 0;
531 unlock_super(sb);
532 MOD_DEC_USE_COUNT;
533 }
534
535 void sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
536 {
537 struct statfs tmp;
538
539 tmp.f_type = sb->s_magic;
540 tmp.f_bsize = sb->sv_block_size;
541 tmp.f_blocks = sb->sv_ndatazones;
542 tmp.f_bfree = sysv_count_free_blocks(sb);
543 tmp.f_bavail = tmp.f_bfree;
544 tmp.f_files = sb->sv_ninodes;
545 tmp.f_ffree = sysv_count_free_inodes(sb);
546 tmp.f_namelen = SYSV_NAMELEN;
547
548 memcpy_tofs(buf, &tmp, bufsiz);
549 }
550
551
552
553
554 static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr)
555 {
556 int tmp = inode->u.sysv_i.i_data[nr];
557 if (!tmp)
558 return 0;
559 return tmp + sb->sv_block_base;
560 }
561
562 static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert)
563 {
564 int tmp;
565
566 if (!bh)
567 return 0;
568 tmp = ((sysv_zone_t *) bh->b_data) [nr];
569 if (convert)
570 tmp = from_coh_ulong(tmp);
571 brelse(bh);
572 if (!tmp)
573 return 0;
574 return tmp + sb->sv_block_base;
575 }
576
577 int sysv_bmap(struct inode * inode,int block_nr)
578 {
579 unsigned int block = block_nr;
580 struct super_block * sb = inode->i_sb;
581 int convert;
582 int i;
583 struct buffer_head * bh;
584
585 if (block < 10)
586 return inode_bmap(sb,inode,block);
587 block -= 10;
588 convert = sb->sv_convert;
589 if (block < sb->sv_ind_per_block) {
590 i = inode_bmap(sb,inode,10);
591 if (!i)
592 return 0;
593 bh = bread(inode->i_dev,i,sb->sv_block_size);
594 return block_bmap(sb, bh, block, convert);
595 }
596 block -= sb->sv_ind_per_block;
597 if (block < sb->sv_ind_per_block_2) {
598 i = inode_bmap(sb,inode,11);
599 if (!i)
600 return 0;
601 bh = bread(inode->i_dev,i,sb->sv_block_size);
602 i = block_bmap(sb, bh, block >> sb->sv_ind_per_block_bits, convert);
603 if (!i)
604 return 0;
605 bh = bread(inode->i_dev,i,sb->sv_block_size);
606 return block_bmap(sb, bh, block & sb->sv_ind_per_block_1, convert);
607 }
608 block -= sb->sv_ind_per_block_2;
609 if (block < sb->sv_ind_per_block_3) {
610 i = inode_bmap(sb,inode,12);
611 if (!i)
612 return 0;
613 bh = bread(inode->i_dev,i,sb->sv_block_size);
614 i = block_bmap(sb, bh, block >> sb->sv_ind_per_block_2_bits, convert);
615 if (!i)
616 return 0;
617 bh = bread(inode->i_dev,i,sb->sv_block_size);
618 i = block_bmap(sb, bh, (block >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1,convert);
619 if (!i)
620 return 0;
621 bh = bread(inode->i_dev,i,sb->sv_block_size);
622 return block_bmap(sb, bh, block & sb->sv_ind_per_block_1, convert);
623 }
624 if ((int)block<0) {
625 printk("sysv_bmap: block<0");
626 return 0;
627 }
628 printk("sysv_bmap: block>big");
629 return 0;
630 }
631
632
633
634
635
636
637 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
638 {
639 struct super_block *sb;
640 unsigned long tmp;
641 unsigned long *p;
642 struct buffer_head * result;
643
644 sb = inode->i_sb;
645 p = inode->u.sysv_i.i_data + nr;
646 repeat:
647 tmp = *p;
648 if (tmp) {
649 result = sv_getblk(sb, inode->i_dev, tmp);
650 if (tmp == *p)
651 return result;
652 brelse(result);
653 goto repeat;
654 }
655 if (!create)
656 return NULL;
657 tmp = sysv_new_block(sb);
658 if (!tmp)
659 return NULL;
660 result = sv_getblk(sb, inode->i_dev, tmp);
661 if (*p) {
662 sysv_free_block(sb,tmp);
663 brelse(result);
664 goto repeat;
665 }
666 *p = tmp;
667 inode->i_ctime = CURRENT_TIME;
668 inode->i_dirt = 1;
669 return result;
670 }
671
672 static struct buffer_head * block_getblk(struct inode * inode,
673 struct buffer_head * bh, int nr, int create)
674 {
675 struct super_block *sb;
676 unsigned long tmp, block;
677 sysv_zone_t *p;
678 struct buffer_head * result;
679
680 if (!bh)
681 return NULL;
682 if (!buffer_uptodate(bh)) {
683 ll_rw_block(READ, 1, &bh);
684 wait_on_buffer(bh);
685 if (!buffer_uptodate(bh)) {
686 brelse(bh);
687 return NULL;
688 }
689 }
690 sb = inode->i_sb;
691 p = nr + (sysv_zone_t *) bh->b_data;
692 repeat:
693 block = tmp = *p;
694 if (sb->sv_convert)
695 block = from_coh_ulong(block);
696 if (tmp) {
697 result = sv_getblk(sb, bh->b_dev, block);
698 if (tmp == *p) {
699 brelse(bh);
700 return result;
701 }
702 brelse(result);
703 goto repeat;
704 }
705 if (!create) {
706 brelse(bh);
707 return NULL;
708 }
709 block = sysv_new_block(sb);
710 if (!block) {
711 brelse(bh);
712 return NULL;
713 }
714 result = sv_getblk(sb, bh->b_dev, block);
715 if (*p) {
716 sysv_free_block(sb,block);
717 brelse(result);
718 goto repeat;
719 }
720 *p = (sb->sv_convert ? to_coh_ulong(block) : block);
721 mark_buffer_dirty(bh, 1);
722 brelse(bh);
723 return result;
724 }
725
726 struct buffer_head * sysv_getblk(struct inode * inode, unsigned int block, int create)
727 {
728 struct super_block * sb = inode->i_sb;
729 struct buffer_head * bh;
730
731 if (block < 10)
732 return inode_getblk(inode,block,create);
733 block -= 10;
734 if (block < sb->sv_ind_per_block) {
735 bh = inode_getblk(inode,10,create);
736 return block_getblk(inode, bh, block, create);
737 }
738 block -= sb->sv_ind_per_block;
739 if (block < sb->sv_ind_per_block_2) {
740 bh = inode_getblk(inode,11,create);
741 bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_bits, create);
742 return block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create);
743 }
744 block -= sb->sv_ind_per_block_2;
745 if (block < sb->sv_ind_per_block_3) {
746 bh = inode_getblk(inode,12,create);
747 bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_2_bits, create);
748 bh = block_getblk(inode, bh, (block >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1, create);
749 return block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create);
750 }
751 if ((int)block<0) {
752 printk("sysv_getblk: block<0");
753 return NULL;
754 }
755 printk("sysv_getblk: block>big");
756 return NULL;
757 }
758
759 struct buffer_head * sysv_file_bread(struct inode * inode, int block, int create)
760 {
761 struct buffer_head * bh;
762
763 bh = sysv_getblk(inode,block,create);
764 if (!bh || buffer_uptodate(bh))
765 return bh;
766 ll_rw_block(READ, 1, &bh);
767 wait_on_buffer(bh);
768 if (buffer_uptodate(bh))
769 return bh;
770 brelse(bh);
771 return NULL;
772 }
773
774
775 static inline unsigned long read3byte (char * p)
776 {
777 return (unsigned long)(*(unsigned short *)p)
778 | (unsigned long)(*(unsigned char *)(p+2)) << 16;
779 }
780
781 static inline void write3byte (char * p, unsigned long val)
782 {
783 *(unsigned short *)p = (unsigned short) val;
784 *(unsigned char *)(p+2) = val >> 16;
785 }
786
787 static inline unsigned long coh_read3byte (char * p)
788 {
789 return (unsigned long)(*(unsigned char *)p) << 16
790 | (unsigned long)(*(unsigned short *)(p+1));
791 }
792
793 static inline void coh_write3byte (char * p, unsigned long val)
794 {
795 *(unsigned char *)p = val >> 16;
796 *(unsigned short *)(p+1) = (unsigned short) val;
797 }
798
799 void sysv_read_inode(struct inode * inode)
800 {
801 struct super_block * sb = inode->i_sb;
802 struct buffer_head * bh;
803 struct sysv_inode * raw_inode;
804 unsigned int block, ino;
805 umode_t mode;
806
807 ino = inode->i_ino;
808 inode->i_op = NULL;
809 inode->i_mode = 0;
810 if (!ino || ino > sb->sv_ninodes) {
811 printk("Bad inode number on dev %s"
812 ": %d is out of range\n",
813 kdevname(inode->i_dev), ino);
814 return;
815 }
816 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
817 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
818 printk("Major problem: unable to read inode from dev "
819 "%s\n",
820 kdevname(inode->i_dev));
821 return;
822 }
823 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
824 mode = raw_inode->i_mode;
825 if (sb->sv_kludge_symlinks)
826 mode = from_coh_imode(mode);
827
828 inode->i_mode = mode;
829 inode->i_uid = raw_inode->i_uid;
830 inode->i_gid = raw_inode->i_gid;
831 inode->i_nlink = raw_inode->i_nlink;
832 if (sb->sv_convert) {
833 inode->i_size = from_coh_ulong(raw_inode->i_size);
834 inode->i_atime = from_coh_ulong(raw_inode->i_atime);
835 inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);
836 inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);
837 } else {
838 inode->i_size = raw_inode->i_size;
839 inode->i_atime = raw_inode->i_atime;
840 inode->i_mtime = raw_inode->i_mtime;
841 inode->i_ctime = raw_inode->i_ctime;
842 }
843 inode->i_blocks = inode->i_blksize = 0;
844 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
845 inode->i_rdev = to_kdev_t(raw_inode->i_a.i_rdev);
846 else
847 if (sb->sv_convert)
848 for (block = 0; block < 10+1+1+1; block++)
849 inode->u.sysv_i.i_data[block] =
850 coh_read3byte(&raw_inode->i_a.i_addb[3*block]);
851 else
852 for (block = 0; block < 10+1+1+1; block++)
853 inode->u.sysv_i.i_data[block] =
854 read3byte(&raw_inode->i_a.i_addb[3*block]);
855 brelse(bh);
856 if (S_ISREG(inode->i_mode))
857 inode->i_op = &sysv_file_inode_operations;
858 else if (S_ISDIR(inode->i_mode))
859 inode->i_op = &sysv_dir_inode_operations;
860 else if (S_ISLNK(inode->i_mode))
861 inode->i_op = &sysv_symlink_inode_operations;
862 else if (S_ISCHR(inode->i_mode))
863 inode->i_op = &chrdev_inode_operations;
864 else if (S_ISBLK(inode->i_mode))
865 inode->i_op = &blkdev_inode_operations;
866 else if (S_ISFIFO(inode->i_mode))
867 init_fifo(inode);
868 }
869
870
871 extern int sysv_notify_change(struct inode *inode, struct iattr *attr)
872 {
873 int error;
874
875 if ((error = inode_change_ok(inode, attr)) != 0)
876 return error;
877
878 if (attr->ia_valid & ATTR_MODE)
879 if (inode->i_sb->sv_kludge_symlinks)
880 if (attr->ia_mode == COH_KLUDGE_SYMLINK_MODE)
881 attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;
882
883 inode_setattr(inode, attr);
884
885 return 0;
886 }
887
888 static struct buffer_head * sysv_update_inode(struct inode * inode)
889 {
890 struct super_block * sb = inode->i_sb;
891 struct buffer_head * bh;
892 struct sysv_inode * raw_inode;
893 unsigned int ino, block;
894 umode_t mode;
895
896 ino = inode->i_ino;
897 if (!ino || ino > sb->sv_ninodes) {
898 printk("Bad inode number on dev %s"
899 ": %d is out of range\n",
900 kdevname(inode->i_dev), ino);
901 inode->i_dirt = 0;
902 return 0;
903 }
904 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
905 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
906 printk("unable to read i-node block\n");
907 inode->i_dirt = 0;
908 return 0;
909 }
910 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
911 mode = inode->i_mode;
912 if (sb->sv_kludge_symlinks)
913 mode = to_coh_imode(mode);
914 raw_inode->i_mode = mode;
915 raw_inode->i_uid = inode->i_uid;
916 raw_inode->i_gid = inode->i_gid;
917 raw_inode->i_nlink = inode->i_nlink;
918 if (sb->sv_convert) {
919 raw_inode->i_size = to_coh_ulong(inode->i_size);
920 raw_inode->i_atime = to_coh_ulong(inode->i_atime);
921 raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);
922 raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);
923 } else {
924 raw_inode->i_size = inode->i_size;
925 raw_inode->i_atime = inode->i_atime;
926 raw_inode->i_mtime = inode->i_mtime;
927 raw_inode->i_ctime = inode->i_ctime;
928 }
929 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
930 raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev);
931 else
932 if (sb->sv_convert)
933 for (block = 0; block < 10+1+1+1; block++)
934 coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
935 else
936 for (block = 0; block < 10+1+1+1; block++)
937 write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
938 inode->i_dirt=0;
939 mark_buffer_dirty(bh, 1);
940 return bh;
941 }
942
943 void sysv_write_inode(struct inode * inode)
944 {
945 struct buffer_head *bh;
946 bh = sysv_update_inode(inode);
947 brelse(bh);
948 }
949
950 int sysv_sync_inode(struct inode * inode)
951 {
952 int err = 0;
953 struct buffer_head *bh;
954
955 bh = sysv_update_inode(inode);
956 if (bh && buffer_dirty(bh)) {
957 ll_rw_block(WRITE, 1, &bh);
958 wait_on_buffer(bh);
959 if (buffer_req(bh) && !buffer_uptodate(bh))
960 {
961 printk ("IO error syncing sysv inode ["
962 "%s:%08lx]\n",
963 kdevname(inode->i_dev), inode->i_ino);
964 err = -1;
965 }
966 }
967 else if (!bh)
968 err = -1;
969 brelse (bh);
970 return err;
971 }
972
973
974
975 static struct file_system_type sysv_fs_type[3] = {
976 {sysv_read_super, "xenix", 1, NULL},
977 {sysv_read_super, "sysv", 1, NULL},
978 {sysv_read_super, "coherent", 1, NULL}
979 };
980
981 int init_sysv_fs(void)
982 {
983 int i;
984 int ouch;
985
986 for (i = 0; i < 3; i++) {
987 if ((ouch = register_filesystem(&sysv_fs_type[i])) != 0)
988 return ouch;
989 }
990 return ouch;
991 }
992
993 #ifdef MODULE
994 int init_module(void)
995 {
996 int status;
997
998 if ((status = init_sysv_fs()) == 0)
999 register_symtab(0);
1000 return status;
1001 }
1002
1003 void cleanup_module(void)
1004 {
1005 int i;
1006
1007 for (i = 0; i < 3; i++)
1008
1009 unregister_filesystem(&sysv_fs_type[i]);
1010 }
1011
1012 #endif