Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/fs/freevxfs/Makefile b/fs/freevxfs/Makefile
new file mode 100644
index 0000000..87ad097
--- /dev/null
+++ b/fs/freevxfs/Makefile
@@ -0,0 +1,8 @@
+#
+# VxFS Makefile
+#
+
+obj-$(CONFIG_VXFS_FS) += freevxfs.o
+
+freevxfs-objs := vxfs_bmap.o vxfs_fshead.o vxfs_immed.o vxfs_inode.o \
+		 vxfs_lookup.o vxfs_olt.o vxfs_subr.o vxfs_super.o
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
new file mode 100644
index 0000000..8da0252
--- /dev/null
+++ b/fs/freevxfs/vxfs.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _VXFS_SUPER_H_
+#define _VXFS_SUPER_H_
+
+/*
+ * Veritas filesystem driver - superblock structure.
+ *
+ * This file contains the definition of the disk and core
+ * superblocks of the Veritas Filesystem.
+ */
+#include <linux/types.h>
+#include "vxfs_kcompat.h"
+
+
+/*
+ * Data types for use with the VxFS ondisk format.
+ */
+typedef	int32_t		vx_daddr_t;
+typedef int32_t		vx_ino_t;
+
+/*
+ * Superblock magic number (vxfs_super->vs_magic).
+ */
+#define VXFS_SUPER_MAGIC	0xa501FCF5
+
+/*
+ * The root inode.
+ */
+#define VXFS_ROOT_INO		2
+
+/*
+ * Num of entries in free extent array
+ */
+#define VXFS_NEFREE		32
+
+
+/*
+ * VxFS superblock (disk).
+ */
+struct vxfs_sb {
+	/*
+	 * Readonly fields for the version 1 superblock.
+	 *
+	 * Lots of this fields are no more used by version 2
+	 * and never filesystems.
+	 */
+	u_int32_t	vs_magic;		/* Magic number */
+	int32_t		vs_version;		/* VxFS version */
+	u_int32_t	vs_ctime;		/* create time - secs */
+	u_int32_t	vs_cutime;		/* create time - usecs */
+	int32_t		__unused1;		/* unused */
+	int32_t		__unused2;		/* unused */
+	vx_daddr_t	vs_old_logstart;	/* obsolete */
+	vx_daddr_t	vs_old_logend;		/* obsolete */
+	int32_t		vs_bsize;		/* block size */
+	int32_t		vs_size;		/* number of blocks */
+	int32_t		vs_dsize;		/* number of data blocks */
+	u_int32_t	vs_old_ninode;		/* obsolete */
+	int32_t		vs_old_nau;		/* obsolete */
+	int32_t		__unused3;		/* unused */
+	int32_t		vs_old_defiextsize;	/* obsolete */
+	int32_t		vs_old_ilbsize;		/* obsolete */
+	int32_t		vs_immedlen;		/* size of immediate data area */
+	int32_t		vs_ndaddr;		/* number of direct extentes */
+	vx_daddr_t	vs_firstau;		/* address of first AU */
+	vx_daddr_t	vs_emap;		/* offset of extent map in AU */
+	vx_daddr_t	vs_imap;		/* offset of inode map in AU */
+	vx_daddr_t	vs_iextop;		/* offset of ExtOp. map in AU */
+	vx_daddr_t	vs_istart;		/* offset of inode list in AU */
+	vx_daddr_t	vs_bstart;		/* offset of fdblock in AU */
+	vx_daddr_t	vs_femap;		/* aufirst + emap */
+	vx_daddr_t	vs_fimap;		/* aufirst + imap */
+	vx_daddr_t	vs_fiextop;		/* aufirst + iextop */
+	vx_daddr_t	vs_fistart;		/* aufirst + istart */
+	vx_daddr_t	vs_fbstart;		/* aufirst + bstart */
+	int32_t		vs_nindir;		/* number of entries in indir */
+	int32_t		vs_aulen;		/* length of AU in blocks */
+	int32_t		vs_auimlen;		/* length of imap in blocks */
+	int32_t		vs_auemlen;		/* length of emap in blocks */
+	int32_t		vs_auilen;		/* length of ilist in blocks */
+	int32_t		vs_aupad;		/* length of pad in blocks */
+	int32_t		vs_aublocks;		/* data blocks in AU */
+	int32_t		vs_maxtier;		/* log base 2 of aublocks */
+	int32_t		vs_inopb;		/* number of inodes per blk */
+	int32_t		vs_old_inopau;		/* obsolete */
+	int32_t		vs_old_inopilb;		/* obsolete */
+	int32_t		vs_old_ndiripau;	/* obsolete */
+	int32_t		vs_iaddrlen;		/* size of indirect addr ext. */
+	int32_t		vs_bshift;		/* log base 2 of bsize */
+	int32_t		vs_inoshift;		/* log base 2 of inobp */
+	int32_t		vs_bmask;		/* ~( bsize - 1 ) */
+	int32_t		vs_boffmask;		/* bsize - 1 */
+	int32_t		vs_old_inomask;		/* old_inopilb - 1 */
+	int32_t		vs_checksum;		/* checksum of V1 data */
+	
+	/*
+	 * Version 1, writable
+	 */
+	int32_t		vs_free;		/* number of free blocks */
+	int32_t		vs_ifree;		/* number of free inodes */
+	int32_t		vs_efree[VXFS_NEFREE];	/* number of free extents by size */
+	int32_t		vs_flags;		/* flags ?!? */
+	u_int8_t	vs_mod;			/* filesystem has been changed */
+	u_int8_t	vs_clean;		/* clean FS */
+	u_int16_t	__unused4;		/* unused */
+	u_int32_t	vs_firstlogid;		/* mount time log ID */
+	u_int32_t	vs_wtime;		/* last time written - sec */
+	u_int32_t	vs_wutime;		/* last time written - usec */
+	u_int8_t	vs_fname[6];		/* FS name */
+	u_int8_t	vs_fpack[6];		/* FS pack name */
+	int32_t		vs_logversion;		/* log format version */
+	int32_t		__unused5;		/* unused */
+	
+	/*
+	 * Version 2, Read-only
+	 */
+	vx_daddr_t	vs_oltext[2];		/* OLT extent and replica */
+	int32_t		vs_oltsize;		/* OLT extent size */
+	int32_t		vs_iauimlen;		/* size of inode map */
+	int32_t		vs_iausize;		/* size of IAU in blocks */
+	int32_t		vs_dinosize;		/* size of inode in bytes */
+	int32_t		vs_old_dniaddr;		/* indir levels per inode */
+	int32_t		vs_checksum2;		/* checksum of V2 RO */
+
+	/*
+	 * Actually much more...
+	 */
+};
+
+
+/*
+ * In core superblock filesystem private data for VxFS.
+ */
+struct vxfs_sb_info {
+	struct vxfs_sb		*vsi_raw;	/* raw (on disk) supeblock */
+	struct buffer_head	*vsi_bp;	/* buffer for raw superblock*/
+	struct inode		*vsi_fship;	/* fileset header inode */
+	struct inode		*vsi_ilist;	/* inode list inode */
+	struct inode		*vsi_stilist;	/* structual inode list inode */
+	u_long			vsi_iext;	/* initial inode list */
+	ino_t			vsi_fshino;	/* fileset header inode */
+	daddr_t			vsi_oltext;	/* OLT extent */
+	daddr_t			vsi_oltsize;	/* OLT size */
+};
+
+
+/*
+ * File modes.  File types above 0xf000 are vxfs internal only, they should
+ * not be passed back to higher levels of the system.  vxfs file types must
+ * never have one of the regular file type bits set.
+ */
+enum vxfs_mode {
+	VXFS_ISUID = 0x00000800,	/* setuid */
+	VXFS_ISGID = 0x00000400,	/* setgid */
+	VXFS_ISVTX = 0x00000200,	/* sticky bit */
+	VXFS_IREAD = 0x00000100,	/* read */
+	VXFS_IWRITE = 0x00000080,	/* write */
+	VXFS_IEXEC = 0x00000040,	/* exec */
+
+	VXFS_IFIFO = 0x00001000,	/* Named pipe */
+	VXFS_IFCHR = 0x00002000,	/* Character device */
+	VXFS_IFDIR = 0x00004000,	/* Directory */
+	VXFS_IFNAM = 0x00005000,	/* Xenix device ?? */
+	VXFS_IFBLK = 0x00006000,	/* Block device */
+	VXFS_IFREG = 0x00008000,	/* Regular file */
+	VXFS_IFCMP = 0x00009000,	/* Compressed file ?!? */
+	VXFS_IFLNK = 0x0000a000,	/* Symlink */
+	VXFS_IFSOC = 0x0000c000,	/* Socket */
+
+	/* VxFS internal */
+	VXFS_IFFSH = 0x10000000,	/* Fileset header */
+	VXFS_IFILT = 0x20000000,	/* Inode list */
+	VXFS_IFIAU = 0x30000000,	/* Inode allocation unit */
+	VXFS_IFCUT = 0x40000000,	/* Current usage table */
+	VXFS_IFATT = 0x50000000,	/* Attr. inode */
+	VXFS_IFLCT = 0x60000000,	/* Link count table */
+	VXFS_IFIAT = 0x70000000,	/* Indirect attribute file */
+	VXFS_IFEMR = 0x80000000,	/* Extent map reorg file */
+	VXFS_IFQUO = 0x90000000,	/* BSD quota file */
+	VXFS_IFPTI = 0xa0000000,	/* "Pass through" inode */
+	VXFS_IFLAB = 0x11000000,	/* Device label file */
+	VXFS_IFOLT = 0x12000000,	/* OLT file */
+	VXFS_IFLOG = 0x13000000,	/* Log file */
+	VXFS_IFEMP = 0x14000000,	/* Extent map file */
+	VXFS_IFEAU = 0x15000000,	/* Extent AU file */
+	VXFS_IFAUS = 0x16000000,	/* Extent AU summary file */
+	VXFS_IFDEV = 0x17000000,	/* Device config file */
+
+};
+
+#define	VXFS_TYPE_MASK		0xfffff000
+
+#define VXFS_IS_TYPE(ip,type)	(((ip)->vii_mode & VXFS_TYPE_MASK) == (type))
+#define VXFS_ISFIFO(x)		VXFS_IS_TYPE((x),VXFS_IFIFO)
+#define VXFS_ISCHR(x)		VXFS_IS_TYPE((x),VXFS_IFCHR)
+#define VXFS_ISDIR(x)		VXFS_IS_TYPE((x),VXFS_IFDIR)
+#define VXFS_ISNAM(x)		VXFS_IS_TYPE((x),VXFS_IFNAM)
+#define VXFS_ISBLK(x)		VXFS_IS_TYPE((x),VXFS_IFBLK)
+#define VXFS_ISLNK(x)		VXFS_IS_TYPE((x),VXFS_IFLNK)
+#define VXFS_ISREG(x)		VXFS_IS_TYPE((x),VXFS_IFREG)
+#define VXFS_ISCMP(x)		VXFS_IS_TYPE((x),VXFS_IFCMP)
+#define VXFS_ISSOC(x)		VXFS_IS_TYPE((x),VXFS_IFSOC)
+
+#define VXFS_ISFSH(x)		VXFS_IS_TYPE((x),VXFS_IFFSH)
+#define VXFS_ISILT(x)		VXFS_IS_TYPE((x),VXFS_IFILT)
+
+/*
+ * Inmode organisation types.
+ */
+enum {
+	VXFS_ORG_NONE	= 0,	/* Inode has *no* format ?!? */
+	VXFS_ORG_EXT4	= 1,	/* Ext4 */
+	VXFS_ORG_IMMED	= 2,	/* All data stored in inode */
+	VXFS_ORG_TYPED	= 3,	/* Typed extents */
+};
+
+#define VXFS_IS_ORG(ip,org)	((ip)->vii_orgtype == (org))
+#define VXFS_ISNONE(ip)		VXFS_IS_ORG((ip), VXFS_ORG_NONE)
+#define VXFS_ISEXT4(ip)		VXFS_IS_ORG((ip), VXFS_ORG_EXT4)
+#define VXFS_ISIMMED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_IMMED)
+#define VXFS_ISTYPED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_TYPED)
+
+
+/*
+ * Get filesystem private data from VFS inode.
+ */
+#define VXFS_INO(ip) \
+	((struct vxfs_inode_info *)(ip)->u.generic_ip)
+
+/*
+ * Get filesystem private data from VFS superblock.
+ */
+#define VXFS_SBI(sbp) \
+	((struct vxfs_sb_info *)(sbp)->s_fs_info)
+
+#endif /* _VXFS_SUPER_H_ */
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
new file mode 100644
index 0000000..bc4b57d
--- /dev/null
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - filesystem to disk block mapping.
+ */
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/kernel.h>
+
+#include "vxfs.h"
+#include "vxfs_inode.h"
+
+
+#ifdef DIAGNOSTIC
+static void
+vxfs_typdump(struct vxfs_typed *typ)
+{
+	printk(KERN_DEBUG "type=%Lu ", typ->vt_hdr >> VXFS_TYPED_TYPESHIFT);
+	printk("offset=%Lx ", typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
+	printk("block=%x ", typ->vt_block);
+	printk("size=%x\n", typ->vt_size);
+}
+#endif
+
+/**
+ * vxfs_bmap_ext4 - do bmap for ext4 extents
+ * @ip:		pointer to the inode we do bmap for
+ * @iblock:	logical block.
+ *
+ * Description:
+ *   vxfs_bmap_ext4 performs the bmap operation for inodes with
+ *   ext4-style extents (which are much like the traditional UNIX
+ *   inode organisation).
+ *
+ * Returns:
+ *   The physical block number on success, else Zero.
+ */
+static daddr_t
+vxfs_bmap_ext4(struct inode *ip, long bn)
+{
+	struct super_block *sb = ip->i_sb;
+	struct vxfs_inode_info *vip = VXFS_INO(ip);
+	unsigned long bsize = sb->s_blocksize;
+	u32 indsize = vip->vii_ext4.ve4_indsize;
+	int i;
+
+	if (indsize > sb->s_blocksize)
+		goto fail_size;
+
+	for (i = 0; i < VXFS_NDADDR; i++) {
+		struct direct *d = vip->vii_ext4.ve4_direct + i;
+		if (bn >= 0 && bn < d->size)
+			return (bn + d->extent);
+		bn -= d->size;
+	}
+
+	if ((bn / (indsize * indsize * bsize / 4)) == 0) {
+		struct buffer_head *buf;
+		daddr_t	bno;
+		u32 *indir;
+
+		buf = sb_bread(sb, vip->vii_ext4.ve4_indir[0]);
+		if (!buf || !buffer_mapped(buf))
+			goto fail_buf;
+
+		indir = (u32 *)buf->b_data;
+		bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize);
+
+		brelse(buf);
+		return bno;
+	} else
+		printk(KERN_WARNING "no matching indir?");
+
+	return 0;
+
+fail_size:
+	printk("vxfs: indirect extent to big!\n");
+fail_buf:
+	return 0;
+}
+
+/**
+ * vxfs_bmap_indir - recursion for vxfs_bmap_typed
+ * @ip:		pointer to the inode we do bmap for
+ * @indir:	indirect block we start reading at
+ * @size:	size of the typed area to search
+ * @block:	partially result from further searches
+ *
+ * Description:
+ *   vxfs_bmap_indir reads a &struct vxfs_typed at @indir
+ *   and performs the type-defined action.
+ *
+ * Return Value:
+ *   The physical block number on success, else Zero.
+ *
+ * Note:
+ *   Kernelstack is rare.  Unrecurse?
+ */
+static daddr_t
+vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
+{
+	struct buffer_head		*bp = NULL;
+	daddr_t				pblock = 0;
+	int				i;
+
+	for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
+		struct vxfs_typed	*typ;
+		int64_t			off;
+
+		bp = sb_bread(ip->i_sb,
+				indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)));
+		if (!buffer_mapped(bp))
+			return 0;
+
+		typ = ((struct vxfs_typed *)bp->b_data) +
+			(i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
+		off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
+
+		if (block < off) {
+			brelse(bp);
+			continue;
+		}
+
+		switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
+		case VXFS_TYPED_INDIRECT:
+			pblock = vxfs_bmap_indir(ip, typ->vt_block,
+					typ->vt_size, block - off);
+			if (pblock == -2)
+				break;
+			goto out;
+		case VXFS_TYPED_DATA:
+			if ((block - off) >= typ->vt_size)
+				break;
+			pblock = (typ->vt_block + block - off);
+			goto out;
+		case VXFS_TYPED_INDIRECT_DEV4:
+		case VXFS_TYPED_DATA_DEV4: {
+			struct vxfs_typed_dev4	*typ4 =
+				(struct vxfs_typed_dev4 *)typ;
+
+			printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
+			printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
+			       (unsigned long long) typ4->vd4_block,
+			       (unsigned long long) typ4->vd4_size,
+			       typ4->vd4_dev);
+			goto fail;
+		}
+		default:
+			BUG();
+		}
+		brelse(bp);
+	}
+
+fail:
+	pblock = 0;
+out:
+	brelse(bp);
+	return (pblock);
+}
+
+/**
+ * vxfs_bmap_typed - bmap for typed extents
+ * @ip:		pointer to the inode we do bmap for
+ * @iblock:	logical block
+ *
+ * Description:
+ *   Performs the bmap operation for typed extents.
+ *
+ * Return Value:
+ *   The physical block number on success, else Zero.
+ */
+static daddr_t
+vxfs_bmap_typed(struct inode *ip, long iblock)
+{
+	struct vxfs_inode_info		*vip = VXFS_INO(ip);
+	daddr_t				pblock = 0;
+	int				i;
+
+	for (i = 0; i < VXFS_NTYPED; i++) {
+		struct vxfs_typed	*typ = vip->vii_org.typed + i;
+		int64_t			off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
+
+#ifdef DIAGNOSTIC
+		vxfs_typdump(typ);
+#endif
+		if (iblock < off)
+			continue;
+		switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
+		case VXFS_TYPED_INDIRECT:
+			pblock = vxfs_bmap_indir(ip, typ->vt_block,
+					typ->vt_size, iblock - off);
+			if (pblock == -2)
+				break;
+			return (pblock);
+		case VXFS_TYPED_DATA:
+			if ((iblock - off) < typ->vt_size)
+				return (typ->vt_block + iblock - off);
+			break;
+		case VXFS_TYPED_INDIRECT_DEV4:
+		case VXFS_TYPED_DATA_DEV4: {
+			struct vxfs_typed_dev4	*typ4 =
+				(struct vxfs_typed_dev4 *)typ;
+
+			printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
+			printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
+			       (unsigned long long) typ4->vd4_block,
+			       (unsigned long long) typ4->vd4_size,
+			       typ4->vd4_dev);
+			return 0;
+		}
+		default:
+			BUG();
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * vxfs_bmap1 - vxfs-internal bmap operation
+ * @ip:			pointer to the inode we do bmap for
+ * @iblock:		logical block
+ *
+ * Description:
+ *   vxfs_bmap1 perfoms a logical to physical block mapping
+ *   for vxfs-internal purposes.
+ *
+ * Return Value:
+ *   The physical block number on success, else Zero.
+ */
+daddr_t
+vxfs_bmap1(struct inode *ip, long iblock)
+{
+	struct vxfs_inode_info		*vip = VXFS_INO(ip);
+
+	if (VXFS_ISEXT4(vip))
+		return vxfs_bmap_ext4(ip, iblock);
+	if (VXFS_ISTYPED(vip))
+		return vxfs_bmap_typed(ip, iblock);
+	if (VXFS_ISNONE(vip))
+		goto unsupp;
+	if (VXFS_ISIMMED(vip))
+		goto unsupp;
+
+	printk(KERN_WARNING "vxfs: inode %ld has no valid orgtype (%x)\n",
+			ip->i_ino, vip->vii_orgtype);
+	BUG();
+
+unsupp:
+	printk(KERN_WARNING "vxfs: inode %ld has an unsupported orgtype (%x)\n",
+			ip->i_ino, vip->vii_orgtype);
+	return 0;
+}
diff --git a/fs/freevxfs/vxfs_dir.h b/fs/freevxfs/vxfs_dir.h
new file mode 100644
index 0000000..8a4dfef
--- /dev/null
+++ b/fs/freevxfs/vxfs_dir.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _VXFS_DIR_H_
+#define _VXFS_DIR_H_
+
+/*
+ * Veritas filesystem driver - directory structure.
+ *
+ * This file contains the definition of the vxfs directory format.
+ */
+
+
+/*
+ * VxFS directory block header.
+ *
+ * This entry is the head of every filesystem block in a directory.
+ * It is used for free space managment and additionally includes
+ * a hash for speeding up directory search (lookup).
+ *
+ * The hash may be empty and in fact we do not use it all in the
+ * Linux driver for now.
+ */
+struct vxfs_dirblk {
+	u_int16_t	d_free;		/* free space in dirblock */
+	u_int16_t	d_nhash;	/* no of hash chains */
+	u_int16_t	d_hash[1];	/* hash chain */
+};
+
+/*
+ * VXFS_NAMELEN is the maximum length of the d_name field
+ *	of an VxFS directory entry.
+ */
+#define VXFS_NAMELEN	256
+
+/*
+ * VxFS directory entry.
+ */
+struct vxfs_direct {
+	vx_ino_t	d_ino;			/* inode number */
+	u_int16_t	d_reclen;		/* record length */
+	u_int16_t	d_namelen;		/* d_name length */
+	u_int16_t	d_hashnext;		/* next hash entry */
+	char		d_name[VXFS_NAMELEN];	/* name */
+};
+
+/*
+ * VXFS_DIRPAD defines the directory entry boundaries, is _must_ be
+ *	a multiple of four.
+ * VXFS_NAMEMIN is the length of a directory entry with a NULL d_name.
+ * VXFS_DIRROUND is an internal macros that rounds a length to a value
+ *	usable for directory sizes.
+ * VXFS_DIRLEN calculates the directory entry size for an entry with
+ *	a d_name with size len.
+ */
+#define VXFS_DIRPAD		4
+#define VXFS_NAMEMIN		((int)((struct vxfs_direct *)0)->d_name)
+#define VXFS_DIRROUND(len)	((VXFS_DIRPAD + (len) - 1) & ~(VXFS_DIRPAD -1))
+#define VXFS_DIRLEN(len)	(VXFS_DIRROUND(VXFS_NAMEMIN + (len)))
+
+/*
+ * VXFS_DIRBLKOV is the overhead of a specific dirblock.
+ */
+#define VXFS_DIRBLKOV(dbp)	((sizeof(short) * dbp->d_nhash) + 4)
+
+#endif /* _VXFS_DIR_H_ */
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
new file mode 100644
index 0000000..d8be917
--- /dev/null
+++ b/fs/freevxfs/vxfs_extern.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _VXFS_EXTERN_H_
+#define _VXFS_EXTERN_H_
+
+/*
+ * Veritas filesystem driver - external prototypes.
+ *
+ * This file contains prototypes for all vxfs functions used
+ * outside their respective source files.
+ */
+
+
+struct kmem_cache_s;
+struct super_block;
+struct vxfs_inode_info;
+struct inode;
+
+
+/* vxfs_bmap.c */
+extern daddr_t			vxfs_bmap1(struct inode *, long);
+
+/* vxfs_fshead.c */
+extern int			vxfs_read_fshead(struct super_block *);
+
+/* vxfs_inode.c */
+extern struct kmem_cache_s	*vxfs_inode_cachep;
+extern void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
+extern struct inode *		vxfs_get_fake_inode(struct super_block *,
+					struct vxfs_inode_info *);
+extern void			vxfs_put_fake_inode(struct inode *);
+extern struct vxfs_inode_info *	vxfs_blkiget(struct super_block *, u_long, ino_t);
+extern struct vxfs_inode_info *	vxfs_stiget(struct super_block *, ino_t);
+extern void			vxfs_read_inode(struct inode *);
+extern void			vxfs_clear_inode(struct inode *);
+
+/* vxfs_lookup.c */
+extern struct inode_operations	vxfs_dir_inode_ops;
+extern struct file_operations	vxfs_dir_operations;
+
+/* vxfs_olt.c */
+extern int			vxfs_read_olt(struct super_block *, u_long);
+
+/* vxfs_subr.c */
+extern struct page *		vxfs_get_page(struct address_space *, u_long);
+extern void			vxfs_put_page(struct page *);
+extern struct buffer_head *	vxfs_bread(struct inode *, int);
+
+#endif /* _VXFS_EXTERN_H_ */
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
new file mode 100644
index 0000000..05b19f7
--- /dev/null
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - fileset header routines.
+ */
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "vxfs.h"
+#include "vxfs_inode.h"
+#include "vxfs_extern.h"
+#include "vxfs_fshead.h"
+
+
+#ifdef DIAGNOSTIC
+static void
+vxfs_dumpfsh(struct vxfs_fsh *fhp)
+{
+	printk("\n\ndumping fileset header:\n");
+	printk("----------------------------\n");
+	printk("version: %u\n", fhp->fsh_version);
+	printk("fsindex: %u\n", fhp->fsh_fsindex);
+	printk("iauino: %u\tninodes:%u\n",
+			fhp->fsh_iauino, fhp->fsh_ninodes);
+	printk("maxinode: %u\tlctino: %u\n",
+			fhp->fsh_maxinode, fhp->fsh_lctino);
+	printk("nau: %u\n", fhp->fsh_nau);
+	printk("ilistino[0]: %u\tilistino[1]: %u\n",
+			fhp->fsh_ilistino[0], fhp->fsh_ilistino[1]);
+}
+#endif
+
+/**
+ * vxfs_getfsh - read fileset header into memory
+ * @ip:		the (fake) fileset header inode
+ * @which:	0 for the structural, 1 for the primary fsh.
+ *
+ * Description:
+ *   vxfs_getfsh reads either the structural or primary fileset header
+ *   described by @ip into memory.
+ *
+ * Returns:
+ *   The fileset header structure on success, else Zero.
+ */
+static struct vxfs_fsh *
+vxfs_getfsh(struct inode *ip, int which)
+{
+	struct buffer_head		*bp;
+
+	bp = vxfs_bread(ip, which);
+	if (buffer_mapped(bp)) {
+		struct vxfs_fsh		*fhp;
+
+		if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL)))
+			return NULL;
+		memcpy(fhp, bp->b_data, sizeof(*fhp));
+
+		brelse(bp);
+		return (fhp);
+	}
+
+	return NULL;
+}
+
+/**
+ * vxfs_read_fshead - read the fileset headers
+ * @sbp:	superblock to which the fileset belongs
+ *
+ * Description:
+ *   vxfs_read_fshead will fill the inode and structural inode list in @sb.
+ *
+ * Returns:
+ *   Zero on success, else a negative error code (-EINVAL).
+ */
+int
+vxfs_read_fshead(struct super_block *sbp)
+{
+	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
+	struct vxfs_fsh			*pfp, *sfp;
+	struct vxfs_inode_info		*vip, *tip;
+
+	vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
+	if (!vip) {
+		printk(KERN_ERR "vxfs: unabled to read fsh inode\n");
+		return -EINVAL;
+	}
+	if (!VXFS_ISFSH(vip)) {
+		printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
+				vip->vii_mode & VXFS_TYPE_MASK); 
+		goto out_free_fship;
+	}
+
+
+#ifdef DIAGNOSTIC
+	printk("vxfs: fsh inode dump:\n");
+	vxfs_dumpi(vip, infp->vsi_fshino);
+#endif
+
+	infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
+	if (!infp->vsi_fship) {
+		printk(KERN_ERR "vxfs: unabled to get fsh inode\n");
+		goto out_free_fship;
+	}
+
+	sfp = vxfs_getfsh(infp->vsi_fship, 0);
+	if (!sfp) {
+		printk(KERN_ERR "vxfs: unabled to get structural fsh\n");
+		goto out_iput_fship;
+	} 
+
+#ifdef DIAGNOSTIC
+	vxfs_dumpfsh(sfp);
+#endif
+
+	pfp = vxfs_getfsh(infp->vsi_fship, 1);
+	if (!pfp) {
+		printk(KERN_ERR "vxfs: unabled to get primary fsh\n");
+		goto out_free_sfp;
+	}
+
+#ifdef DIAGNOSTIC
+	vxfs_dumpfsh(pfp);
+#endif
+
+	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
+	if (!tip)
+		goto out_free_pfp;
+
+	infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
+	if (!infp->vsi_stilist) {
+		printk(KERN_ERR "vxfs: unabled to get structual list inode\n");
+		kfree(tip);
+		goto out_free_pfp;
+	}
+	if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
+		printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n",
+				VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
+		goto out_iput_stilist;
+	}
+
+	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
+	if (!tip)
+		goto out_iput_stilist;
+	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
+	if (!infp->vsi_ilist) {
+		printk(KERN_ERR "vxfs: unabled to get inode list inode\n");
+		kfree(tip);
+		goto out_iput_stilist;
+	}
+	if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
+		printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
+				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
+		goto out_iput_ilist;
+	}
+
+	return 0;
+
+ out_iput_ilist:
+ 	iput(infp->vsi_ilist);
+ out_iput_stilist:
+ 	iput(infp->vsi_stilist);
+ out_free_pfp:
+	kfree(pfp);
+ out_free_sfp:
+ 	kfree(sfp);
+ out_iput_fship:
+	iput(infp->vsi_fship);
+	return -EINVAL;
+ out_free_fship:
+ 	kfree(vip);
+	return -EINVAL;
+}
diff --git a/fs/freevxfs/vxfs_fshead.h b/fs/freevxfs/vxfs_fshead.h
new file mode 100644
index 0000000..ead0d64
--- /dev/null
+++ b/fs/freevxfs/vxfs_fshead.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _VXFS_FSHEAD_H_
+#define _VXFS_FSHEAD_H_
+
+/*
+ * Veritas filesystem driver - fileset header structures.
+ *
+ * This file contains the physical structure of the VxFS
+ * fileset header.
+ */
+
+
+/*
+ * Fileset header 
+ */
+struct vxfs_fsh {
+	u_int32_t	fsh_version;		/* fileset header version */
+	u_int32_t	fsh_fsindex;		/* fileset index */
+	u_int32_t	fsh_time;		/* modification time - sec */
+	u_int32_t	fsh_utime;		/* modification time - usec */
+	u_int32_t	fsh_extop;		/* extop flags */
+	vx_ino_t	fsh_ninodes;		/* allocated inodes */
+	u_int32_t	fsh_nau;		/* number of IAUs */
+	u_int32_t	fsh_old_ilesize;	/* old size of ilist */
+	u_int32_t	fsh_dflags;		/* flags */
+	u_int32_t	fsh_quota;		/* quota limit */
+	vx_ino_t	fsh_maxinode;		/* maximum inode number */
+	vx_ino_t	fsh_iauino;		/* IAU inode */
+	vx_ino_t	fsh_ilistino[2];	/* ilist inodes */
+	vx_ino_t	fsh_lctino;		/* link count table inode */
+
+	/*
+	 * Slightly more fields follow, but they
+	 *  a) are not of any interest for us, and
+	 *  b) differ a lot in different vxfs versions/ports
+	 */
+};
+
+#endif /* _VXFS_FSHEAD_H_ */
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
new file mode 100644
index 0000000..ac677ab
--- /dev/null
+++ b/fs/freevxfs/vxfs_immed.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - support for 'immed' inodes.
+ */
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/namei.h>
+
+#include "vxfs.h"
+#include "vxfs_inode.h"
+
+
+static int	vxfs_immed_follow_link(struct dentry *, struct nameidata *);
+
+static int	vxfs_immed_readpage(struct file *, struct page *);
+
+/*
+ * Inode operations for immed symlinks.
+ *
+ * Unliked all other operations we do not go through the pagecache,
+ * but do all work directly on the inode.
+ */
+struct inode_operations vxfs_immed_symlink_iops = {
+	.readlink =		generic_readlink,
+	.follow_link =		vxfs_immed_follow_link,
+};
+
+/*
+ * Adress space operations for immed files and directories.
+ */
+struct address_space_operations vxfs_immed_aops = {
+	.readpage =		vxfs_immed_readpage,
+};
+
+/**
+ * vxfs_immed_follow_link - follow immed symlink
+ * @dp:		dentry for the link
+ * @np:		pathname lookup data for the current path walk
+ *
+ * Description:
+ *   vxfs_immed_follow_link restarts the pathname lookup with
+ *   the data obtained from @dp.
+ *
+ * Returns:
+ *   Zero on success, else a negative error code.
+ */
+static int
+vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np)
+{
+	struct vxfs_inode_info		*vip = VXFS_INO(dp->d_inode);
+	nd_set_link(np, vip->vii_immed.vi_immed);
+	return 0;
+}
+
+/**
+ * vxfs_immed_readpage - read part of an immed inode into pagecache
+ * @file:	file context (unused)
+ * @page:	page frame to fill in.
+ *
+ * Description:
+ *   vxfs_immed_readpage reads a part of the immed area of the
+ *   file that hosts @pp into the pagecache.
+ *
+ * Returns:
+ *   Zero on success, else a negative error code.
+ *
+ * Locking status:
+ *   @page is locked and will be unlocked.
+ */
+static int
+vxfs_immed_readpage(struct file *fp, struct page *pp)
+{
+	struct vxfs_inode_info	*vip = VXFS_INO(pp->mapping->host);
+	u_int64_t		offset = pp->index << PAGE_CACHE_SHIFT;
+	caddr_t			kaddr;
+
+	kaddr = kmap(pp);
+	memcpy(kaddr, vip->vii_immed.vi_immed + offset, PAGE_CACHE_SIZE);
+	kunmap(pp);
+	
+	flush_dcache_page(pp);
+	SetPageUptodate(pp);
+        unlock_page(pp);
+
+	return 0;
+}
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
new file mode 100644
index 0000000..9672d2f
--- /dev/null
+++ b/fs/freevxfs/vxfs_inode.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - inode routines.
+ */
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/pagemap.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "vxfs.h"
+#include "vxfs_inode.h"
+#include "vxfs_extern.h"
+
+
+extern struct address_space_operations vxfs_aops;
+extern struct address_space_operations vxfs_immed_aops;
+
+extern struct inode_operations vxfs_immed_symlink_iops;
+
+static struct file_operations vxfs_file_operations = {
+	.open =			generic_file_open,
+	.llseek =		generic_file_llseek,
+	.read =			generic_file_read,
+	.mmap =			generic_file_mmap,
+	.sendfile =		generic_file_sendfile,
+};
+
+
+kmem_cache_t		*vxfs_inode_cachep;
+
+
+#ifdef DIAGNOSTIC
+/*
+ * Dump inode contents (partially).
+ */
+void
+vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
+{
+	printk(KERN_DEBUG "\n\n");
+	if (ino)
+		printk(KERN_DEBUG "dumping vxfs inode %ld\n", ino);
+	else
+		printk(KERN_DEBUG "dumping unknown vxfs inode\n");
+
+	printk(KERN_DEBUG "---------------------------\n");
+	printk(KERN_DEBUG "mode is %x\n", vip->vii_mode);
+	printk(KERN_DEBUG "nlink:%u, uid:%u, gid:%u\n",
+			vip->vii_nlink, vip->vii_uid, vip->vii_gid);
+	printk(KERN_DEBUG "size:%Lx, blocks:%u\n",
+			vip->vii_size, vip->vii_blocks);
+	printk(KERN_DEBUG "orgtype:%u\n", vip->vii_orgtype);
+}
+#endif
+
+
+/**
+ * vxfs_blkiget - find inode based on extent #
+ * @sbp:	superblock of the filesystem we search in
+ * @extent:	number of the extent to search
+ * @ino:	inode number to search
+ *
+ * Description:
+ *  vxfs_blkiget searches inode @ino in the filesystem described by
+ *  @sbp in the extent @extent.
+ *  Returns the matching VxFS inode on success, else a NULL pointer.
+ *
+ * NOTE:
+ *  While __vxfs_iget uses the pagecache vxfs_blkiget uses the
+ *  buffercache.  This function should not be used outside the
+ *  read_super() method, otherwise the data may be incoherent.
+ */
+struct vxfs_inode_info *
+vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
+{
+	struct buffer_head		*bp;
+	u_long				block, offset;
+
+	block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize);
+	offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE);
+	bp = sb_bread(sbp, block);
+
+	if (buffer_mapped(bp)) {
+		struct vxfs_inode_info	*vip;
+		struct vxfs_dinode	*dip;
+
+		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL)))
+			goto fail;
+		dip = (struct vxfs_dinode *)(bp->b_data + offset);
+		memcpy(vip, dip, sizeof(*vip));
+#ifdef DIAGNOSTIC
+		vxfs_dumpi(vip, ino);
+#endif
+		brelse(bp);
+		return (vip);
+	}
+
+fail:
+	printk(KERN_WARNING "vxfs: unable to read block %ld\n", block);
+	brelse(bp);
+	return NULL;
+}
+
+/**
+ * __vxfs_iget - generic find inode facility
+ * @sbp:		VFS superblock
+ * @ino:		inode number
+ * @ilistp:		inode list
+ *
+ * Description:
+ *  Search the for inode number @ino in the filesystem
+ *  described by @sbp.  Use the specified inode table (@ilistp).
+ *  Returns the matching VxFS inode on success, else a NULL pointer.
+ */
+static struct vxfs_inode_info *
+__vxfs_iget(ino_t ino, struct inode *ilistp)
+{
+	struct page			*pp;
+	u_long				offset;
+
+	offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE;
+	pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE);
+
+	if (!IS_ERR(pp)) {
+		struct vxfs_inode_info	*vip;
+		struct vxfs_dinode	*dip;
+		caddr_t			kaddr = (char *)page_address(pp);
+
+		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL)))
+			goto fail;
+		dip = (struct vxfs_dinode *)(kaddr + offset);
+		memcpy(vip, dip, sizeof(*vip));
+#ifdef DIAGNOSTIC
+		vxfs_dumpi(vip, ino);
+#endif
+		vxfs_put_page(pp);
+		return (vip);
+	}
+
+	printk(KERN_WARNING "vxfs: error on page %p\n", pp);
+	return NULL;
+
+fail:
+	printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned long)ino);
+	vxfs_put_page(pp);
+	return NULL;
+}
+
+/**
+ * vxfs_stiget - find inode using the structural inode list
+ * @sbp:	VFS superblock
+ * @ino:	inode #
+ *
+ * Description:
+ *  Find inode @ino in the filesystem described by @sbp using
+ *  the structural inode list.
+ *  Returns the matching VxFS inode on success, else a NULL pointer.
+ */
+struct vxfs_inode_info *
+vxfs_stiget(struct super_block *sbp, ino_t ino)
+{
+        return __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist);
+}
+
+/**
+ * vxfs_transmod - mode for a VxFS inode
+ * @vip:	VxFS inode
+ *
+ * Description:
+ *  vxfs_transmod returns a Linux mode_t for a given
+ *  VxFS inode structure.
+ */
+static __inline__ mode_t
+vxfs_transmod(struct vxfs_inode_info *vip)
+{
+	mode_t			ret = vip->vii_mode & ~VXFS_TYPE_MASK;
+
+	if (VXFS_ISFIFO(vip))
+		ret |= S_IFIFO;
+	if (VXFS_ISCHR(vip))
+		ret |= S_IFCHR;
+	if (VXFS_ISDIR(vip))
+		ret |= S_IFDIR;
+	if (VXFS_ISBLK(vip))
+		ret |= S_IFBLK;
+	if (VXFS_ISLNK(vip))
+		ret |= S_IFLNK;
+	if (VXFS_ISREG(vip))
+		ret |= S_IFREG;
+	if (VXFS_ISSOC(vip))
+		ret |= S_IFSOCK;
+
+	return (ret);
+}
+
+/**
+ * vxfs_iinit- helper to fill inode fields
+ * @ip:		VFS inode
+ * @vip:	VxFS inode
+ *
+ * Description:
+ *  vxfs_instino is a helper function to fill in all relevant
+ *  fields in @ip from @vip.
+ */
+static void
+vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip)
+{
+
+	ip->i_mode = vxfs_transmod(vip);
+	ip->i_uid = (uid_t)vip->vii_uid;
+	ip->i_gid = (gid_t)vip->vii_gid;
+
+	ip->i_nlink = vip->vii_nlink;
+	ip->i_size = vip->vii_size;
+
+	ip->i_atime.tv_sec = vip->vii_atime;
+	ip->i_ctime.tv_sec = vip->vii_ctime;
+	ip->i_mtime.tv_sec = vip->vii_mtime;
+	ip->i_atime.tv_nsec = 0;
+	ip->i_ctime.tv_nsec = 0;
+	ip->i_mtime.tv_nsec = 0;
+
+	ip->i_blksize = PAGE_SIZE;
+	ip->i_blocks = vip->vii_blocks;
+	ip->i_generation = vip->vii_gen;
+
+	ip->u.generic_ip = (void *)vip;
+	
+}
+
+/**
+ * vxfs_get_fake_inode - get fake inode structure
+ * @sbp:		filesystem superblock
+ * @vip:		fspriv inode
+ *
+ * Description:
+ *  vxfs_fake_inode gets a fake inode (not in the inode hash) for a
+ *  superblock, vxfs_inode pair.
+ *  Returns the filled VFS inode.
+ */
+struct inode *
+vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip)
+{
+	struct inode			*ip = NULL;
+
+	if ((ip = new_inode(sbp))) {
+		vxfs_iinit(ip, vip);
+		ip->i_mapping->a_ops = &vxfs_aops;
+	}
+	return (ip);
+}
+
+/**
+ * vxfs_put_fake_inode - free faked inode
+ * *ip:			VFS inode
+ *
+ * Description:
+ *  vxfs_put_fake_inode frees all data asssociated with @ip.
+ */
+void
+vxfs_put_fake_inode(struct inode *ip)
+{
+	iput(ip);
+}
+
+/**
+ * vxfs_read_inode - fill in inode information
+ * @ip:		inode pointer to fill
+ *
+ * Description:
+ *  vxfs_read_inode reads the disk inode for @ip and fills
+ *  in all relevant fields in @ip.
+ */
+void
+vxfs_read_inode(struct inode *ip)
+{
+	struct super_block		*sbp = ip->i_sb;
+	struct vxfs_inode_info		*vip;
+	struct address_space_operations	*aops;
+	ino_t				ino = ip->i_ino;
+
+	if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist)))
+		return;
+
+	vxfs_iinit(ip, vip);
+
+	if (VXFS_ISIMMED(vip))
+		aops = &vxfs_immed_aops;
+	else
+		aops = &vxfs_aops;
+
+	if (S_ISREG(ip->i_mode)) {
+		ip->i_fop = &vxfs_file_operations;
+		ip->i_mapping->a_ops = aops;
+	} else if (S_ISDIR(ip->i_mode)) {
+		ip->i_op = &vxfs_dir_inode_ops;
+		ip->i_fop = &vxfs_dir_operations;
+		ip->i_mapping->a_ops = aops;
+	} else if (S_ISLNK(ip->i_mode)) {
+		if (!VXFS_ISIMMED(vip)) {
+			ip->i_op = &page_symlink_inode_operations;
+			ip->i_mapping->a_ops = &vxfs_aops;
+		} else
+			ip->i_op = &vxfs_immed_symlink_iops;
+	} else
+		init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev));
+
+	return;
+}
+
+/**
+ * vxfs_clear_inode - remove inode from main memory
+ * @ip:		inode to discard.
+ *
+ * Description:
+ *  vxfs_clear_inode() is called on the final iput and frees the private
+ *  inode area.
+ */
+void
+vxfs_clear_inode(struct inode *ip)
+{
+	kmem_cache_free(vxfs_inode_cachep, ip->u.generic_ip);
+}
diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h
new file mode 100644
index 0000000..240aeb1
--- /dev/null
+++ b/fs/freevxfs/vxfs_inode.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _VXFS_INODE_H_
+#define _VXFS_INODE_H_
+
+/*
+ * Veritas filesystem driver - inode structure.
+ *
+ * This file contains the definition of the disk and core
+ * inodes of the Veritas Filesystem.
+ */
+
+
+#define VXFS_ISIZE		0x100		/* Inode size */
+
+#define VXFS_NDADDR		10		/* Number of direct addrs in inode */
+#define VXFS_NIADDR		2		/* Number of indirect addrs in inode */
+#define VXFS_NIMMED		96		/* Size of immediate data in inode */
+#define VXFS_NTYPED		6		/* Num of typed extents */
+
+#define VXFS_TYPED_OFFSETMASK	(0x00FFFFFFFFFFFFFFULL)
+#define VXFS_TYPED_TYPEMASK	(0xFF00000000000000ULL)
+#define VXFS_TYPED_TYPESHIFT	56
+
+#define VXFS_TYPED_PER_BLOCK(sbp) \
+	((sbp)->s_blocksize / sizeof(struct vxfs_typed))
+
+/*
+ * Possible extent descriptor types for %VXFS_ORG_TYPED extents.
+ */
+enum {
+	VXFS_TYPED_INDIRECT		= 1,
+	VXFS_TYPED_DATA			= 2,
+	VXFS_TYPED_INDIRECT_DEV4	= 3,
+	VXFS_TYPED_DATA_DEV4		= 4,
+};
+
+/*
+ * Data stored immediately in the inode.
+ */
+struct vxfs_immed {
+	u_int8_t	vi_immed[VXFS_NIMMED];
+};
+
+struct vxfs_ext4 {
+	u_int32_t		ve4_spare;		/* ?? */
+	u_int32_t		ve4_indsize;		/* Indirect extent size */
+	vx_daddr_t		ve4_indir[VXFS_NIADDR];	/* Indirect extents */
+	struct direct {					/* Direct extents */
+		vx_daddr_t	extent;			/* Extent number */
+		int32_t		size;			/* Size of extent */
+	} ve4_direct[VXFS_NDADDR];
+};
+
+struct vxfs_typed {
+	u_int64_t	vt_hdr;		/* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
+	vx_daddr_t	vt_block;	/* Extent block */
+	int32_t		vt_size;	/* Size in blocks */
+};
+
+struct vxfs_typed_dev4 {
+	u_int64_t	vd4_hdr;	/* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
+	u_int64_t	vd4_block;	/* Extent block */
+	u_int64_t	vd4_size;	/* Size in blocks */
+	int32_t		vd4_dev;	/* Device ID */
+	u_int32_t	__pad1;
+};
+
+/*
+ * The inode as contained on the physical device.
+ */
+struct vxfs_dinode {
+	int32_t		vdi_mode;
+	u_int32_t	vdi_nlink;	/* Link count */
+	u_int32_t	vdi_uid;	/* UID */
+	u_int32_t	vdi_gid;	/* GID */
+	u_int64_t	vdi_size;	/* Inode size in bytes */
+	u_int32_t	vdi_atime;	/* Last time accessed - sec */
+	u_int32_t	vdi_autime;	/* Last time accessed - usec */
+	u_int32_t	vdi_mtime;	/* Last modify time - sec */
+	u_int32_t	vdi_mutime;	/* Last modify time - usec */
+	u_int32_t	vdi_ctime;	/* Create time - sec */
+	u_int32_t	vdi_cutime;	/* Create time - usec */
+	u_int8_t	vdi_aflags;	/* Allocation flags */
+	u_int8_t	vdi_orgtype;	/* Organisation type */
+	u_int16_t	vdi_eopflags;
+	u_int32_t	vdi_eopdata;
+	union {
+		u_int32_t		rdev;
+		u_int32_t		dotdot;
+		struct {
+			u_int32_t	reserved;
+			u_int32_t	fixextsize;
+		} i_regular;
+		struct {
+			u_int32_t	matchino;
+			u_int32_t	fsetindex;
+		} i_vxspec;
+		u_int64_t		align;
+	} vdi_ftarea;
+	u_int32_t	vdi_blocks;	/* How much blocks does inode occupy */
+	u_int32_t	vdi_gen;	/* Inode generation */
+	u_int64_t	vdi_version;	/* Version */
+	union {
+		struct vxfs_immed	immed;
+		struct vxfs_ext4	ext4;
+		struct vxfs_typed	typed[VXFS_NTYPED];
+	} vdi_org;
+	u_int32_t	vdi_iattrino;
+};
+
+#define vdi_rdev	vdi_ftarea.rdev
+#define vdi_dotdot	vdi_ftarea.dotdot
+#define vdi_fixextsize	vdi_ftarea.regular.fixextsize
+#define vdi_matchino	vdi_ftarea.vxspec.matchino
+#define vdi_fsetindex	vdi_ftarea.vxspec.fsetindex
+
+#define vdi_immed	vdi_org.immed
+#define vdi_ext4	vdi_org.ext4
+#define vdi_typed	vdi_org.typed
+
+
+/*
+ * The inode as represented in the main memory.
+ *
+ * TBD: This should become a separate structure...
+ */
+#define vxfs_inode_info	vxfs_dinode
+
+#define vii_mode	vdi_mode
+#define vii_uid		vdi_uid
+#define vii_gid		vdi_gid
+#define vii_nlink	vdi_nlink
+#define vii_size	vdi_size
+#define vii_atime	vdi_atime
+#define vii_ctime	vdi_ctime
+#define vii_mtime	vdi_mtime
+#define vii_blocks	vdi_blocks
+#define vii_org		vdi_org
+#define vii_orgtype	vdi_orgtype
+#define vii_gen		vdi_gen
+
+#define vii_rdev	vdi_ftarea.rdev
+#define vii_dotdot	vdi_ftarea.dotdot
+#define vii_fixextsize	vdi_ftarea.regular.fixextsize
+#define vii_matchino	vdi_ftarea.vxspec.matchino
+#define vii_fsetindex	vdi_ftarea.vxspec.fsetindex
+
+#define vii_immed	vdi_org.immed
+#define vii_ext4	vdi_org.ext4
+#define vii_typed	vdi_org.typed
+
+#endif /* _VXFS_INODE_H_ */
diff --git a/fs/freevxfs/vxfs_kcompat.h b/fs/freevxfs/vxfs_kcompat.h
new file mode 100644
index 0000000..342a4cc
--- /dev/null
+++ b/fs/freevxfs/vxfs_kcompat.h
@@ -0,0 +1,49 @@
+#ifndef _VXFS_KCOMPAT_H
+#define _VXFS_KCOMPAT_H
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+
+#include <linux/blkdev.h>
+
+typedef long sector_t;
+
+/* From include/linux/fs.h (Linux 2.5.2-pre3)  */
+static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
+{
+	return bread(sb->s_dev, block, sb->s_blocksize);
+}
+
+/* Dito.  */
+static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block)
+{
+	bh->b_state |= 1 << BH_Mapped;
+	bh->b_dev = sb->s_dev;
+	bh->b_blocknr = block;
+}
+
+/* From fs/block_dev.c (Linux 2.5.2-pre2)  */
+static inline int sb_set_blocksize(struct super_block *sb, int size)
+{
+	int bits;
+	if (set_blocksize(sb->s_dev, size) < 0)
+		return 0;
+	sb->s_blocksize = size;
+	for (bits = 9, size >>= 9; size >>= 1; bits++)
+		;
+	sb->s_blocksize_bits = bits;
+	return sb->s_blocksize;
+}
+
+/* Dito.  */
+static inline int sb_min_blocksize(struct super_block *sb, int size)
+{
+	int minsize = get_hardsect_size(sb->s_dev);
+	if (size < minsize)
+		size = minsize;
+	return sb_set_blocksize(sb, size);
+}
+
+#endif /* Kernel 2.4 */
+#endif /* _VXFS_KCOMPAT_H */
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
new file mode 100644
index 0000000..506ae25
--- /dev/null
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - lookup and other directory related code.
+ */
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/kernel.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+#include "vxfs.h"
+#include "vxfs_dir.h"
+#include "vxfs_inode.h"
+#include "vxfs_extern.h"
+
+/*
+ * Number of VxFS blocks per page.
+ */
+#define VXFS_BLOCK_PER_PAGE(sbp)  ((PAGE_CACHE_SIZE / (sbp)->s_blocksize))
+
+
+static struct dentry *	vxfs_lookup(struct inode *, struct dentry *, struct nameidata *);
+static int		vxfs_readdir(struct file *, void *, filldir_t);
+
+struct inode_operations vxfs_dir_inode_ops = {
+	.lookup =		vxfs_lookup,
+};
+
+struct file_operations vxfs_dir_operations = {
+	.readdir =		vxfs_readdir,
+};
+
+ 
+static __inline__ u_long
+dir_pages(struct inode *inode)
+{
+	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+}
+ 
+static __inline__ u_long
+dir_blocks(struct inode *ip)
+{
+	u_long			bsize = ip->i_sb->s_blocksize;
+	return (ip->i_size + bsize - 1) & ~(bsize - 1);
+}
+
+/*
+ * NOTE! unlike strncmp, vxfs_match returns 1 for success, 0 for failure.
+ *
+ * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
+ */
+static __inline__ int
+vxfs_match(int len, const char * const name, struct vxfs_direct *de)
+{
+	if (len != de->d_namelen)
+		return 0;
+	if (!de->d_ino)
+		return 0;
+	return !memcmp(name, de->d_name, len);
+}
+
+static __inline__ struct vxfs_direct *
+vxfs_next_entry(struct vxfs_direct *de)
+{
+	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
+}
+
+/**
+ * vxfs_find_entry - find a mathing directory entry for a dentry
+ * @ip:		directory inode
+ * @dp:		dentry for which we want to find a direct
+ * @ppp:	gets filled with the page the return value sits in
+ *
+ * Description:
+ *   vxfs_find_entry finds a &struct vxfs_direct for the VFS directory
+ *   cache entry @dp.  @ppp will be filled with the page the return
+ *   value resides in.
+ *
+ * Returns:
+ *   The wanted direct on success, else a NULL pointer.
+ */
+static struct vxfs_direct *
+vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
+{
+	u_long				npages, page, nblocks, pblocks, block;
+	u_long				bsize = ip->i_sb->s_blocksize;
+	const char			*name = dp->d_name.name;
+	int				namelen = dp->d_name.len;
+
+	npages = dir_pages(ip);
+	nblocks = dir_blocks(ip);
+	pblocks = VXFS_BLOCK_PER_PAGE(ip->i_sb);
+	
+	for (page = 0; page < npages; page++) {
+		caddr_t			kaddr;
+		struct page		*pp;
+
+		pp = vxfs_get_page(ip->i_mapping, page);
+		if (IS_ERR(pp))
+			continue;
+		kaddr = (caddr_t)page_address(pp);
+
+		for (block = 0; block <= nblocks && block <= pblocks; block++) {
+			caddr_t			baddr, limit;
+			struct vxfs_dirblk	*dbp;
+			struct vxfs_direct	*de;
+
+			baddr = kaddr + (block * bsize);
+			limit = baddr + bsize - VXFS_DIRLEN(1);
+			
+			dbp = (struct vxfs_dirblk *)baddr;
+			de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp));
+
+			for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
+				if (!de->d_reclen)
+					break;
+				if (!de->d_ino)
+					continue;
+				if (vxfs_match(namelen, name, de)) {
+					*ppp = pp;
+					return (de);
+				}
+			}
+		}
+		vxfs_put_page(pp);
+	}
+
+	return NULL;
+}
+
+/**
+ * vxfs_inode_by_name - find inode number for dentry
+ * @dip:	directory to search in
+ * @dp:		dentry we seach for
+ *
+ * Description:
+ *   vxfs_inode_by_name finds out the inode number of
+ *   the path component described by @dp in @dip.
+ *
+ * Returns:
+ *   The wanted inode number on success, else Zero.
+ */
+static ino_t
+vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
+{
+	struct vxfs_direct		*de;
+	struct page			*pp;
+	ino_t				ino = 0;
+
+	de = vxfs_find_entry(dip, dp, &pp);
+	if (de) {
+		ino = de->d_ino;
+		kunmap(pp);
+		page_cache_release(pp);
+	}
+	
+	return (ino);
+}
+
+/**
+ * vxfs_lookup - lookup pathname component
+ * @dip:	dir in which we lookup
+ * @dp:		dentry we lookup
+ * @nd:		lookup nameidata
+ *
+ * Description:
+ *   vxfs_lookup tries to lookup the pathname component described
+ *   by @dp in @dip.
+ *
+ * Returns:
+ *   A NULL-pointer on success, else an negative error code encoded
+ *   in the return pointer.
+ */
+static struct dentry *
+vxfs_lookup(struct inode *dip, struct dentry *dp, struct nameidata *nd)
+{
+	struct inode		*ip = NULL;
+	ino_t			ino;
+			 
+	if (dp->d_name.len > VXFS_NAMELEN)
+		return ERR_PTR(-ENAMETOOLONG);
+				 
+	lock_kernel();
+	ino = vxfs_inode_by_name(dip, dp);
+	if (ino) {
+		ip = iget(dip->i_sb, ino);
+		if (!ip) {
+			unlock_kernel();
+			return ERR_PTR(-EACCES);
+		}
+	}
+	unlock_kernel();
+	d_add(dp, ip);
+	return NULL;
+}
+
+/**
+ * vxfs_readdir - read a directory
+ * @fp:		the directory to read
+ * @retp:	return buffer
+ * @filler:	filldir callback
+ *
+ * Description:
+ *   vxfs_readdir fills @retp with directory entries from @fp
+ *   using the VFS supplied callback @filler.
+ *
+ * Returns:
+ *   Zero.
+ */
+static int
+vxfs_readdir(struct file *fp, void *retp, filldir_t filler)
+{
+	struct inode		*ip = fp->f_dentry->d_inode;
+	struct super_block	*sbp = ip->i_sb;
+	u_long			bsize = sbp->s_blocksize;
+	u_long			page, npages, block, pblocks, nblocks, offset;
+	loff_t			pos;
+
+	switch ((long)fp->f_pos) {
+	case 0:
+		if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 0)
+			goto out;
+		fp->f_pos++;
+		/* fallthrough */
+	case 1:
+		if (filler(retp, "..", 2, fp->f_pos, VXFS_INO(ip)->vii_dotdot, DT_DIR) < 0)
+			goto out;
+		fp->f_pos++;
+		/* fallthrough */
+	}
+
+	pos = fp->f_pos - 2;
+	
+	if (pos > VXFS_DIRROUND(ip->i_size)) {
+		unlock_kernel();
+		return 0;
+	}
+
+	npages = dir_pages(ip);
+	nblocks = dir_blocks(ip);
+	pblocks = VXFS_BLOCK_PER_PAGE(sbp);
+
+	page = pos >> PAGE_CACHE_SHIFT;
+	offset = pos & ~PAGE_CACHE_MASK;
+	block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks;
+
+	for (; page < npages; page++, block = 0) {
+		caddr_t			kaddr;
+		struct page		*pp;
+
+		pp = vxfs_get_page(ip->i_mapping, page);
+		if (IS_ERR(pp))
+			continue;
+		kaddr = (caddr_t)page_address(pp);
+
+		for (; block <= nblocks && block <= pblocks; block++) {
+			caddr_t			baddr, limit;
+			struct vxfs_dirblk	*dbp;
+			struct vxfs_direct	*de;
+
+			baddr = kaddr + (block * bsize);
+			limit = baddr + bsize - VXFS_DIRLEN(1);
+	
+			dbp = (struct vxfs_dirblk *)baddr;
+			de = (struct vxfs_direct *)
+				(offset ?
+				 (kaddr + offset) :
+				 (baddr + VXFS_DIRBLKOV(dbp)));
+
+			for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
+				int	over;
+
+				if (!de->d_reclen)
+					break;
+				if (!de->d_ino)
+					continue;
+
+				offset = (caddr_t)de - kaddr;
+				over = filler(retp, de->d_name, de->d_namelen,
+					((page << PAGE_CACHE_SHIFT) | offset) + 2,
+					de->d_ino, DT_UNKNOWN);
+				if (over) {
+					vxfs_put_page(pp);
+					goto done;
+				}
+			}
+			offset = 0;
+		}
+		vxfs_put_page(pp);
+		offset = 0;
+	}
+
+done:
+	fp->f_pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
+out:
+	unlock_kernel();
+	return 0;
+}
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
new file mode 100644
index 0000000..7a204e3
--- /dev/null
+++ b/fs/freevxfs/vxfs_olt.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* 
+ * Veritas filesystem driver - object location table support.
+ */
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/kernel.h>
+
+#include "vxfs.h"
+#include "vxfs_olt.h"
+
+
+static __inline__ void
+vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
+{
+	if (infp->vsi_fshino)
+		BUG();
+	infp->vsi_fshino = fshp->olt_fsino[0];
+}
+
+static __inline__ void
+vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
+{
+	if (infp->vsi_iext)
+		BUG();
+	infp->vsi_iext = ilistp->olt_iext[0]; 
+}
+
+static __inline__ u_long
+vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
+{
+	if (sbp->s_blocksize % bsize)
+		BUG();
+	return (block * (sbp->s_blocksize / bsize));
+}
+
+
+/**
+ * vxfs_read_olt - read olt
+ * @sbp:	superblock of the filesystem
+ * @bsize:	blocksize of the filesystem
+ *
+ * Description:
+ *   vxfs_read_olt reads the olt of the filesystem described by @sbp
+ *   into main memory and does some basic setup.
+ *
+ * Returns:
+ *   Zero on success, else a negative error code.
+ */
+int
+vxfs_read_olt(struct super_block *sbp, u_long bsize)
+{
+	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
+	struct buffer_head	*bp;
+	struct vxfs_olt		*op;
+	char			*oaddr, *eaddr;
+
+
+	bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
+	if (!bp || !bp->b_data)
+		goto fail;
+
+	op = (struct vxfs_olt *)bp->b_data;
+	if (op->olt_magic != VXFS_OLT_MAGIC) {
+		printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
+		goto fail;
+	}
+
+	/*
+	 * It is in theory possible that vsi_oltsize is > 1.
+	 * I've not seen any such filesystem yet and I'm lazy..  --hch
+	 */
+	if (infp->vsi_oltsize > 1) {
+		printk(KERN_NOTICE "vxfs: oltsize > 1 detected.\n");
+		printk(KERN_NOTICE "vxfs: please notify hch@infradead.org\n");
+		goto fail;
+	}
+
+	oaddr = (char *)bp->b_data + op->olt_size;
+	eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+
+	while (oaddr < eaddr) {
+		struct vxfs_oltcommon	*ocp =
+			(struct vxfs_oltcommon *)oaddr;
+		
+		switch (ocp->olt_type) {
+		case VXFS_OLT_FSHEAD:
+			vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
+			break;
+		case VXFS_OLT_ILIST:
+			vxfs_get_ilist((struct vxfs_oltilist *)oaddr, infp);
+			break;
+		}
+
+		oaddr += ocp->olt_size;
+	}
+
+	brelse(bp);
+	return 0;
+
+fail:
+	brelse(bp);
+	return -EINVAL;
+}
diff --git a/fs/freevxfs/vxfs_olt.h b/fs/freevxfs/vxfs_olt.h
new file mode 100644
index 0000000..d832429
--- /dev/null
+++ b/fs/freevxfs/vxfs_olt.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _VXFS_OLT_H_
+#define _VXFS_OLT_H_
+
+/*
+ * Veritas filesystem driver - Object Location Table data structures.
+ *
+ * This file contains definitions for the Object Location Table used
+ * by the Veritas Filesystem version 2 and newer.
+ */
+
+
+/*
+ * OLT magic number (vxfs_olt->olt_magic).
+ */
+#define VXFS_OLT_MAGIC		0xa504FCF5
+
+/*
+ * VxFS OLT entry types.
+ */
+enum {
+	VXFS_OLT_FREE	= 1,
+	VXFS_OLT_FSHEAD	= 2,
+	VXFS_OLT_CUT	= 3,
+	VXFS_OLT_ILIST	= 4,
+	VXFS_OLT_DEV	= 5,
+	VXFS_OLT_SB	= 6
+};
+
+/*
+ * VxFS OLT header.
+ *
+ * The Object Location Table header is placed at the beginning of each
+ * OLT extent.  It is used to fing certain filesystem-wide metadata, e.g.
+ * the inital inode list, the fileset header or the device configuration.
+ */
+struct vxfs_olt {
+	u_int32_t	olt_magic;	/* magic number			*/
+	u_int32_t	olt_size;	/* size of this entry		*/
+	u_int32_t	olt_checksum;	/* checksum of extent		*/
+	u_int32_t	__unused1;	/* ???				*/
+	u_int32_t	olt_mtime;	/* time of last mod. (sec)	*/
+	u_int32_t	olt_mutime;	/* time of last mod. (usec)	*/
+	u_int32_t	olt_totfree;	/* free space in OLT extent	*/
+	vx_daddr_t	olt_extents[2];	/* addr of this extent, replica	*/
+	u_int32_t	olt_esize;	/* size of this extent		*/
+	vx_daddr_t	olt_next[2];    /* addr of next extent, replica	*/
+	u_int32_t	olt_nsize;	/* size of next extent		*/
+	u_int32_t	__unused2;	/* align to 8 byte boundary	*/
+};
+
+/*
+ * VxFS common OLT entry (on disk).
+ */
+struct vxfs_oltcommon {
+	u_int32_t	olt_type;	/* type of this record		*/
+	u_int32_t	olt_size;	/* size of this record		*/
+};
+
+/*
+ * VxFS free OLT entry (on disk).
+ */
+struct vxfs_oltfree {
+	u_int32_t	olt_type;	/* type of this record		*/
+	u_int32_t	olt_fsize;	/* size of this free record	*/
+};
+
+/*
+ * VxFS initial-inode list (on disk).
+ */
+struct vxfs_oltilist {
+	u_int32_t	olt_type;	/* type of this record		*/
+	u_int32_t	olt_size;	/* size of this record		*/
+	vx_ino_t	olt_iext[2];	/* initial inode list, replica	*/
+};
+
+/*
+ * Current Usage Table 
+ */
+struct vxfs_oltcut {
+	u_int32_t	olt_type;	/* type of this record		*/
+	u_int32_t	olt_size;	/* size of this record		*/
+	vx_ino_t	olt_cutino;	/* inode of current usage table	*/
+	u_int32_t	__pad;		/* unused, 8 byte align		*/
+};
+
+/*
+ * Inodes containing Superblock, Intent log and OLTs 
+ */
+struct vxfs_oltsb {
+	u_int32_t	olt_type;	/* type of this record		*/
+	u_int32_t	olt_size;	/* size of this record		*/
+	vx_ino_t	olt_sbino;	/* inode of superblock file	*/
+	u_int32_t	__unused1;	/* ???				*/
+	vx_ino_t	olt_logino[2];	/* inode of log file,replica	*/
+	vx_ino_t	olt_oltino[2];	/* inode of OLT, replica	*/
+};
+
+/*
+ * Inode containing device configuration + it's replica 
+ */
+struct vxfs_oltdev {
+	u_int32_t	olt_type;	/* type of this record		*/
+	u_int32_t	olt_size;	/* size of this record		*/
+	vx_ino_t	olt_devino[2];	/* inode of device config files	*/
+};
+
+/*
+ * Fileset header 
+ */
+struct vxfs_oltfshead {
+	u_int32_t	olt_type;	/* type number			*/
+	u_int32_t	olt_size;	/* size of this record		*/
+	vx_ino_t	olt_fsino[2];   /* inodes of fileset header	*/
+};
+
+#endif /* _VXFS_OLT_H_ */
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
new file mode 100644
index 0000000..5e30561
--- /dev/null
+++ b/fs/freevxfs/vxfs_subr.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - shared subroutines.
+ */
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+
+#include "vxfs_kcompat.h"
+#include "vxfs_extern.h"
+
+
+static int		vxfs_readpage(struct file *, struct page *);
+static sector_t		vxfs_bmap(struct address_space *, sector_t);
+
+struct address_space_operations vxfs_aops = {
+	.readpage =		vxfs_readpage,
+	.bmap =			vxfs_bmap,
+	.sync_page =		block_sync_page,
+};
+
+inline void
+vxfs_put_page(struct page *pp)
+{
+	kunmap(pp);
+	page_cache_release(pp);
+}
+
+/**
+ * vxfs_get_page - read a page into memory.
+ * @ip:		inode to read from
+ * @n:		page number
+ *
+ * Description:
+ *   vxfs_get_page reads the @n th page of @ip into the pagecache.
+ *
+ * Returns:
+ *   The wanted page on success, else a NULL pointer.
+ */
+struct page *
+vxfs_get_page(struct address_space *mapping, u_long n)
+{
+	struct page *			pp;
+
+	pp = read_cache_page(mapping, n,
+			(filler_t*)mapping->a_ops->readpage, NULL);
+
+	if (!IS_ERR(pp)) {
+		wait_on_page_locked(pp);
+		kmap(pp);
+		if (!PageUptodate(pp))
+			goto fail;
+		/** if (!PageChecked(pp)) **/
+			/** vxfs_check_page(pp); **/
+		if (PageError(pp))
+			goto fail;
+	}
+	
+	return (pp);
+		 
+fail:
+	vxfs_put_page(pp);
+	return ERR_PTR(-EIO);
+}
+
+/**
+ * vxfs_bread - read buffer for a give inode,block tuple
+ * @ip:		inode
+ * @block:	logical block
+ *
+ * Description:
+ *   The vxfs_bread function reads block no @block  of
+ *   @ip into the buffercache.
+ *
+ * Returns:
+ *   The resulting &struct buffer_head.
+ */
+struct buffer_head *
+vxfs_bread(struct inode *ip, int block)
+{
+	struct buffer_head	*bp;
+	daddr_t			pblock;
+
+	pblock = vxfs_bmap1(ip, block);
+	bp = sb_bread(ip->i_sb, pblock);
+
+	return (bp);
+}
+
+/**
+ * vxfs_get_block - locate buffer for given inode,block tuple 
+ * @ip:		inode
+ * @iblock:	logical block
+ * @bp:		buffer skeleton
+ * @create:	%TRUE if blocks may be newly allocated.
+ *
+ * Description:
+ *   The vxfs_get_block function fills @bp with the right physical
+ *   block and device number to perform a lowlevel read/write on
+ *   it.
+ *
+ * Returns:
+ *   Zero on success, else a negativ error code (-EIO).
+ */
+static int
+vxfs_getblk(struct inode *ip, sector_t iblock,
+	    struct buffer_head *bp, int create)
+{
+	daddr_t			pblock;
+
+	pblock = vxfs_bmap1(ip, iblock);
+	if (pblock != 0) {
+		map_bh(bp, ip->i_sb, pblock);
+		return 0;
+	}
+
+	return -EIO;
+}
+
+/**
+ * vxfs_readpage - read one page synchronously into the pagecache
+ * @file:	file context (unused)
+ * @page:	page frame to fill in.
+ *
+ * Description:
+ *   The vxfs_readpage routine reads @page synchronously into the
+ *   pagecache.
+ *
+ * Returns:
+ *   Zero on success, else a negative error code.
+ *
+ * Locking status:
+ *   @page is locked and will be unlocked.
+ */
+static int
+vxfs_readpage(struct file *file, struct page *page)
+{
+	return block_read_full_page(page, vxfs_getblk);
+}
+ 
+/**
+ * vxfs_bmap - perform logical to physical block mapping
+ * @mapping:	logical to physical mapping to use
+ * @block:	logical block (relative to @mapping).
+ *
+ * Description:
+ *   Vxfs_bmap find out the corresponding phsical block to the
+ *   @mapping, @block pair.
+ *
+ * Returns:
+ *   Physical block number on success, else Zero.
+ *
+ * Locking status:
+ *   We are under the bkl.
+ */
+static sector_t
+vxfs_bmap(struct address_space *mapping, sector_t block)
+{
+	return generic_block_bmap(mapping, block, vxfs_getblk);
+}
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
new file mode 100644
index 0000000..0ae2c7b
--- /dev/null
+++ b/fs/freevxfs/vxfs_super.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2000-2001 Christoph Hellwig.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL").
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Veritas filesystem driver - superblock related routines.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <linux/blkdev.h>
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/vfs.h>
+
+#include "vxfs.h"
+#include "vxfs_extern.h"
+#include "vxfs_dir.h"
+#include "vxfs_inode.h"
+
+
+MODULE_AUTHOR("Christoph Hellwig");
+MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */
+
+
+static void		vxfs_put_super(struct super_block *);
+static int		vxfs_statfs(struct super_block *, struct kstatfs *);
+static int		vxfs_remount(struct super_block *, int *, char *);
+
+static struct super_operations vxfs_super_ops = {
+	.read_inode =		vxfs_read_inode,
+	.clear_inode =		vxfs_clear_inode,
+	.put_super =		vxfs_put_super,
+	.statfs =		vxfs_statfs,
+	.remount_fs =		vxfs_remount,
+};
+
+/**
+ * vxfs_put_super - free superblock resources
+ * @sbp:	VFS superblock.
+ *
+ * Description:
+ *   vxfs_put_super frees all resources allocated for @sbp
+ *   after the last instance of the filesystem is unmounted.
+ */
+
+static void
+vxfs_put_super(struct super_block *sbp)
+{
+	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
+
+	vxfs_put_fake_inode(infp->vsi_fship);
+	vxfs_put_fake_inode(infp->vsi_ilist);
+	vxfs_put_fake_inode(infp->vsi_stilist);
+
+	brelse(infp->vsi_bp);
+	kfree(infp);
+}
+
+/**
+ * vxfs_statfs - get filesystem information
+ * @sbp:	VFS superblock
+ * @bufp:	output buffer
+ *
+ * Description:
+ *   vxfs_statfs fills the statfs buffer @bufp with information
+ *   about the filesystem described by @sbp.
+ *
+ * Returns:
+ *   Zero.
+ *
+ * Locking:
+ *   No locks held.
+ *
+ * Notes:
+ *   This is everything but complete...
+ */
+static int
+vxfs_statfs(struct super_block *sbp, struct kstatfs *bufp)
+{
+	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
+
+	bufp->f_type = VXFS_SUPER_MAGIC;
+	bufp->f_bsize = sbp->s_blocksize;
+	bufp->f_blocks = infp->vsi_raw->vs_dsize;
+	bufp->f_bfree = infp->vsi_raw->vs_free;
+	bufp->f_bavail = 0;
+	bufp->f_files = 0;
+	bufp->f_ffree = infp->vsi_raw->vs_ifree;
+	bufp->f_namelen = VXFS_NAMELEN;
+
+	return 0;
+}
+
+static int vxfs_remount(struct super_block *sb, int *flags, char *data)
+{
+	*flags |= MS_RDONLY;
+	return 0;
+}
+
+/**
+ * vxfs_read_super - read superblock into memory and initalize filesystem
+ * @sbp:		VFS superblock (to fill)
+ * @dp:			fs private mount data
+ * @silent:		do not complain loudly when sth is wrong
+ *
+ * Description:
+ *   We are called on the first mount of a filesystem to read the
+ *   superblock into memory and do some basic setup.
+ *
+ * Returns:
+ *   The superblock on success, else %NULL.
+ *
+ * Locking:
+ *   We are under the bkl and @sbp->s_lock.
+ */
+static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
+{
+	struct vxfs_sb_info	*infp;
+	struct vxfs_sb		*rsbp;
+	struct buffer_head	*bp = NULL;
+	u_long			bsize;
+	struct inode *root;
+
+	sbp->s_flags |= MS_RDONLY;
+
+	infp = kmalloc(sizeof(*infp), GFP_KERNEL);
+	if (!infp) {
+		printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
+		return -ENOMEM;
+	}
+	memset(infp, 0, sizeof(*infp));
+
+	bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
+	if (!bsize) {
+		printk(KERN_WARNING "vxfs: unable to set blocksize\n");
+		goto out;
+	}
+
+	bp = sb_bread(sbp, 1);
+	if (!bp || !buffer_mapped(bp)) {
+		if (!silent) {
+			printk(KERN_WARNING
+				"vxfs: unable to read disk superblock\n");
+		}
+		goto out;
+	}
+
+	rsbp = (struct vxfs_sb *)bp->b_data;
+	if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
+		if (!silent)
+			printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
+		goto out;
+	}
+
+	if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) {
+		printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n",
+		       rsbp->vs_version);
+		goto out;
+	}
+
+#ifdef DIAGNOSTIC
+	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", rsbp->vs_version);
+	printk(KERN_DEBUG "vxfs: blocksize: %d\n", rsbp->vs_bsize);
+#endif
+
+	sbp->s_magic = rsbp->vs_magic;
+	sbp->s_fs_info = (void *)infp;
+
+	infp->vsi_raw = rsbp;
+	infp->vsi_bp = bp;
+	infp->vsi_oltext = rsbp->vs_oltext[0];
+	infp->vsi_oltsize = rsbp->vs_oltsize;
+
+	if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
+		printk(KERN_WARNING "vxfs: unable to set final block size\n");
+		goto out;
+	}
+
+	if (vxfs_read_olt(sbp, bsize)) {
+		printk(KERN_WARNING "vxfs: unable to read olt\n");
+		goto out;
+	}
+
+	if (vxfs_read_fshead(sbp)) {
+		printk(KERN_WARNING "vxfs: unable to read fshead\n");
+		goto out;
+	}
+
+	sbp->s_op = &vxfs_super_ops;
+	root = iget(sbp, VXFS_ROOT_INO);
+	sbp->s_root = d_alloc_root(root);
+	if (!sbp->s_root) {
+		iput(root);
+		printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
+		goto out_free_ilist;
+	}
+
+	return 0;
+	
+out_free_ilist:
+	vxfs_put_fake_inode(infp->vsi_fship);
+	vxfs_put_fake_inode(infp->vsi_ilist);
+	vxfs_put_fake_inode(infp->vsi_stilist);
+out:
+	brelse(bp);
+	kfree(infp);
+	return -EINVAL;
+}
+
+/*
+ * The usual module blurb.
+ */
+static struct super_block *vxfs_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, vxfs_fill_super);
+}
+
+static struct file_system_type vxfs_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "vxfs",
+	.get_sb		= vxfs_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
+};
+
+static int __init
+vxfs_init(void)
+{
+	vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
+			sizeof(struct vxfs_inode_info), 0, 
+			SLAB_RECLAIM_ACCOUNT, NULL, NULL);
+	if (vxfs_inode_cachep)
+		return (register_filesystem(&vxfs_fs_type));
+	return -ENOMEM;
+}
+
+static void __exit
+vxfs_cleanup(void)
+{
+	unregister_filesystem(&vxfs_fs_type);
+	kmem_cache_destroy(vxfs_inode_cachep);
+}
+
+module_init(vxfs_init);
+module_exit(vxfs_cleanup);