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_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 memcpy_tofs(buf, &tmp, bufsiz);
548 }
549
550
551
552
553 static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr)
554 {
555 int tmp = inode->u.sysv_i.i_data[nr];
556 if (!tmp)
557 return 0;
558 return tmp + sb->sv_block_base;
559 }
560
561 static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert)
562 {
563 int tmp;
564
565 if (!bh)
566 return 0;
567 tmp = ((sysv_zone_t *) bh->b_data) [nr];
568 if (convert)
569 tmp = from_coh_ulong(tmp);
570 brelse(bh);
571 if (!tmp)
572 return 0;
573 return tmp + sb->sv_block_base;
574 }
575
576 int sysv_bmap(struct inode * inode,int block_nr)
577 {
578 unsigned int block = block_nr;
579 struct super_block * sb = inode->i_sb;
580 int convert;
581 int i;
582 struct buffer_head * bh;
583
584 if (block < 10)
585 return inode_bmap(sb,inode,block);
586 block -= 10;
587 convert = sb->sv_convert;
588 if (block < sb->sv_ind_per_block) {
589 i = inode_bmap(sb,inode,10);
590 if (!i)
591 return 0;
592 bh = bread(inode->i_dev,i,sb->sv_block_size);
593 return block_bmap(sb, bh, block, convert);
594 }
595 block -= sb->sv_ind_per_block;
596 if (block < sb->sv_ind_per_block_2) {
597 i = inode_bmap(sb,inode,11);
598 if (!i)
599 return 0;
600 bh = bread(inode->i_dev,i,sb->sv_block_size);
601 i = block_bmap(sb, bh, block >> sb->sv_ind_per_block_bits, convert);
602 if (!i)
603 return 0;
604 bh = bread(inode->i_dev,i,sb->sv_block_size);
605 return block_bmap(sb, bh, block & sb->sv_ind_per_block_1, convert);
606 }
607 block -= sb->sv_ind_per_block_2;
608 if (block < sb->sv_ind_per_block_3) {
609 i = inode_bmap(sb,inode,12);
610 if (!i)
611 return 0;
612 bh = bread(inode->i_dev,i,sb->sv_block_size);
613 i = block_bmap(sb, bh, block >> sb->sv_ind_per_block_2_bits, convert);
614 if (!i)
615 return 0;
616 bh = bread(inode->i_dev,i,sb->sv_block_size);
617 i = block_bmap(sb, bh, (block >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1,convert);
618 if (!i)
619 return 0;
620 bh = bread(inode->i_dev,i,sb->sv_block_size);
621 return block_bmap(sb, bh, block & sb->sv_ind_per_block_1, convert);
622 }
623 if ((int)block<0) {
624 printk("sysv_bmap: block<0");
625 return 0;
626 }
627 printk("sysv_bmap: block>big");
628 return 0;
629 }
630
631
632
633
634
635
636 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
637 {
638 struct super_block *sb;
639 unsigned long tmp;
640 unsigned long *p;
641 struct buffer_head * result;
642
643 sb = inode->i_sb;
644 p = inode->u.sysv_i.i_data + nr;
645 repeat:
646 tmp = *p;
647 if (tmp) {
648 result = sv_getblk(sb, inode->i_dev, tmp);
649 if (tmp == *p)
650 return result;
651 brelse(result);
652 goto repeat;
653 }
654 if (!create)
655 return NULL;
656 tmp = sysv_new_block(sb);
657 if (!tmp)
658 return NULL;
659 result = sv_getblk(sb, inode->i_dev, tmp);
660 if (*p) {
661 sysv_free_block(sb,tmp);
662 brelse(result);
663 goto repeat;
664 }
665 *p = tmp;
666 inode->i_ctime = CURRENT_TIME;
667 inode->i_dirt = 1;
668 return result;
669 }
670
671 static struct buffer_head * block_getblk(struct inode * inode,
672 struct buffer_head * bh, int nr, int create)
673 {
674 struct super_block *sb;
675 unsigned long tmp, block;
676 sysv_zone_t *p;
677 struct buffer_head * result;
678
679 if (!bh)
680 return NULL;
681 if (!buffer_uptodate(bh)) {
682 ll_rw_block(READ, 1, &bh);
683 wait_on_buffer(bh);
684 if (!buffer_uptodate(bh)) {
685 brelse(bh);
686 return NULL;
687 }
688 }
689 sb = inode->i_sb;
690 p = nr + (sysv_zone_t *) bh->b_data;
691 repeat:
692 block = tmp = *p;
693 if (sb->sv_convert)
694 block = from_coh_ulong(block);
695 if (tmp) {
696 result = sv_getblk(sb, bh->b_dev, block);
697 if (tmp == *p) {
698 brelse(bh);
699 return result;
700 }
701 brelse(result);
702 goto repeat;
703 }
704 if (!create) {
705 brelse(bh);
706 return NULL;
707 }
708 block = sysv_new_block(sb);
709 if (!block) {
710 brelse(bh);
711 return NULL;
712 }
713 result = sv_getblk(sb, bh->b_dev, block);
714 if (*p) {
715 sysv_free_block(sb,block);
716 brelse(result);
717 goto repeat;
718 }
719 *p = (sb->sv_convert ? to_coh_ulong(block) : block);
720 mark_buffer_dirty(bh, 1);
721 brelse(bh);
722 return result;
723 }
724
725 struct buffer_head * sysv_getblk(struct inode * inode, unsigned int block, int create)
726 {
727 struct super_block * sb = inode->i_sb;
728 struct buffer_head * bh;
729
730 if (block < 10)
731 return inode_getblk(inode,block,create);
732 block -= 10;
733 if (block < sb->sv_ind_per_block) {
734 bh = inode_getblk(inode,10,create);
735 return block_getblk(inode, bh, block, create);
736 }
737 block -= sb->sv_ind_per_block;
738 if (block < sb->sv_ind_per_block_2) {
739 bh = inode_getblk(inode,11,create);
740 bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_bits, create);
741 return block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create);
742 }
743 block -= sb->sv_ind_per_block_2;
744 if (block < sb->sv_ind_per_block_3) {
745 bh = inode_getblk(inode,12,create);
746 bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_2_bits, create);
747 bh = block_getblk(inode, bh, (block >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1, create);
748 return block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create);
749 }
750 if ((int)block<0) {
751 printk("sysv_getblk: block<0");
752 return NULL;
753 }
754 printk("sysv_getblk: block>big");
755 return NULL;
756 }
757
758 struct buffer_head * sysv_file_bread(struct inode * inode, int block, int create)
759 {
760 struct buffer_head * bh;
761
762 bh = sysv_getblk(inode,block,create);
763 if (!bh || buffer_uptodate(bh))
764 return bh;
765 ll_rw_block(READ, 1, &bh);
766 wait_on_buffer(bh);
767 if (buffer_uptodate(bh))
768 return bh;
769 brelse(bh);
770 return NULL;
771 }
772
773
774 static inline unsigned long read3byte (char * p)
775 {
776 return (unsigned long)(*(unsigned short *)p)
777 | (unsigned long)(*(unsigned char *)(p+2)) << 16;
778 }
779
780 static inline void write3byte (char * p, unsigned long val)
781 {
782 *(unsigned short *)p = (unsigned short) val;
783 *(unsigned char *)(p+2) = val >> 16;
784 }
785
786 static inline unsigned long coh_read3byte (char * p)
787 {
788 return (unsigned long)(*(unsigned char *)p) << 16
789 | (unsigned long)(*(unsigned short *)(p+1));
790 }
791
792 static inline void coh_write3byte (char * p, unsigned long val)
793 {
794 *(unsigned char *)p = val >> 16;
795 *(unsigned short *)(p+1) = (unsigned short) val;
796 }
797
798 void sysv_read_inode(struct inode * inode)
799 {
800 struct super_block * sb = inode->i_sb;
801 struct buffer_head * bh;
802 struct sysv_inode * raw_inode;
803 unsigned int block, ino;
804 umode_t mode;
805
806 ino = inode->i_ino;
807 inode->i_op = NULL;
808 inode->i_mode = 0;
809 if (!ino || ino > sb->sv_ninodes) {
810 printk("Bad inode number on dev %s"
811 ": %d is out of range\n",
812 kdevname(inode->i_dev), ino);
813 return;
814 }
815 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
816 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
817 printk("Major problem: unable to read inode from dev "
818 "%s\n",
819 kdevname(inode->i_dev));
820 return;
821 }
822 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
823 mode = raw_inode->i_mode;
824 if (sb->sv_kludge_symlinks)
825 mode = from_coh_imode(mode);
826
827 inode->i_mode = mode;
828 inode->i_uid = raw_inode->i_uid;
829 inode->i_gid = raw_inode->i_gid;
830 inode->i_nlink = raw_inode->i_nlink;
831 if (sb->sv_convert) {
832 inode->i_size = from_coh_ulong(raw_inode->i_size);
833 inode->i_atime = from_coh_ulong(raw_inode->i_atime);
834 inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);
835 inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);
836 } else {
837 inode->i_size = raw_inode->i_size;
838 inode->i_atime = raw_inode->i_atime;
839 inode->i_mtime = raw_inode->i_mtime;
840 inode->i_ctime = raw_inode->i_ctime;
841 }
842 inode->i_blocks = inode->i_blksize = 0;
843 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
844 inode->i_rdev = to_kdev_t(raw_inode->i_a.i_rdev);
845 else
846 if (sb->sv_convert)
847 for (block = 0; block < 10+1+1+1; block++)
848 inode->u.sysv_i.i_data[block] =
849 coh_read3byte(&raw_inode->i_a.i_addb[3*block]);
850 else
851 for (block = 0; block < 10+1+1+1; block++)
852 inode->u.sysv_i.i_data[block] =
853 read3byte(&raw_inode->i_a.i_addb[3*block]);
854 brelse(bh);
855 if (S_ISREG(inode->i_mode))
856 inode->i_op = &sysv_file_inode_operations;
857 else if (S_ISDIR(inode->i_mode))
858 inode->i_op = &sysv_dir_inode_operations;
859 else if (S_ISLNK(inode->i_mode))
860 inode->i_op = &sysv_symlink_inode_operations;
861 else if (S_ISCHR(inode->i_mode))
862 inode->i_op = &chrdev_inode_operations;
863 else if (S_ISBLK(inode->i_mode))
864 inode->i_op = &blkdev_inode_operations;
865 else if (S_ISFIFO(inode->i_mode))
866 init_fifo(inode);
867 }
868
869
870 extern int sysv_notify_change(struct inode *inode, struct iattr *attr)
871 {
872 int error;
873
874 if ((error = inode_change_ok(inode, attr)) != 0)
875 return error;
876
877 if (attr->ia_valid & ATTR_MODE)
878 if (inode->i_sb->sv_kludge_symlinks)
879 if (attr->ia_mode == COH_KLUDGE_SYMLINK_MODE)
880 attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;
881
882 inode_setattr(inode, attr);
883
884 return 0;
885 }
886
887 static struct buffer_head * sysv_update_inode(struct inode * inode)
888 {
889 struct super_block * sb = inode->i_sb;
890 struct buffer_head * bh;
891 struct sysv_inode * raw_inode;
892 unsigned int ino, block;
893 umode_t mode;
894
895 ino = inode->i_ino;
896 if (!ino || ino > sb->sv_ninodes) {
897 printk("Bad inode number on dev %s"
898 ": %d is out of range\n",
899 kdevname(inode->i_dev), ino);
900 inode->i_dirt = 0;
901 return 0;
902 }
903 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
904 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
905 printk("unable to read i-node block\n");
906 inode->i_dirt = 0;
907 return 0;
908 }
909 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
910 mode = inode->i_mode;
911 if (sb->sv_kludge_symlinks)
912 mode = to_coh_imode(mode);
913 raw_inode->i_mode = mode;
914 raw_inode->i_uid = inode->i_uid;
915 raw_inode->i_gid = inode->i_gid;
916 raw_inode->i_nlink = inode->i_nlink;
917 if (sb->sv_convert) {
918 raw_inode->i_size = to_coh_ulong(inode->i_size);
919 raw_inode->i_atime = to_coh_ulong(inode->i_atime);
920 raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);
921 raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);
922 } else {
923 raw_inode->i_size = inode->i_size;
924 raw_inode->i_atime = inode->i_atime;
925 raw_inode->i_mtime = inode->i_mtime;
926 raw_inode->i_ctime = inode->i_ctime;
927 }
928 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
929 raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev);
930 else
931 if (sb->sv_convert)
932 for (block = 0; block < 10+1+1+1; block++)
933 coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
934 else
935 for (block = 0; block < 10+1+1+1; block++)
936 write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
937 inode->i_dirt=0;
938 mark_buffer_dirty(bh, 1);
939 return bh;
940 }
941
942 void sysv_write_inode(struct inode * inode)
943 {
944 struct buffer_head *bh;
945 bh = sysv_update_inode(inode);
946 brelse(bh);
947 }
948
949 int sysv_sync_inode(struct inode * inode)
950 {
951 int err = 0;
952 struct buffer_head *bh;
953
954 bh = sysv_update_inode(inode);
955 if (bh && buffer_dirty(bh)) {
956 ll_rw_block(WRITE, 1, &bh);
957 wait_on_buffer(bh);
958 if (buffer_req(bh) && !buffer_uptodate(bh))
959 {
960 printk ("IO error syncing sysv inode ["
961 "%s:%08lx]\n",
962 kdevname(inode->i_dev), inode->i_ino);
963 err = -1;
964 }
965 }
966 else if (!bh)
967 err = -1;
968 brelse (bh);
969 return err;
970 }
971
972 #ifdef MODULE
973
974
975
976 static struct file_system_type sysv_fs_type[3] = {
977 {sysv_read_super, "xenix", 1, NULL},
978 {sysv_read_super, "sysv", 1, NULL},
979 {sysv_read_super, "coherent", 1, NULL}
980 };
981
982 int init_module(void)
983 {
984 int i;
985 int ouch;
986
987 for (i = 0; i < 3; i++) {
988 if ((ouch = register_filesystem(&sysv_fs_type[i])) != 0)
989 return ouch;
990 }
991 return 0;
992 }
993
994 void cleanup_module(void)
995 {
996 int i;
997
998 for (i = 0; i < 3; i++)
999
1000 unregister_filesystem(&sysv_fs_type[i]);
1001 }
1002
1003 #endif