Import 2.3.7pre9
[davej-history.git] / fs / sysv / inode.c
blobd335b5b501ec352398252d0b5b2d2c92297b3ce6
1 /*
2 * linux/fs/sysv/inode.c
4 * minix/inode.c
5 * Copyright (C) 1991, 1992 Linus Torvalds
7 * xenix/inode.c
8 * Copyright (C) 1992 Doug Evans
10 * coh/inode.c
11 * Copyright (C) 1993 Pascal Haible, Bruno Haible
13 * sysv/inode.c
14 * Copyright (C) 1993 Paul B. Monday
16 * sysv/inode.c
17 * Copyright (C) 1993 Bruno Haible
18 * Copyright (C) 1997, 1998 Krzysztof G. Baranowski
20 * This file contains code for allocating/freeing inodes and for read/writing
21 * the superblock.
24 #include <linux/module.h>
26 #include <linux/sched.h>
27 #include <linux/kernel.h>
28 #include <linux/fs.h>
29 #include <linux/sysv_fs.h>
30 #include <linux/stat.h>
31 #include <linux/string.h>
32 #include <linux/locks.h>
33 #include <linux/init.h>
34 #include <asm/byteorder.h>
35 #include <asm/uaccess.h>
37 #if 0
38 void sysv_print_inode(struct inode * inode)
40 printk("ino %lu mode 0%6.6o lk %d uid %d gid %d"
41 " sz %lu blks %lu cnt %u\n",
42 inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,
43 inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count);
44 printk(" db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"
45 " 0x%lx 0x%lx>\n",
46 inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],
47 inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],
48 inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],
49 inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],
50 inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);
51 printk(" ib <0x%lx 0x%lx 0x%lx>\n",
52 inode->u.sysv_i.i_data[10],
53 inode->u.sysv_i.i_data[11],
54 inode->u.sysv_i.i_data[12]);
56 #endif
58 static void sysv_delete_inode(struct inode *inode)
60 inode->i_size = 0;
61 sysv_truncate(inode);
62 sysv_free_inode(inode);
66 static struct super_operations sysv_sops = {
67 sysv_read_inode,
68 sysv_write_inode,
69 NULL, /* nothing special on put_inode() */
70 sysv_delete_inode,
71 sysv_notify_change,
72 sysv_put_super,
73 sysv_write_super,
74 sysv_statfs,
75 NULL /* remount_fs */
78 /* The following functions try to recognize specific filesystems.
79 * We recognize:
80 * - Xenix FS by its magic number.
81 * - SystemV FS by its magic number.
82 * - Coherent FS by its funny fname/fpack field.
83 * We discriminate among SystemV4 and SystemV2 FS by the assumption that
84 * the time stamp is not < 01-01-1980.
87 static void detected_bs (u_char type, struct super_block *sb)
89 u_char n_bits = type+8;
90 int bsize = 1 << n_bits;
91 int bsize_4 = bsize >> 2;
93 sb->sv_block_size = bsize;
94 sb->sv_block_size_1 = bsize-1;
95 sb->sv_block_size_bits = n_bits;
96 sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
97 sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
98 sb->sv_inodes_per_block = bsize >> 6;
99 sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
100 sb->sv_inodes_per_block_bits = n_bits-6;
101 sb->sv_toobig_block = 10 +
102 (sb->sv_ind_per_block = bsize_4) +
103 (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
104 (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
105 sb->sv_ind_per_block_1 = bsize_4-1;
106 sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
107 sb->sv_ind_per_block_2_bits = 2 *
108 (sb->sv_ind_per_block_bits = n_bits-2);
109 sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
110 sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
111 sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
112 sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
113 sb->sv_ind0_size = 10 * bsize;
114 sb->sv_ind1_size = (10 + bsize_4)* bsize;
115 sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
118 static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
120 struct xenix_super_block * sbd;
122 sbd = (struct xenix_super_block *) bh->b_data;
123 if (sbd->s_magic != 0x2b5544)
124 return NULL;
125 if (sbd->s_type > 2 || sbd->s_type < 1)
126 return NULL;
127 detected_bs(sbd->s_type, sb);
128 sb->sv_type = FSTYPE_XENIX;
129 return "Xenix";
131 static struct super_block * detected_xenix (struct super_block *sb, struct buffer_head *bh1, struct buffer_head *bh2)
133 struct xenix_super_block * sbd1;
134 struct xenix_super_block * sbd2;
136 if (sb->sv_block_size >= BLOCK_SIZE)
137 /* block size >= 1024, so bh1 = bh2 */
138 sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
139 else {
140 /* block size = 512, so bh1 != bh2 */
141 sbd1 = (struct xenix_super_block *) bh1->b_data;
142 sbd2 = (struct xenix_super_block *) (bh2->b_data - BLOCK_SIZE/2);
143 /* sanity check */
144 if (sbd2->s_magic != 0x2b5544)
145 return NULL;
148 sb->sv_convert = 0;
149 sb->sv_kludge_symlinks = 1;
150 sb->sv_truncate = 1;
151 sb->sv_link_max = XENIX_LINK_MAX;
152 sb->sv_fic_size = XENIX_NICINOD;
153 sb->sv_flc_size = XENIX_NICFREE;
154 sb->sv_bh1 = bh1;
155 sb->sv_bh2 = bh2;
156 sb->sv_sbd1 = (char *) sbd1;
157 sb->sv_sbd2 = (char *) sbd2;
158 sb->sv_sb_fic_count = &sbd1->s_ninode;
159 sb->sv_sb_fic_inodes = &sbd1->s_inode[0];
160 sb->sv_sb_total_free_inodes = &sbd2->s_tinode;
161 sb->sv_sb_flc_count = &sbd1->s_nfree;
162 sb->sv_sb_flc_blocks = &sbd1->s_free[0];
163 sb->sv_sb_total_free_blocks = &sbd2->s_tfree;
164 sb->sv_sb_time = &sbd2->s_time;
165 sb->sv_firstinodezone = 2;
166 sb->sv_firstdatazone = sbd1->s_isize;
167 sb->sv_nzones = sbd1->s_fsize;
168 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
169 return sb;
172 static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
174 struct sysv4_super_block * sbd;
176 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
177 if (sbd->s_magic != 0xfd187e20)
178 return NULL;
179 if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
180 return NULL;
181 if ((sbd->s_type > 3 || sbd->s_type < 1) && (sbd->s_type > 0x30 || sbd->s_type < 0x10))
182 return NULL;
184 /* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
185 0x20 or 0x30 indicates that symbolic links and the 14-character
186 filename limit is gone. Due to lack of information about this
187 feature read-only mode seems to be a reasonable approach... -KGB */
189 if (sbd->s_type >= 0x10) {
190 printk("SysV FS: can't handle long file names on %s, "
191 "forcing read-only mode.\n", kdevname(sb->s_dev));
192 sb->s_flags |= MS_RDONLY;
195 detected_bs(sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type, sb);
196 sb->sv_type = FSTYPE_SYSV4;
197 return "SystemV";
200 static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh)
202 struct sysv4_super_block * sbd;
204 if (sb->sv_block_size >= BLOCK_SIZE)
205 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
206 else {
207 sbd = (struct sysv4_super_block *) bh->b_data;
208 /* sanity check */
209 if (sbd->s_magic != 0xfd187e20)
210 return NULL;
211 if (sbd->s_time < 315532800)
212 return NULL;
215 sb->sv_convert = 0;
216 sb->sv_kludge_symlinks = 0; /* ?? */
217 sb->sv_truncate = 1;
218 sb->sv_link_max = SYSV_LINK_MAX;
219 sb->sv_fic_size = SYSV_NICINOD;
220 sb->sv_flc_size = SYSV_NICFREE;
221 sb->sv_bh1 = bh;
222 sb->sv_bh2 = bh;
223 sb->sv_sbd1 = (char *) sbd;
224 sb->sv_sbd2 = (char *) sbd;
225 sb->sv_sb_fic_count = &sbd->s_ninode;
226 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
227 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
228 sb->sv_sb_flc_count = &sbd->s_nfree;
229 sb->sv_sb_flc_blocks = &sbd->s_free[0];
230 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
231 sb->sv_sb_time = &sbd->s_time;
232 sb->sv_sb_state = &sbd->s_state;
233 sb->sv_firstinodezone = 2;
234 sb->sv_firstdatazone = sbd->s_isize;
235 sb->sv_nzones = sbd->s_fsize;
236 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
237 return sb;
240 static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh)
242 struct sysv2_super_block * sbd;
244 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
245 if (sbd->s_magic != 0xfd187e20)
246 return NULL;
247 if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
248 return NULL;
249 if (sbd->s_type > 3 || sbd->s_type < 1)
250 return NULL;
251 detected_bs(sbd->s_type, sb);
252 sb->sv_type = FSTYPE_SYSV2;
253 return "SystemV Release 2";
255 static struct super_block * detected_sysv2 (struct super_block *sb, struct buffer_head *bh)
257 struct sysv2_super_block * sbd;
259 if (sb->sv_block_size >= BLOCK_SIZE)
260 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
261 else {
262 sbd = (struct sysv2_super_block *) bh->b_data;
263 /* sanity check */
264 if (sbd->s_magic != 0xfd187e20)
265 return NULL;
266 if (sbd->s_time < 315532800)
267 return NULL;
270 sb->sv_convert = 0;
271 sb->sv_kludge_symlinks = 0; /* ?? */
272 sb->sv_truncate = 1;
273 sb->sv_link_max = SYSV_LINK_MAX;
274 sb->sv_fic_size = SYSV_NICINOD;
275 sb->sv_flc_size = SYSV_NICFREE;
276 sb->sv_bh1 = bh;
277 sb->sv_bh2 = bh;
278 sb->sv_sbd1 = (char *) sbd;
279 sb->sv_sbd2 = (char *) sbd;
280 sb->sv_sb_fic_count = &sbd->s_ninode;
281 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
282 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
283 sb->sv_sb_flc_count = &sbd->s_nfree;
284 sb->sv_sb_flc_blocks = &sbd->s_free[0];
285 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
286 sb->sv_sb_time = &sbd->s_time;
287 sb->sv_sb_state = &sbd->s_state;
288 sb->sv_firstinodezone = 2;
289 sb->sv_firstdatazone = sbd->s_isize;
290 sb->sv_nzones = sbd->s_fsize;
291 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
292 return sb;
295 static const char* detect_coherent (struct super_block *sb, struct buffer_head *bh)
297 struct coh_super_block * sbd;
299 sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);
300 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
301 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
302 return NULL;
303 detected_bs(1, sb);
304 sb->sv_type = FSTYPE_COH;
305 return "Coherent";
307 static struct super_block * detected_coherent (struct super_block *sb, struct buffer_head *bh)
309 struct coh_super_block * sbd;
311 sbd = (struct coh_super_block *) bh->b_data;
312 /* sanity check */
313 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
314 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
315 return NULL;
317 sb->sv_convert = 1;
318 sb->sv_kludge_symlinks = 1;
319 sb->sv_truncate = 1;
320 sb->sv_link_max = COH_LINK_MAX;
321 sb->sv_fic_size = COH_NICINOD;
322 sb->sv_flc_size = COH_NICFREE;
323 sb->sv_bh1 = bh;
324 sb->sv_bh2 = bh;
325 sb->sv_sbd1 = (char *) sbd;
326 sb->sv_sbd2 = (char *) sbd;
327 sb->sv_sb_fic_count = &sbd->s_ninode;
328 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
329 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
330 sb->sv_sb_flc_count = &sbd->s_nfree;
331 sb->sv_sb_flc_blocks = &sbd->s_free[0];
332 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
333 sb->sv_sb_time = &sbd->s_time;
334 sb->sv_firstinodezone = 2;
335 sb->sv_firstdatazone = sbd->s_isize;
336 sb->sv_nzones = from_coh_ulong(sbd->s_fsize);
337 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
338 return sb;
341 struct super_block *sysv_read_super(struct super_block *sb,void *data,
342 int silent)
344 struct buffer_head *bh;
345 const char *found;
346 kdev_t dev = sb->s_dev;
347 struct inode *root_inode;
348 unsigned long blocknr;
350 if (1024 != sizeof (struct xenix_super_block))
351 panic("Xenix FS: bad super-block size");
352 if ((512 != sizeof (struct sysv4_super_block))
353 || (512 != sizeof (struct sysv2_super_block)))
354 panic("SystemV FS: bad super-block size");
355 if (500 != sizeof (struct coh_super_block))
356 panic("Coherent FS: bad super-block size");
357 if (64 != sizeof (struct sysv_inode))
358 panic("sysv fs: bad i-node size");
359 MOD_INC_USE_COUNT;
360 lock_super(sb);
361 set_blocksize(dev,BLOCK_SIZE);
362 sb->sv_block_base = 0;
364 /* Try to read Xenix superblock */
365 if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
366 if ((found = detect_xenix(sb,bh)) != NULL)
367 goto ok;
368 brelse(bh);
370 if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {
371 /* Try to recognize SystemV superblock */
372 if ((found = detect_sysv4(sb,bh)) != NULL)
373 goto ok;
374 if ((found = detect_sysv2(sb,bh)) != NULL)
375 goto ok;
376 /* Try to recognize Coherent superblock */
377 if ((found = detect_coherent(sb,bh)) != NULL)
378 goto ok;
379 brelse(bh);
381 /* Try to recognize SystemV superblock */
382 /* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
383 /* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
384 /* Maybe we should also check the device geometry ? */
385 { static int offsets[] = { 9, 15, 18, };
386 int i;
387 for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
388 if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
389 /* Try to recognize SystemV superblock */
390 if ((found = detect_sysv4(sb,bh)) != NULL) {
391 if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
392 goto bad_shift;
393 sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
394 goto ok;
396 if ((found = detect_sysv2(sb,bh)) != NULL) {
397 if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
398 goto bad_shift;
399 sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
400 goto ok;
402 brelse(bh);
405 bad_shift:
406 sb->s_dev = 0;
407 unlock_super(sb);
408 if (!silent)
409 printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
410 "%s\n", kdevname(dev));
411 failed:
412 MOD_DEC_USE_COUNT;
413 return NULL;
416 if (sb->sv_block_size >= BLOCK_SIZE) {
417 if (sb->sv_block_size != BLOCK_SIZE) {
418 brelse(bh);
419 set_blocksize(dev, sb->sv_block_size);
420 blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
421 if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
422 goto bad_superblock;
424 switch (sb->sv_type) {
425 case FSTYPE_XENIX:
426 if (!detected_xenix(sb,bh,bh))
427 goto bad_superblock;
428 break;
429 case FSTYPE_SYSV4:
430 if (!detected_sysv4(sb,bh))
431 goto bad_superblock;
432 break;
433 case FSTYPE_SYSV2:
434 if (!detected_sysv2(sb,bh))
435 goto bad_superblock;
436 break;
437 default: goto bad_superblock;
438 goto superblock_ok;
439 bad_superblock:
440 brelse(bh);
441 sb->s_dev = 0;
442 unlock_super(sb);
443 printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
444 goto failed;
445 superblock_ok:
447 } else {
448 /* Switch to 512 block size. Unfortunately, we have to
449 release the block bh and read it again. */
450 struct buffer_head *bh1, *bh2;
451 unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
453 brelse(bh);
454 set_blocksize(dev,sb->sv_block_size);
455 bh1 = NULL; bh2 = NULL;
456 switch (sb->sv_type) {
457 case FSTYPE_XENIX:
458 if ((bh1 = bread(dev, blocknr, sb->sv_block_size)) == NULL)
459 goto bad_superblock2;
460 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
461 goto bad_superblock2;
462 if (!detected_xenix(sb,bh1,bh2))
463 goto bad_superblock2;
464 break;
465 case FSTYPE_SYSV4:
466 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
467 goto bad_superblock2;
468 if (!detected_sysv4(sb,bh2))
469 goto bad_superblock2;
470 break;
471 case FSTYPE_SYSV2:
472 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
473 goto bad_superblock2;
474 if (!detected_sysv2(sb,bh2))
475 goto bad_superblock2;
476 break;
477 case FSTYPE_COH:
478 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
479 goto bad_superblock2;
480 if (!detected_coherent(sb,bh2))
481 goto bad_superblock2;
482 break;
483 default:
484 bad_superblock2:
485 brelse(bh1);
486 brelse(bh2);
487 set_blocksize(sb->s_dev,BLOCK_SIZE);
488 sb->s_dev = 0;
489 unlock_super(sb);
490 printk("SysV FS: cannot read superblock in 512 byte mode\n");
491 goto failed;
494 sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
495 if (!silent)
496 printk("VFS: Found a %s FS (block size = %d) on device %s\n",
497 found, sb->sv_block_size, kdevname(dev));
498 sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;
499 /* The buffer code now supports block size 512 as well as 1024. */
500 sb->s_blocksize = sb->sv_block_size;
501 sb->s_blocksize_bits = sb->sv_block_size_bits;
502 /* set up enough so that it can read an inode */
503 sb->s_dev = dev;
504 sb->s_op = &sysv_sops;
505 root_inode = iget(sb,SYSV_ROOT_INO);
506 sb->s_root = d_alloc_root(root_inode);
507 if (!sb->s_root) {
508 printk("SysV FS: get root inode failed\n");
509 sysv_put_super(sb);
510 sb->s_dev = 0;
511 unlock_super(sb);
512 return NULL;
514 unlock_super(sb);
515 sb->s_dirt = 1;
516 /* brelse(bh); resp. brelse(bh1); brelse(bh2);
517 occurs when the disk is unmounted. */
518 return sb;
521 /* This is only called on sync() and umount(), when s_dirt=1. */
522 void sysv_write_super (struct super_block *sb)
524 lock_super(sb);
525 if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {
526 /* If we are going to write out the super block,
527 then attach current time stamp.
528 But if the filesystem was marked clean, keep it clean. */
529 unsigned long time = CURRENT_TIME;
530 unsigned long old_time = *sb->sv_sb_time;
531 if (sb->sv_convert)
532 old_time = from_coh_ulong(old_time);
533 if (sb->sv_type == FSTYPE_SYSV4)
534 if (*sb->sv_sb_state == 0x7c269d38 - old_time)
535 *sb->sv_sb_state = 0x7c269d38 - time;
536 if (sb->sv_convert)
537 time = to_coh_ulong(time);
538 *sb->sv_sb_time = time;
539 mark_buffer_dirty(sb->sv_bh2, 1);
541 sb->s_dirt = 0;
542 unlock_super(sb);
545 void sysv_put_super(struct super_block *sb)
547 /* we can assume sysv_write_super() has already been called,
548 and that the superblock is locked */
549 brelse(sb->sv_bh1);
550 if (sb->sv_bh1 != sb->sv_bh2) brelse(sb->sv_bh2);
551 /* switch back to default block size */
552 if (sb->s_blocksize != BLOCK_SIZE)
553 set_blocksize(sb->s_dev,BLOCK_SIZE);
555 MOD_DEC_USE_COUNT;
558 int sysv_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
560 struct statfs tmp;
562 tmp.f_type = sb->s_magic; /* type of filesystem */
563 tmp.f_bsize = sb->sv_block_size; /* block size */
564 tmp.f_blocks = sb->sv_ndatazones; /* total data blocks in file system */
565 tmp.f_bfree = sysv_count_free_blocks(sb); /* free blocks in fs */
566 tmp.f_bavail = tmp.f_bfree; /* free blocks available to non-superuser */
567 tmp.f_files = sb->sv_ninodes; /* total file nodes in file system */
568 tmp.f_ffree = sysv_count_free_inodes(sb); /* free file nodes in fs */
569 tmp.f_namelen = SYSV_NAMELEN;
570 /* Don't know what value to put in tmp.f_fsid */ /* file system id */
571 return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
575 /* bmap support for running executables and shared libraries. */
577 static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr)
579 int tmp = inode->u.sysv_i.i_data[nr];
580 if (!tmp)
581 return 0;
582 return tmp + sb->sv_block_base;
585 static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert)
587 int tmp;
589 if (!bh)
590 return 0;
591 tmp = ((sysv_zone_t *) bh->b_data) [nr];
592 if (convert)
593 tmp = from_coh_ulong(tmp);
594 brelse(bh);
595 if (!tmp)
596 return 0;
597 return tmp + sb->sv_block_base;
600 int sysv_bmap(struct inode * inode,int block_nr)
602 unsigned int block = block_nr;
603 struct super_block * sb = inode->i_sb;
604 int convert;
605 int i;
606 struct buffer_head * bh;
608 if (block < 10)
609 return inode_bmap(sb,inode,block);
610 block -= 10;
611 convert = sb->sv_convert;
612 if (block < sb->sv_ind_per_block) {
613 i = inode_bmap(sb,inode,10);
614 if (!i)
615 return 0;
616 bh = bread(inode->i_dev,i,sb->sv_block_size);
617 return block_bmap(sb, bh, block, convert);
619 block -= sb->sv_ind_per_block;
620 if (block < sb->sv_ind_per_block_2) {
621 i = inode_bmap(sb,inode,11);
622 if (!i)
623 return 0;
624 bh = bread(inode->i_dev,i,sb->sv_block_size);
625 i = block_bmap(sb, bh, block >> sb->sv_ind_per_block_bits, convert);
626 if (!i)
627 return 0;
628 bh = bread(inode->i_dev,i,sb->sv_block_size);
629 return block_bmap(sb, bh, block & sb->sv_ind_per_block_1, convert);
631 block -= sb->sv_ind_per_block_2;
632 if (block < sb->sv_ind_per_block_3) {
633 i = inode_bmap(sb,inode,12);
634 if (!i)
635 return 0;
636 bh = bread(inode->i_dev,i,sb->sv_block_size);
637 i = block_bmap(sb, bh, block >> sb->sv_ind_per_block_2_bits, convert);
638 if (!i)
639 return 0;
640 bh = bread(inode->i_dev,i,sb->sv_block_size);
641 i = block_bmap(sb, bh, (block >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1,convert);
642 if (!i)
643 return 0;
644 bh = bread(inode->i_dev,i,sb->sv_block_size);
645 return block_bmap(sb, bh, block & sb->sv_ind_per_block_1, convert);
647 if ((int)block<0) {
648 printk("sysv_bmap: block<0");
649 return 0;
651 printk("sysv_bmap: block>big");
652 return 0;
655 /* End of bmap support. */
658 /* Access selected blocks of regular files (or directories) */
660 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create,
661 int metadata, int *phys_block, int *created)
663 struct super_block *sb;
664 u32 tmp;
665 u32 *p;
666 struct buffer_head * result;
668 sb = inode->i_sb;
669 p = inode->u.sysv_i.i_data + nr;
670 repeat:
671 tmp = *p;
672 if (tmp) {
673 if (metadata) {
674 result = sv_getblk(sb, inode->i_dev, tmp);
675 if (tmp == *p)
676 return result;
677 brelse(result);
678 goto repeat;
679 } else {
680 *phys_block = tmp;
681 return NULL;
684 if (!create)
685 return NULL;
686 tmp = sysv_new_block(sb);
687 if (!tmp)
688 return NULL;
689 if (metadata) {
690 result = sv_getblk(sb, inode->i_dev, tmp);
691 if (*p) {
692 sysv_free_block(sb, tmp);
693 brelse(result);
694 goto repeat;
696 } else {
697 if (*p) {
698 sysv_free_block(sb, tmp);
699 goto repeat;
701 *phys_block = tmp;
702 result = NULL;
703 *created = 1;
705 *p = tmp;
707 inode->i_ctime = CURRENT_TIME;
708 mark_inode_dirty(inode);
709 return result;
712 static struct buffer_head * block_getblk(struct inode * inode,
713 struct buffer_head * bh, int nr, int create,
714 int metadata, int *phys_block, int *created)
716 struct super_block *sb;
717 u32 tmp, block;
718 sysv_zone_t *p;
719 struct buffer_head * result;
721 if (!bh)
722 return NULL;
723 if (!buffer_uptodate(bh)) {
724 ll_rw_block(READ, 1, &bh);
725 wait_on_buffer(bh);
726 if (!buffer_uptodate(bh)) {
727 brelse(bh);
728 return NULL;
731 sb = inode->i_sb;
732 p = nr + (sysv_zone_t *) bh->b_data;
733 repeat:
734 block = tmp = *p;
735 if (sb->sv_convert)
736 block = from_coh_ulong(block);
737 if (tmp) {
738 if (metadata) {
739 result = sv_getblk(sb, bh->b_dev, block);
740 if (tmp == *p) {
741 brelse(bh);
742 return result;
744 brelse(result);
745 goto repeat;
746 } else {
747 *phys_block = tmp;
748 brelse(bh);
749 return NULL;
752 if (!create) {
753 brelse(bh);
754 return NULL;
756 block = sysv_new_block(sb);
757 if (!block) {
758 brelse(bh);
759 return NULL;
761 if (metadata) {
762 result = sv_getblk(sb, bh->b_dev, block);
763 if (*p) {
764 sysv_free_block(sb,block);
765 brelse(result);
766 goto repeat;
768 } else {
769 *phys_block = tmp;
770 result = NULL;
771 *created = 1;
773 *p = (sb->sv_convert ? to_coh_ulong(block) : block);
774 mark_buffer_dirty(bh, 1);
775 brelse(bh);
776 return result;
779 int sysv_getblk_block(struct inode *inode, long block, int create,
780 int *err, int *created)
782 struct super_block *sb = inode->i_sb;
783 struct buffer_head *bh, *tmp;
784 int phys_block;
786 *err = -EIO;
787 if (block < 0) {
788 printk("sysv_getblk: block<0");
789 return 0;
791 if (block > sb->sv_ind_per_block_3) {
792 printk("sysv_getblk: block>big");
793 return 0;
795 if (block < 10) {
796 tmp = inode_getblk(inode, block, create,
797 0, &phys_block, created);
798 goto out;
800 block -= 10;
801 if (block < sb->sv_ind_per_block) {
802 bh = inode_getblk(inode, 10, create, 1, NULL, NULL);
803 tmp = block_getblk(inode, bh, block, create,
804 0, &phys_block, created);
805 goto out;
807 block -= sb->sv_ind_per_block;
808 if (block < sb->sv_ind_per_block_2) {
809 bh = inode_getblk(inode, 11, create, 1, NULL, NULL);
810 bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_bits, create,
811 1, NULL, NULL);
812 tmp = block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create,
813 0, &phys_block, created);
814 goto out;
816 block -= sb->sv_ind_per_block_2;
817 bh = inode_getblk(inode, 12, create, 1, NULL, NULL);
818 bh = block_getblk(inode, bh, block >> sb->sv_ind_per_block_2_bits, create,
819 1, NULL, NULL);
820 bh = block_getblk(inode, bh,
821 (block >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1,
822 create, 1, NULL, NULL);
823 tmp = block_getblk(inode, bh, block & sb->sv_ind_per_block_1, create,
824 0, &phys_block, created);
826 out:
827 *err = 0;
828 return phys_block;
831 struct buffer_head *sysv_getblk (struct inode *inode, unsigned int block, int create)
833 struct buffer_head *tmp = NULL;
834 int phys_block;
835 int err, created;
837 phys_block = sysv_getblk_block(inode, block, create, &err, &created);
838 if (phys_block) {
839 tmp = getblk(inode->i_dev, phys_block, BLOCK_SIZE);
840 if (created) {
841 memset(tmp->b_data, 0, BLOCK_SIZE);
842 mark_buffer_uptodate(tmp, 1);
843 mark_buffer_dirty(tmp, 1);
846 return tmp;
849 struct buffer_head * sysv_file_bread(struct inode * inode, int block, int create)
851 struct buffer_head * bh;
853 bh = sysv_getblk(inode,block,create);
854 if (!bh || buffer_uptodate(bh))
855 return bh;
856 ll_rw_block(READ, 1, &bh);
857 wait_on_buffer(bh);
858 if (buffer_uptodate(bh))
859 return bh;
860 brelse(bh);
861 return NULL;
864 #ifdef __BIG_ENDIAN
866 static inline unsigned long read3byte (unsigned char * p)
868 return (p[2] | (p[1]<<8) | (p[0]<<16));
871 static inline void write3byte (unsigned char *p , unsigned long val)
873 p[2]=val&0xFF;
874 p[1]=(val>>8)&0xFF;
875 p[0]=(val>>16)&0xFF;
878 #else
880 static inline unsigned long read3byte (unsigned char * p)
882 return (unsigned long)(*(unsigned short *)p)
883 | (unsigned long)(*(unsigned char *)(p+2)) << 16;
886 static inline void write3byte (unsigned char * p, unsigned long val)
888 *(unsigned short *)p = (unsigned short) val;
889 *(unsigned char *)(p+2) = val >> 16;
892 #endif
894 static inline unsigned long coh_read3byte (unsigned char * p)
896 return (unsigned long)(*(unsigned char *)p) << 16
897 | (unsigned long)(*(unsigned short *)(p+1));
900 static inline void coh_write3byte (unsigned char * p, unsigned long val)
902 *(unsigned char *)p = val >> 16;
903 *(unsigned short *)(p+1) = (unsigned short) val;
906 void sysv_read_inode(struct inode * inode)
908 struct super_block * sb = inode->i_sb;
909 struct buffer_head * bh;
910 struct sysv_inode * raw_inode;
911 unsigned int block, ino;
912 umode_t mode;
914 ino = inode->i_ino;
915 inode->i_op = NULL;
916 inode->i_mode = 0;
917 if (!ino || ino > sb->sv_ninodes) {
918 printk("Bad inode number on dev %s"
919 ": %d is out of range\n",
920 kdevname(inode->i_dev), ino);
921 return;
923 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
924 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
925 printk("Major problem: unable to read inode from dev "
926 "%s\n",
927 kdevname(inode->i_dev));
928 return;
930 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
931 mode = raw_inode->i_mode;
932 if (sb->sv_kludge_symlinks)
933 mode = from_coh_imode(mode);
934 /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
935 inode->i_mode = mode;
936 inode->i_uid = raw_inode->i_uid;
937 inode->i_gid = raw_inode->i_gid;
938 inode->i_nlink = raw_inode->i_nlink;
939 if (sb->sv_convert) {
940 inode->i_size = from_coh_ulong(raw_inode->i_size);
941 inode->i_atime = from_coh_ulong(raw_inode->i_atime);
942 inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);
943 inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);
944 } else {
945 inode->i_size = raw_inode->i_size;
946 inode->i_atime = raw_inode->i_atime;
947 inode->i_mtime = raw_inode->i_mtime;
948 inode->i_ctime = raw_inode->i_ctime;
950 inode->i_blocks = inode->i_blksize = 0;
951 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
953 else
954 if (sb->sv_convert)
955 for (block = 0; block < 10+1+1+1; block++)
956 inode->u.sysv_i.i_data[block] =
957 coh_read3byte(&raw_inode->i_a.i_addb[3*block]);
958 else
959 for (block = 0; block < 10+1+1+1; block++)
960 inode->u.sysv_i.i_data[block] =
961 read3byte(&raw_inode->i_a.i_addb[3*block]);
962 if (S_ISREG(inode->i_mode))
963 inode->i_op = &sysv_file_inode_operations;
964 else if (S_ISDIR(inode->i_mode))
965 inode->i_op = &sysv_dir_inode_operations;
966 else if (S_ISLNK(inode->i_mode))
967 inode->i_op = &sysv_symlink_inode_operations;
968 else
969 init_special_inode(inode, inode->i_mode,raw_inode->i_a.i_rdev);
970 brelse(bh);
973 /* To avoid inconsistencies between inodes in memory and inodes on disk. */
974 int sysv_notify_change(struct dentry *dentry, struct iattr *attr)
976 struct inode *inode = dentry->d_inode;
977 int error;
979 if ((error = inode_change_ok(inode, attr)) != 0)
980 return error;
982 if (attr->ia_valid & ATTR_MODE)
983 if (inode->i_sb->sv_kludge_symlinks)
984 if (attr->ia_mode == COH_KLUDGE_SYMLINK_MODE)
985 attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;
987 inode_setattr(inode, attr);
989 return 0;
992 static struct buffer_head * sysv_update_inode(struct inode * inode)
994 struct super_block * sb = inode->i_sb;
995 struct buffer_head * bh;
996 struct sysv_inode * raw_inode;
997 unsigned int ino, block;
998 umode_t mode;
1000 ino = inode->i_ino;
1001 if (!ino || ino > sb->sv_ninodes) {
1002 printk("Bad inode number on dev %s"
1003 ": %d is out of range\n",
1004 kdevname(inode->i_dev), ino);
1005 return 0;
1007 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
1008 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
1009 printk("unable to read i-node block\n");
1010 return 0;
1012 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
1013 mode = inode->i_mode;
1014 if (sb->sv_kludge_symlinks)
1015 mode = to_coh_imode(mode);
1016 raw_inode->i_mode = mode;
1017 raw_inode->i_uid = inode->i_uid;
1018 raw_inode->i_gid = inode->i_gid;
1019 raw_inode->i_nlink = inode->i_nlink;
1020 if (sb->sv_convert) {
1021 raw_inode->i_size = to_coh_ulong(inode->i_size);
1022 raw_inode->i_atime = to_coh_ulong(inode->i_atime);
1023 raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);
1024 raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);
1025 } else {
1026 raw_inode->i_size = inode->i_size;
1027 raw_inode->i_atime = inode->i_atime;
1028 raw_inode->i_mtime = inode->i_mtime;
1029 raw_inode->i_ctime = inode->i_ctime;
1031 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1032 raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */
1033 else
1034 if (sb->sv_convert)
1035 for (block = 0; block < 10+1+1+1; block++)
1036 coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
1037 else
1038 for (block = 0; block < 10+1+1+1; block++)
1039 write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
1040 mark_buffer_dirty(bh, 1);
1041 return bh;
1044 void sysv_write_inode(struct inode * inode)
1046 struct buffer_head *bh;
1047 bh = sysv_update_inode(inode);
1048 brelse(bh);
1051 int sysv_sync_inode(struct inode * inode)
1053 int err = 0;
1054 struct buffer_head *bh;
1056 bh = sysv_update_inode(inode);
1057 if (bh && buffer_dirty(bh)) {
1058 ll_rw_block(WRITE, 1, &bh);
1059 wait_on_buffer(bh);
1060 if (buffer_req(bh) && !buffer_uptodate(bh))
1062 printk ("IO error syncing sysv inode ["
1063 "%s:%08lx]\n",
1064 kdevname(inode->i_dev), inode->i_ino);
1065 err = -1;
1068 else if (!bh)
1069 err = -1;
1070 brelse (bh);
1071 return err;
1074 /* Every kernel module contains stuff like this. */
1076 static struct file_system_type sysv_fs_type[3] = {
1077 {"xenix", FS_REQUIRES_DEV, sysv_read_super, NULL},
1078 {"sysv", FS_REQUIRES_DEV, sysv_read_super, NULL},
1079 {"coherent", FS_REQUIRES_DEV, sysv_read_super, NULL}
1082 __initfunc(int init_sysv_fs(void))
1084 int i;
1085 int ouch;
1087 for (i = 0; i < 3; i++) {
1088 if ((ouch = register_filesystem(&sysv_fs_type[i])) != 0)
1089 break;
1091 return ouch;
1094 #ifdef MODULE
1095 EXPORT_NO_SYMBOLS;
1097 int init_module(void)
1099 return init_sysv_fs();
1102 void cleanup_module(void)
1104 int i;
1106 for (i = 0; i < 3; i++)
1107 /* No error message if this breaks... that's OK... */
1108 unregister_filesystem(&sysv_fs_type[i]);
1111 #endif