Import 2.4.0-test2pre6
[davej-history.git] / fs / sysv / inode.c
blob45581895975f4f7521d49e674f3cf004a5b7152c
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 inode->i_size = 0;
65 sysv_truncate(inode);
66 sysv_free_inode(inode);
69 static void sysv_put_super(struct super_block *);
70 static void sysv_write_super(struct super_block *);
71 static void sysv_read_inode(struct inode *);
72 static int sysv_statfs(struct super_block *, struct statfs *);
74 static struct super_operations sysv_sops = {
75 read_inode: sysv_read_inode,
76 write_inode: sysv_write_inode,
77 delete_inode: sysv_delete_inode,
78 put_super: sysv_put_super,
79 write_super: sysv_write_super,
80 statfs: sysv_statfs,
83 /* The following functions try to recognize specific filesystems.
84 * We recognize:
85 * - Xenix FS by its magic number.
86 * - SystemV FS by its magic number.
87 * - Coherent FS by its funny fname/fpack field.
88 * We discriminate among SystemV4 and SystemV2 FS by the assumption that
89 * the time stamp is not < 01-01-1980.
92 static void detected_bs (u_char type, struct super_block *sb)
94 u_char n_bits = type+8;
95 int bsize = 1 << n_bits;
96 int bsize_4 = bsize >> 2;
98 sb->sv_block_size = bsize;
99 sb->sv_block_size_1 = bsize-1;
100 sb->sv_block_size_bits = n_bits;
101 sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
102 sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
103 sb->sv_inodes_per_block = bsize >> 6;
104 sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
105 sb->sv_inodes_per_block_bits = n_bits-6;
106 sb->sv_toobig_block = 10 +
107 (sb->sv_ind_per_block = bsize_4) +
108 (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
109 (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
110 sb->sv_ind_per_block_1 = bsize_4-1;
111 sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
112 sb->sv_ind_per_block_2_bits = 2 *
113 (sb->sv_ind_per_block_bits = n_bits-2);
114 sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
115 sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
116 sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
117 sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
118 sb->sv_ind0_size = 10 * bsize;
119 sb->sv_ind1_size = (10 + bsize_4)* bsize;
120 sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
123 static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
125 struct xenix_super_block * sbd;
127 sbd = (struct xenix_super_block *) bh->b_data;
128 if (sbd->s_magic != 0x2b5544)
129 return NULL;
130 if (sbd->s_type > 2 || sbd->s_type < 1)
131 return NULL;
132 detected_bs(sbd->s_type, sb);
133 sb->sv_type = FSTYPE_XENIX;
134 return "Xenix";
136 static struct super_block * detected_xenix (struct super_block *sb, struct buffer_head *bh1, struct buffer_head *bh2)
138 struct xenix_super_block * sbd1;
139 struct xenix_super_block * sbd2;
141 if (sb->sv_block_size >= BLOCK_SIZE)
142 /* block size >= 1024, so bh1 = bh2 */
143 sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
144 else {
145 /* block size = 512, so bh1 != bh2 */
146 sbd1 = (struct xenix_super_block *) bh1->b_data;
147 sbd2 = (struct xenix_super_block *) (bh2->b_data - BLOCK_SIZE/2);
148 /* sanity check */
149 if (sbd2->s_magic != 0x2b5544)
150 return NULL;
153 sb->sv_convert = 0;
154 sb->sv_kludge_symlinks = 1;
155 sb->sv_truncate = 1;
156 sb->sv_link_max = XENIX_LINK_MAX;
157 sb->sv_fic_size = XENIX_NICINOD;
158 sb->sv_flc_size = XENIX_NICFREE;
159 sb->sv_bh1 = bh1;
160 sb->sv_bh2 = bh2;
161 sb->sv_sbd1 = (char *) sbd1;
162 sb->sv_sbd2 = (char *) sbd2;
163 sb->sv_sb_fic_count = &sbd1->s_ninode;
164 sb->sv_sb_fic_inodes = &sbd1->s_inode[0];
165 sb->sv_sb_total_free_inodes = &sbd2->s_tinode;
166 sb->sv_sb_flc_count = &sbd1->s_nfree;
167 sb->sv_sb_flc_blocks = &sbd1->s_free[0];
168 sb->sv_sb_total_free_blocks = &sbd2->s_tfree;
169 sb->sv_sb_time = &sbd2->s_time;
170 sb->sv_firstinodezone = 2;
171 sb->sv_firstdatazone = sbd1->s_isize;
172 sb->sv_nzones = sbd1->s_fsize;
173 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
174 return sb;
177 static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
179 struct sysv4_super_block * sbd;
181 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
182 if (sbd->s_magic != 0xfd187e20)
183 return NULL;
184 if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
185 return NULL;
186 if ((sbd->s_type > 3 || sbd->s_type < 1) && (sbd->s_type > 0x30 || sbd->s_type < 0x10))
187 return NULL;
189 /* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
190 0x20 or 0x30 indicates that symbolic links and the 14-character
191 filename limit is gone. Due to lack of information about this
192 feature read-only mode seems to be a reasonable approach... -KGB */
194 if (sbd->s_type >= 0x10) {
195 printk("SysV FS: can't handle long file names on %s, "
196 "forcing read-only mode.\n", kdevname(sb->s_dev));
197 sb->s_flags |= MS_RDONLY;
200 detected_bs(sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type, sb);
201 sb->sv_type = FSTYPE_SYSV4;
202 return "SystemV";
205 static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh)
207 struct sysv4_super_block * sbd;
209 if (sb->sv_block_size >= BLOCK_SIZE)
210 sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
211 else {
212 sbd = (struct sysv4_super_block *) bh->b_data;
213 /* sanity check */
214 if (sbd->s_magic != 0xfd187e20)
215 return NULL;
216 if (sbd->s_time < 315532800)
217 return NULL;
220 sb->sv_convert = 0;
221 sb->sv_kludge_symlinks = 0; /* ?? */
222 sb->sv_truncate = 1;
223 sb->sv_link_max = SYSV_LINK_MAX;
224 sb->sv_fic_size = SYSV_NICINOD;
225 sb->sv_flc_size = SYSV_NICFREE;
226 sb->sv_bh1 = bh;
227 sb->sv_bh2 = bh;
228 sb->sv_sbd1 = (char *) sbd;
229 sb->sv_sbd2 = (char *) sbd;
230 sb->sv_sb_fic_count = &sbd->s_ninode;
231 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
232 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
233 sb->sv_sb_flc_count = &sbd->s_nfree;
234 sb->sv_sb_flc_blocks = &sbd->s_free[0];
235 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
236 sb->sv_sb_time = &sbd->s_time;
237 sb->sv_sb_state = &sbd->s_state;
238 sb->sv_firstinodezone = 2;
239 sb->sv_firstdatazone = sbd->s_isize;
240 sb->sv_nzones = sbd->s_fsize;
241 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
242 return sb;
245 static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh)
247 struct sysv2_super_block * sbd;
249 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
250 if (sbd->s_magic != 0xfd187e20)
251 return NULL;
252 if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
253 return NULL;
254 if (sbd->s_type > 3 || sbd->s_type < 1)
255 return NULL;
256 detected_bs(sbd->s_type, sb);
257 sb->sv_type = FSTYPE_SYSV2;
258 return "SystemV Release 2";
260 static struct super_block * detected_sysv2 (struct super_block *sb, struct buffer_head *bh)
262 struct sysv2_super_block * sbd;
264 if (sb->sv_block_size >= BLOCK_SIZE)
265 sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
266 else {
267 sbd = (struct sysv2_super_block *) bh->b_data;
268 /* sanity check */
269 if (sbd->s_magic != 0xfd187e20)
270 return NULL;
271 if (sbd->s_time < 315532800)
272 return NULL;
275 sb->sv_convert = 0;
276 sb->sv_kludge_symlinks = 0; /* ?? */
277 sb->sv_truncate = 1;
278 sb->sv_link_max = SYSV_LINK_MAX;
279 sb->sv_fic_size = SYSV_NICINOD;
280 sb->sv_flc_size = SYSV_NICFREE;
281 sb->sv_bh1 = bh;
282 sb->sv_bh2 = bh;
283 sb->sv_sbd1 = (char *) sbd;
284 sb->sv_sbd2 = (char *) sbd;
285 sb->sv_sb_fic_count = &sbd->s_ninode;
286 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
287 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
288 sb->sv_sb_flc_count = &sbd->s_nfree;
289 sb->sv_sb_flc_blocks = &sbd->s_free[0];
290 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
291 sb->sv_sb_time = &sbd->s_time;
292 sb->sv_sb_state = &sbd->s_state;
293 sb->sv_firstinodezone = 2;
294 sb->sv_firstdatazone = sbd->s_isize;
295 sb->sv_nzones = sbd->s_fsize;
296 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
297 return sb;
300 static const char* detect_coherent (struct super_block *sb, struct buffer_head *bh)
302 struct coh_super_block * sbd;
304 sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);
305 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
306 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
307 return NULL;
308 detected_bs(1, sb);
309 sb->sv_type = FSTYPE_COH;
310 return "Coherent";
312 static struct super_block * detected_coherent (struct super_block *sb, struct buffer_head *bh)
314 struct coh_super_block * sbd;
316 sbd = (struct coh_super_block *) bh->b_data;
317 /* sanity check */
318 if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
319 || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
320 return NULL;
322 sb->sv_convert = 1;
323 sb->sv_kludge_symlinks = 1;
324 sb->sv_truncate = 1;
325 sb->sv_link_max = COH_LINK_MAX;
326 sb->sv_fic_size = COH_NICINOD;
327 sb->sv_flc_size = COH_NICFREE;
328 sb->sv_bh1 = bh;
329 sb->sv_bh2 = bh;
330 sb->sv_sbd1 = (char *) sbd;
331 sb->sv_sbd2 = (char *) sbd;
332 sb->sv_sb_fic_count = &sbd->s_ninode;
333 sb->sv_sb_fic_inodes = &sbd->s_inode[0];
334 sb->sv_sb_total_free_inodes = &sbd->s_tinode;
335 sb->sv_sb_flc_count = &sbd->s_nfree;
336 sb->sv_sb_flc_blocks = &sbd->s_free[0];
337 sb->sv_sb_total_free_blocks = &sbd->s_tfree;
338 sb->sv_sb_time = &sbd->s_time;
339 sb->sv_firstinodezone = 2;
340 sb->sv_firstdatazone = sbd->s_isize;
341 sb->sv_nzones = from_coh_ulong(sbd->s_fsize);
342 sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
343 return sb;
346 static struct super_block *sysv_read_super(struct super_block *sb,
347 void *data, int silent)
349 struct buffer_head *bh;
350 const char *found;
351 kdev_t dev = sb->s_dev;
352 struct inode *root_inode;
353 unsigned long blocknr;
355 if (1024 != sizeof (struct xenix_super_block))
356 panic("Xenix FS: bad super-block size");
357 if ((512 != sizeof (struct sysv4_super_block))
358 || (512 != sizeof (struct sysv2_super_block)))
359 panic("SystemV FS: bad super-block size");
360 if (500 != sizeof (struct coh_super_block))
361 panic("Coherent FS: bad super-block size");
362 if (64 != sizeof (struct sysv_inode))
363 panic("sysv fs: bad i-node size");
364 set_blocksize(dev,BLOCK_SIZE);
365 sb->sv_block_base = 0;
367 /* Try to read Xenix superblock */
368 if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
369 if ((found = detect_xenix(sb,bh)) != NULL)
370 goto ok;
371 brelse(bh);
373 if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {
374 /* Try to recognize SystemV superblock */
375 if ((found = detect_sysv4(sb,bh)) != NULL)
376 goto ok;
377 if ((found = detect_sysv2(sb,bh)) != NULL)
378 goto ok;
379 /* Try to recognize Coherent superblock */
380 if ((found = detect_coherent(sb,bh)) != NULL)
381 goto ok;
382 brelse(bh);
384 /* Try to recognize SystemV superblock */
385 /* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
386 /* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
387 /* Maybe we should also check the device geometry ? */
388 { static int offsets[] = { 9, 15, 18, };
389 int i;
390 for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
391 if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
392 /* Try to recognize SystemV superblock */
393 if ((found = detect_sysv4(sb,bh)) != NULL) {
394 if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
395 goto bad_shift;
396 sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
397 goto ok;
399 if ((found = detect_sysv2(sb,bh)) != NULL) {
400 if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
401 goto bad_shift;
402 sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
403 goto ok;
405 brelse(bh);
408 bad_shift:
409 if (!silent)
410 printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
411 "%s\n", kdevname(dev));
412 failed:
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 printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
442 goto failed;
443 superblock_ok:
445 } else {
446 /* Switch to 512 block size. Unfortunately, we have to
447 release the block bh and read it again. */
448 struct buffer_head *bh1, *bh2;
449 unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
451 brelse(bh);
452 set_blocksize(dev,sb->sv_block_size);
453 bh1 = NULL; bh2 = NULL;
454 switch (sb->sv_type) {
455 case FSTYPE_XENIX:
456 if ((bh1 = bread(dev, blocknr, sb->sv_block_size)) == NULL)
457 goto bad_superblock2;
458 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
459 goto bad_superblock2;
460 if (!detected_xenix(sb,bh1,bh2))
461 goto bad_superblock2;
462 break;
463 case FSTYPE_SYSV4:
464 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
465 goto bad_superblock2;
466 if (!detected_sysv4(sb,bh2))
467 goto bad_superblock2;
468 break;
469 case FSTYPE_SYSV2:
470 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
471 goto bad_superblock2;
472 if (!detected_sysv2(sb,bh2))
473 goto bad_superblock2;
474 break;
475 case FSTYPE_COH:
476 if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
477 goto bad_superblock2;
478 if (!detected_coherent(sb,bh2))
479 goto bad_superblock2;
480 break;
481 default:
482 bad_superblock2:
483 brelse(bh1);
484 brelse(bh2);
485 set_blocksize(sb->s_dev,BLOCK_SIZE);
486 printk("SysV FS: cannot read superblock in 512 byte mode\n");
487 goto failed;
490 sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
491 if (!silent)
492 printk("VFS: Found a %s FS (block size = %d) on device %s\n",
493 found, sb->sv_block_size, kdevname(dev));
494 sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;
495 /* The buffer code now supports block size 512 as well as 1024. */
496 sb->s_blocksize = sb->sv_block_size;
497 sb->s_blocksize_bits = sb->sv_block_size_bits;
498 /* set up enough so that it can read an inode */
499 sb->s_dev = dev;
500 sb->s_op = &sysv_sops;
501 root_inode = iget(sb,SYSV_ROOT_INO);
502 sb->s_root = d_alloc_root(root_inode);
503 if (!sb->s_root) {
504 printk("SysV FS: get root inode failed\n");
505 sysv_put_super(sb);
506 return NULL;
508 #ifndef CONFIG_SYSV_FS_WRITE
509 sb->s_flags |= MS_RDONLY;
510 #endif
511 sb->s_dirt = 1;
512 /* brelse(bh); resp. brelse(bh1); brelse(bh2);
513 occurs when the disk is unmounted. */
514 return sb;
517 /* This is only called on sync() and umount(), when s_dirt=1. */
518 static void sysv_write_super(struct super_block *sb)
520 if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {
521 /* If we are going to write out the super block,
522 then attach current time stamp.
523 But if the filesystem was marked clean, keep it clean. */
524 unsigned long time = CURRENT_TIME;
525 unsigned long old_time = *sb->sv_sb_time;
526 if (sb->sv_convert)
527 old_time = from_coh_ulong(old_time);
528 if (sb->sv_type == FSTYPE_SYSV4)
529 if (*sb->sv_sb_state == 0x7c269d38 - old_time)
530 *sb->sv_sb_state = 0x7c269d38 - time;
531 if (sb->sv_convert)
532 time = to_coh_ulong(time);
533 *sb->sv_sb_time = time;
534 mark_buffer_dirty(sb->sv_bh2, 1);
536 sb->s_dirt = 0;
539 static void sysv_put_super(struct super_block *sb)
541 /* we can assume sysv_write_super() has already been called,
542 and that the superblock is locked */
543 brelse(sb->sv_bh1);
544 if (sb->sv_bh1 != sb->sv_bh2) brelse(sb->sv_bh2);
545 /* switch back to default block size */
546 if (sb->s_blocksize != BLOCK_SIZE)
547 set_blocksize(sb->s_dev,BLOCK_SIZE);
550 static int sysv_statfs(struct super_block *sb, struct statfs *buf)
552 buf->f_type = sb->s_magic; /* type of filesystem */
553 buf->f_bsize = sb->sv_block_size; /* block size */
554 buf->f_blocks = sb->sv_ndatazones; /* total data blocks in file system */
555 buf->f_bfree = sysv_count_free_blocks(sb); /* free blocks in fs */
556 buf->f_bavail = buf->f_bfree; /* free blocks available to non-superuser */
557 buf->f_files = sb->sv_ninodes; /* total file nodes in file system */
558 buf->f_ffree = sysv_count_free_inodes(sb); /* free file nodes in fs */
559 buf->f_namelen = SYSV_NAMELEN;
560 /* Don't know what value to put in buf->f_fsid */ /* file system id */
561 return 0;
565 /* bmap support for running executables and shared libraries. */
567 static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr)
569 int tmp = inode->u.sysv_i.i_data[nr];
570 if (!tmp)
571 return 0;
572 return tmp + sb->sv_block_base;
575 static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert)
577 int tmp;
579 if (!bh)
580 return 0;
581 tmp = ((sysv_zone_t *) bh->b_data) [nr];
582 if (convert)
583 tmp = from_coh_ulong(tmp);
584 brelse(bh);
585 if (!tmp)
586 return 0;
587 return tmp + sb->sv_block_base;
590 static unsigned int sysv_block_map(struct inode *inode, unsigned int block)
592 struct super_block *sb;
593 int i, ret, convert;
595 ret = 0;
596 lock_kernel();
597 sb = inode->i_sb;
598 if (block < 10) {
599 ret = inode_bmap(sb, inode, block);
600 goto out;
602 block -= 10;
603 convert = sb->sv_convert;
604 if (block < sb->sv_ind_per_block) {
605 i = inode_bmap(sb, inode, 10);
606 if (!i)
607 goto out;
608 ret = block_bmap(sb,
609 bread(inode->i_dev, i, sb->sv_block_size),
610 block, convert);
611 goto out;
613 block -= sb->sv_ind_per_block;
614 if (block < sb->sv_ind_per_block_2) {
615 i = inode_bmap(sb, inode, 11);
616 if (!i)
617 goto out;
618 i = block_bmap(sb,
619 bread(inode->i_dev, i, sb->sv_block_size),
620 (block >> sb->sv_ind_per_block_bits), convert);
621 if (!i)
622 goto out;
623 ret = block_bmap(sb,
624 bread(inode->i_dev, i, sb->sv_block_size),
625 (block & sb->sv_ind_per_block_1), convert);
626 goto out;
628 block -= sb->sv_ind_per_block_2;
629 if (block < sb->sv_ind_per_block_3) {
630 i = inode_bmap(sb, inode, 12);
631 if (!i)
632 goto out;
633 i = block_bmap(sb,
634 bread(inode->i_dev, i, sb->sv_block_size),
635 (block >> sb->sv_ind_per_block_2_bits), convert);
636 if (!i)
637 goto out;
638 ret = block_bmap(sb,
639 bread(inode->i_dev, i, sb->sv_block_size),
640 ((block >> sb->sv_ind_per_block_bits) &
641 sb->sv_ind_per_block_1), convert);
642 if (!i)
643 goto out;
644 ret = block_bmap(sb,
645 bread(inode->i_dev, i, sb->sv_block_size),
646 (block & sb->sv_ind_per_block_1), convert);
647 goto out;
649 if ((int)block < 0)
650 printk("sysv_block_map: block < 0\n");
651 else
652 printk("sysv_block_map: block > big\n");
653 out:
654 unlock_kernel();
655 return ret;
658 /* End of bmap support. */
661 /* Access selected blocks of regular files (or directories) */
663 static struct buffer_head *inode_getblk(struct inode *inode, int nr, int new_block,
664 int *err, int metadata, long *phys, int *new)
666 struct super_block *sb;
667 u32 tmp;
668 u32 *p;
669 struct buffer_head * result;
671 sb = inode->i_sb;
672 p = inode->u.sysv_i.i_data + nr;
673 repeat:
674 tmp = *p;
675 if (tmp) {
676 if (metadata) {
677 result = sv_getblk(sb, inode->i_dev, tmp);
678 if (tmp == *p)
679 return result;
680 brelse(result);
681 goto repeat;
682 } else {
683 *phys = tmp;
684 return NULL;
687 *err = -EFBIG;
689 /* Check file limits.. */
691 unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
692 if (limit < RLIM_INFINITY) {
693 limit >>= sb->sv_block_size_bits;
694 if (new_block >= limit) {
695 send_sig(SIGXFSZ, current, 0);
696 *err = -EFBIG;
697 return NULL;
702 tmp = sysv_new_block(sb);
703 if (!tmp) {
704 *err = -ENOSPC;
705 return NULL;
707 if (metadata) {
708 result = sv_getblk(sb, inode->i_dev, tmp);
709 if (*p) {
710 sysv_free_block(sb, tmp);
711 brelse(result);
712 goto repeat;
714 } else {
715 if (*p) {
717 * Nobody is allowed to change block allocation
718 * state from under us:
720 BUG();
721 sysv_free_block(sb, tmp);
722 goto repeat;
724 *phys = tmp;
725 result = NULL;
726 *err = 0;
727 *new = 1;
729 *p = tmp;
731 inode->i_ctime = CURRENT_TIME;
732 mark_inode_dirty(inode);
733 return result;
736 static struct buffer_head *block_getblk(struct inode *inode,
737 struct buffer_head *bh, int nr, int new_block, int *err,
738 int metadata, long *phys, int *new)
740 struct super_block *sb;
741 u32 tmp, block;
742 sysv_zone_t *p;
743 struct buffer_head * result;
744 unsigned long limit;
746 result = NULL;
747 if (!bh)
748 goto out;
749 if (!buffer_uptodate(bh)) {
750 ll_rw_block(READ, 1, &bh);
751 wait_on_buffer(bh);
752 if (!buffer_uptodate(bh))
753 goto out;
755 sb = inode->i_sb;
756 p = nr + (sysv_zone_t *) bh->b_data;
757 repeat:
758 block = tmp = *p;
759 if (sb->sv_convert)
760 block = from_coh_ulong(block);
761 if (tmp) {
762 if (metadata) {
763 result = sv_getblk(sb, bh->b_dev, block);
764 if (tmp == *p)
765 goto out;
766 brelse(result);
767 goto repeat;
768 } else {
769 *phys = tmp;
770 goto out;
773 *err = -EFBIG;
775 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
776 if (limit < RLIM_INFINITY) {
777 limit >>= sb->sv_block_size_bits;
778 if (new_block >= limit) {
779 send_sig(SIGXFSZ, current, 0);
780 goto out;
784 block = sysv_new_block(sb);
785 if (!block)
786 goto out;
787 if (metadata) {
788 result = sv_getblk(sb, bh->b_dev, block);
789 if (*p) {
790 sysv_free_block(sb, block);
791 brelse(result);
792 goto repeat;
794 memset(result->b_data, 0, sb->sv_block_size);
795 mark_buffer_uptodate(result, 1);
796 mark_buffer_dirty(result, 1);
797 } else {
798 *phys = tmp;
799 *new = 1;
801 if (*p) {
802 sysv_free_block(sb, block);
803 brelse(result);
804 goto repeat;
806 *p = (sb->sv_convert ? to_coh_ulong(block) : block);
807 mark_buffer_dirty(bh, 1);
808 *err = 0;
809 out:
810 brelse(bh);
811 return result;
814 static int sysv_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
816 struct super_block *sb;
817 int ret, err, new;
818 struct buffer_head *bh;
819 unsigned long ptr, phys;
821 if (!create) {
822 phys = sysv_block_map(inode, iblock);
823 if (phys) {
824 bh_result->b_dev = inode->i_dev;
825 bh_result->b_blocknr = phys;
826 bh_result->b_state |= (1UL << BH_Mapped);
828 return 0;
831 err = -EIO;
832 new = 0;
833 ret = 0;
834 bh = NULL;
836 lock_kernel();
837 sb = inode->i_sb;
838 if (iblock < 0)
839 goto abort_negative;
840 if (iblock > sb->sv_ind_per_block_3)
841 goto abort_too_big;
843 err = 0;
844 ptr = iblock;
847 * ok, these macros clean the logic up a bit and make
848 * it much more readable:
850 #define GET_INODE_DATABLOCK(x) \
851 inode_getblk(inode, x, iblock, &err, 0, &phys, &new)
852 #define GET_INODE_PTR(x) \
853 inode_getblk(inode, x, iblock, &err, 1, NULL, NULL)
854 #define GET_INDIRECT_DATABLOCK(x) \
855 block_getblk (inode, bh, x, iblock, &err, 0, &phys, &new);
856 #define GET_INDIRECT_PTR(x) \
857 block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL);
859 if (ptr < 10) {
860 bh = GET_INODE_DATABLOCK(ptr);
861 goto out;
863 ptr -= 10;
864 if (ptr < sb->sv_ind_per_block) {
865 bh = GET_INODE_PTR(10);
866 goto get_indirect;
868 ptr -= sb->sv_ind_per_block;
869 if (ptr < sb->sv_ind_per_block_2) {
870 bh = GET_INODE_PTR(11);
871 goto get_double;
873 ptr -= sb->sv_ind_per_block_2;
874 bh = GET_INODE_PTR(12);
875 bh = GET_INDIRECT_PTR(ptr >> sb->sv_ind_per_block_2_bits);
876 get_double:
877 bh = GET_INDIRECT_PTR((ptr >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1);
878 get_indirect:
879 bh = GET_INDIRECT_DATABLOCK(ptr & sb->sv_ind_per_block_1);
881 #undef GET_INODE_DATABLOCK
882 #undef GET_INODE_PTR
883 #undef GET_INDIRECT_DATABLOCK
884 #undef GET_INDIRECT_PTR
886 out:
887 if (err)
888 goto abort;
889 bh_result->b_dev = inode->i_dev;
890 bh_result->b_blocknr = phys;
891 bh_result->b_state |= (1UL << BH_Mapped);
892 if (new)
893 bh_result->b_state |= (1UL << BH_New);
894 abort:
895 unlock_kernel();
896 return err;
898 abort_negative:
899 printk("sysv_get_block: block < 0\n");
900 goto abort;
902 abort_too_big:
903 printk("sysv_get_block: block > big\n");
904 goto abort;
907 static struct buffer_head *sysv_getblk(struct inode *inode, unsigned int block, int create)
909 struct buffer_head dummy;
910 int error;
912 dummy.b_state = 0;
913 dummy.b_blocknr = -1000;
914 error = sysv_get_block(inode, block, &dummy, create);
915 if (!error && buffer_mapped(&dummy)) {
916 struct buffer_head *bh;
917 bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->sv_block_size);
918 if (buffer_new(&dummy)) {
919 memset(bh->b_data, 0, inode->i_sb->sv_block_size);
920 mark_buffer_uptodate(bh, 1);
921 mark_buffer_dirty(bh, 1);
923 return bh;
925 return NULL;
928 struct buffer_head *sysv_file_bread(struct inode *inode, int block, int create)
930 struct buffer_head *bh;
932 bh = sysv_getblk(inode, block, create);
933 if (!bh || buffer_uptodate(bh))
934 return bh;
935 ll_rw_block(READ, 1, &bh);
936 wait_on_buffer(bh);
937 if (buffer_uptodate(bh))
938 return bh;
939 brelse(bh);
940 return NULL;
943 static int sysv_writepage(struct file *file, struct page *page)
945 return block_write_full_page(page,sysv_get_block);
947 static int sysv_readpage(struct file *file, struct page *page)
949 return block_read_full_page(page,sysv_get_block);
951 static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
953 return block_prepare_write(page,from,to,sysv_get_block);
955 static int sysv_bmap(struct address_space *mapping, long block)
957 return generic_block_bmap(mapping,block,sysv_get_block);
959 struct address_space_operations sysv_aops = {
960 readpage: sysv_readpage,
961 writepage: sysv_writepage,
962 sync_page: block_sync_page,
963 prepare_write: sysv_prepare_write,
964 commit_write: generic_commit_write,
965 bmap: sysv_bmap
968 #ifdef __BIG_ENDIAN
970 static inline unsigned long read3byte (unsigned char * p)
972 return (p[2] | (p[1]<<8) | (p[0]<<16));
975 static inline void write3byte (unsigned char *p , unsigned long val)
977 p[2]=val&0xFF;
978 p[1]=(val>>8)&0xFF;
979 p[0]=(val>>16)&0xFF;
982 #else
984 static inline unsigned long read3byte (unsigned char * p)
986 return (unsigned long)(*(unsigned short *)p)
987 | (unsigned long)(*(unsigned char *)(p+2)) << 16;
990 static inline void write3byte (unsigned char * p, unsigned long val)
992 *(unsigned short *)p = (unsigned short) val;
993 *(unsigned char *)(p+2) = val >> 16;
996 #endif
998 static inline unsigned long coh_read3byte (unsigned char * p)
1000 return (unsigned long)(*(unsigned char *)p) << 16
1001 | (unsigned long)(*(unsigned short *)(p+1));
1004 static inline void coh_write3byte (unsigned char * p, unsigned long val)
1006 *(unsigned char *)p = val >> 16;
1007 *(unsigned short *)(p+1) = (unsigned short) val;
1010 struct inode_operations sysv_symlink_inode_operations = {
1011 readlink: page_readlink,
1012 follow_link: page_follow_link,
1013 setattr: sysv_notify_change,
1016 static void sysv_read_inode(struct inode *inode)
1018 struct super_block * sb = inode->i_sb;
1019 struct buffer_head * bh;
1020 struct sysv_inode * raw_inode;
1021 unsigned int block, ino;
1022 umode_t mode;
1024 ino = inode->i_ino;
1025 inode->i_mode = 0;
1026 if (!ino || ino > sb->sv_ninodes) {
1027 printk("Bad inode number on dev %s"
1028 ": %d is out of range\n",
1029 kdevname(inode->i_dev), ino);
1030 return;
1032 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
1033 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
1034 printk("Major problem: unable to read inode from dev "
1035 "%s\n",
1036 kdevname(inode->i_dev));
1037 return;
1039 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
1040 mode = raw_inode->i_mode;
1041 if (sb->sv_kludge_symlinks)
1042 mode = from_coh_imode(mode);
1043 /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
1044 inode->i_mode = mode;
1045 inode->i_uid = (uid_t)raw_inode->i_uid;
1046 inode->i_gid = (gid_t)raw_inode->i_gid;
1047 inode->i_nlink = raw_inode->i_nlink;
1048 if (sb->sv_convert) {
1049 inode->i_size = from_coh_ulong(raw_inode->i_size);
1050 inode->i_atime = from_coh_ulong(raw_inode->i_atime);
1051 inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);
1052 inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);
1053 } else {
1054 inode->i_size = raw_inode->i_size;
1055 inode->i_atime = raw_inode->i_atime;
1056 inode->i_mtime = raw_inode->i_mtime;
1057 inode->i_ctime = raw_inode->i_ctime;
1059 inode->i_blocks = inode->i_blksize = 0;
1060 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1062 else
1063 if (sb->sv_convert)
1064 for (block = 0; block < 10+1+1+1; block++)
1065 inode->u.sysv_i.i_data[block] =
1066 coh_read3byte(&raw_inode->i_a.i_addb[3*block]);
1067 else
1068 for (block = 0; block < 10+1+1+1; block++)
1069 inode->u.sysv_i.i_data[block] =
1070 read3byte(&raw_inode->i_a.i_addb[3*block]);
1071 if (S_ISREG(inode->i_mode)) {
1072 inode->i_op = &sysv_file_inode_operations;
1073 inode->i_fop = &sysv_file_operations;
1074 inode->i_mapping->a_ops = &sysv_aops;
1075 } else if (S_ISDIR(inode->i_mode)) {
1076 inode->i_op = &sysv_dir_inode_operations;
1077 inode->i_fop = &sysv_dir_operations;
1078 } else if (S_ISLNK(inode->i_mode)) {
1079 inode->i_op = &sysv_symlink_inode_operations;
1080 inode->i_mapping->a_ops = &sysv_aops;
1081 } else
1082 init_special_inode(inode, inode->i_mode,raw_inode->i_a.i_rdev);
1083 brelse(bh);
1086 /* To avoid inconsistencies between inodes in memory and inodes on disk. */
1087 int sysv_notify_change(struct dentry *dentry, struct iattr *attr)
1089 struct inode *inode = dentry->d_inode;
1090 int error;
1092 if ((error = inode_change_ok(inode, attr)) != 0)
1093 return error;
1095 if (attr->ia_valid & ATTR_MODE)
1096 if (inode->i_sb->sv_kludge_symlinks)
1097 if (attr->ia_mode == COH_KLUDGE_SYMLINK_MODE)
1098 attr->ia_mode = COH_KLUDGE_NOT_SYMLINK;
1100 inode_setattr(inode, attr);
1102 return 0;
1105 static struct buffer_head * sysv_update_inode(struct inode * inode)
1107 struct super_block * sb = inode->i_sb;
1108 struct buffer_head * bh;
1109 struct sysv_inode * raw_inode;
1110 unsigned int ino, block;
1111 umode_t mode;
1113 ino = inode->i_ino;
1114 if (!ino || ino > sb->sv_ninodes) {
1115 printk("Bad inode number on dev %s"
1116 ": %d is out of range\n",
1117 kdevname(inode->i_dev), ino);
1118 return 0;
1120 block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
1121 if (!(bh = sv_bread(sb,inode->i_dev,block))) {
1122 printk("unable to read i-node block\n");
1123 return 0;
1125 raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
1126 mode = inode->i_mode;
1127 if (sb->sv_kludge_symlinks)
1128 mode = to_coh_imode(mode);
1129 raw_inode->i_mode = mode;
1130 raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
1131 raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
1132 raw_inode->i_nlink = inode->i_nlink;
1133 if (sb->sv_convert) {
1134 raw_inode->i_size = to_coh_ulong(inode->i_size);
1135 raw_inode->i_atime = to_coh_ulong(inode->i_atime);
1136 raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);
1137 raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);
1138 } else {
1139 raw_inode->i_size = inode->i_size;
1140 raw_inode->i_atime = inode->i_atime;
1141 raw_inode->i_mtime = inode->i_mtime;
1142 raw_inode->i_ctime = inode->i_ctime;
1144 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
1145 raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */
1146 else
1147 if (sb->sv_convert)
1148 for (block = 0; block < 10+1+1+1; block++)
1149 coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
1150 else
1151 for (block = 0; block < 10+1+1+1; block++)
1152 write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
1153 mark_buffer_dirty(bh, 1);
1154 return bh;
1157 void sysv_write_inode(struct inode * inode)
1159 struct buffer_head *bh;
1160 bh = sysv_update_inode(inode);
1161 brelse(bh);
1164 int sysv_sync_inode(struct inode * inode)
1166 int err = 0;
1167 struct buffer_head *bh;
1169 bh = sysv_update_inode(inode);
1170 if (bh && buffer_dirty(bh)) {
1171 ll_rw_block(WRITE, 1, &bh);
1172 wait_on_buffer(bh);
1173 if (buffer_req(bh) && !buffer_uptodate(bh))
1175 printk ("IO error syncing sysv inode ["
1176 "%s:%08lx]\n",
1177 kdevname(inode->i_dev), inode->i_ino);
1178 err = -1;
1181 else if (!bh)
1182 err = -1;
1183 brelse (bh);
1184 return err;
1187 /* Every kernel module contains stuff like this. */
1189 static DECLARE_FSTYPE_DEV(sysv_fs_type, "sysv", sysv_read_super);
1191 static int __init init_sysv_fs(void)
1193 return register_filesystem(&sysv_fs_type);
1196 static void __exit exit_sysv_fs(void)
1198 unregister_filesystem(&sysv_fs_type);
1201 EXPORT_NO_SYMBOLS;
1203 module_init(init_sysv_fs)
1204 module_exit(exit_sysv_fs)