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

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

 



Hi Christoph,

On Tue, 2016-05-31 at 05:25 -0700, Christoph Hellwig wrote:
> Hi Krzysztof,
> 
> I found some time to go over the patches and spent that on the byte
> swap one. 

Thanks.


>  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.

okay.

>   I also used that as an opportunity to write a proper changelog,

many thanks. 

> xpand your full name in the signed off line and fix up small deviations
> from the Linux coding style.
> 

once again thanks. yes, I will look at this further soon.

> 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.

I can check but here are my remarks:
the dip2vip_cpy() does partial byte-swap from file system endian to cpu
endian, so the union uses fs native endianess and this raises difficulty
of using struct vxfs_inode_info to yet another level.
Is this a good practice ? (apart from a benefit like some minor speed
gain)

Are there any real benefits from marking anything "bitwise" except that
it is just another type ?

I reckon that this is just reworked my 0001 patch and one of chunks does
not apply to lookup.c

"
--- vxfs_lookup.c
+++ vxfs_lookup.c
@@ -298,8 +306,10 @@
 
 				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;
 				}
"

because for some strange reason the patch uses "PAGE_SHIFT" while
original lookup.c from 3.16 or 3.18 kernels uses PAGE_CACHE_SHIFT but
4.6 kernel. so the patch below does not apply cleanly to source from 3.x
kernels. I use 3.16, double checked latest 3.18.

Anyway because readdir() is not aware of fs endianess (because 0004
patch is not in there) the hp-ux tests will fail with some general
protection fault very likely.

I am almost sure that this patch stands also for that patch 6/7 will
have to be changed heavily because it will not apply.

I can't see also patches which fix these obvious bugs like freeing
kmem_cache_alloc() objects with kfree.
Even worse is releasing inode->i_private from the "evict_inode"
callback.
This leads to dangling objects in vxfs's kmem_cache when the fs is
unmounted. Destroying cache on module unload causes kmem_cache_destroy
to complain about it and after a few tries ((module load, mount, some
ops on mountpoint, unmount, unload) x few times) hard lockup is
inevitable.

A fix is to utilize the "destroy_inode" callback however this will lead
to memory leaks to fs/inode.c cache. So it is partial fix.
A proper fix is to use both "alloc_inode" and "destroy_inode" callbacks
but this stands for that the vxfs inode structure must inherit generic
struct inode and the patch 0006 addresses this.


This is what, I think, is right in this situation: you put big effort to
split vxfs_dinfo from vxfs_inode_info, which was on "to do", fs endian
fields are marked bitwise. This work should not be wasted and I think
that it is wise to modify remaining patches to your "0001" and I can do
this.

It is pointless to give a try to that patch only below because of
readdir() and inode_cachep issue. (and wrong error handling:
kfree(kmem_cache_alloc()), small memory leak in fshead.c - these are
minors despite of that look bad)

Do you think other patches should be updated with regard to the patch
you sent ?

If so then let me do this.



> 
> [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;
>  }

-- 
Krzysztof Blaszkowski


--
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