- pre5:
[davej-history.git] / fs / sysv / inode.c
blob7e5f6c54a468917e25492de82f60beff2003038d
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/config.h>
25 #include <linux/module.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.h>
29 #include <linux/fs.h>
30 #include <linux/sysv_fs.h>
31 #include <linux/stat.h>
32 #include <linux/string.h>
33 #include <linux/locks.h>
34 #include <linux/init.h>
35 #include <linux/smp_lock.h>
36 #include <linux/highuid.h>
37 #include <asm/byteorder.h>
38 #include <asm/uaccess.h>
40 #if 0
41 void sysv_print_inode(struct inode * inode)
43 printk("ino %lu mode 0%6.6o lk %d uid %d gid %d"
44 " sz %lu blks %lu cnt %u\n",
45 inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,
46 inode->i_gid, inode->i_size, inode->i_blocks,
47 atomic_read(&inode->i_count));
48 printk(" db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"
49 " 0x%lx 0x%lx>\n",
50 inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],
51 inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],
52 inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],
53 inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],
54 inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);
55 printk(" ib <0x%lx 0x%lx 0x%lx>\n",
56 inode->u.sysv_i.i_data[10],
57 inode->u.sysv_i.i_data[11],
58 inode->u.sysv_i.i_data[12]);
60 #endif
62 static void sysv_delete_inode(struct inode *inode)
64 lock_kernel();
65 inode->i_size = 0;
66 sysv_truncate(inode);
67 sysv_free_inode(inode);
68 unlock_kernel();
71 static void sysv_put_super(struct super_block *);
72 static void sysv_write_super(struct super_block *);
73 static void sysv_read_inode(struct inode *);
74 static int sysv_statfs(struct super_block *, struct statfs *);
76 static struct super_operations sysv_sops = {
77 read_inode: sysv_read_inode,
78 write_inode: sysv_write_inode,
79 delete_inode: sysv_delete_inode,
80 put_super: sysv_put_super,
81 write_super: sysv_write_super,
82 statfs: sysv_statfs,
85 /* The following functions try to recognize specific filesystems.
86 * We recognize:
87 * - Xenix FS by its magic number.
88 * - SystemV FS by its magic number.
89 * - Coherent FS by its funny fname/fpack field.
90 * We discriminate among SystemV4 and SystemV2 FS by the assumption that
91 * the time stamp is not < 01-01-1980.
94 static void detected_bs (u_char type, struct super_block *sb)
96 u_char n_bits = type+8;
97 int bsize = 1 << n_bits;
98 int bsize_4 = bsize >> 2;
100 sb->sv_block_size = bsize;
101 sb->sv_block_size_1 = bsize-1;
102 sb->sv_block_size_bits = n_bits;
103 sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
104 sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
105 sb->sv_inodes_per_block = bsize >> 6;
106 sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
107 sb->sv_inodes_per_block_bits = n_bits-6;
108 sb->sv_toobig_block = 10 +
109 (sb->sv_ind_per_block = bsize_4) +
110 (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
111 (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
112 sb->sv_ind_per_block_1 = bsize_4-1;
113 sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
114 sb->sv_ind_per_block_2_bits = 2 *
115 (sb->sv_ind_per_block_bits = n_bits-2);
116 sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
117 sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
118 sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
119 sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
120 sb->sv_ind0_size = 10 * bsize;
121 sb->sv_ind1_size = (10 + bsize_4)* bsize;
122 sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
125 static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
127 struct xenix_super_block * sbd;
129 sbd = (struct xenix_super_block *) bh->b_data;
130 if (sbd->s_magic != 0x2b5544)
131 return NULL;
132 if (sbd->s_type > 2 || sbd->s_type < 1)
133 return NULL;
134 detected_bs(sbd->s_type, sb);
135 sb->sv_type = FSTYPE_XENIX;
136 return "Xenix";
138 static struct super_block * detected_xenix (struct super_block *sb, struct buffer_head *bh1, struct buffer_head *bh2)
140 struct xenix_super_block * sbd1;
141 struct xenix_super_block * sbd2;
143 if (sb->sv_block_size >= BLOCK_SIZE)
144 /* block size >= 1024, so bh1 = bh2 */
145 sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
146 else {
147 /* block size = 512, so bh1 != bh2 */
148 sbd1 = (struct xenix_super_block *) bh1->b_data;
149 sbd2 = (struct xenix_super_block *) (bh2->b_data - BLOCK_SIZE/2);
150 /* sanity check */
151 if (sbd2->s_magic != 0x2b5544)
152 return NULL;
155 sb->sv_convert = 0;
156 sb->sv_kludge_symlinks = 1;
157 sb->sv_truncate = 1;
158 sb->sv_link_max = XENIX_LINK_MAX;
159 sb->sv_fic_size = XENIX_NICINOD;
160 sb->sv_flc_size = XENIX_NICFREE;
161 sb->sv_bh1 = bh1;
162 sb->sv_bh2 = bh2;
163 sb->sv_sbd1 = (char *) sbd1;
164 sb->sv_sbd2 = (char *) sbd2;
165 sb->sv_sb_fic_count = &sbd1->s_ninode;
166 sb->sv_sb_fic_inodes = &sbd1->s_inode[0];
167 sb->sv_sb_total_free_inodes = &sbd2->s_tinode;
168 sb->sv_sb_flc_count = &sbd1->s_nfree;
169 sb->sv_sb_flc_blocks = &sbd1->s_free[0];
170 sb->sv_sb_total_free_blocks = &sbd2->s_tfree;
171 sb->sv_sb_time = &sbd2->s_time;
172 sb->sv_firstinodezone = 2;
173 sb->sv_firstdatazone = sbd1->s_isize;
174 sb->sv_nzones = sbd1->s_fsize;
175 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
176 return sb;
179 static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
181 struct sysv4_super_block * sbd;
183 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
184 if (sbd->s_magic != 0xfd187e20)
185 return NULL;
186 if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
187 return NULL;
188 if ((sbd->s_type > 3 || sbd->s_type < 1) && (sbd->s_type > 0x30 || sbd->s_type < 0x10))
189 return NULL;
191 /* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
192 0x20 or 0x30 indicates that symbolic links and the 14-character
193 filename limit is gone. Due to lack of information about this
194 feature read-only mode seems to be a reasonable approach... -KGB */
196 if (sbd->s_type >= 0x10) {
197 printk("SysV FS: can't handle long file names on %s, "
198 "forcing read-only mode.\n", kdevname(sb->s_dev));
199 sb->s_flags |= MS_RDONLY;
202 detected_bs(sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type, sb);
203 sb->sv_type = FSTYPE_SYSV4;
204 return "SystemV";
207 static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh)
209 struct sysv4_super_block * sbd;
211 if (sb->sv_block_size >= BLOCK_SIZE)
212 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
213 else {
214 sbd = (struct sysv4_super_block *) bh->b_data;
215 /* sanity check */
216 if (sbd->s_magic != 0xfd187e20)
217 return NULL;
218 if (sbd->s_time < 315532800)
219 return NULL;
222 sb->sv_convert = 0;
223 sb->sv_kludge_symlinks = 0; /* ?? */
224 sb->sv_truncate = 1;
225 sb->sv_link_max = SYSV_LINK_MAX;
226 sb->sv_fic_size = SYSV_NICINOD;
227 sb->sv_flc_size = SYSV_NICFREE;
228 sb->sv_bh1 = bh;
229 sb->sv_bh2 = bh;
230 sb->sv_sbd1 = (char *) sbd;
231 sb->sv_sbd2 = (char *) sbd;
232 sb->sv_sb_fic_count = &sbd->s_ninode;
233 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
234 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
235 sb->sv_sb_flc_count = &sbd->s_nfree;
236 sb->sv_sb_flc_blocks = &sbd->s_free[0];
237 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
238 sb->sv_sb_time = &sbd->s_time;
239 sb->sv_sb_state = &sbd->s_state;
240 sb->sv_firstinodezone = 2;
241 sb->sv_firstdatazone = sbd->s_isize;
242 sb->sv_nzones = sbd->s_fsize;
243 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
244 return sb;
247 static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh)
249 struct sysv2_super_block * sbd;
251 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
252 if (sbd->s_magic != 0xfd187e20)
253 return NULL;
254 if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
255 return NULL;
256 if (sbd->s_type > 3 || sbd->s_type < 1)
257 return NULL;
258 detected_bs(sbd->s_type, sb);
259 sb->sv_type = FSTYPE_SYSV2;
260 return "SystemV Release 2";
262 static struct super_block * detected_sysv2 (struct super_block *sb, struct buffer_head *bh)
264 struct sysv2_super_block * sbd;
266 if (sb->sv_block_size >= BLOCK_SIZE)
267 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
268 else {
269 sbd = (struct sysv2_super_block *) bh->b_data;
270 /* sanity check */
271 if (sbd->s_magic != 0xfd187e20)
272 return NULL;
273 if (sbd->s_time < 315532800)
274 return NULL;
277 sb->sv_convert = 0;
278 sb->sv_kludge_symlinks = 0; /* ?? */
279 sb->sv_truncate = 1;
280 sb->sv_link_max = SYSV_LINK_MAX;
281 sb->sv_fic_size = SYSV_NICINOD;
282 sb->sv_flc_size = SYSV_NICFREE;
283 sb->sv_bh1 = bh;
284 sb->sv_bh2 = bh;
285 sb->sv_sbd1 = (char *) sbd;
286 sb->sv_sbd2 = (char *) sbd;
287 sb->sv_sb_fic_count = &sbd->s_ninode;
288 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
289 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
290 sb->sv_sb_flc_count = &sbd->s_nfree;
291 sb->sv_sb_flc_blocks = &sbd->s_free[0];
292 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
293 sb->sv_sb_time = &sbd->s_time;
294 sb->sv_sb_state = &sbd->s_state;
295 sb->sv_firstinodezone = 2;
296 sb->sv_firstdatazone = sbd->s_isize;
297 sb->sv_nzones = sbd->s_fsize;
298 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
299 return sb;
302 static const char* detect_coherent (struct super_block *sb, struct buffer_head *bh)
304 struct coh_super_block * sbd;
306 sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);
307 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
308 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
309 return NULL;
310 detected_bs(1, sb);
311 sb->sv_type = FSTYPE_COH;
312 return "Coherent";
314 static struct super_block * detected_coherent (struct super_block *sb, struct buffer_head *bh)
316 struct coh_super_block * sbd;
318 sbd = (struct coh_super_block *) bh->b_data;
319 /* sanity check */
320 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
321 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
322 return NULL;
324 sb->sv_convert = 1;
325 sb->sv_kludge_symlinks = 1;
326 sb->sv_truncate = 1;
327 sb->sv_link_max = COH_LINK_MAX;
328 sb->sv_fic_size = COH_NICINOD;
329 sb->sv_flc_size = COH_NICFREE;
330 sb->sv_bh1 = bh;
331 sb->sv_bh2 = bh;
332 sb->sv_sbd1 = (char *) sbd;
333 sb->sv_sbd2 = (char *) sbd;
334 sb->sv_sb_fic_count = &sbd->s_ninode;
335 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
336 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
337 sb->sv_sb_flc_count = &sbd->s_nfree;
338 sb->sv_sb_flc_blocks = &sbd->s_free[0];
339 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
340 sb->sv_sb_time = &sbd->s_time;
341 sb->sv_firstinodezone = 2;
342 sb->sv_firstdatazone = sbd->s_isize;
343 sb->sv_nzones = from_coh_ulong(sbd->s_fsize);
344 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
345 return sb;
348 static struct super_block *sysv_read_super(struct super_block *sb,
349 void *data, int silent)
351 struct buffer_head *bh;
352 const char *found;
353 kdev_t dev = sb->s_dev;
354 struct inode *root_inode;
355 unsigned long blocknr;
357 if (1024 != sizeof (struct xenix_super_block))
358 panic("Xenix FS: bad super-block size");
359 if ((512 != sizeof (struct sysv4_super_block))
360 || (512 != sizeof (struct sysv2_super_block)))
361 panic("SystemV FS: bad super-block size");
362 if (500 != sizeof (struct coh_super_block))
363 panic("Coherent FS: bad super-block size");
364 if (64 != sizeof (struct sysv_inode))
365 panic("sysv fs: bad i-node size");
366 set_blocksize(dev,BLOCK_SIZE);
367 sb->sv_block_base = 0;
369 /* Try to read Xenix superblock */
370 if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
371 if ((found = detect_xenix(sb,bh)) != NULL)
372 goto ok;
373 brelse(bh);
375 if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {
376 /* Try to recognize SystemV superblock */
377 if ((found = detect_sysv4(sb,bh)) != NULL)
378 goto ok;
379 if ((found = detect_sysv2(sb,bh)) != NULL)
380 goto ok;
381 /* Try to recognize Coherent superblock */
382 if ((found = detect_coherent(sb,bh)) != NULL)
383 goto ok;
384 brelse(bh);
386 /* Try to recognize SystemV superblock */
387 /* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
388 /* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
389 /* Maybe we should also check the device geometry ? */
390 { static int offsets[] = { 9, 15, 18, };
391 int i;
392 for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
393 if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
394 /* Try to recognize SystemV superblock */
395 if ((found = detect_sysv4(sb,bh)) != NULL) {
396 if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
397 goto bad_shift;
398 sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
399 goto ok;
401 if ((found = detect_sysv2(sb,bh)) != NULL) {
402 if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
403 goto bad_shift;
404 sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
405 goto ok;
407 brelse(bh);
410 bad_shift:
411 if (!silent)
412 printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
413 "%s\n", kdevname(dev));
414 failed:
415 return NULL;
418 if (sb->sv_block_size >= BLOCK_SIZE) {
419 if (sb->sv_block_size != BLOCK_SIZE) {
420 brelse(bh);
421 set_blocksize(dev, sb->sv_block_size);
422 blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
423 if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
424 goto bad_superblock;
426 switch (sb->sv_type) {
427 case FSTYPE_XENIX:
428 if (!detected_xenix(sb,bh,bh))
429 goto bad_superblock;
430 break;
431 case FSTYPE_SYSV4:
432 if (!detected_sysv4(sb,bh))
433 goto bad_superblock;
434 break;
435 case FSTYPE_SYSV2:
436 if (!detected_sysv2(sb,bh))
437 goto bad_superblock;
438 break;
439 default: goto bad_superblock;
440 goto superblock_ok;
441 bad_superblock:
442 brelse(bh);
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 printk("SysV FS: cannot read superblock in 512 byte mode\n");
489 goto failed;
492 sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
493 if (!silent)
494 printk("VFS: Found a %s FS (block size = %d) on device %s\n",
495 found, sb->sv_block_size, kdevname(dev));
496 sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;
497 /* The buffer code now supports block size 512 as well as 1024. */
498 sb->s_blocksize = sb->sv_block_size;
499 sb->s_blocksize_bits = sb->sv_block_size_bits;
500 /* set up enough so that it can read an inode */
501 sb->s_op = &sysv_sops;
502 root_inode = iget(sb,SYSV_ROOT_INO);
503 sb->s_root = d_alloc_root(root_inode);
504 if (!sb->s_root) {
505 printk("SysV FS: get root inode failed\n");
506 sysv_put_super(sb);
507 return NULL;
509 #ifndef CONFIG_SYSV_FS_WRITE
510 sb->s_flags |= MS_RDONLY;
511 #endif
512 sb->s_dirt = 1;
513 /* brelse(bh); resp. brelse(bh1); brelse(bh2);
514 occurs when the disk is unmounted. */
515 return sb;
518 /* This is only called on sync() and umount(), when s_dirt=1. */
519 static void sysv_write_super(struct super_block *sb)
521 if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {
522 /* If we are going to write out the super block,
523 then attach current time stamp.
524 But if the filesystem was marked clean, keep it clean. */
525 unsigned long time = CURRENT_TIME;
526 unsigned long old_time = *sb->sv_sb_time;
527 if (sb->sv_convert)
528 old_time = from_coh_ulong(old_time);
529 if (sb->sv_type == FSTYPE_SYSV4)
530 if (*sb->sv_sb_state == 0x7c269d38 - old_time)
531 *sb->sv_sb_state = 0x7c269d38 - time;
532 if (sb->sv_convert)
533 time = to_coh_ulong(time);
534 *sb->sv_sb_time = time;
535 mark_buffer_dirty(sb->sv_bh2);
537 sb->s_dirt = 0;
540 static void sysv_put_super(struct super_block *sb)
542 /* we can assume sysv_write_super() has already been called,
543 and that the superblock is locked */
544 brelse(sb->sv_bh1);
545 if (sb->sv_bh1 != sb->sv_bh2) brelse(sb->sv_bh2);
546 /* switch back to default block size */
547 if (sb->s_blocksize != BLOCK_SIZE)
548 set_blocksize(sb->s_dev,BLOCK_SIZE);
551 static int sysv_statfs(struct super_block *sb, struct statfs *buf)
553 buf->f_type = sb->s_magic; /* type of filesystem */
554 buf->f_bsize = sb->sv_block_size; /* block size */
555 buf->f_blocks = sb->sv_ndatazones; /* total data blocks in file system */
556 buf->f_bfree = sysv_count_free_blocks(sb); /* free blocks in fs */
557 buf->f_bavail = buf->f_bfree; /* free blocks available to non-superuser */
558 buf->f_files = sb->sv_ninodes; /* total file nodes in file system */
559 buf->f_ffree = sysv_count_free_inodes(sb); /* free file nodes in fs */
560 buf->f_namelen = SYSV_NAMELEN;
561 /* Don't know what value to put in buf->f_fsid */ /* file system id */
562 return 0;
566 /* bmap support for running executables and shared libraries. */
568 static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr)
570 int tmp = inode->u.sysv_i.i_data[nr];
571 if (!tmp)
572 return 0;
573 return tmp + sb->sv_block_base;
576 static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert)
578 int tmp;
580 if (!bh)
581 return 0;
582 tmp = ((sysv_zone_t *) bh->b_data) [nr];
583 if (convert)
584 tmp = from_coh_ulong(tmp);
585 brelse(bh);
586 if (!tmp)
587 return 0;
588 return tmp + sb->sv_block_base;
591 static unsigned int sysv_block_map(struct inode *inode, unsigned int block)
593 struct super_block *sb;
594 int i, ret, convert;
596 ret = 0;
597 lock_kernel();
598 sb = inode->i_sb;
599 if (block < 10) {
600 ret = inode_bmap(sb, inode, block);
601 goto out;
603 block -= 10;
604 convert = sb->sv_convert;
605 if (block < sb->sv_ind_per_block) {
606 i = inode_bmap(sb, inode, 10);
607 if (!i)
608 goto out;
609 ret = block_bmap(sb,
610 bread(inode->i_dev, i, sb->sv_block_size),
611 block, convert);
612 goto out;
614 block -= sb->sv_ind_per_block;
615 if (block < sb->sv_ind_per_block_2) {
616 i = inode_bmap(sb, inode, 11);
617 if (!i)
618 goto out;
619 i = block_bmap(sb,
620 bread(inode->i_dev, i, sb->sv_block_size),
621 (block >> sb->sv_ind_per_block_bits), convert);
622 if (!i)
623 goto out;
624 ret = block_bmap(sb,
625 bread(inode->i_dev, i, sb->sv_block_size),
626 (block & sb->sv_ind_per_block_1), convert);
627 goto out;
629 block -= sb->sv_ind_per_block_2;
630 if (block < sb->sv_ind_per_block_3) {
631 i = inode_bmap(sb, inode, 12);
632 if (!i)
633 goto out;
634 i = block_bmap(sb,
635 bread(inode->i_dev, i, sb->sv_block_size),
636 (block >> sb->sv_ind_per_block_2_bits), convert);
637 if (!i)
638 goto out;
639 ret = block_bmap(sb,
640 bread(inode->i_dev, i, sb->sv_block_size),
641 ((block >> sb->sv_ind_per_block_bits) &
642 sb->sv_ind_per_block_1), convert);
643 if (!i)
644 goto out;
645 ret = block_bmap(sb,
646 bread(inode->i_dev, i, sb->sv_block_size),
647 (block & sb->sv_ind_per_block_1), convert);
648 goto out;
650 if ((int)block < 0)
651 printk("sysv_block_map: block < 0\n");
652 else
653 printk("sysv_block_map: block > big\n");
654 out:
655 unlock_kernel();
656 return ret;
659 /* End of bmap support. */
662 /* Access selected blocks of regular files (or directories) */
664 static struct buffer_head *inode_getblk(struct inode *inode, int nr, int new_block,
665 int *err, int metadata, long *phys, int *new)
667 struct super_block *sb;
668 u32 tmp;
669 u32 *p;
670 struct buffer_head * result;
672 sb = inode->i_sb;
673 p = inode->u.sysv_i.i_data + nr;
674 repeat:
675 tmp = *p;
676 if (tmp) {
677 if (metadata) {
678 result = sv_getblk(sb, inode->i_dev, tmp);
679 if (tmp == *p)
680 return result;
681 brelse(result);
682 goto repeat;
683 } else {
684 *phys = tmp;
685 return NULL;
689 tmp = sysv_new_block(sb);
690 if (!tmp) {
691 *err = -ENOSPC;
692 return NULL;
694 if (metadata) {
695 result = sv_getblk(sb, inode->i_dev, tmp);
696 if (*p) {
697 sysv_free_block(sb, tmp);
698 brelse(result);
699 goto repeat;
701 } else {
702 if (*p) {
704 * Nobody is allowed to change block allocation
705 * state from under us:
707 BUG();
708 sysv_free_block(sb, tmp);
709 goto repeat;
711 *phys = tmp;
712 result = NULL;
713 *err = 0;
714 *new = 1;
716 *p = tmp;
718 inode->i_ctime = CURRENT_TIME;
719 mark_inode_dirty(inode);
720 return result;
723 static struct buffer_head *block_getblk(struct inode *inode,
724 struct buffer_head *bh, int nr, int new_block, int *err,
725 int metadata, long *phys, int *new)
727 struct super_block *sb;
728 u32 tmp, block;
729 sysv_zone_t *p;
730 struct buffer_head * result;
732 result = NULL;
733 if (!bh)
734 goto out;
735 if (!buffer_uptodate(bh)) {
736 ll_rw_block(READ, 1, &bh);
737 wait_on_buffer(bh);
738 if (!buffer_uptodate(bh))
739 goto out;
741 sb = inode->i_sb;
742 p = nr + (sysv_zone_t *) bh->b_data;
743 repeat:
744 block = tmp = *p;
745 if (sb->sv_convert)
746 block = from_coh_ulong(block);
747 if (tmp) {
748 if (metadata) {
749 result = sv_getblk(sb, bh->b_dev, block);
750 if (tmp == *p)
751 goto out;
752 brelse(result);
753 goto repeat;
754 } else {
755 *phys = tmp;
756 goto out;
760 block = sysv_new_block(sb);
761 if (!block)
762 goto out;
763 if (metadata) {
764 result = sv_getblk(sb, bh->b_dev, block);
765 if (*p) {
766 sysv_free_block(sb, block);
767 brelse(result);
768 goto repeat;
770 memset(result->b_data, 0, sb->sv_block_size);
771 mark_buffer_uptodate(result, 1);
772 mark_buffer_dirty(result);
773 } else {
774 *phys = tmp;
775 *new = 1;
777 if (*p) {
778 sysv_free_block(sb, block);
779 brelse(result);
780 goto repeat;
782 *p = (sb->sv_convert ? to_coh_ulong(block) : block);
783 mark_buffer_dirty(bh);
784 *err = 0;
785 out:
786 brelse(bh);
787 return result;
790 static int sysv_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
792 struct super_block *sb;
793 int ret, err, new;
794 struct buffer_head *bh;
795 unsigned long ptr, phys;
797 if (!create) {
798 phys = sysv_block_map(inode, iblock);
799 if (phys) {
800 bh_result->b_dev = inode->i_dev;
801 bh_result->b_blocknr = phys;
802 bh_result->b_state |= (1UL << BH_Mapped);
804 return 0;
807 err = -EIO;
808 new = 0;
809 ret = 0;
810 bh = NULL;
812 lock_kernel();
813 sb = inode->i_sb;
814 if (iblock < 0)
815 goto abort_negative;
816 if (iblock > sb->sv_ind_per_block_3)
817 goto abort_too_big;
819 err = 0;
820 ptr = iblock;
823 * ok, these macros clean the logic up a bit and make
824 * it much more readable:
826 #define GET_INODE_DATABLOCK(x) \
827 inode_getblk(inode, x, iblock, &err, 0, &phys, &new)
828 #define GET_INODE_PTR(x) \
829 inode_getblk(inode, x, iblock, &err, 1, NULL, NULL)
830 #define GET_INDIRECT_DATABLOCK(x) \
831 block_getblk (inode, bh, x, iblock, &err, 0, &phys, &new);
832 #define GET_INDIRECT_PTR(x) \
833 block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL);
835 if (ptr < 10) {
836 bh = GET_INODE_DATABLOCK(ptr);
837 goto out;
839 ptr -= 10;
840 if (ptr < sb->sv_ind_per_block) {
841 bh = GET_INODE_PTR(10);
842 goto get_indirect;
844 ptr -= sb->sv_ind_per_block;
845 if (ptr < sb->sv_ind_per_block_2) {
846 bh = GET_INODE_PTR(11);
847 goto get_double;
849 ptr -= sb->sv_ind_per_block_2;
850 bh = GET_INODE_PTR(12);
851 bh = GET_INDIRECT_PTR(ptr >> sb->sv_ind_per_block_2_bits);
852 get_double:
853 bh = GET_INDIRECT_PTR((ptr >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1);
854 get_indirect:
855 bh = GET_INDIRECT_DATABLOCK(ptr & sb->sv_ind_per_block_1);
857 #undef GET_INODE_DATABLOCK
858 #undef GET_INODE_PTR
859 #undef GET_INDIRECT_DATABLOCK
860 #undef GET_INDIRECT_PTR
862 out:
863 if (err)
864 goto abort;
865 bh_result->b_dev = inode->i_dev;
866 bh_result->b_blocknr = phys;
867 bh_result->b_state |= (1UL << BH_Mapped);
868 if (new)
869 bh_result->b_state |= (1UL << BH_New);
870 abort:
871 unlock_kernel();
872 return err;
874 abort_negative:
875 printk("sysv_get_block: block < 0\n");
876 goto abort;
878 abort_too_big:
879 printk("sysv_get_block: block > big\n");
880 goto abort;
883 static struct buffer_head *sysv_getblk(struct inode *inode, unsigned int block, int create)
885 struct buffer_head dummy;
886 int error;
888 dummy.b_state = 0;
889 dummy.b_blocknr = -1000;
890 error = sysv_get_block(inode, block, &dummy, create);
891 if (!error && buffer_mapped(&dummy)) {
892 struct buffer_head *bh;
893 bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->sv_block_size);
894 if (buffer_new(&dummy)) {
895 memset(bh->b_data, 0, inode->i_sb->sv_block_size);
896 mark_buffer_uptodate(bh, 1);
897 mark_buffer_dirty(bh);
899 return bh;
901 return NULL;
904 struct buffer_head *sysv_file_bread(struct inode *inode, int block, int create)
906 struct buffer_head *bh;
908 bh = sysv_getblk(inode, block, create);
909 if (!bh || buffer_uptodate(bh))
910 return bh;
911 ll_rw_block(READ, 1, &bh);
912 wait_on_buffer(bh);
913 if (buffer_uptodate(bh))
914 return bh;
915 brelse(bh);
916 return NULL;
919 static int sysv_writepage(struct file *file, struct page *page)
921 return block_write_full_page(page,sysv_get_block);
923 static int sysv_readpage(struct file *file, struct page *page)
925 return block_read_full_page(page,sysv_get_block);
927 static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
929 return block_prepare_write(page,from,to,sysv_get_block);
931 static int sysv_bmap(struct address_space *mapping, long block)
933 return generic_block_bmap(mapping,block,sysv_get_block);
935 struct address_space_operations sysv_aops = {
936 readpage: sysv_readpage,
937 writepage: sysv_writepage,
938 sync_page: block_sync_page,
939 prepare_write: sysv_prepare_write,
940 commit_write: generic_commit_write,
941 bmap: sysv_bmap
944 #ifdef __BIG_ENDIAN
946 static inline unsigned long read3byte (unsigned char * p)
948 return (p[2] | (p[1]<<8) | (p[0]<<16));
951 static inline void write3byte (unsigned char *p , unsigned long val)
953 p[2]=val&0xFF;
954 p[1]=(val>>8)&0xFF;
955 p[0]=(val>>16)&0xFF;
958 #else
960 static inline unsigned long read3byte (unsigned char * p)
962 return (unsigned long)(*(unsigned short *)p)
963 | (unsigned long)(*(unsigned char *)(p+2)) << 16;
966 static inline void write3byte (unsigned char * p, unsigned long val)
968 *(unsigned short *)p = (unsigned short) val;
969 *(unsigned char *)(p+2) = val >> 16;
972 #endif
974 static inline unsigned long coh_read3byte (unsigned char * p)
976 return (unsigned long)(*(unsigned char *)p) << 16
977 | (unsigned long)(*(unsigned short *)(p+1));
980 static inline void coh_write3byte (unsigned char * p, unsigned long val)
982 *(unsigned char *)p = val >> 16;
983 *(unsigned short *)(p+1) = (unsigned short) val;
986 struct inode_operations sysv_symlink_inode_operations = {
987 readlink: page_readlink,
988 follow_link: page_follow_link,
989 setattr: sysv_notify_change,
992 static void sysv_read_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 block, ino;
998 umode_t mode;
1000 ino = inode->i_ino;
1001 inode->i_mode = 0;
1002 if (!ino || ino > sb->sv_ninodes) {
1003 printk("Bad inode number on dev %s"
1004 ": %d is out of range\n",
1005 kdevname(inode->i_dev), ino);
1006 return;
1008 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
1009 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
1010 printk("Major problem: unable to read inode from dev "
1011 "%s\n",
1012 kdevname(inode->i_dev));
1013 return;
1015 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
1016 mode = raw_inode->i_mode;
1017 if (sb->sv_kludge_symlinks)
1018 mode = from_coh_imode(mode);
1019 /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
1020 inode->i_mode = mode;
1021 inode->i_uid = (uid_t)raw_inode->i_uid;
1022 inode->i_gid = (gid_t)raw_inode->i_gid;
1023 inode->i_nlink = raw_inode->i_nlink;
1024 if (sb->sv_convert) {
1025 inode->i_size = from_coh_ulong(raw_inode->i_size);
1026 inode->i_atime = from_coh_ulong(raw_inode->i_atime);
1027 inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);
1028 inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);
1029 } else {
1030 inode->i_size = raw_inode->i_size;
1031 inode->i_atime = raw_inode->i_atime;
1032 inode->i_mtime = raw_inode->i_mtime;
1033 inode->i_ctime = raw_inode->i_ctime;
1035 inode->i_blocks = inode->i_blksize = 0;
1036 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1038 else
1039 if (sb->sv_convert)
1040 for (block = 0; block < 10+1+1+1; block++)
1041 inode->u.sysv_i.i_data[block] =
1042 coh_read3byte(&raw_inode->i_a.i_addb[3*block]);
1043 else
1044 for (block = 0; block < 10+1+1+1; block++)
1045 inode->u.sysv_i.i_data[block] =
1046 read3byte(&raw_inode->i_a.i_addb[3*block]);
1047 if (S_ISREG(inode->i_mode)) {
1048 inode->i_op = &sysv_file_inode_operations;
1049 inode->i_fop = &sysv_file_operations;
1050 inode->i_mapping->a_ops = &sysv_aops;
1051 } else if (S_ISDIR(inode->i_mode)) {
1052 inode->i_op = &sysv_dir_inode_operations;
1053 inode->i_fop = &sysv_dir_operations;
1054 } else if (S_ISLNK(inode->i_mode)) {
1055 inode->i_op = &sysv_symlink_inode_operations;
1056 inode->i_mapping->a_ops = &sysv_aops;
1057 } else
1058 init_special_inode(inode, inode->i_mode,raw_inode->i_a.i_rdev);
1059 brelse(bh);
1062 /* To avoid inconsistencies between inodes in memory and inodes on disk. */
1063 int sysv_notify_change(struct dentry *dentry, struct iattr *attr)
1065 struct inode *inode = dentry->d_inode;
1066 int error;
1068 if ((error = inode_change_ok(inode, attr)) != 0)
1069 return error;
1071 if (attr->ia_valid & ATTR_MODE)
1072 if (inode->i_sb->sv_kludge_symlinks)
1073 if (attr->ia_mode == COH_KLUDGE_SYMLINK_MODE)
1074 attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;
1076 inode_setattr(inode, attr);
1078 return 0;
1081 static struct buffer_head * sysv_update_inode(struct inode * inode)
1083 struct super_block * sb = inode->i_sb;
1084 struct buffer_head * bh;
1085 struct sysv_inode * raw_inode;
1086 unsigned int ino, block;
1087 umode_t mode;
1089 ino = inode->i_ino;
1090 if (!ino || ino > sb->sv_ninodes) {
1091 printk("Bad inode number on dev %s"
1092 ": %d is out of range\n",
1093 kdevname(inode->i_dev), ino);
1094 return 0;
1096 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
1097 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
1098 printk("unable to read i-node block\n");
1099 return 0;
1101 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
1102 mode = inode->i_mode;
1103 if (sb->sv_kludge_symlinks)
1104 mode = to_coh_imode(mode);
1105 raw_inode->i_mode = mode;
1106 raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
1107 raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
1108 raw_inode->i_nlink = inode->i_nlink;
1109 if (sb->sv_convert) {
1110 raw_inode->i_size = to_coh_ulong(inode->i_size);
1111 raw_inode->i_atime = to_coh_ulong(inode->i_atime);
1112 raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);
1113 raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);
1114 } else {
1115 raw_inode->i_size = inode->i_size;
1116 raw_inode->i_atime = inode->i_atime;
1117 raw_inode->i_mtime = inode->i_mtime;
1118 raw_inode->i_ctime = inode->i_ctime;
1120 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1121 raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */
1122 else
1123 if (sb->sv_convert)
1124 for (block = 0; block < 10+1+1+1; block++)
1125 coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
1126 else
1127 for (block = 0; block < 10+1+1+1; block++)
1128 write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
1129 mark_buffer_dirty(bh);
1130 return bh;
1133 void sysv_write_inode(struct inode * inode, int wait)
1135 struct buffer_head *bh;
1136 lock_kernel();
1137 bh = sysv_update_inode(inode);
1138 brelse(bh);
1139 unlock_kernel();
1142 int sysv_sync_inode(struct inode * inode)
1144 int err = 0;
1145 struct buffer_head *bh;
1147 bh = sysv_update_inode(inode);
1148 if (bh && buffer_dirty(bh)) {
1149 ll_rw_block(WRITE, 1, &bh);
1150 wait_on_buffer(bh);
1151 if (buffer_req(bh) && !buffer_uptodate(bh))
1153 printk ("IO error syncing sysv inode ["
1154 "%s:%08lx]\n",
1155 kdevname(inode->i_dev), inode->i_ino);
1156 err = -1;
1159 else if (!bh)
1160 err = -1;
1161 brelse (bh);
1162 return err;
1165 /* Every kernel module contains stuff like this. */
1167 static DECLARE_FSTYPE_DEV(sysv_fs_type, "sysv", sysv_read_super);
1169 static int __init init_sysv_fs(void)
1171 return register_filesystem(&sysv_fs_type);
1174 static void __exit exit_sysv_fs(void)
1176 unregister_filesystem(&sysv_fs_type);
1179 EXPORT_NO_SYMBOLS;
1181 module_init(init_sysv_fs)
1182 module_exit(exit_sysv_fs)