diff mbox

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

Message ID 1464702291.900.75.camel@linux-q3cb.site (mailing list archive)
State New, archived
Headers show

Commit Message

Krzysztof Błaszkowski May 31, 2016, 1:44 p.m. UTC
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

"
"

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@sysmikro.com.pl>
> 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@sysmikro.com.pl>
> [hch: make spare happy]
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  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;
>  }

Comments

Christoph Hellwig June 1, 2016, 7:33 a.m. UTC | #1
Hi Krzysztof,

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

It seems easier this way around.  If you think byte swapping makes
life easier for you I'm happy to take an incremental patch.  Howerver
that means we'll need separate structure defintions for the union
members.

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

bitwise is an annotation for sparse so that you can't directly assign
to the variable, and need to use accessors instead.  In this case it's
used so that we are forced to use the byte swapping helpers and get a
warning from sparse if that's not done properly.

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

Yes, PAGE_CACHE_SIZE, PAGE_CACHE_SHIFT and co were removed in kernel
4.6, as they have always been identical to the versions without _CACHE.

> 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 think all readdir structures are fixed up now, please check.

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

Yeah, this was just getting started.  I've spent some more time on the
whole inode issues and have implemented this a bit different from what
you did, although the end result is very similar.  Can you take a look
at the tree here:

	http://git.infradead.org/users/hch/vfs.git/shortlog/refs/heads/freevxfs

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

Please take a look at the branch above.  The only major thing that
should be missing is your directory code refactoring.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Krzysztof Błaszkowski June 1, 2016, 8:38 a.m. UTC | #2
Hi Christoph,

On Wed, 2016-06-01 at 00:33 -0700, Christoph Hellwig wrote:
> Hi Krzysztof,
> 
> > 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)
> 
> It seems easier this way around.  If you think byte swapping makes
> life easier for you I'm happy to take an incremental patch.  Howerver
> that means we'll need separate structure defintions for the union
> members.

yes, you are right. bitwise attribute is convenient for endian
annotation for automated checks. I did not know this feature and it
seemed like excessive typing overhead to me.
Anyway I must admit that it has benefits. Without that I wouldn't dare
to have a mixed endian structure. I would just put a //note somewhere
aside for me to remember that this structure requires special handling
with regard to endianess and whether it has been copied already or it is
just mapped piece of memory from backend device. 
Would I do this with every member of the structure ? of course,
wouldn't. (too many to remember)


> 
> > Are there any real benefits from marking anything "bitwise" except that
> > it is just another type ?
> 
> bitwise is an annotation for sparse so that you can't directly assign
> to the variable, and need to use accessors instead.  In this case it's
> used so that we are forced to use the byte swapping helpers and get a
> warning from sparse if that's not done properly.
> 
indeed, I realized this.


> > 
> > 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.
> 
> Yes, PAGE_CACHE_SIZE, PAGE_CACHE_SHIFT and co were removed in kernel
> 4.6, as they have always been identical to the versions without _CACHE.

I see. sorry, I reworked these remaining patches with 3.16 so you will
hit the issue with applying them again.

I will post them shortly soon. Good news is that regression tests are
ok. The patchset will start from 2nd patch. I think there is no need to
re-post the patch you created.

> 
> > 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 think all readdir structures are fixed up now, please check.

right.

> 
> > 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.
> 
> Yeah, this was just getting started.  I've spent some more time on the
> whole inode issues and have implemented this a bit different from what
> you did, although the end result is very similar.  Can you take a look
> at the tree here:
> 
> 	http://git.infradead.org/users/hch/vfs.git/shortlog/refs/heads/freevxfs
> 
> > Do you think other patches should be updated with regard to the patch
> > you sent ?
> 


okay .. once again we did the same thing in parallel without a mutex ...
will see your solution.

we will need to sort out which one is better and/or looks better.
I am afraid that I may loose because don't care about tabs&spaces.


> Please take a look at the branch above.  The only major thing that
> should be missing is your directory code refactoring.

Thanks. yes, the old readdir has a bug. this time my change logs are
more verbose.
Krzysztof Błaszkowski June 1, 2016, 9:23 a.m. UTC | #3
Hi Christoph,

On Wed, 2016-06-01 at 00:33 -0700, Christoph Hellwig wrote:

> Yeah, this was just getting started.  I've spent some more time on the
> whole inode issues and have implemented this a bit different from what
> you did, although the end result is very similar.  Can you take a look
> at the tree here:
> 
> 	http://git.infradead.org/users/hch/vfs.git/shortlog/refs/heads/freevxfs
> 
> > Do you think other patches should be updated with regard to the patch
> > you sent ?
> 
> Please take a look at the branch above.  

I think that there are no "kfree(pfp); kfree(sfp); return 0;" in
vxfs_read_fshead() still. Are pfp and sfp needed anywhere ? I am sure
they are not so there is a memory leak without these kfrees every mount.

I am not sure absolutely of that read_fshead() is missing these kfrees
because I have seen just these diffs, anyway I did not notice "+kfree".

so .. whose patch is more accurate ?

needles to say that I prefer to have limited scope of visibility of
inode_cachep to the inode.c only.

Thanks,
Krzysztof Błaszkowski June 1, 2016, 9:27 a.m. UTC | #4
I forgot to say that 
http://git.infradead.org/users/hch/vfs.git/commit/1cce17017970c0797943e069cc520e17d068ca4b

looks good. I am fine with it so let's forget about 4th "the credits"
patch I have posted.

Thanks !
Christoph Hellwig June 2, 2016, 8:25 a.m. UTC | #5
On Wed, Jun 01, 2016 at 11:23:32AM +0200, Krzysztof B??aszkowski wrote:
> I think that there are no "kfree(pfp); kfree(sfp); return 0;" in
> vxfs_read_fshead() still. Are pfp and sfp needed anywhere ? I am sure
> they are not so there is a memory leak without these kfrees every mount.
> 
> I am not sure absolutely of that read_fshead() is missing these kfrees
> because I have seen just these diffs, anyway I did not notice "+kfree".

The frees are still missing.  Do you want to send me a patch for those?

> needles to say that I prefer to have limited scope of visibility of
> inode_cachep to the inode.c only.

In my tree the visibility is in vxfs_super.c only.  Given that the
alloc/destroy methods are super operations that seems to fit better
as they can have local scope, too.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Krzysztof Błaszkowski June 2, 2016, 9:16 a.m. UTC | #6
On Thu, 2016-06-02 at 01:25 -0700, Christoph Hellwig wrote:
> On Wed, Jun 01, 2016 at 11:23:32AM +0200, Krzysztof B??aszkowski wrote:
> > I think that there are no "kfree(pfp); kfree(sfp); return 0;" in
> > vxfs_read_fshead() still. Are pfp and sfp needed anywhere ? I am sure
> > they are not so there is a memory leak without these kfrees every mount.
> > 
> > I am not sure absolutely of that read_fshead() is missing these kfrees
> > because I have seen just these diffs, anyway I did not notice "+kfree".
> 
> The frees are still missing.  Do you want to send me a patch for those?

I see. Don't hesitate to add them, I was thinking that creating a
special patch because of these just two kfree()s is just too much formal
work.

> 
> > needles to say that I prefer to have limited scope of visibility of
> > inode_cachep to the inode.c only.
> 
> In my tree the visibility is in vxfs_super.c only.  Given that the
> alloc/destroy methods are super operations that seems to fit better
> as they can have local scope, too.

I see. We differ in point of views. I presumed that it is more
consistent to have everything regarding inodes creation
(getting)/destroying, etc in the inode.c. Anyway this is just pure
academic debate, we could argue on anything else (weather, politics and
politicians - hot topic especially in Poland) as well.

You decide. You enjoy more your approach - good enough.
diff mbox

Patch

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