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