patch-2.4.6 linux/fs/sysv/inode.c

Next file: linux/fs/sysv/itree.c
Previous file: linux/fs/sysv/ialloc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.5/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
@@ -21,499 +21,13 @@
  *  the superblock.
  */
 
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/sysv_fs.h>
-#include <linux/stat.h>
-#include <linux/string.h>
 #include <linux/locks.h>
-#include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/highuid.h>
 #include <asm/byteorder.h>
-#include <asm/uaccess.h>
-
-#if 0
-void sysv_print_inode(struct inode * inode)
-{
-        printk("ino %lu  mode 0%6.6o  lk %d  uid %d  gid %d"
-               "  sz %lu  blks %lu  cnt %u\n",
-               inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,
-               inode->i_gid, inode->i_size, inode->i_blocks,
-               atomic_read(&inode->i_count));
-        printk("  db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"
-               " 0x%lx 0x%lx>\n",
-                inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],
-                inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],
-                inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],
-                inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],
-                inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);
-        printk("  ib <0x%lx 0x%lx 0x%lx>\n",
-                inode->u.sysv_i.i_data[10],
-                inode->u.sysv_i.i_data[11],
-                inode->u.sysv_i.i_data[12]);
-}
-#endif
-
-static void sysv_delete_inode(struct inode *inode)
-{
-	lock_kernel();
-	inode->i_size = 0;
-	sysv_truncate(inode);
-	sysv_free_inode(inode);
-	unlock_kernel();
-}
-
-static void sysv_put_super(struct super_block *);
-static void sysv_write_super(struct super_block *);
-static void sysv_read_inode(struct inode *);
-static int sysv_statfs(struct super_block *, struct statfs *);
-
-static struct super_operations sysv_sops = {
-	read_inode:	sysv_read_inode,
-	write_inode:	sysv_write_inode,
-	delete_inode:	sysv_delete_inode,
-	put_super:	sysv_put_super,
-	write_super:	sysv_write_super,
-	statfs:		sysv_statfs,
-};
-
-/* The following functions try to recognize specific filesystems.
- * We recognize:
- * - Xenix FS by its magic number.
- * - SystemV FS by its magic number.
- * - Coherent FS by its funny fname/fpack field.
- * We discriminate among SystemV4 and SystemV2 FS by the assumption that
- * the time stamp is not < 01-01-1980.
- */
-
-static void detected_bs (u_char type, struct super_block *sb)
-{
-	u_char n_bits = type+8;
-	int bsize = 1 << n_bits;
-	int bsize_4 = bsize >> 2;
-	
-	sb->sv_block_size = bsize;
-	sb->sv_block_size_1 = bsize-1;
-	sb->sv_block_size_bits = n_bits;
-	sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
-	sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
-	sb->sv_inodes_per_block = bsize >> 6;
-	sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
-	sb->sv_inodes_per_block_bits = n_bits-6;
-	sb->sv_toobig_block = 10 +
-	  (sb->sv_ind_per_block = bsize_4) +
-	  (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
-	  (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
-	sb->sv_ind_per_block_1 = bsize_4-1;
-	sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
-	sb->sv_ind_per_block_2_bits = 2 *
-	  (sb->sv_ind_per_block_bits = n_bits-2);
-	sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
-	sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
-	sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
-	sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
-	sb->sv_ind0_size = 10 * bsize;
-	sb->sv_ind1_size = (10 + bsize_4)* bsize;
-	sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
-}
-
-static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
-{
-	struct xenix_super_block * sbd;
-
-	sbd = (struct xenix_super_block *) bh->b_data;
-	if (sbd->s_magic != 0x2b5544)
-		return NULL;
-	if (sbd->s_type > 2 || sbd->s_type < 1)
-		return NULL;
-	detected_bs(sbd->s_type, sb);
-	sb->sv_type = FSTYPE_XENIX;
-	return "Xenix";
-}
-static struct super_block * detected_xenix (struct super_block *sb, struct buffer_head *bh1, struct buffer_head *bh2)
-{
-	struct xenix_super_block * sbd1;
-	struct xenix_super_block * sbd2;
-
-	if (sb->sv_block_size >= BLOCK_SIZE)
-		/* block size >= 1024, so bh1 = bh2 */
-		sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
-	else {
-		/* block size = 512, so bh1 != bh2 */
-		sbd1 = (struct xenix_super_block *) bh1->b_data;
-		sbd2 = (struct xenix_super_block *) (bh2->b_data - BLOCK_SIZE/2);
-		/* sanity check */
-		if (sbd2->s_magic != 0x2b5544)
-			return NULL;
-	}
-
-	sb->sv_convert = 0;
-	sb->sv_kludge_symlinks = 1;
-	sb->sv_truncate = 1;
-	sb->sv_link_max = XENIX_LINK_MAX;
-	sb->sv_fic_size = XENIX_NICINOD;
-	sb->sv_flc_size = XENIX_NICFREE;
-	sb->sv_bh1 = bh1;
-	sb->sv_bh2 = bh2;
-	sb->sv_sbd1 = (char *) sbd1;
-	sb->sv_sbd2 = (char *) sbd2;
-	sb->sv_sb_fic_count = &sbd1->s_ninode;
-	sb->sv_sb_fic_inodes = &sbd1->s_inode[0];
-	sb->sv_sb_total_free_inodes = &sbd2->s_tinode;
-	sb->sv_sb_flc_count = &sbd1->s_nfree;
-	sb->sv_sb_flc_blocks = &sbd1->s_free[0];
-	sb->sv_sb_total_free_blocks = &sbd2->s_tfree;
-	sb->sv_sb_time = &sbd2->s_time;
-	sb->sv_firstinodezone = 2;
-	sb->sv_firstdatazone = sbd1->s_isize;
-	sb->sv_nzones = sbd1->s_fsize;
-	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
-	return sb;
-}
-
-static const char* detect_sysv4 (struct super_block *sb, struct buffer_head *bh)
-{
-	struct sysv4_super_block * sbd;
-
-	sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
-	if (sbd->s_magic != 0xfd187e20)
-		return NULL;
-	if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
-		return NULL;
-	if ((sbd->s_type > 3 || sbd->s_type < 1) && (sbd->s_type > 0x30 || sbd->s_type < 0x10))
-		return NULL;
-
-	/* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
-	   0x20 or 0x30 indicates that symbolic links and the 14-character
-	   filename limit is gone. Due to lack of information about this
-           feature read-only mode seems to be a reasonable approach... -KGB */
-
-	if (sbd->s_type >= 0x10) {
-		printk("SysV FS: can't handle long file names on %s, "
-		       "forcing read-only mode.\n", kdevname(sb->s_dev));
-		sb->s_flags |= MS_RDONLY;
-	}
-
-	detected_bs(sbd->s_type >= 0x10 ? (sbd->s_type >> 4) : sbd->s_type, sb);
-	sb->sv_type = FSTYPE_SYSV4;
-	return "SystemV";
-}
-
-static struct super_block * detected_sysv4 (struct super_block *sb, struct buffer_head *bh)
-{
-	struct sysv4_super_block * sbd;
-
-	if (sb->sv_block_size >= BLOCK_SIZE)
-		sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
-	else {
-		sbd = (struct sysv4_super_block *) bh->b_data;
-		/* sanity check */
-		if (sbd->s_magic != 0xfd187e20)
-			return NULL;
-		if (sbd->s_time < 315532800)
-			return NULL;
-	}
-
-	sb->sv_convert = 0;
-	sb->sv_kludge_symlinks = 0; /* ?? */
-	sb->sv_truncate = 1;
-	sb->sv_link_max = SYSV_LINK_MAX;
-	sb->sv_fic_size = SYSV_NICINOD;
-	sb->sv_flc_size = SYSV_NICFREE;
-	sb->sv_bh1 = bh;
-	sb->sv_bh2 = bh;
-	sb->sv_sbd1 = (char *) sbd;
-	sb->sv_sbd2 = (char *) sbd;
-	sb->sv_sb_fic_count = &sbd->s_ninode;
-	sb->sv_sb_fic_inodes = &sbd->s_inode[0];
-	sb->sv_sb_total_free_inodes = &sbd->s_tinode;
-	sb->sv_sb_flc_count = &sbd->s_nfree;
-	sb->sv_sb_flc_blocks = &sbd->s_free[0];
-	sb->sv_sb_total_free_blocks = &sbd->s_tfree;
-	sb->sv_sb_time = &sbd->s_time;
-	sb->sv_sb_state = &sbd->s_state;
-	sb->sv_firstinodezone = 2;
-	sb->sv_firstdatazone = sbd->s_isize;
-	sb->sv_nzones = sbd->s_fsize;
-	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
-	return sb;
-}
-
-static const char* detect_sysv2 (struct super_block *sb, struct buffer_head *bh)
-{
-	struct sysv2_super_block * sbd;
-
-	sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
-	if (sbd->s_magic != 0xfd187e20)
-		return NULL;
-	if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
-		return NULL;
-	if (sbd->s_type > 3 || sbd->s_type < 1)
-		return NULL;
-	detected_bs(sbd->s_type, sb);
-	sb->sv_type = FSTYPE_SYSV2;
-	return "SystemV Release 2";
-}
-static struct super_block * detected_sysv2 (struct super_block *sb, struct buffer_head *bh)
-{
-	struct sysv2_super_block * sbd;
-
-	if (sb->sv_block_size >= BLOCK_SIZE)
-		sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
-	else {
-		sbd = (struct sysv2_super_block *) bh->b_data;
-		/* sanity check */
-		if (sbd->s_magic != 0xfd187e20)
-			return NULL;
-		if (sbd->s_time < 315532800)
-			return NULL;
-	}
-
-	sb->sv_convert = 0;
-	sb->sv_kludge_symlinks = 0; /* ?? */
-	sb->sv_truncate = 1;
-	sb->sv_link_max = SYSV_LINK_MAX;
-	sb->sv_fic_size = SYSV_NICINOD;
-	sb->sv_flc_size = SYSV_NICFREE;
-	sb->sv_bh1 = bh;
-	sb->sv_bh2 = bh;
-	sb->sv_sbd1 = (char *) sbd;
-	sb->sv_sbd2 = (char *) sbd;
-	sb->sv_sb_fic_count = &sbd->s_ninode;
-	sb->sv_sb_fic_inodes = &sbd->s_inode[0];
-	sb->sv_sb_total_free_inodes = &sbd->s_tinode;
-	sb->sv_sb_flc_count = &sbd->s_nfree;
-	sb->sv_sb_flc_blocks = &sbd->s_free[0];
-	sb->sv_sb_total_free_blocks = &sbd->s_tfree;
-	sb->sv_sb_time = &sbd->s_time;
-	sb->sv_sb_state = &sbd->s_state;
-	sb->sv_firstinodezone = 2;
-	sb->sv_firstdatazone = sbd->s_isize;
-	sb->sv_nzones = sbd->s_fsize;
-	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
-	return sb;
-}
-
-static const char* detect_coherent (struct super_block *sb, struct buffer_head *bh)
-{
-	struct coh_super_block * sbd;
-
-	sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2);
-	if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
-	    || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
-		return NULL;
-	detected_bs(1, sb);
-	sb->sv_type = FSTYPE_COH;
-	return "Coherent";
-}
-static struct super_block * detected_coherent (struct super_block *sb, struct buffer_head *bh)
-{
-	struct coh_super_block * sbd;
-
-	sbd = (struct coh_super_block *) bh->b_data;
-	/* sanity check */
-	if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
-	    || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
-		return NULL;
-
-	sb->sv_convert = 1;
-	sb->sv_kludge_symlinks = 1;
-	sb->sv_truncate = 1;
-	sb->sv_link_max = COH_LINK_MAX;
-	sb->sv_fic_size = COH_NICINOD;
-	sb->sv_flc_size = COH_NICFREE;
-	sb->sv_bh1 = bh;
-	sb->sv_bh2 = bh;
-	sb->sv_sbd1 = (char *) sbd;
-	sb->sv_sbd2 = (char *) sbd;
-	sb->sv_sb_fic_count = &sbd->s_ninode;
-	sb->sv_sb_fic_inodes = &sbd->s_inode[0];
-	sb->sv_sb_total_free_inodes = &sbd->s_tinode;
-	sb->sv_sb_flc_count = &sbd->s_nfree;
-	sb->sv_sb_flc_blocks = &sbd->s_free[0];
-	sb->sv_sb_total_free_blocks = &sbd->s_tfree;
-	sb->sv_sb_time = &sbd->s_time;
-	sb->sv_firstinodezone = 2;
-	sb->sv_firstdatazone = sbd->s_isize;
-	sb->sv_nzones = from_coh_ulong(sbd->s_fsize);
-	sb->sv_ndatazones = sb->sv_nzones - sb->sv_firstdatazone;
-	return sb;
-}
 
-static struct super_block *sysv_read_super(struct super_block *sb,
-					   void *data, int silent)
-{
-	struct buffer_head *bh;
-	const char *found;
-	kdev_t dev = sb->s_dev;
-	struct inode *root_inode;
-	unsigned long blocknr;
-	
-	if (1024 != sizeof (struct xenix_super_block))
-		panic("Xenix FS: bad super-block size");
-	if ((512 != sizeof (struct sysv4_super_block))
-            || (512 != sizeof (struct sysv2_super_block)))
-		panic("SystemV FS: bad super-block size");
-	if (500 != sizeof (struct coh_super_block))
-		panic("Coherent FS: bad super-block size");
-	if (64 != sizeof (struct sysv_inode))
-		panic("sysv fs: bad i-node size");
-	set_blocksize(dev,BLOCK_SIZE);
-	sb->sv_block_base = 0;
-
-	/* Try to read Xenix superblock */
-	if ((bh = bread(dev, 1, BLOCK_SIZE)) != NULL) {
-		if ((found = detect_xenix(sb,bh)) != NULL)
-			goto ok;
-		brelse(bh);
-	}
-	if ((bh = bread(dev, 0, BLOCK_SIZE)) != NULL) {
-		/* Try to recognize SystemV superblock */
-		if ((found = detect_sysv4(sb,bh)) != NULL)
-			goto ok;
-		if ((found = detect_sysv2(sb,bh)) != NULL)
-			goto ok;
-		/* Try to recognize Coherent superblock */
-		if ((found = detect_coherent(sb,bh)) != NULL)
-			goto ok;
-		brelse(bh);
-	}
-	/* Try to recognize SystemV superblock */
-	/* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
-	/* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
-	/* Maybe we should also check the device geometry ? */
-	{	static int offsets[] = { 9, 15, 18, };
-		int i;
-		for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
-			if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
-				/* Try to recognize SystemV superblock */
-				if ((found = detect_sysv4(sb,bh)) != NULL) {
-					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
-						goto bad_shift;
-					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
-					goto ok;
-				}
-				if ((found = detect_sysv2(sb,bh)) != NULL) {
-					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
-						goto bad_shift;
-					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
-					goto ok;
-				}
-				brelse(bh);
-			}
-	}
-	bad_shift:
-	if (!silent)
-		printk("VFS: unable to read Xenix/SystemV/Coherent superblock on device "
-		       "%s\n", kdevname(dev));
-	failed:
-	return NULL;
-
-	ok:
-	if (sb->sv_block_size >= BLOCK_SIZE) {
-		if (sb->sv_block_size != BLOCK_SIZE) {
-			brelse(bh);
-			set_blocksize(dev, sb->sv_block_size);
-			blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
-			if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
-				goto bad_superblock;
-		}
-		switch (sb->sv_type) {
-			case FSTYPE_XENIX:
-				if (!detected_xenix(sb,bh,bh))
-					goto bad_superblock;
-				break;
-			case FSTYPE_SYSV4:
-				if (!detected_sysv4(sb,bh))
-					goto bad_superblock;
-				break;
-			case FSTYPE_SYSV2:
-				if (!detected_sysv2(sb,bh))
-					goto bad_superblock;
-				break;
-			default: goto bad_superblock;
-		goto superblock_ok;
-		bad_superblock:
-			brelse(bh);
-			printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
-			goto failed;
-		superblock_ok:
-		}
-	} else {
-		/* Switch to 512 block size. Unfortunately, we have to
-		   release the block bh and read it again. */
-		struct buffer_head *bh1, *bh2;
-		unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
-
-		brelse(bh);
-		set_blocksize(dev,sb->sv_block_size);
-		bh1 = NULL; bh2 = NULL;
-		switch (sb->sv_type) {
-			case FSTYPE_XENIX:
-				if ((bh1 = bread(dev, blocknr, sb->sv_block_size)) == NULL)
-					goto bad_superblock2;
-				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
-					goto bad_superblock2;
-				if (!detected_xenix(sb,bh1,bh2))
-					goto bad_superblock2;
-				break;
-			case FSTYPE_SYSV4:
-				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
-					goto bad_superblock2;
-				if (!detected_sysv4(sb,bh2))
-					goto bad_superblock2;
-				break;
-			case FSTYPE_SYSV2:
-				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
-					goto bad_superblock2;
-				if (!detected_sysv2(sb,bh2))
-					goto bad_superblock2;
-				break;
-			case FSTYPE_COH:
-				if ((bh2 = bread(dev, blocknr+1, sb->sv_block_size)) == NULL)
-					goto bad_superblock2;
-				if (!detected_coherent(sb,bh2))
-					goto bad_superblock2;
-				break;
-			default:
-			bad_superblock2:
-				brelse(bh1);
-				brelse(bh2);
-				set_blocksize(sb->s_dev,BLOCK_SIZE);
-				printk("SysV FS: cannot read superblock in 512 byte mode\n");
-				goto failed;
-		}
-	}
-	sb->sv_ninodes = (sb->sv_firstdatazone - sb->sv_firstinodezone) << sb->sv_inodes_per_block_bits;
-	if (!silent)
-		printk("VFS: Found a %s FS (block size = %d) on device %s\n",
-		       found, sb->sv_block_size, kdevname(dev));
-	sb->s_magic = SYSV_MAGIC_BASE + sb->sv_type;
-	/* The buffer code now supports block size 512 as well as 1024. */
-	sb->s_blocksize = sb->sv_block_size;
-	sb->s_blocksize_bits = sb->sv_block_size_bits;
-	/* set up enough so that it can read an inode */
-	sb->s_op = &sysv_sops;
-	root_inode = iget(sb,SYSV_ROOT_INO);
-	sb->s_root = d_alloc_root(root_inode);
-	if (!sb->s_root) {
-		printk("SysV FS: get root inode failed\n");
-		sysv_put_super(sb);
-		return NULL;
-	}
-#ifndef CONFIG_SYSV_FS_WRITE
-	sb->s_flags |= MS_RDONLY;
-#endif
-	sb->s_dirt = 1;
-	/* brelse(bh);  resp.  brelse(bh1); brelse(bh2);
-	   occurs when the disk is unmounted. */
-	return sb;
-}
 
 /* This is only called on sync() and umount(), when s_dirt=1. */
 static void sysv_write_super(struct super_block *sb)
@@ -523,15 +37,11 @@
 		   then attach current time stamp.
 		   But if the filesystem was marked clean, keep it clean. */
 		unsigned long time = CURRENT_TIME;
-		unsigned long old_time = *sb->sv_sb_time;
-		if (sb->sv_convert)
-			old_time = from_coh_ulong(old_time);
+		unsigned long old_time = fs32_to_cpu(sb, *sb->sv_sb_time);
 		if (sb->sv_type == FSTYPE_SYSV4)
-			if (*sb->sv_sb_state == 0x7c269d38 - old_time)
-				*sb->sv_sb_state = 0x7c269d38 - time;
-		if (sb->sv_convert)
-			time = to_coh_ulong(time);
-		*sb->sv_sb_time = time;
+			if (*sb->sv_sb_state == cpu_to_fs32(sb, 0x7c269d38 - old_time))
+				*sb->sv_sb_state = cpu_to_fs32(sb, 0x7c269d38 - time);
+		*sb->sv_sb_time = cpu_to_fs32(sb, time);
 		mark_buffer_dirty(sb->sv_bh2);
 	}
 	sb->s_dirt = 0;
@@ -550,445 +60,81 @@
 
 static int sysv_statfs(struct super_block *sb, struct statfs *buf)
 {
-	buf->f_type = sb->s_magic;			/* type of filesystem */
-	buf->f_bsize = sb->sv_block_size;		/* block size */
-	buf->f_blocks = sb->sv_ndatazones;		/* total data blocks in file system */
-	buf->f_bfree = sysv_count_free_blocks(sb);	/* free blocks in fs */
-	buf->f_bavail = buf->f_bfree;			/* free blocks available to non-superuser */
-	buf->f_files = sb->sv_ninodes;			/* total file nodes in file system */
-	buf->f_ffree = sysv_count_free_inodes(sb);	/* free file nodes in fs */
+	buf->f_type = sb->s_magic;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = sb->sv_ndatazones;
+	buf->f_bavail = buf->f_bfree = sysv_count_free_blocks(sb);
+	buf->f_files = sb->sv_ninodes;
+	buf->f_ffree = sysv_count_free_inodes(sb);
 	buf->f_namelen = SYSV_NAMELEN;
-	/* Don't know what value to put in buf->f_fsid */ /* file system id */
 	return 0;
 }
 
-
-/* bmap support for running executables and shared libraries. */
-
-static inline int inode_bmap(struct super_block * sb, struct inode * inode, int nr)
-{
-	int tmp = inode->u.sysv_i.i_data[nr];
-	if (!tmp)
-		return 0;
-	return tmp + sb->sv_block_base;
-}
-
-static int block_bmap(struct super_block * sb, struct buffer_head * bh, int nr, int convert)
-{
-	int tmp;
-
-	if (!bh)
-		return 0;
-	tmp = ((sysv_zone_t *) bh->b_data) [nr];
-	if (convert)
-		tmp = from_coh_ulong(tmp);
-	brelse(bh);
-	if (!tmp)
-		return 0;
-	return tmp + sb->sv_block_base;
-}
-
-static unsigned int sysv_block_map(struct inode *inode, unsigned int block)
-{
-	struct super_block *sb;
-	int i, ret, convert;
-
-	ret = 0;
-	lock_kernel();
-	sb = inode->i_sb;
-	if (block < 10) {
-		ret = inode_bmap(sb, inode, block);
-		goto out;
-	}
-	block -= 10;
-	convert = sb->sv_convert;
-	if (block < sb->sv_ind_per_block) {
-		i = inode_bmap(sb, inode, 10);
-		if (!i)
-			goto out;
-		ret = block_bmap(sb,
-				 bread(inode->i_dev, i, sb->sv_block_size),
-				 block, convert);
-		goto out;
-	}
-	block -= sb->sv_ind_per_block;
-	if (block < sb->sv_ind_per_block_2) {
-		i = inode_bmap(sb, inode, 11);
-		if (!i)
-			goto out;
-		i = block_bmap(sb,
-			       bread(inode->i_dev, i, sb->sv_block_size),
-			       (block >> sb->sv_ind_per_block_bits), convert);
-		if (!i)
-			goto out;
-		ret = block_bmap(sb,
-				 bread(inode->i_dev, i, sb->sv_block_size),
-				 (block & sb->sv_ind_per_block_1), convert);
-		goto out;
-	}
-	block -= sb->sv_ind_per_block_2;
-	if (block < sb->sv_ind_per_block_3) {
-		i = inode_bmap(sb, inode, 12);
-		if (!i)
-			goto out;
-		i = block_bmap(sb,
-			       bread(inode->i_dev, i, sb->sv_block_size),
-			       (block >> sb->sv_ind_per_block_2_bits), convert);
-		if (!i)
-			goto out;
-		ret = block_bmap(sb,
-				 bread(inode->i_dev, i, sb->sv_block_size),
-				 ((block >> sb->sv_ind_per_block_bits) &
-				  sb->sv_ind_per_block_1), convert);
-		if (!i)
-			goto out;
-		ret = block_bmap(sb,
-				 bread(inode->i_dev, i, sb->sv_block_size),
-				 (block & sb->sv_ind_per_block_1), convert);
-		goto out;
-	}
-	if ((int)block < 0)
-		printk("sysv_block_map: block < 0\n");
-	else
-		printk("sysv_block_map: block > big\n");
-out:
-	unlock_kernel();
-	return ret;
-}
-
-/* End of bmap support. */
-
-
-/* Access selected blocks of regular files (or directories) */
-
-static struct buffer_head *inode_getblk(struct inode *inode, int nr, int new_block,
-	int *err, int metadata, long *phys, int *new)
+/* 
+ * NXI <-> N0XI for PDP, XIN <-> XIN0 for le32, NIX <-> 0NIX for be32
+ */
+static inline void read3byte(struct super_block *sb,
+	unsigned char * from, unsigned char * to)
 {
-	struct super_block *sb;
-	u32 tmp;
-	u32 *p;
-	struct buffer_head * result;
-
-	sb = inode->i_sb;
-	p = inode->u.sysv_i.i_data + nr;
-repeat:
-	tmp = *p;
-	if (tmp) {
-		if (metadata) {
-			result = sv_getblk(sb, inode->i_dev, tmp);
-			if (tmp == *p)
-				return result;
-			brelse(result);
-			goto repeat;
-		} else {
-			*phys = tmp;
-			return NULL;
-		}
-	}
-
-	tmp = sysv_new_block(sb);
-	if (!tmp) {
-		*err = -ENOSPC;
-		return NULL;
-	}
-	if (metadata) {
-		result = sv_getblk(sb, inode->i_dev, tmp);
-		if (*p) {
-			sysv_free_block(sb, tmp);
-			brelse(result);
-			goto repeat;
-		}
+	if (sb->sv_bytesex == BYTESEX_PDP) {
+		to[0] = from[0];
+		to[1] = 0;
+		to[2] = from[1];
+		to[3] = from[2];
+	} else if (sb->sv_bytesex == BYTESEX_LE) {
+		to[0] = from[0];
+		to[1] = from[1];
+		to[2] = from[2];
+		to[3] = 0;
 	} else {
-		if (*p) {
-			/*
-			 * Nobody is allowed to change block allocation
-			 * state from under us:
-			 */
-			BUG();
-			sysv_free_block(sb, tmp);
-			goto repeat;
-		}
-		*phys = tmp;
-		result = NULL;
-		*err = 0;
-		*new = 1;
+		to[0] = 0;
+		to[1] = from[0];
+		to[2] = from[1];
+		to[3] = from[2];
 	}
-	*p = tmp;
-
-	inode->i_ctime = CURRENT_TIME;
-	mark_inode_dirty(inode);
-	return result;
 }
 
-static struct buffer_head *block_getblk(struct inode *inode,
-	struct buffer_head *bh, int nr, int new_block, int *err,
-	int metadata, long *phys, int *new)
-{
-	struct super_block *sb;
-	u32 tmp, block;
-	sysv_zone_t *p;
-	struct buffer_head * result;
-
-	result = NULL;
-	if (!bh)
-		goto out;
-	if (!buffer_uptodate(bh)) {
-		ll_rw_block(READ, 1, &bh);
-		wait_on_buffer(bh);
-		if (!buffer_uptodate(bh))
-			goto out;
-	}
-	sb = inode->i_sb;
-	p = nr + (sysv_zone_t *) bh->b_data;
-repeat:
-	block = tmp = *p;
-	if (sb->sv_convert)
-		block = from_coh_ulong(block);
-	if (tmp) {
-		if (metadata) {
-			result = sv_getblk(sb, bh->b_dev, block);
-			if (tmp == *p)
-				goto out;
-			brelse(result);
-			goto repeat;
-		} else {
-			*phys = tmp;
-			goto out;
-		}
-	}
-
-	block = sysv_new_block(sb);
-	if (!block)
-		goto out;
-	if (metadata) {
-		result = sv_getblk(sb, bh->b_dev, block);
-		if (*p) {
-			sysv_free_block(sb, block);
-			brelse(result);
-			goto repeat;
-		}
-		memset(result->b_data, 0, sb->sv_block_size);
-		mark_buffer_uptodate(result, 1);
-		mark_buffer_dirty(result);
+static inline void write3byte(struct super_block *sb,
+	unsigned char * from, unsigned char * to)
+{
+	if (sb->sv_bytesex == BYTESEX_PDP) {
+		to[0] = from[0];
+		to[1] = from[2];
+		to[2] = from[3];
+	} else if (sb->sv_bytesex == BYTESEX_LE) {
+		to[0] = from[0];
+		to[1] = from[1];
+		to[2] = from[2];
 	} else {
-		*phys = tmp;
-		*new = 1;
-	}
-	if (*p) {
-		sysv_free_block(sb, block);
-		brelse(result);
-		goto repeat;
+		to[0] = from[1];
+		to[1] = from[2];
+		to[2] = from[3];
 	}
-	*p = (sb->sv_convert ? to_coh_ulong(block) : block);
-	mark_buffer_dirty(bh);
-	*err = 0;
-out:
-	brelse(bh);
-	return result;
 }
 
-static int sysv_get_block(struct inode *inode, long iblock, struct buffer_head *bh_result, int create)
-{
-	struct super_block *sb;
-	int ret, err, new;
-	struct buffer_head *bh;
-	unsigned long ptr, phys;
-
-	if (!create) {
-		phys = sysv_block_map(inode, iblock);
-		if (phys) {
-			bh_result->b_dev = inode->i_dev;
-			bh_result->b_blocknr = phys;
-			bh_result->b_state |= (1UL << BH_Mapped);
-		}
-		return 0;
-	}
-
-	err = -EIO;
-	new = 0;
-	ret = 0;
-	bh = NULL;
-
-	lock_kernel();
-	sb = inode->i_sb;
-	if (iblock < 0)
-		goto abort_negative;
-	if (iblock > sb->sv_ind_per_block_3)
-		goto abort_too_big;
-
-	err = 0;
-	ptr = iblock;
-
-	/*
-	 * ok, these macros clean the logic up a bit and make
-	 * it much more readable:
-	 */
-#define GET_INODE_DATABLOCK(x) \
-		inode_getblk(inode, x, iblock, &err, 0, &phys, &new)
-#define GET_INODE_PTR(x) \
-		inode_getblk(inode, x, iblock, &err, 1, NULL, NULL)
-#define GET_INDIRECT_DATABLOCK(x) \
-		block_getblk (inode, bh, x, iblock, &err, 0, &phys, &new);
-#define GET_INDIRECT_PTR(x) \
-		block_getblk (inode, bh, x, iblock, &err, 1, NULL, NULL);
-
-	if (ptr < 10) {
-		bh = GET_INODE_DATABLOCK(ptr);
-		goto out;
-	}
-	ptr -= 10;
-	if (ptr < sb->sv_ind_per_block) {
-		bh = GET_INODE_PTR(10);
-		goto get_indirect;
-	}
-	ptr -= sb->sv_ind_per_block;
-	if (ptr < sb->sv_ind_per_block_2) {
-		bh = GET_INODE_PTR(11);
-		goto get_double;
-	}
-	ptr -= sb->sv_ind_per_block_2;
-	bh = GET_INODE_PTR(12);
-	bh = GET_INDIRECT_PTR(ptr >> sb->sv_ind_per_block_2_bits);
-get_double:
-	bh = GET_INDIRECT_PTR((ptr >> sb->sv_ind_per_block_bits) & sb->sv_ind_per_block_1);
-get_indirect:
-	bh = GET_INDIRECT_DATABLOCK(ptr & sb->sv_ind_per_block_1);
-
-#undef GET_INODE_DATABLOCK
-#undef GET_INODE_PTR
-#undef GET_INDIRECT_DATABLOCK
-#undef GET_INDIRECT_PTR
-
-out:
-	if (err)
-		goto abort;
-	bh_result->b_dev = inode->i_dev;
-	bh_result->b_blocknr = phys;
-	bh_result->b_state |= (1UL << BH_Mapped);
-	if (new)
-		bh_result->b_state |= (1UL << BH_New);
-abort:
-	unlock_kernel();
-	return err;
-
-abort_negative:
-	printk("sysv_get_block: block < 0\n");
-	goto abort;
-
-abort_too_big:
-	printk("sysv_get_block: block > big\n");
-	goto abort;
-}
-
-static struct buffer_head *sysv_getblk(struct inode *inode, unsigned int block, int create)
-{
-	struct buffer_head dummy;
-	int error;
-
-	dummy.b_state = 0;
-	dummy.b_blocknr = -1000;
-	error = sysv_get_block(inode, block, &dummy, create);
-	if (!error && buffer_mapped(&dummy)) {
-		struct buffer_head *bh;
-		bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->sv_block_size);
-		if (buffer_new(&dummy)) {
-			memset(bh->b_data, 0, inode->i_sb->sv_block_size);
-			mark_buffer_uptodate(bh, 1);
-			mark_buffer_dirty(bh);
-		}
-		return bh;
-	}
-	return NULL;
-}
-
-struct buffer_head *sysv_file_bread(struct inode *inode, int block, int create)
-{
-	struct buffer_head *bh;
-
-	bh = sysv_getblk(inode, block, create);
-	if (!bh || buffer_uptodate(bh))
-		return bh;
-	ll_rw_block(READ, 1, &bh);
-	wait_on_buffer(bh);
-	if (buffer_uptodate(bh))
-		return bh;
-	brelse(bh);
-	return NULL;
-}
-
-static int sysv_writepage(struct page *page)
-{
-	return block_write_full_page(page,sysv_get_block);
-}
-static int sysv_readpage(struct file *file, struct page *page)
-{
-	return block_read_full_page(page,sysv_get_block);
-}
-static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
-{
-	return block_prepare_write(page,from,to,sysv_get_block);
-}
-static int sysv_bmap(struct address_space *mapping, long block)
-{
-	return generic_block_bmap(mapping,block,sysv_get_block);
-}
-struct address_space_operations sysv_aops = {
-	readpage: sysv_readpage,
-	writepage: sysv_writepage,
-	sync_page: block_sync_page,
-	prepare_write: sysv_prepare_write,
-	commit_write: generic_commit_write,
-	bmap: sysv_bmap
-};
-
-#ifdef __BIG_ENDIAN
-
-static inline unsigned long read3byte (unsigned char * p)
-{
-	return (p[2] | (p[1]<<8) | (p[0]<<16));
-}
-
-static inline void write3byte (unsigned char *p , unsigned long val)
-{
-	p[2]=val&0xFF;
-	p[1]=(val>>8)&0xFF;
-	p[0]=(val>>16)&0xFF;
-}
-
-#else
-
-static inline unsigned long read3byte (unsigned char * p)
-{
-	return (unsigned long)(*(unsigned short *)p)
-	     | (unsigned long)(*(unsigned char *)(p+2)) << 16;
-}
-
-static inline void write3byte (unsigned char * p, unsigned long val)
-{
-	*(unsigned short *)p = (unsigned short) val;
-	*(unsigned char *)(p+2) = val >> 16;
-}
-
-#endif
-
-static inline unsigned long coh_read3byte (unsigned char * p)
-{
-	return (unsigned long)(*(unsigned char *)p) << 16
-	     | (unsigned long)(*(unsigned short *)(p+1));
-}
-
-static inline void coh_write3byte (unsigned char * p, unsigned long val)
-{
-	*(unsigned char *)p = val >> 16;
-	*(unsigned short *)(p+1) = (unsigned short) val;
-}
-
-struct inode_operations sysv_symlink_inode_operations = {
+static struct inode_operations sysv_symlink_inode_operations = {
 	readlink:	page_readlink,
 	follow_link:	page_follow_link,
 	setattr:	sysv_notify_change,
 };
 
+void sysv_set_inode(struct inode *inode, dev_t rdev)
+{
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_op = &sysv_file_inode_operations;
+		inode->i_fop = &sysv_file_operations;
+		inode->i_mapping->a_ops = &sysv_aops;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &sysv_dir_inode_operations;
+		inode->i_fop = &sysv_dir_operations;
+		inode->i_mapping->a_ops = &sysv_aops;
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &sysv_symlink_inode_operations;
+		inode->i_mapping->a_ops = &sysv_aops;
+	} else
+		init_special_inode(inode, inode->i_mode, rdev);
+}
+
 static void sysv_read_inode(struct inode *inode)
 {
 	struct super_block * sb = inode->i_sb;
@@ -996,67 +142,41 @@
 	struct sysv_inode * raw_inode;
 	unsigned int block, ino;
 	umode_t mode;
+	dev_t rdev = 0;
 
 	ino = inode->i_ino;
-	inode->i_mode = 0;
 	if (!ino || ino > sb->sv_ninodes) {
 		printk("Bad inode number on dev %s"
 		       ": %d is out of range\n",
 		       kdevname(inode->i_dev), ino);
 		return;
 	}
-	block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
-	if (!(bh = sv_bread(sb,inode->i_dev,block))) {
-		printk("Major problem: unable to read inode from dev "
-		       "%s\n",
-		       kdevname(inode->i_dev));
+	raw_inode = sysv_raw_inode(sb, ino, &bh);
+	if (!raw_inode) {
+		printk("Major problem: unable to read inode from dev %s\n",
+		       bdevname(inode->i_dev));
 		return;
 	}
-	raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
-	mode = raw_inode->i_mode;
+	mode = fs16_to_cpu(sb, raw_inode->i_mode);
 	if (sb->sv_kludge_symlinks)
 		mode = from_coh_imode(mode);
 	/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
 	inode->i_mode = mode;
-	inode->i_uid = (uid_t)raw_inode->i_uid;
-	inode->i_gid = (gid_t)raw_inode->i_gid;
-	inode->i_nlink = raw_inode->i_nlink;
-	if (sb->sv_convert) {
-		inode->i_size = from_coh_ulong(raw_inode->i_size);
-		inode->i_atime = from_coh_ulong(raw_inode->i_atime);
-		inode->i_mtime = from_coh_ulong(raw_inode->i_mtime);
-		inode->i_ctime = from_coh_ulong(raw_inode->i_ctime);
-	} else {
-		inode->i_size = raw_inode->i_size;
-		inode->i_atime = raw_inode->i_atime;
-		inode->i_mtime = raw_inode->i_mtime;
-		inode->i_ctime = raw_inode->i_ctime;
-	}
+	inode->i_uid = (uid_t)fs16_to_cpu(sb, raw_inode->i_uid);
+	inode->i_gid = (gid_t)fs16_to_cpu(sb, raw_inode->i_gid);
+	inode->i_nlink = fs16_to_cpu(sb, raw_inode->i_nlink);
+	inode->i_size = fs32_to_cpu(sb, raw_inode->i_size);
+	inode->i_atime = fs32_to_cpu(sb, raw_inode->i_atime);
+	inode->i_mtime = fs32_to_cpu(sb, raw_inode->i_mtime);
+	inode->i_ctime = fs32_to_cpu(sb, raw_inode->i_ctime);
 	inode->i_blocks = inode->i_blksize = 0;
-	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
-		;
-	else
-	if (sb->sv_convert)
-		for (block = 0; block < 10+1+1+1; block++)
-			inode->u.sysv_i.i_data[block] =
-				coh_read3byte(&raw_inode->i_a.i_addb[3*block]);
-	else
-		for (block = 0; block < 10+1+1+1; block++)
-			inode->u.sysv_i.i_data[block] =
-				read3byte(&raw_inode->i_a.i_addb[3*block]);
-	if (S_ISREG(inode->i_mode)) {
-		inode->i_op = &sysv_file_inode_operations;
-		inode->i_fop = &sysv_file_operations;
-		inode->i_mapping->a_ops = &sysv_aops;
-	} else if (S_ISDIR(inode->i_mode)) {
-		inode->i_op = &sysv_dir_inode_operations;
-		inode->i_fop = &sysv_dir_operations;
-	} else if (S_ISLNK(inode->i_mode)) {
-		inode->i_op = &sysv_symlink_inode_operations;
-		inode->i_mapping->a_ops = &sysv_aops;
-	} else
-		init_special_inode(inode, inode->i_mode,raw_inode->i_a.i_rdev);
+	for (block = 0; block < 10+1+1+1; block++)
+		read3byte(sb, &raw_inode->i_a.i_addb[3*block],
+			(unsigned char*)&inode->u.sysv_i.i_data[block]);
 	brelse(bh);
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+		rdev = (u16)fs32_to_cpu(sb, inode->u.sysv_i.i_data[0]);
+	sysv_set_inode(inode, rdev);
 }
 
 /* To avoid inconsistencies between inodes in memory and inodes on disk. */
@@ -1088,44 +208,32 @@
 
 	ino = inode->i_ino;
 	if (!ino || ino > sb->sv_ninodes) {
-		printk("Bad inode number on dev %s"
-		       ": %d is out of range\n",
-		       kdevname(inode->i_dev), ino);
+		printk("Bad inode number on dev %s: %d is out of range\n",
+		       bdevname(inode->i_dev), ino);
 		return 0;
 	}
-	block = sb->sv_firstinodezone + ((ino-1) >> sb->sv_inodes_per_block_bits);
-	if (!(bh = sv_bread(sb,inode->i_dev,block))) {
+	raw_inode = sysv_raw_inode(sb, ino, &bh);
+	if (!raw_inode) {
 		printk("unable to read i-node block\n");
 		return 0;
 	}
-	raw_inode = (struct sysv_inode *) bh->b_data + ((ino-1) & sb->sv_inodes_per_block_1);
 	mode = inode->i_mode;
 	if (sb->sv_kludge_symlinks)
 		mode = to_coh_imode(mode);
-	raw_inode->i_mode = mode;
-	raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
-	raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
-	raw_inode->i_nlink = inode->i_nlink;
-	if (sb->sv_convert) {
-		raw_inode->i_size = to_coh_ulong(inode->i_size);
-		raw_inode->i_atime = to_coh_ulong(inode->i_atime);
-		raw_inode->i_mtime = to_coh_ulong(inode->i_mtime);
-		raw_inode->i_ctime = to_coh_ulong(inode->i_ctime);
-	} else {
-		raw_inode->i_size = inode->i_size;
-		raw_inode->i_atime = inode->i_atime;
-		raw_inode->i_mtime = inode->i_mtime;
-		raw_inode->i_ctime = inode->i_ctime;
-	}
+	raw_inode->i_mode = cpu_to_fs16(sb, mode);
+	raw_inode->i_uid = cpu_to_fs16(sb, fs_high2lowuid(inode->i_uid));
+	raw_inode->i_gid = cpu_to_fs16(sb, fs_high2lowgid(inode->i_gid));
+	raw_inode->i_nlink = cpu_to_fs16(sb, inode->i_nlink);
+	raw_inode->i_size = cpu_to_fs32(sb, inode->i_size);
+	raw_inode->i_atime = cpu_to_fs32(sb, inode->i_atime);
+	raw_inode->i_mtime = cpu_to_fs32(sb, inode->i_mtime);
+	raw_inode->i_ctime = cpu_to_fs32(sb, inode->i_ctime);
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
-		raw_inode->i_a.i_rdev = kdev_t_to_nr(inode->i_rdev); /* write 2 or 3 bytes ?? */
-	else
-	if (sb->sv_convert)
-		for (block = 0; block < 10+1+1+1; block++)
-			coh_write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
-	else
-		for (block = 0; block < 10+1+1+1; block++)
-			write3byte(&raw_inode->i_a.i_addb[3*block],inode->u.sysv_i.i_data[block]);
+		inode->u.sysv_i.i_data[0] = 
+			cpu_to_fs32(sb, kdev_t_to_nr(inode->i_rdev));
+	for (block = 0; block < 10+1+1+1; block++)
+		write3byte(sb, (unsigned char*)&inode->u.sysv_i.i_data[block],
+			&raw_inode->i_a.i_addb[3*block]);
 	mark_buffer_dirty(bh);
 	return bh;
 }
@@ -1148,11 +256,9 @@
         if (bh && buffer_dirty(bh)) {
                 ll_rw_block(WRITE, 1, &bh);
                 wait_on_buffer(bh);
-                if (buffer_req(bh) && !buffer_uptodate(bh))
-                {
-                        printk ("IO error syncing sysv inode ["
-				"%s:%08lx]\n",
-                                kdevname(inode->i_dev), inode->i_ino);
+                if (buffer_req(bh) && !buffer_uptodate(bh)) {
+                        printk ("IO error syncing sysv inode [%s:%08lx]\n",
+                                bdevname(inode->i_dev), inode->i_ino);
                         err = -1;
                 }
         }
@@ -1162,21 +268,20 @@
         return err;
 }
 
-/* Every kernel module contains stuff like this. */
-
-static DECLARE_FSTYPE_DEV(sysv_fs_type, "sysv", sysv_read_super);
-
-static int __init init_sysv_fs(void)
-{
-	return register_filesystem(&sysv_fs_type);
-}
-
-static void __exit exit_sysv_fs(void)
+static void sysv_delete_inode(struct inode *inode)
 {
-	unregister_filesystem(&sysv_fs_type);
+	lock_kernel();
+	inode->i_size = 0;
+	sysv_truncate(inode);
+	sysv_free_inode(inode);
+	unlock_kernel();
 }
 
-EXPORT_NO_SYMBOLS;
-
-module_init(init_sysv_fs)
-module_exit(exit_sysv_fs)
+struct super_operations sysv_sops = {
+	read_inode:	sysv_read_inode,
+	write_inode:	sysv_write_inode,
+	delete_inode:	sysv_delete_inode,
+	put_super:	sysv_put_super,
+	write_super:	sysv_write_super,
+	statfs:		sysv_statfs,
+};

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)