Re: freevxfs: hp-ux support. patchset 1-7/7 rev 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Krzysztof,

I found some time to go over the patches and spent that on the byte
swap one.  I like it in general, but I'd really like to keep sparse
[1] happy to be able to static type check for it, so I reworked it
a bit.  I also used that as an opportunity to write a proper changelog,
xpand your full name in the signed off line and fix up small deviations
from the Linux coding style.

Can you check if this patch works for you and you are fine with it?
If so I'd like to commit it to a git tree and then work relative to it
for the other patches.

[1] See Documentation/sparse.txt in the kernel tree for instructions

Thanks,
	Christoph

---
>From a510a0e366e8bae7f825d131ad6f6f74dd4bef01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krzysztof=20B=C5=82aszkowski?= <kb@xxxxxxxxxxxxxxx>
Date: Tue, 31 May 2016 08:45:13 +0200
Subject: freevxfs: handle big endian HP-UX file systems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

To support VxFS filesystems from HP-UX on x86 systems we need to
implement byte swapping, and to keep support for Unixware filesystems
it needs to be the complicated dual-endian kind ala sysvfs.

To do this properly we have to split the on disk and in-core inode
so that we can keep the in-core one in native endianness.  All other
structures are byteswapped on demand.

Signed-off-by: Krzysztof Błaszkowski <kb@xxxxxxxxxxxxxxx>
[hch: make spare happy]
Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 fs/freevxfs/vxfs.h        | 177 ++++++++++++++++++++++++++--------------------
 fs/freevxfs/vxfs_bmap.c   |  70 ++++++++++--------
 fs/freevxfs/vxfs_dir.h    |  17 ++---
 fs/freevxfs/vxfs_fshead.c |   5 +-
 fs/freevxfs/vxfs_fshead.h |  28 ++++----
 fs/freevxfs/vxfs_inode.c  |  31 +++++++-
 fs/freevxfs/vxfs_inode.h  | 140 +++++++++++++++++++-----------------
 fs/freevxfs/vxfs_lookup.c |  34 +++++----
 fs/freevxfs/vxfs_olt.c    |  15 ++--
 fs/freevxfs/vxfs_olt.h    |  70 +++++++++---------
 fs/freevxfs/vxfs_super.c  | 101 ++++++++++++++++++--------
 11 files changed, 409 insertions(+), 279 deletions(-)

diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
index c8a9265..4b561de 100644
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -38,13 +38,6 @@
  */
 #include <linux/types.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).
  */
@@ -60,6 +53,14 @@ typedef int32_t		vx_ino_t;
  */
 #define VXFS_NEFREE		32
 
+enum vxfs_byte_order {
+	VXFS_BO_LE,
+	VXFS_BO_BE,
+};
+
+typedef __u16 __bitwise __fs16;
+typedef __u32 __bitwise __fs32;
+typedef __u64 __bitwise __fs64;
 
 /*
  * VxFS superblock (disk).
@@ -71,83 +72,83 @@ struct vxfs_sb {
 	 * 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 */
+	__fs32		vs_magic;		/* Magic number */
+	__fs32		vs_version;		/* VxFS version */
+	__fs32		vs_ctime;		/* create time - secs */
+	__fs32		vs_cutime;		/* create time - usecs */
+	__fs32		__unused1;		/* unused */
+	__fs32		__unused2;		/* unused */
+	__fs32		vs_old_logstart;	/* obsolete */
+	__fs32		vs_old_logend;		/* obsolete */
+	__fs32		vs_bsize;		/* block size */
+	__fs32		vs_size;		/* number of blocks */
+	__fs32		vs_dsize;		/* number of data blocks */
+	__fs32		vs_old_ninode;		/* obsolete */
+	__fs32		vs_old_nau;		/* obsolete */
+	__fs32		__unused3;		/* unused */
+	__fs32		vs_old_defiextsize;	/* obsolete */
+	__fs32		vs_old_ilbsize;		/* obsolete */
+	__fs32		vs_immedlen;		/* size of immediate data area */
+	__fs32		vs_ndaddr;		/* number of direct extentes */
+	__fs32		vs_firstau;		/* address of first AU */
+	__fs32		vs_emap;		/* offset of extent map in AU */
+	__fs32		vs_imap;		/* offset of inode map in AU */
+	__fs32		vs_iextop;		/* offset of ExtOp. map in AU */
+	__fs32		vs_istart;		/* offset of inode list in AU */
+	__fs32		vs_bstart;		/* offset of fdblock in AU */
+	__fs32		vs_femap;		/* aufirst + emap */
+	__fs32		vs_fimap;		/* aufirst + imap */
+	__fs32		vs_fiextop;		/* aufirst + iextop */
+	__fs32		vs_fistart;		/* aufirst + istart */
+	__fs32		vs_fbstart;		/* aufirst + bstart */
+	__fs32		vs_nindir;		/* number of entries in indir */
+	__fs32		vs_aulen;		/* length of AU in blocks */
+	__fs32		vs_auimlen;		/* length of imap in blocks */
+	__fs32		vs_auemlen;		/* length of emap in blocks */
+	__fs32		vs_auilen;		/* length of ilist in blocks */
+	__fs32		vs_aupad;		/* length of pad in blocks */
+	__fs32		vs_aublocks;		/* data blocks in AU */
+	__fs32		vs_maxtier;		/* log base 2 of aublocks */
+	__fs32		vs_inopb;		/* number of inodes per blk */
+	__fs32		vs_old_inopau;		/* obsolete */
+	__fs32		vs_old_inopilb;		/* obsolete */
+	__fs32		vs_old_ndiripau;	/* obsolete */
+	__fs32		vs_iaddrlen;		/* size of indirect addr ext. */
+	__fs32		vs_bshift;		/* log base 2 of bsize */
+	__fs32		vs_inoshift;		/* log base 2 of inobp */
+	__fs32		vs_bmask;		/* ~( bsize - 1 ) */
+	__fs32		vs_boffmask;		/* bsize - 1 */
+	__fs32		vs_old_inomask;		/* old_inopilb - 1 */
+	__fs32		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 */
+	__fs32		vs_free;		/* number of free blocks */
+	__fs32		vs_ifree;		/* number of free inodes */
+	__fs32		vs_efree[VXFS_NEFREE];	/* number of free extents by size */
+	__fs32		vs_flags;		/* flags ?!? */
+	__u8		vs_mod;			/* filesystem has been changed */
+	__u8		vs_clean;		/* clean FS */
+	__fs16		__unused4;		/* unused */
+	__fs32		vs_firstlogid;		/* mount time log ID */
+	__fs32		vs_wtime;		/* last time written - sec */
+	__fs32		vs_wutime;		/* last time written - usec */
+	__u8		vs_fname[6];		/* FS name */
+	__u8		vs_fpack[6];		/* FS pack name */
+	__fs32		vs_logversion;		/* log format version */
+	__u32		__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 */
+	__fs32		vs_oltext[2];		/* OLT extent and replica */
+	__fs32		vs_oltsize;		/* OLT extent size */
+	__fs32		vs_iauimlen;		/* size of inode map */
+	__fs32		vs_iausize;		/* size of IAU in blocks */
+	__fs32		vs_dinosize;		/* size of inode in bytes */
+	__fs32		vs_old_dniaddr;		/* indir levels per inode */
+	__fs32		vs_checksum2;		/* checksum of V2 RO */
 
 	/*
 	 * Actually much more...
@@ -168,8 +169,32 @@ struct vxfs_sb_info {
 	ino_t			vsi_fshino;	/* fileset header inode */
 	daddr_t			vsi_oltext;	/* OLT extent */
 	daddr_t			vsi_oltsize;	/* OLT size */
+	enum vxfs_byte_order	byte_order;
 };
 
+static inline u16 fs16_to_cpu(struct vxfs_sb_info *sbi, __fs16 a)
+{
+	if (sbi->byte_order == VXFS_BO_BE)
+		return be16_to_cpu((__force __be16)a);
+	else
+		return le16_to_cpu((__force __le16)a);
+}
+
+static inline u32 fs32_to_cpu(struct vxfs_sb_info *sbi, __fs32 a)
+{
+	if (sbi->byte_order == VXFS_BO_BE)
+		return be32_to_cpu((__force __be32)a);
+	else
+		return le32_to_cpu((__force __le32)a);
+}
+
+static inline u64 fs64_to_cpu(struct vxfs_sb_info *sbi, __fs64 a)
+{
+	if (sbi->byte_order == VXFS_BO_BE)
+		return be64_to_cpu((__force __be64)a);
+	else
+		return le64_to_cpu((__force __le64)a);
+}
 
 /*
  * File modes.  File types above 0xf000 are vxfs internal only, they should
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
index f86fd3c..1fd41cf 100644
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -68,8 +68,9 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 {
 	struct super_block *sb = ip->i_sb;
 	struct vxfs_inode_info *vip = VXFS_INO(ip);
+	struct vxfs_sb_info *sbi = VXFS_SBI(sb);
 	unsigned long bsize = sb->s_blocksize;
-	u32 indsize = vip->vii_ext4.ve4_indsize;
+	u32 indsize = fs32_to_cpu(sbi, vip->vii_ext4.ve4_indsize);
 	int i;
 
 	if (indsize > sb->s_blocksize)
@@ -77,22 +78,24 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 
 	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 >= 0 && bn < fs32_to_cpu(sbi, d->size))
+			return (bn + fs32_to_cpu(sbi, d->extent));
+		bn -= fs32_to_cpu(sbi, d->size);
 	}
 
 	if ((bn / (indsize * indsize * bsize / 4)) == 0) {
 		struct buffer_head *buf;
 		daddr_t	bno;
-		u32 *indir;
+		__fs32 *indir;
 
-		buf = sb_bread(sb, vip->vii_ext4.ve4_indir[0]);
+		buf = sb_bread(sb,
+			fs32_to_cpu(sbi, 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);
+		indir = (__fs32 *)buf->b_data;
+		bno = fs32_to_cpu(sbi, indir[(bn / indsize) % (indsize * bn)]) +
+			(bn % indsize);
 
 		brelse(buf);
 		return bno;
@@ -127,6 +130,7 @@ fail_buf:
 static daddr_t
 vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
 {
+	struct vxfs_sb_info		*sbi = VXFS_SBI(ip->i_sb);
 	struct buffer_head		*bp = NULL;
 	daddr_t				pblock = 0;
 	int				i;
@@ -142,24 +146,27 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
 
 		typ = ((struct vxfs_typed *)bp->b_data) +
 			(i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
-		off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
+		off = fs64_to_cpu(sbi, typ->vt_hdr) & VXFS_TYPED_OFFSETMASK;
 
 		if (block < off) {
 			brelse(bp);
 			continue;
 		}
 
-		switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
+		switch ((u_int32_t)(fs64_to_cpu(sbi, typ->vt_hdr) >>
+				VXFS_TYPED_TYPESHIFT)) {
 		case VXFS_TYPED_INDIRECT:
-			pblock = vxfs_bmap_indir(ip, typ->vt_block,
-					typ->vt_size, block - off);
+			pblock = vxfs_bmap_indir(ip,
+					fs32_to_cpu(sbi, typ->vt_block),
+					fs32_to_cpu(sbi, typ->vt_size),
+					block - off);
 			if (pblock == -2)
 				break;
 			goto out;
 		case VXFS_TYPED_DATA:
-			if ((block - off) >= typ->vt_size)
+			if ((block - off) >= fs32_to_cpu(sbi, typ->vt_size))
 				break;
-			pblock = (typ->vt_block + block - off);
+			pblock = fs32_to_cpu(sbi, typ->vt_block) + block - off;
 			goto out;
 		case VXFS_TYPED_INDIRECT_DEV4:
 		case VXFS_TYPED_DATA_DEV4: {
@@ -167,13 +174,15 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
 				(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);
+			printk(KERN_INFO "block: %llu\tsize: %lld\tdev: %d\n",
+			       fs64_to_cpu(sbi, typ4->vd4_block),
+			       fs64_to_cpu(sbi, typ4->vd4_size),
+			       fs32_to_cpu(sbi, typ4->vd4_dev));
 			goto fail;
 		}
 		default:
+			printk(KERN_ERR "%s:%d vt_hdr %llu\n", __func__,
+				__LINE__, fs64_to_cpu(sbi, typ->vt_hdr));
 			BUG();
 		}
 		brelse(bp);
@@ -201,28 +210,33 @@ static daddr_t
 vxfs_bmap_typed(struct inode *ip, long iblock)
 {
 	struct vxfs_inode_info		*vip = VXFS_INO(ip);
+	struct vxfs_sb_info		*sbi = VXFS_SBI(ip->i_sb);
 	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);
+		u64			hdr = fs64_to_cpu(sbi, typ->vt_hdr);
+		int64_t			off = (hdr & VXFS_TYPED_OFFSETMASK);
 
 #ifdef DIAGNOSTIC
 		vxfs_typdump(typ);
 #endif
 		if (iblock < off)
 			continue;
-		switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
+		switch ((u32)(hdr >> VXFS_TYPED_TYPESHIFT)) {
 		case VXFS_TYPED_INDIRECT:
-			pblock = vxfs_bmap_indir(ip, typ->vt_block,
-					typ->vt_size, iblock - off);
+			pblock = vxfs_bmap_indir(ip,
+					fs32_to_cpu(sbi, typ->vt_block),
+					fs32_to_cpu(sbi, 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);
+			if ((iblock - off) < fs32_to_cpu(sbi, typ->vt_size))
+				return (fs32_to_cpu(sbi, typ->vt_block) +
+						iblock - off);
 			break;
 		case VXFS_TYPED_INDIRECT_DEV4:
 		case VXFS_TYPED_DATA_DEV4: {
@@ -230,10 +244,10 @@ vxfs_bmap_typed(struct inode *ip, long iblock)
 				(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);
+			printk(KERN_INFO "block: %llu\tsize: %lld\tdev: %d\n",
+			       fs64_to_cpu(sbi, typ4->vd4_block),
+			       fs64_to_cpu(sbi, typ4->vd4_size),
+			       fs32_to_cpu(sbi, typ4->vd4_dev));
 			return 0;
 		}
 		default:
diff --git a/fs/freevxfs/vxfs_dir.h b/fs/freevxfs/vxfs_dir.h
index aaf1fb0..acc5477 100644
--- a/fs/freevxfs/vxfs_dir.h
+++ b/fs/freevxfs/vxfs_dir.h
@@ -48,9 +48,9 @@
  * 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 */
+	__fs16		d_free;		/* free space in dirblock */
+	__fs16		d_nhash;	/* no of hash chains */
+	__fs16		d_hash[1];	/* hash chain */
 };
 
 /*
@@ -63,10 +63,10 @@ struct vxfs_dirblk {
  * 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 */
+	__fs32		d_ino;			/* inode number */
+	__fs16		d_reclen;		/* record length */
+	__fs16		d_namelen;		/* d_name length */
+	__fs16		d_hashnext;		/* next hash entry */
 	char		d_name[VXFS_NAMELEN];	/* name */
 };
 
@@ -87,6 +87,7 @@ struct vxfs_direct {
 /*
  * VXFS_DIRBLKOV is the overhead of a specific dirblock.
  */
-#define VXFS_DIRBLKOV(dbp)	((sizeof(short) * dbp->d_nhash) + 4)
+#define VXFS_DIRBLKOV(sbi, dbp)	\
+	((sizeof(short) * fs16_to_cpu(sbi, dbp->d_nhash)) + 4)
 
 #endif /* _VXFS_DIR_H_ */
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index c9a6a94..e7501cb 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -153,7 +153,8 @@ vxfs_read_fshead(struct super_block *sbp)
 	vxfs_dumpfsh(pfp);
 #endif
 
-	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
+	tip = vxfs_blkiget(sbp, infp->vsi_iext,
+			fs32_to_cpu(infp, sfp->fsh_ilistino[0]));
 	if (!tip)
 		goto out_free_pfp;
 
@@ -169,7 +170,7 @@ vxfs_read_fshead(struct super_block *sbp)
 		goto out_iput_stilist;
 	}
 
-	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
+	tip = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0]));
 	if (!tip)
 		goto out_iput_stilist;
 	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
diff --git a/fs/freevxfs/vxfs_fshead.h b/fs/freevxfs/vxfs_fshead.h
index ead0d64..a786cc5 100644
--- a/fs/freevxfs/vxfs_fshead.h
+++ b/fs/freevxfs/vxfs_fshead.h
@@ -42,20 +42,20 @@
  * 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 */
+	__fs32		fsh_version;		/* fileset header version */
+	__fs32		fsh_fsindex;		/* fileset index */
+	__fs32		fsh_time;		/* modification time - sec */
+	__fs32		fsh_utime;		/* modification time - usec */
+	__fs32		fsh_extop;		/* extop flags */
+	__fs32		fsh_ninodes;		/* allocated inodes */
+	__fs32		fsh_nau;		/* number of IAUs */
+	__fs32		fsh_old_ilesize;	/* old size of ilist */
+	__fs32		fsh_dflags;		/* flags */
+	__fs32		fsh_quota;		/* quota limit */
+	__fs32		fsh_maxinode;		/* maximum inode number */
+	__fs32		fsh_iauino;		/* IAU inode */
+	__fs32		fsh_ilistino[2];	/* ilist inodes */
+	__fs32		fsh_lctino;		/* link count table inode */
 
 	/*
 	 * Slightly more fields follow, but they
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 3e2ccad..15de300 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -68,6 +68,33 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
 }
 #endif
 
+static inline void dip2vip_cpy(struct vxfs_sb_info *sbi,
+		struct vxfs_inode_info *vip, struct vxfs_dinode *dip)
+{
+	vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode);
+	vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink);
+	vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid);
+	vip->vii_gid = fs32_to_cpu(sbi, dip->vdi_gid);
+	vip->vii_size = fs64_to_cpu(sbi, dip->vdi_size);
+	vip->vii_atime = fs32_to_cpu(sbi, dip->vdi_atime);
+	vip->vii_autime = fs32_to_cpu(sbi, dip->vdi_autime);
+	vip->vii_mtime = fs32_to_cpu(sbi, dip->vdi_mtime);
+	vip->vii_mutime = fs32_to_cpu(sbi, dip->vdi_mutime);
+	vip->vii_ctime = fs32_to_cpu(sbi, dip->vdi_ctime);
+	vip->vii_cutime = fs32_to_cpu(sbi, dip->vdi_cutime);
+	vip->vii_orgtype = dip->vdi_orgtype;
+
+	vip->vii_blocks = fs32_to_cpu(sbi, dip->vdi_blocks);
+	vip->vii_gen = fs32_to_cpu(sbi, dip->vdi_gen);
+
+	if (VXFS_ISDIR(vip))
+		vip->vii_dotdot = fs32_to_cpu(sbi, dip->vdi_dotdot);
+	else if (!VXFS_ISREG(vip) && !VXFS_ISLNK(vip))
+		vip->vii_rdev = fs32_to_cpu(sbi, dip->vdi_rdev);
+
+	/* don't endian swap the fields that differ by orgtype */
+	memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org));
+}
 
 /**
  * vxfs_blkiget - find inode based on extent #
@@ -102,7 +129,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
 		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
 			goto fail;
 		dip = (struct vxfs_dinode *)(bp->b_data + offset);
-		memcpy(vip, dip, sizeof(*vip));
+		dip2vip_cpy(VXFS_SBI(sbp), vip, dip);
 #ifdef DIAGNOSTIC
 		vxfs_dumpi(vip, ino);
 #endif
@@ -144,7 +171,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
 		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
 			goto fail;
 		dip = (struct vxfs_dinode *)(kaddr + offset);
-		memcpy(vip, dip, sizeof(*vip));
+		dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip);
 #ifdef DIAGNOSTIC
 		vxfs_dumpi(vip, ino);
 #endif
diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h
index 240aeb1..3a29662 100644
--- a/fs/freevxfs/vxfs_inode.h
+++ b/fs/freevxfs/vxfs_inode.h
@@ -66,74 +66,74 @@ enum {
  * Data stored immediately in the inode.
  */
 struct vxfs_immed {
-	u_int8_t	vi_immed[VXFS_NIMMED];
+	__u8			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 */
+	__fs32			ve4_spare;		/* ?? */
+	__fs32			ve4_indsize;		/* Indirect extent size */
+	__fs32			ve4_indir[VXFS_NIADDR];	/* Indirect extents */
 	struct direct {					/* Direct extents */
-		vx_daddr_t	extent;			/* Extent number */
-		int32_t		size;			/* Size of extent */
+		__fs32		extent;			/* Extent number */
+		__fs32		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 */
+	__fs64		vt_hdr;		/* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
+	__fs32		vt_block;	/* Extent block */
+	__fs32		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;
+	__fs64		vd4_hdr;	/* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
+	__fs64		vd4_block;	/* Extent block */
+	__fs64		vd4_size;	/* Size in blocks */
+	__fs32		vd4_dev;	/* Device ID */
+	__u8		__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;
+	__fs32		vdi_mode;
+	__fs32		vdi_nlink;	/* Link count */
+	__fs32		vdi_uid;	/* UID */
+	__fs32		vdi_gid;	/* GID */
+	__fs64		vdi_size;	/* Inode size in bytes */
+	__fs32		vdi_atime;	/* Last time accessed - sec */
+	__fs32		vdi_autime;	/* Last time accessed - usec */
+	__fs32		vdi_mtime;	/* Last modify time - sec */
+	__fs32		vdi_mutime;	/* Last modify time - usec */
+	__fs32		vdi_ctime;	/* Create time - sec */
+	__fs32		vdi_cutime;	/* Create time - usec */
+	__u8		vdi_aflags;	/* Allocation flags */
+	__u8		vdi_orgtype;	/* Organisation type */
+	__fs16		vdi_eopflags;
+	__fs32		vdi_eopdata;
 	union {
-		u_int32_t		rdev;
-		u_int32_t		dotdot;
+		__fs32			rdev;
+		__fs32			dotdot;
 		struct {
-			u_int32_t	reserved;
-			u_int32_t	fixextsize;
+			__u32		reserved;
+			__fs32		fixextsize;
 		} i_regular;
 		struct {
-			u_int32_t	matchino;
-			u_int32_t	fsetindex;
+			__fs32		matchino;
+			__fs32		fsetindex;
 		} i_vxspec;
-		u_int64_t		align;
+		__u64			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 */
+	__fs32		vdi_blocks;	/* How much blocks does inode occupy */
+	__fs32		vdi_gen;	/* Inode generation */
+	__fs64		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;
+	__fs32		vdi_iattrino;
 };
 
 #define vdi_rdev	vdi_ftarea.rdev
@@ -149,32 +149,40 @@ struct vxfs_dinode {
 
 /*
  * 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
+struct vxfs_inode_info {
+	struct inode	vfs_inode;
+
+	__u32		vii_mode;
+	__u32		vii_nlink;	/* Link count */
+	__u32		vii_uid;	/* UID */
+	__u32		vii_gid;	/* GID */
+	__u64		vii_size;	/* Inode size in bytes */
+	__u32		vii_atime;	/* Last time accessed - sec */
+	__u32		vii_autime;	/* Last time accessed - usec */
+	__u32		vii_mtime;	/* Last modify time - sec */
+	__u32		vii_mutime;	/* Last modify time - usec */
+	__u32		vii_ctime;	/* Create time - sec */
+	__u32		vii_cutime;	/* Create time - usec */
+	__u8		vii_orgtype;	/* Organisation type */
+	union {
+		__u32			rdev;
+		__u32			dotdot;
+	} vii_ftarea;
+	__u32		vii_blocks;	/* How much blocks does inode occupy */
+	__u32		vii_gen;	/* Inode generation */
+	union {
+		struct vxfs_immed	immed;
+		struct vxfs_ext4	ext4;
+		struct vxfs_typed	typed[VXFS_NTYPED];
+	} vii_org;
+};
+
+#define vii_rdev	vii_ftarea.rdev
+#define vii_dotdot	vii_ftarea.dotdot
+
+#define vii_immed	vii_org.immed
+#define vii_ext4	vii_org.ext4
+#define vii_typed	vii_org.typed
 
 #endif /* _VXFS_INODE_H_ */
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 6d576b9..09e93b3 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -74,9 +74,10 @@ dir_blocks(struct inode *ip)
  * 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)
+vxfs_match(struct vxfs_sb_info *sbi, int len, const char *const name,
+		struct vxfs_direct *de)
 {
-	if (len != de->d_namelen)
+	if (len != fs16_to_cpu(sbi, de->d_namelen))
 		return 0;
 	if (!de->d_ino)
 		return 0;
@@ -84,9 +85,10 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de)
 }
 
 static inline struct vxfs_direct *
-vxfs_next_entry(struct vxfs_direct *de)
+vxfs_next_entry(struct vxfs_sb_info *sbi, struct vxfs_direct *de)
 {
-	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
+	return ((struct vxfs_direct *)
+		((char *)de + fs16_to_cpu(sbi, de->d_reclen)));
 }
 
 /**
@@ -106,6 +108,7 @@ vxfs_next_entry(struct vxfs_direct *de)
 static struct vxfs_direct *
 vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
 {
+	struct vxfs_sb_info		*sbi = VXFS_SBI(ip->i_sb);
 	u_long				npages, page, nblocks, pblocks, block;
 	u_long				bsize = ip->i_sb->s_blocksize;
 	const char			*name = dp->d_name.name;
@@ -133,14 +136,16 @@ vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
 			limit = baddr + bsize - VXFS_DIRLEN(1);
 			
 			dbp = (struct vxfs_dirblk *)baddr;
-			de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp));
+			de = (struct vxfs_direct *)
+				(baddr + VXFS_DIRBLKOV(sbi, dbp));
 
-			for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
+			for (; (caddr_t)de <= limit;
+					de = vxfs_next_entry(sbi, de)) {
 				if (!de->d_reclen)
 					break;
 				if (!de->d_ino)
 					continue;
-				if (vxfs_match(namelen, name, de)) {
+				if (vxfs_match(sbi, namelen, name, de)) {
 					*ppp = pp;
 					return (de);
 				}
@@ -173,7 +178,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
 
 	de = vxfs_find_entry(dip, dp, &pp);
 	if (de) {
-		ino = de->d_ino;
+		ino = fs32_to_cpu(VXFS_SBI(dip->i_sb), de->d_ino);
 		kunmap(pp);
 		put_page(pp);
 	}
@@ -232,10 +237,12 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 {
 	struct inode		*ip = file_inode(fp);
 	struct super_block	*sbp = ip->i_sb;
+	struct vxfs_sb_info	*sbi = VXFS_SBI(sbp);
 	u_long			bsize = sbp->s_blocksize;
 	u_long			page, npages, block, pblocks, nblocks, offset;
 	loff_t			pos;
 
+
 	if (ctx->pos == 0) {
 		if (!dir_emit_dot(fp, ctx))
 			return 0;
@@ -280,9 +287,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 			de = (struct vxfs_direct *)
 				(offset ?
 				 (kaddr + offset) :
-				 (baddr + VXFS_DIRBLKOV(dbp)));
+				 (baddr + VXFS_DIRBLKOV(sbi, dbp)));
 
-			for (; (char *)de <= limit; de = vxfs_next_entry(de)) {
+			for (; (char *)de <= limit;
+					de = vxfs_next_entry(sbi, de)) {
 				if (!de->d_reclen)
 					break;
 				if (!de->d_ino)
@@ -290,8 +298,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 
 				offset = (char *)de - kaddr;
 				ctx->pos = ((page << PAGE_SHIFT) | offset) + 2;
-				if (!dir_emit(ctx, de->d_name, de->d_namelen,
-					de->d_ino, DT_UNKNOWN)) {
+				if (!dir_emit(ctx, de->d_name,
+						fs16_to_cpu(sbi, de->d_namelen),
+						fs32_to_cpu(sbi, de->d_ino),
+						DT_UNKNOWN)) {
 					vxfs_put_page(pp);
 					return 0;
 				}
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 049500847..813da66 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -43,14 +43,14 @@ static inline void
 vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
 {
 	BUG_ON(infp->vsi_fshino);
-	infp->vsi_fshino = fshp->olt_fsino[0];
+	infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]);
 }
 
 static inline void
 vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
 {
 	BUG_ON(infp->vsi_iext);
-	infp->vsi_iext = ilistp->olt_iext[0]; 
+	infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]);
 }
 
 static inline u_long
@@ -81,13 +81,12 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
 	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) {
+	if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) {
 		printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
 		goto fail;
 	}
@@ -102,14 +101,14 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
 		goto fail;
 	}
 
-	oaddr = bp->b_data + op->olt_size;
+	oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
 	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
 
 	while (oaddr < eaddr) {
 		struct vxfs_oltcommon	*ocp =
 			(struct vxfs_oltcommon *)oaddr;
 		
-		switch (ocp->olt_type) {
+		switch (fs32_to_cpu(infp, ocp->olt_type)) {
 		case VXFS_OLT_FSHEAD:
 			vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
 			break;
@@ -118,11 +117,11 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
 			break;
 		}
 
-		oaddr += ocp->olt_size;
+		oaddr += fs32_to_cpu(infp, ocp->olt_size);
 	}
 
 	brelse(bp);
-	return 0;
+	return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
 
 fail:
 	brelse(bp);
diff --git a/fs/freevxfs/vxfs_olt.h b/fs/freevxfs/vxfs_olt.h
index b7b3af5..0c0b0c9 100644
--- a/fs/freevxfs/vxfs_olt.h
+++ b/fs/freevxfs/vxfs_olt.h
@@ -63,83 +63,83 @@ enum {
  * the initial 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	*/
+	__fs32		olt_magic;	/* magic number			*/
+	__fs32		olt_size;	/* size of this entry		*/
+	__fs32		olt_checksum;	/* checksum of extent		*/
+	__u32		__unused1;	/* ???				*/
+	__fs32		olt_mtime;	/* time of last mod. (sec)	*/
+	__fs32		olt_mutime;	/* time of last mod. (usec)	*/
+	__fs32		olt_totfree;	/* free space in OLT extent	*/
+	__fs32		olt_extents[2];	/* addr of this extent, replica	*/
+	__fs32		olt_esize;	/* size of this extent		*/
+	__fs32		olt_next[2];    /* addr of next extent, replica	*/
+	__fs32		olt_nsize;	/* size of next extent		*/
+	__u32		__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		*/
+	__fs32		olt_type;	/* type of this record		*/
+	__fs32		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	*/
+	__fs32		olt_type;	/* type of this record		*/
+	__fs32		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	*/
+	__fs32	olt_type;	/* type of this record		*/
+	__fs32	olt_size;	/* size of this record		*/
+	__fs32		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		*/
+	__fs32		olt_type;	/* type of this record		*/
+	__fs32		olt_size;	/* size of this record		*/
+	__fs32		olt_cutino;	/* inode of current usage table	*/
+	__u8		__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	*/
+	__fs32		olt_type;	/* type of this record		*/
+	__fs32		olt_size;	/* size of this record		*/
+	__fs32		olt_sbino;	/* inode of superblock file	*/
+	__u32		__unused1;	/* ???				*/
+	__fs32		olt_logino[2];	/* inode of log file,replica	*/
+	__fs32		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	*/
+	__fs32		olt_type;	/* type of this record		*/
+	__fs32		olt_size;	/* size of this record		*/
+	__fs32		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	*/
+	__fs32		olt_type;	/* type number			*/
+	__fs32		olt_size;	/* size of this record		*/
+	__fs32		olt_fsino[2];   /* inodes of fileset header	*/
 };
 
 #endif /* _VXFS_OLT_H_ */
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 7ca8c75..6124091 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -109,14 +109,15 @@ static int
 vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
 {
 	struct vxfs_sb_info		*infp = VXFS_SBI(dentry->d_sb);
+	struct vxfs_sb *raw_sb = infp->vsi_raw;
 
 	bufp->f_type = VXFS_SUPER_MAGIC;
 	bufp->f_bsize = dentry->d_sb->s_blocksize;
-	bufp->f_blocks = infp->vsi_raw->vs_dsize;
-	bufp->f_bfree = infp->vsi_raw->vs_free;
+	bufp->f_blocks = fs32_to_cpu(infp, raw_sb->vs_dsize);
+	bufp->f_bfree = fs32_to_cpu(infp, raw_sb->vs_free);
 	bufp->f_bavail = 0;
 	bufp->f_files = 0;
-	bufp->f_ffree = infp->vsi_raw->vs_ifree;
+	bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree);
 	bufp->f_namelen = VXFS_NAMELEN;
 
 	return 0;
@@ -129,6 +130,50 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data)
 	return 0;
 }
 
+
+static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
+		unsigned blk, __fs32 magic)
+{
+	struct buffer_head *bp;
+	struct vxfs_sb *rsbp;
+	struct vxfs_sb_info *infp = VXFS_SBI(sbp);
+	int rc = -ENOMEM;
+
+	bp = sb_bread(sbp, blk);
+	do {
+		if (!bp || !buffer_mapped(bp)) {
+			if (!silent) {
+				printk(KERN_WARNING
+					"vxfs: unable to read disk superblock at %u\n",
+					blk);
+			}
+			break;
+		}
+
+		rc = -EINVAL;
+		rsbp = (struct vxfs_sb *)bp->b_data;
+		if (rsbp->vs_magic != magic) {
+			if (!silent)
+				printk(KERN_NOTICE
+					"vxfs: WRONG superblock magic %08x at %u\n",
+					rsbp->vs_magic, blk);
+			break;
+		}
+
+		rc = 0;
+		infp->vsi_raw = rsbp;
+		infp->vsi_bp = bp;
+	} while (0);
+
+	if (rc) {
+		infp->vsi_raw = NULL;
+		infp->vsi_bp = NULL;
+		brelse(bp);
+	}
+
+	return rc;
+}
+
 /**
  * vxfs_read_super - read superblock into memory and initialize filesystem
  * @sbp:		VFS superblock (to fill)
@@ -149,10 +194,10 @@ 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;
 	int ret = -EINVAL;
+	u32 j;
 
 	sbp->s_flags |= MS_RDONLY;
 
@@ -168,42 +213,42 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 		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;
-	}
+	sbp->s_fs_info = infp;
 
-	rsbp = (struct vxfs_sb *)bp->b_data;
-	if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
+	if (!vxfs_try_sb_magic(sbp, silent, 1,
+			(__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
+		/* Unixware, x86 */
+		infp->byte_order = VXFS_BO_LE;
+	} else if (!vxfs_try_sb_magic(sbp, silent, 8,
+			(__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) {
+		/* HP-UX, parisc */
+		infp->byte_order = VXFS_BO_BE;
+	} else {
 		if (!silent)
-			printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
+			printk(KERN_NOTICE "vxfs: can't find superblock.\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);
+	rsbp = infp->vsi_raw;
+	j = fs32_to_cpu(infp, rsbp->vs_version);
+	if ((j < 2 || j > 4) && !silent) {
+		printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j);
 		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);
+	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
+	printk(KERN_DEBUG "vxfs: blocksize: %d\n",
+		fs32_to_cpu(infp, rsbp->vs_bsize));
 #endif
 
-	sbp->s_magic = rsbp->vs_magic;
-	sbp->s_fs_info = infp;
+	sbp->s_magic = fs32_to_cpu(infp, rsbp->vs_magic);
 
-	infp->vsi_raw = rsbp;
-	infp->vsi_bp = bp;
-	infp->vsi_oltext = rsbp->vs_oltext[0];
-	infp->vsi_oltsize = rsbp->vs_oltsize;
+	infp->vsi_oltext = fs32_to_cpu(infp, rsbp->vs_oltext[0]);
+	infp->vsi_oltsize = fs32_to_cpu(infp, rsbp->vs_oltsize);
 
-	if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
+	j = fs32_to_cpu(infp, rsbp->vs_bsize);
+	if (!sb_set_blocksize(sbp, j)) {
 		printk(KERN_WARNING "vxfs: unable to set final block size\n");
 		goto out;
 	}
@@ -237,7 +282,7 @@ out_free_ilist:
 	vxfs_put_fake_inode(infp->vsi_ilist);
 	vxfs_put_fake_inode(infp->vsi_stilist);
 out:
-	brelse(bp);
+	brelse(infp->vsi_bp);
 	kfree(infp);
 	return ret;
 }
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux