Re: freevxfs

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

 



Hi,

Yes, I think I can do this.
Sure, will use the script.

I reckon that this process will take more time than I expect because of
preserving functionality of SCO.

On Mon, 2016-05-23 at 10:23 +0200, Carlos Maiolino wrote:
> On Sun, May 22, 2016 at 05:13:14PM +0200, Krzysztof Błaszkowski wrote:
> > Hello All,
> > 
> > I recently gave a try to vxfs (veritas fs) which is common to HP-UX and
> > it turned out that the module has been broken for very long time.
> > 
> > I fixed several issues with current freevxfs and also designed a
> > userspace tool which helps creating dm block devices from e.g. regular
> > file with raw image of hp-ux disk.
> > https://sourceforge.net/projects/linux-vxfs/
> > 
> > 
> > I send the patch because I believe that some people would appreciate
> > support for this vintage file system (e.g. me) and also it will be nice
> > to see my name in the kernel.
> > 
> 
> Hi,
> 
> - Can you please split this patch into individual patches fixing each specific
>   problem? It's easier to review, instead of a big patch with several fixes into
>   it.
> 
> - Also, as a quick view, there are a lot of trailing white spaces over the whole
>   patch, which, should be removed.
> 
>   you can use the scripts/checkpatch.pl script to check your patches and see
>   match at least the basics requirements for sending patches to kernel and, a
>   read of Documentation/SubmittingPatches is interesting too.
> 
> > Regards,
> > 
> > -- 
> > Krzysztof Blaszkowski
> 
> > diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
> > index c8a9265..9890a84 100644
> > --- a/fs/freevxfs/vxfs.h
> > +++ b/fs/freevxfs/vxfs.h
> > @@ -2,6 +2,39 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + *
> > + * (c) 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests.
> > + *
> > + * These bugs and improvements were as follows:
> > + *   - code not aware of cpu endianess and ondisk data is BE.
> > + *   - misaligned structures read from block device
> > + *   - wrong SB block number. default offset is 8kB
> > + *   - kmem_cache_alloc() objectes released with kfree()
> > + *   - inode.i_private released in evict_inode() callback.
> > + *   - refactored vxfs_readdir() and vxfs_find_entry()
> > + *
> > + * Tests were performed with image of HP 9000/779 disk (/ lvol)
> > + * Example: */
> > +// *  cksum mnt/usr/share/man/man3.Z/* 
> > +// *  cksum mnt/usr/share/doc/10.20RelNotes 
> > +// *  cksum mnt/usr/local/doom/*
> > +// *  cksum mnt/usr/sprockets/tools/instrument/16700/*
> > +// *  cksum mnt/usr/share/doc/*
> > +// *  cksum mnt/usr/sprockets/lib/*
> > +// *  cksum mnt/usr/sprockets/bin/*
> > +/*
> 
> Don't use //
> 
> > + * Needles to say that checksums of files match these evaluated by
> > + * HP-UX B.10.20 cksum. E.g.:
> > + *  3457951056 4196020 /usr/local/doom/doom1.wad
> > + *  2527157998 35344 /usr/local/doom/doomlaunch
> > + *  2974998129 413696 /usr/local/doom/hpdoom
> > + *
> > + * The hpux_mdsetup tool project which is aimed at making possible
> > + * accessing HP-UX logical volumes by device mapper is here:
> > + *       https://sourceforge.net/projects/linux-vxfs/
> > + *
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -38,6 +71,10 @@
> >   */
> >  #include <linux/types.h>
> >  
> > +//#define DIAGNOSTIC
> > +#undef DIAGNOSTIC
> > +#undef DIAGNOSTIC_V2
> > +#undef DIAGNOSTIC_V3
> >  
> >  /*
> >   * Data types for use with the VxFS ondisk format.
> > @@ -152,7 +189,7 @@ struct vxfs_sb {
> >  	/*
> >  	 * Actually much more...
> >  	 */
> > -};
> > +} __attribute__((packed));
> >  
> >  
> >  /*
> > @@ -260,4 +297,35 @@ enum {
> >  #define VXFS_SBI(sbp) \
> >  	((struct vxfs_sb_info *)(sbp)->s_fs_info)
> >  
> > +
> > +#ifdef DIAGNOSTIC
> > +#define F_ENTER(fmt, arg...) printk("%s:%d ENTER. " fmt "\n", __FUNCTION__, __LINE__, ##arg)
> > +#define F_EXIT(fmt, arg...) printk("%s:%d EXIT. " fmt "\n", __FUNCTION__, __LINE__, ##arg)
> > +
> > +#ifdef DIAGNOSTIC_V2
> > +#define F_ENTER_V2(fmt, arg...) printk("%s:%d ENTER. " fmt "\n", __FUNCTION__, __LINE__, ##arg)
> > +#define F_EXIT_V2(fmt, arg...) printk("%s:%d EXIT. " fmt "\n", __FUNCTION__, __LINE__, ##arg)
> > +#else
> > +#define F_ENTER_V2(a, b...) 
> > +#define F_EXIT_V2(a, b...) 
> > +#endif
> > +
> > +#ifdef DIAGNOSTIC_V3
> > +#define F_ENTER_V3(fmt, arg...) printk("%s:%d ENTER. " fmt "\n", __FUNCTION__, __LINE__, ##arg)
> > +#define F_EXIT_V3(fmt, arg...) printk("%s:%d EXIT. " fmt "\n", __FUNCTION__, __LINE__, ##arg)
> > +#else
> > +#define F_ENTER_V3(a, b...) 
> > +#define F_EXIT_V3(a, b...) 
> > +#endif
> > +
> > +#else // DIAGNOSTIC
> > +#define F_ENTER(a, b...) 
> > +#define F_EXIT(a, b...) 
> > +#define F_ENTER_V2(a, b...) 
> > +#define F_EXIT_V2(a, b...) 
> > +#define F_ENTER_V3(a, b...) 
> > +#define F_EXIT_V3(a, b...) 
> > +#endif
> > +
> 
> Lots of trailing white spaces here
> 
> > +
> >  #endif /* _VXFS_SUPER_H_ */
> > diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
> > index f86fd3c..58e6a17 100644
> > --- a/fs/freevxfs/vxfs_bmap.c
> > +++ b/fs/freevxfs/vxfs_bmap.c
> > @@ -2,6 +2,10 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + *
> > + * 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -39,17 +43,6 @@
> >  #include "vxfs_extern.h"
> >  
> >  
> > -#ifdef DIAGNOSTIC
> > -static void
> > -vxfs_typdump(struct vxfs_typed *typ)
> > -{
> > -	printk(KERN_DEBUG "type=%Lu ", typ->vt_hdr >> VXFS_TYPED_TYPESHIFT);
> > -	printk("offset=%Lx ", typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
> > -	printk("block=%x ", typ->vt_block);
> > -	printk("size=%x\n", typ->vt_size);
> > -}
> > -#endif
> > -
> >  /**
> >   * vxfs_bmap_ext4 - do bmap for ext4 extents
> >   * @ip:		pointer to the inode we do bmap for
> > @@ -71,18 +64,23 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
> >  	unsigned long bsize = sb->s_blocksize;
> >  	u32 indsize = vip->vii_ext4.ve4_indsize;
> >  	int i;
> > +	daddr_t rc = 0;
> > +
> > +	F_ENTER_V2();
> >  
> >  	if (indsize > sb->s_blocksize)
> >  		goto fail_size;
> >  
> >  	for (i = 0; i < VXFS_NDADDR; i++) {
> > -		struct direct *d = vip->vii_ext4.ve4_direct + i;
> > -		if (bn >= 0 && bn < d->size)
> > -			return (bn + d->extent);
> > +		struct direct *d = vip->vii_ext4.ve4_direct + i; // cpu endian
> > +		if (bn >= 0 && bn < d->size) {
> > +			rc = bn + d->extent;
> > +			break;
> > +		}
> >  		bn -= d->size;
> >  	}
> >  
> > -	if ((bn / (indsize * indsize * bsize / 4)) == 0) {
> > +	if (!rc && ((bn / (indsize * indsize * bsize / 4)) == 0)) {
> >  		struct buffer_head *buf;
> >  		daddr_t	bno;
> >  		u32 *indir;
> > @@ -92,18 +90,21 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
> >  			goto fail_buf;
> >  
> >  		indir = (u32 *)buf->b_data;
> > -		bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize);
> > +		bno = be32_to_cpu(indir[(bn/indsize) % (indsize*bn)]) + (bn%indsize);
> >  
> >  		brelse(buf);
> > -		return bno;
> > -	} else
> > -		printk(KERN_WARNING "no matching indir?");
> > +		rc = bno;
> > +	}
> > +	if (!rc)
> > +		printk(KERN_WARNING "%s:%d no matching indir?\n", __FUNCTION__, __LINE__);
> >  
> > -	return 0;
> > +	F_EXIT_V2("pblk %d", rc);
> > +	return rc;
> >  
> >  fail_size:
> >  	printk("vxfs: indirect extent too big!\n");
> >  fail_buf:
> > +	F_EXIT();
> >  	return 0;
> >  }
> >  
> > @@ -129,51 +130,53 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
> >  {
> >  	struct buffer_head		*bp = NULL;
> >  	daddr_t				pblock = 0;
> > -	int				i;
> > +	int i;
> >  
> > +	F_ENTER_V2();
> >  	for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
> >  		struct vxfs_typed	*typ;
> > -		int64_t			off;
> > +		int64_t off;
> >  
> >  		bp = sb_bread(ip->i_sb,
> >  				indir + (i / VXFS_TYPED_PER_BLOCK(ip->i_sb)));
> >  		if (!bp || !buffer_mapped(bp))
> > -			return 0;
> > +			break;
> >  
> >  		typ = ((struct vxfs_typed *)bp->b_data) +
> >  			(i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
> > -		off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
> > +		off = be64_to_cpu(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)(be64_to_cpu(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, be32_to_cpu(typ->vt_block),
> > +					be32_to_cpu(typ->vt_size), block - off);
> >  			if (pblock == -2)
> >  				break;
> >  			goto out;
> >  		case VXFS_TYPED_DATA:
> > -			if ((block - off) >= typ->vt_size)
> > +			if ((block - off) >= be32_to_cpu(typ->vt_size))
> >  				break;
> > -			pblock = (typ->vt_block + block - off);
> > +			pblock = be32_to_cpu(typ->vt_block) + block - off;
> >  			goto out;
> >  		case VXFS_TYPED_INDIRECT_DEV4:
> >  		case VXFS_TYPED_DATA_DEV4: {
> >  			struct vxfs_typed_dev4	*typ4 =
> >  				(struct vxfs_typed_dev4 *)typ;
> >  
> > -			printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
> > -			printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
> > -			       (unsigned long long) typ4->vd4_block,
> > -			       (unsigned long long) typ4->vd4_size,
> > -			       typ4->vd4_dev);
> > +			printk(KERN_ERR "%s:%d TYPED_DEV4 detected!. block: %Lu\tsize: %Ld\tdev: %d\n",
> > +				__FUNCTION__, __LINE__,
> > +			       (unsigned long long) be64_to_cpu(typ4->vd4_block),
> > +			       (unsigned long long) be64_to_cpu(typ4->vd4_size),
> > +			       be32_to_cpu(typ4->vd4_dev));
> >  			goto fail;
> >  		}
> >  		default:
> > +			printk(KERN_ERR "%s:%d vt_hdr %llu\n", __FUNCTION__, __LINE__, be64_to_cpu(typ->vt_hdr));
> >  			BUG();
> >  		}
> >  		brelse(bp);
> > @@ -182,7 +185,9 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
> >  fail:
> >  	pblock = 0;
> >  out:
> > -	brelse(bp);
> > +	if (bp)
> > +		brelse(bp);
> > +	F_EXIT_V2();
> >  	return (pblock);
> >  }
> >  
> > @@ -200,16 +205,18 @@ out:
> >  static daddr_t
> >  vxfs_bmap_typed(struct inode *ip, long iblock)
> >  {
> > -	struct vxfs_inode_info		*vip = VXFS_INO(ip);
> > -	daddr_t				pblock = 0;
> > -	int				i;
> > +	struct vxfs_inode_info *vip = VXFS_INO(ip);
> > +	daddr_t pblock = 0;
> > +	int i;
> >  
> > +	F_ENTER_V2();
> >  	for (i = 0; i < VXFS_NTYPED; i++) {
> > -		struct vxfs_typed	*typ = vip->vii_org.typed + i;
> > +		struct vxfs_typed	*typ = vip->vii_org.typed + i; // cpu endian
> >  		int64_t			off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
> >  
> > -#ifdef DIAGNOSTIC
> > -		vxfs_typdump(typ);
> > +#ifdef DIAGNOSTIC_V2
> > +		printk(KERN_DEBUG "%s:%d type=%Lu, ofs=0x%Lx, blk=%d, size=%d\n", __FUNCTION__, __LINE__,
> > +			typ->vt_hdr >> VXFS_TYPED_TYPESHIFT, off, typ->vt_block, typ->vt_size );
> >  #endif
> >  		if (iblock < off)
> >  			continue;
> > @@ -219,29 +226,36 @@ vxfs_bmap_typed(struct inode *ip, long iblock)
> >  					typ->vt_size, iblock - off);
> >  			if (pblock == -2)
> >  				break;
> > -			return (pblock);
> > +			goto out;
> > +
> >  		case VXFS_TYPED_DATA:
> > -			if ((iblock - off) < typ->vt_size)
> > -				return (typ->vt_block + iblock - off);
> > +			if ((iblock - off) < typ->vt_size) {
> > +				pblock = typ->vt_block + iblock - off;
> > +				goto out;
> > +			}
> >  			break;
> >  		case VXFS_TYPED_INDIRECT_DEV4:
> >  		case VXFS_TYPED_DATA_DEV4: {
> >  			struct vxfs_typed_dev4	*typ4 =
> >  				(struct vxfs_typed_dev4 *)typ;
> >  
> > -			printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
> > -			printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
> > +			printk(KERN_ERR "%s:%d TYPED_DEV4 detected!. block: %Lu\tsize: %Ld\tdev: %d\n",
> > +				__FUNCTION__, __LINE__,
> >  			       (unsigned long long) typ4->vd4_block,
> >  			       (unsigned long long) typ4->vd4_size,
> >  			       typ4->vd4_dev);
> > -			return 0;
> > +			pblock = 0;
> > +			goto out;
> >  		}
> >  		default:
> > +			printk(KERN_ERR "%s:%d vt_hdr %llu\n", __FUNCTION__, __LINE__, typ->vt_hdr);
> >  			BUG();
> >  		}
> >  	}
> >  
> > -	return 0;
> > +out:
> > +	F_EXIT_V2("pblk %d", pblock);
> > +	return pblock;
> >  }
> >  
> >  /**
> > @@ -270,12 +284,14 @@ vxfs_bmap1(struct inode *ip, long iblock)
> >  	if (VXFS_ISIMMED(vip))
> >  		goto unsupp;
> >  
> > -	printk(KERN_WARNING "vxfs: inode %ld has no valid orgtype (%x)\n",
> > -			ip->i_ino, vip->vii_orgtype);
> > +	printk(KERN_ERR "%s:%d inode %ld has no valid orgtype (%x)\n",
> > +		__FUNCTION__, __LINE__,
> > +		ip->i_ino, vip->vii_orgtype);
> >  	BUG();
> >  
> >  unsupp:
> > -	printk(KERN_WARNING "vxfs: inode %ld has an unsupported orgtype (%x)\n",
> > -			ip->i_ino, vip->vii_orgtype);
> > +	printk(KERN_WARNING "%s:%d inode %ld has an unsupported orgtype (%x)\n",
> > +		__FUNCTION__, __LINE__,
> > +		ip->i_ino, vip->vii_orgtype);
> >  	return 0;
> >  }
> > diff --git a/fs/freevxfs/vxfs_dir.h b/fs/freevxfs/vxfs_dir.h
> > index aaf1fb0..d8b52e6 100644
> > --- a/fs/freevxfs/vxfs_dir.h
> > +++ b/fs/freevxfs/vxfs_dir.h
> > @@ -84,9 +84,5 @@ struct vxfs_direct {
> >  #define VXFS_DIRROUND(len)	((VXFS_DIRPAD + (len) - 1) & ~(VXFS_DIRPAD -1))
> >  #define VXFS_DIRLEN(len)	(VXFS_DIRROUND(VXFS_NAMEMIN + (len)))
> >  
> > -/*
> > - * VXFS_DIRBLKOV is the overhead of a specific dirblock.
> > - */
> > -#define VXFS_DIRBLKOV(dbp)	((sizeof(short) * dbp->d_nhash) + 4)
> >  
> >  #endif /* _VXFS_DIR_H_ */
> > diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
> > index 881aa3d..3d20421 100644
> > --- a/fs/freevxfs/vxfs_extern.h
> > +++ b/fs/freevxfs/vxfs_extern.h
> > @@ -55,7 +55,7 @@ extern const struct inode_operations vxfs_immed_symlink_iops;
> >  
> >  /* vxfs_inode.c */
> >  extern const struct address_space_operations vxfs_immed_aops;
> > -extern struct kmem_cache	*vxfs_inode_cachep;
> > +//extern struct kmem_cache	*vxfs_inode_cachep;
> >  extern void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
> >  extern struct inode *		vxfs_get_fake_inode(struct super_block *,
> >  					struct vxfs_inode_info *);
> > @@ -64,6 +64,10 @@ extern struct vxfs_inode_info *	vxfs_blkiget(struct super_block *, u_long, ino_t
> >  extern struct vxfs_inode_info *	vxfs_stiget(struct super_block *, ino_t);
> >  extern struct inode *		vxfs_iget(struct super_block *, ino_t);
> >  extern void			vxfs_evict_inode(struct inode *);
> > +extern void vxfs_destroy_inode(struct inode *ip);
> > +extern void vxfs_inode_info_free(struct vxfs_inode_info *vip);
> > +extern int vxfs_inode_info_cache(int setup);
> > +
> >  
> >  /* vxfs_lookup.c */
> >  extern const struct inode_operations	vxfs_dir_inode_ops;
> > diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
> > index c9a6a94..69fcd7f 100644
> > --- a/fs/freevxfs/vxfs_fshead.c
> > +++ b/fs/freevxfs/vxfs_fshead.c
> > @@ -2,6 +2,35 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + *
> > + * (c) 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests.
> > + *
> > + * These bugs and improvements were as follows:
> > + *   - code not aware of cpu endianess and ondisk data is BE.
> > + *   - misaligned structures read from block device
> > + *   - wrong SB block number. default offset is 8kB
> > + *   - kmem_cache_alloc() objectes released with kfree()
> > + *   - inode.i_private released in evict_inode() callback.
> > + *   - refactored vxfs_readdir() and vxfs_find_entry()
> > + *
> > + * Tests were performed with image of HP 9000/779 disk (/ lvol)
> > + * Example: */
> > +// *  cksum mnt/usr/share/man/man3.Z/* 
> > +// *  cksum mnt/usr/share/doc/10.20RelNotes 
> 
> More white spaces and more //
> 
> > +// *  cksum mnt/usr/local/doom/*
> > +// *  cksum mnt/usr/sprockets/tools/instrument/16700/*
> > +// *  cksum mnt/usr/share/doc/*
> > +// *  cksum mnt/usr/sprockets/lib/*
> > +// *  cksum mnt/usr/sprockets/bin/*
> > +/*
> > + * Needles to say that checksums of files match these evaluated by
> > + * HP-UX B.10.20 cksum. E.g.:
> > + *  3457951056 4196020 /usr/local/doom/doom1.wad
> > + *  2527157998 35344 /usr/local/doom/doomlaunch
> > + *  2974998129 413696 /usr/local/doom/hpdoom
> > + *
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -60,6 +89,34 @@ vxfs_dumpfsh(struct vxfs_fsh *fhp)
> >  }
> >  #endif
> >  
> > +#define VXFS_BE32(field1, field2) fhp->field1 = be32_to_cpu(dbh->field2)
> > +
> > +
> > +static void inline dbh2fhp(struct vxfs_fsh *fhp, void *_dbh)
> > +{
> > +#ifdef __LITTLE_ENDIAN
> > +	struct vxfs_fsh *dbh = (struct vxfs_fsh *)_dbh;
> > +
> > +	VXFS_BE32(fsh_version, fsh_version);
> > +	VXFS_BE32(fsh_fsindex, fsh_fsindex);
> > +	VXFS_BE32(fsh_time, fsh_time);
> > +	VXFS_BE32(fsh_utime, fsh_utime);
> > +	VXFS_BE32(fsh_extop, fsh_extop);
> > +	VXFS_BE32(fsh_ninodes, fsh_ninodes);
> > +	VXFS_BE32(fsh_nau, fsh_nau);
> > +	VXFS_BE32(fsh_old_ilesize, fsh_old_ilesize);
> > +	VXFS_BE32(fsh_dflags, fsh_dflags);
> > +	VXFS_BE32(fsh_quota, fsh_quota);
> > +	VXFS_BE32(fsh_maxinode, fsh_maxinode);
> > +	VXFS_BE32(fsh_iauino, fsh_iauino);
> > +	VXFS_BE32(fsh_ilistino[0], fsh_ilistino[0]);
> > +	VXFS_BE32(fsh_ilistino[1], fsh_ilistino[1]);
> > +	VXFS_BE32(fsh_lctino, fsh_lctino);
> > +#else
> > +	memcpy(fhp, _dbh, sizeof(*fhp));
> > +#endif
> > +}
> > +
> >  /**
> >   * vxfs_getfsh - read fileset header into memory
> >   * @ip:		the (fake) fileset header inode
> > @@ -83,7 +140,8 @@ vxfs_getfsh(struct inode *ip, int which)
> >  
> >  		if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
> >  			goto out;
> > -		memcpy(fhp, bp->b_data, sizeof(*fhp));
> > +
> > +		dbh2fhp(fhp, bp->b_data);
> >  
> >  		put_bh(bp);
> >  		return (fhp);
> > @@ -110,9 +168,12 @@ vxfs_read_fshead(struct super_block *sbp)
> >  	struct vxfs_fsh			*pfp, *sfp;
> >  	struct vxfs_inode_info		*vip, *tip;
> >  
> > +	F_ENTER();
> > +
> >  	vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
> >  	if (!vip) {
> >  		printk(KERN_ERR "vxfs: unable to read fsh inode\n");
> > +		F_EXIT();
> >  		return -EINVAL;
> >  	}
> >  	if (!VXFS_ISFSH(vip)) {
> > @@ -121,10 +182,8 @@ vxfs_read_fshead(struct super_block *sbp)
> >  		goto out_free_fship;
> >  	}
> >  
> > -
> >  #ifdef DIAGNOSTIC
> > -	printk("vxfs: fsh inode dump:\n");
> > -	vxfs_dumpi(vip, infp->vsi_fshino);
> > +	printk("%s:%d\n", __FUNCTION__, __LINE__);
> >  #endif
> >  
> >  	infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
> > @@ -160,7 +219,7 @@ vxfs_read_fshead(struct super_block *sbp)
> >  	infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
> >  	if (!infp->vsi_stilist) {
> >  		printk(KERN_ERR "vxfs: unable to get structural list inode\n");
> > -		kfree(tip);
> > +		vxfs_inode_info_free(tip);
> >  		goto out_free_pfp;
> >  	}
> >  	if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
> > @@ -175,7 +234,7 @@ vxfs_read_fshead(struct super_block *sbp)
> >  	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
> >  	if (!infp->vsi_ilist) {
> >  		printk(KERN_ERR "vxfs: unable to get inode list inode\n");
> > -		kfree(tip);
> > +		vxfs_inode_info_free(tip);
> >  		goto out_iput_stilist;
> >  	}
> >  	if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
> > @@ -184,6 +243,7 @@ vxfs_read_fshead(struct super_block *sbp)
> >  		goto out_iput_ilist;
> >  	}
> >  
> > +	F_EXIT();
> >  	return 0;
> >  
> >   out_iput_ilist:
> > @@ -196,8 +256,10 @@ vxfs_read_fshead(struct super_block *sbp)
> >   	kfree(sfp);
> >   out_iput_fship:
> >  	iput(infp->vsi_fship);
> > +	F_EXIT();
> >  	return -EINVAL;
> >   out_free_fship:
> > - 	kfree(vip);
> > +	vxfs_inode_info_free(vip);
> > +	F_EXIT();
> >  	return -EINVAL;
> >  }
> > diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
> > index 363e3ae..84dec28 100644
> > --- a/fs/freevxfs/vxfs_inode.c
> > +++ b/fs/freevxfs/vxfs_inode.c
> > @@ -2,6 +2,34 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + *
> > + * (c) 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests.
> > + *
> > + * These bugs and improvements were as follows:
> > + *   - code not aware of cpu endianess and ondisk data is BE.
> > + *   - misaligned structures read from block device
> > + *   - wrong SB block number. default offset is 8kB
> > + *   - kmem_cache_alloc() objectes released with kfree()
> > + *   - inode.i_private released in evict_inode() callback.
> > + *   - refactored vxfs_readdir() and vxfs_find_entry()
> > + *
> > + * Tests were performed with image of HP 9000/779 disk (/ lvol)
> > + * Example: */
> > +// *  cksum mnt/usr/share/man/man3.Z/* 
> > +// *  cksum mnt/usr/share/doc/10.20RelNotes 
> 
> More white spaces and more //
> 
> > +// *  cksum mnt/usr/local/doom/*
> > +// *  cksum mnt/usr/sprockets/tools/instrument/16700/*
> > +// *  cksum mnt/usr/share/doc/*
> > +// *  cksum mnt/usr/sprockets/lib/*
> > +// *  cksum mnt/usr/sprockets/bin/*
> > +/*
> > + * Needles to say that checksums of files match these evaluated by
> > + * HP-UX B.10.20 cksum. E.g.:
> > + *  3457951056 4196020 /usr/local/doom/doom1.wad
> > + *  2527157998 35344 /usr/local/doom/doomlaunch
> > + *  2974998129 413696 /usr/local/doom/hpdoom
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -41,7 +69,7 @@
> >  #include "vxfs_extern.h"
> >  
> >  
> > -struct kmem_cache		*vxfs_inode_cachep;
> > +static struct kmem_cache *vxfs_inode_cachep;
> >  
> >  
> >  #ifdef DIAGNOSTIC
> > @@ -51,23 +79,88 @@ struct kmem_cache		*vxfs_inode_cachep;
> >  void
> >  vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
> >  {
> > -	printk(KERN_DEBUG "\n\n");
> > -	if (ino)
> > -		printk(KERN_DEBUG "dumping vxfs inode %ld\n", ino);
> > +#ifdef DIAGNOSTIC_V2
> > +	if (ino && vip)
> > +		printk(KERN_DEBUG "\nvxfs inode %ld dump **** %p\n", ino, vip);
> >  	else
> > -		printk(KERN_DEBUG "dumping unknown vxfs inode\n");
> > +		printk(KERN_DEBUG "\ndumping unknown vxfs inode %p\n", vip);
> >  
> > -	printk(KERN_DEBUG "---------------------------\n");
> > -	printk(KERN_DEBUG "mode is %x\n", vip->vii_mode);
> > -	printk(KERN_DEBUG "nlink:%u, uid:%u, gid:%u\n",
> > -			vip->vii_nlink, vip->vii_uid, vip->vii_gid);
> > -	printk(KERN_DEBUG "size:%Lx, blocks:%u\n",
> > +	if (vip) {
> > +		printk(KERN_DEBUG " * mode: %x, type %d\n", vip->vii_mode, vip->vii_orgtype);
> > +		printk(KERN_DEBUG " * size:%Lx, blocks:%u\n",
> >  			vip->vii_size, vip->vii_blocks);
> > -	printk(KERN_DEBUG "orgtype:%u\n", vip->vii_orgtype);
> > +		printk(KERN_DEBUG " * nlink:%u, uid:%u, gid:%u\n",
> > +			vip->vii_nlink, vip->vii_uid, vip->vii_gid);
> > +	}
> > +#endif
> >  }
> >  #endif
> >  
> >  
> > +#define VXFS_BE32(field1, field2) vip->field1 = be32_to_cpu(dip->field2)
> > +#define VXFS_BE64(field1, field2) vip->field1 = be64_to_cpu(dip->field2)
> > +#define VXFS_BE16(field1, field2) vip->field1 = be16_to_cpu(dip->field2)
> > +
> > +
> > +static void inline dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *dip)
> > +{
> > +#ifdef __LITTLE_ENDIAN
> > +	int j;
> > +
> > +	VXFS_BE32(vdi_mode, vdi_mode);
> > +	VXFS_BE32(vdi_nlink, vdi_nlink);
> > +	VXFS_BE32(vdi_uid, vdi_uid);
> > +	VXFS_BE32(vdi_gid, vdi_gid);
> > +	VXFS_BE64(vdi_size, vdi_size);
> > +	VXFS_BE32(vdi_atime, vdi_atime);
> > +	VXFS_BE32(vdi_autime, vdi_autime);
> > +	VXFS_BE32(vdi_mtime, vdi_mtime);
> > +	VXFS_BE32(vdi_mutime, vdi_mutime);
> > +	VXFS_BE32(vdi_ctime, vdi_ctime);
> > +	VXFS_BE32(vdi_cutime, vdi_cutime);
> > +	vip->vdi_aflags = dip->vdi_aflags;
> > +	vip->vdi_orgtype = dip->vdi_orgtype;
> > +	VXFS_BE16(vdi_eopflags, vdi_eopflags);
> > +	VXFS_BE32(vdi_eopdata, vdi_eopdata);
> > +
> > +	VXFS_BE32(vdi_ftarea.i_regular.reserved, vdi_ftarea.i_regular.reserved);
> > +	VXFS_BE32(vdi_ftarea.i_regular.fixextsize, vdi_ftarea.i_regular.fixextsize);
> > +	VXFS_BE32(vdi_blocks, vdi_blocks);
> > +	VXFS_BE32(vdi_gen, vdi_gen);
> > +	VXFS_BE64(vdi_version, vdi_version);
> > +
> > +	switch (dip->vdi_orgtype) {
> > +	case VXFS_ORG_EXT4:
> > +		VXFS_BE32(vdi_org.ext4.ve4_spare, vdi_org.ext4.ve4_spare);
> > +		VXFS_BE32(vdi_org.ext4.ve4_indsize, vdi_org.ext4.ve4_indsize);
> > +		for (j = 0; j < VXFS_NIADDR; j++) {
> > +			VXFS_BE32(vdi_org.ext4.ve4_indir[j], vdi_org.ext4.ve4_indir[j]);
> > +		}
> > +		for (j = 0; j < VXFS_NDADDR; j++) {
> > +			VXFS_BE32(vdi_org.ext4.ve4_direct[j].extent, vdi_org.ext4.ve4_direct[j].extent);
> > +			VXFS_BE32(vdi_org.ext4.ve4_direct[j].size, vdi_org.ext4.ve4_direct[j].size);
> > +		}
> > +		break;
> > +	case VXFS_ORG_IMMED:
> > +		memcpy(&vip->vdi_org.immed, &dip->vdi_org.immed, sizeof(vip->vdi_org.immed));
> > +		break;
> > +	case VXFS_ORG_TYPED:
> > +		for (j = 0; j < VXFS_NTYPED; j++) {
> > +			VXFS_BE64(vdi_org.typed[j].vt_hdr, vdi_org.typed[j].vt_hdr);
> > +			VXFS_BE32(vdi_org.typed[j].vt_block, vdi_org.typed[j].vt_block);
> > +			VXFS_BE32(vdi_org.typed[j].vt_size, vdi_org.typed[j].vt_size);
> > +		}
> > +		break;
> > +	
> > +	};
> > +
> > +	VXFS_BE32(vdi_iattrino, vdi_iattrino);
> > +#else
> > +	memcpy(vip, dip, sizeof(*vip));
> > +#endif
> > +}
> > +
> > +
> >  /**
> >   * vxfs_blkiget - find inode based on extent #
> >   * @sbp:	superblock of the filesystem we search in
> > @@ -84,6 +177,9 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
> >   *  buffercache.  This function should not be used outside the
> >   *  read_super() method, otherwise the data may be incoherent.
> >   */
> > +
> > +
> > +
> >  struct vxfs_inode_info *
> >  vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
> >  {
> > @@ -101,7 +197,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(vip, dip);
> >  #ifdef DIAGNOSTIC
> >  		vxfs_dumpi(vip, ino);
> >  #endif
> > @@ -143,7 +239,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(vip, dip);
> >  #ifdef DIAGNOSTIC
> >  		vxfs_dumpi(vip, ino);
> >  #endif
> > @@ -190,7 +286,7 @@ vxfs_stiget(struct super_block *sbp, ino_t ino)
> >  static __inline__ umode_t
> >  vxfs_transmod(struct vxfs_inode_info *vip)
> >  {
> > -	umode_t			ret = vip->vii_mode & ~VXFS_TYPE_MASK;
> > +	umode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK;
> >  
> >  	if (VXFS_ISFIFO(vip))
> >  		ret |= S_IFIFO;
> > @@ -340,21 +436,61 @@ vxfs_iget(struct super_block *sbp, ino_t ino)
> >  static void vxfs_i_callback(struct rcu_head *head)
> >  {
> >  	struct inode *inode = container_of(head, struct inode, i_rcu);
> > -	kmem_cache_free(vxfs_inode_cachep, inode->i_private);
> > +	void *priv = inode->i_private;
> > +
> > +	inode->i_private = NULL;
> > +	// just in case the same inode was used elsewhere after releasing i_private.
> > +	// if it was then dereferencing NULL is far better than using invalid
> > +	// pointer to memory claimed by something.
> > +	kmem_cache_free(vxfs_inode_cachep, priv);
> > +}
> > +
> > +void vxfs_destroy_inode(struct inode *ip)
> > +{
> > +	call_rcu(&ip->i_rcu, vxfs_i_callback);
> > +}
> > +
> > +void vxfs_inode_info_free(struct vxfs_inode_info *vip)
> > +{
> > +	kmem_cache_free(vxfs_inode_cachep, vip);
> >  }
> >  
> > +
> >  /**
> >   * vxfs_evict_inode - remove inode from main memory
> >   * @ip:		inode to discard.
> >   *
> >   * Description:
> > - *  vxfs_evict_inode() is called on the final iput and frees the private
> > - *  inode area.
> > + *  vxfs_evict_inode() is called on the final iput 
> >   */
> >  void
> >  vxfs_evict_inode(struct inode *ip)
> >  {
> >  	truncate_inode_pages_final(&ip->i_data);
> > +	invalidate_inode_buffers(ip);
> >  	clear_inode(ip);
> > -	call_rcu(&ip->i_rcu, vxfs_i_callback);
> >  }
> > +
> > +int vxfs_inode_info_cache(int setup)
> > +{
> > +	int rc = 0;
> > +
> > +	if (!setup) {
> > +		vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
> > +			sizeof(struct vxfs_inode_info), 0,
> > +			SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
> > +
> > +		if (!vxfs_inode_cachep)
> > +			rc = -ENOMEM;
> > +	} else {
> > +	/*
> > +	 * Make sure all delayed rcu free inodes are flushed before we
> > +	 * destroy cache.
> > +	 */
> > +		rcu_barrier();
> > +		kmem_cache_destroy(vxfs_inode_cachep);
> > +	}
> > +
> > +	return rc;
> > +}
> > +
> > diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h
> > index 240aeb1..9fc3533 100644
> > --- a/fs/freevxfs/vxfs_inode.h
> > +++ b/fs/freevxfs/vxfs_inode.h
> > @@ -77,13 +77,13 @@ struct vxfs_ext4 {
> >  		vx_daddr_t	extent;			/* Extent number */
> >  		int32_t		size;			/* Size of extent */
> >  	} ve4_direct[VXFS_NDADDR];
> > -};
> > +}  __attribute__((packed));
> >  
> >  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 */
> > -};
> > +}  __attribute__((packed));
> >  
> >  struct vxfs_typed_dev4 {
> >  	u_int64_t	vd4_hdr;	/* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
> > @@ -91,7 +91,7 @@ struct vxfs_typed_dev4 {
> >  	u_int64_t	vd4_size;	/* Size in blocks */
> >  	int32_t		vd4_dev;	/* Device ID */
> >  	u_int32_t	__pad1;
> > -};
> > +}  __attribute__((packed));
> >  
> >  /*
> >   * The inode as contained on the physical device.
> > @@ -134,7 +134,7 @@ struct vxfs_dinode {
> >  		struct vxfs_typed	typed[VXFS_NTYPED];
> >  	} vdi_org;
> >  	u_int32_t	vdi_iattrino;
> > -};
> > +} __attribute__((packed));
> >  
> >  #define vdi_rdev	vdi_ftarea.rdev
> >  #define vdi_dotdot	vdi_ftarea.dotdot
> > diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
> > index 99c7f0a..2e5365b 100644
> > --- a/fs/freevxfs/vxfs_lookup.c
> > +++ b/fs/freevxfs/vxfs_lookup.c
> > @@ -2,6 +2,34 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + * (c) 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests.
> > + *
> > + * These bugs and improvements were as follows:
> > + *   - code not aware of cpu endianess and ondisk data is BE.
> > + *   - misaligned structures read from block device
> > + *   - wrong SB block number. default offset is 8kB
> > + *   - kmem_cache_alloc() objectes released with kfree()
> > + *   - inode.i_private released in evict_inode() callback.
> > + *   - refactored vxfs_readdir() and vxfs_find_entry()
> > + *
> > + * Tests were performed with image of HP 9000/779 disk (/ lvol)
> > + * Example: */
> > +// *  cksum mnt/usr/share/man/man3.Z/* 
> > +// *  cksum mnt/usr/share/doc/10.20RelNotes 
> > +// *  cksum mnt/usr/local/doom/*
> > +// *  cksum mnt/usr/sprockets/tools/instrument/16700/*
> > +// *  cksum mnt/usr/share/doc/*
> > +// *  cksum mnt/usr/sprockets/lib/*
> > +// *  cksum mnt/usr/sprockets/bin/*
> > +/*
> > + * Needles to say that checksums of files match these evaluated by
> > + * HP-UX B.10.20 cksum. E.g.:
> > + *  3457951056 4196020 /usr/local/doom/doom1.wad
> > + *  2527157998 35344 /usr/local/doom/doomlaunch
> > + *  2974998129 413696 /usr/local/doom/hpdoom
> > + *
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -76,6 +104,15 @@ dir_blocks(struct inode *ip)
> >  }
> >  
> >  /*
> > + * VXFS_dirblk_ovh is the overhead of a specific dirblock.
> > + */
> > +static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp)
> > +{
> > +	return (sizeof(short) * be16_to_cpu(dbp->d_nhash)) + 4;
> > +}
> > +
> > +
> > +/*
> >   * NOTE! unlike strncmp, vxfs_match returns 1 for success, 0 for failure.
> >   *
> >   * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
> > @@ -83,19 +120,13 @@ dir_blocks(struct inode *ip)
> >  static inline int
> >  vxfs_match(int len, const char * const name, struct vxfs_direct *de)
> >  {
> > -	if (len != de->d_namelen)
> > +	if (len != be16_to_cpu(de->d_namelen))
> >  		return 0;
> >  	if (!de->d_ino)
> >  		return 0;
> >  	return !memcmp(name, de->d_name, len);
> >  }
> >  
> > -static inline struct vxfs_direct *
> > -vxfs_next_entry(struct vxfs_direct *de)
> > -{
> > -	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
> > -}
> > -
> >  /**
> >   * vxfs_find_entry - find a mathing directory entry for a dentry
> >   * @ip:		directory inode
> > @@ -113,50 +144,73 @@ vxfs_next_entry(struct vxfs_direct *de)
> >  static struct vxfs_direct *
> >  vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
> >  {
> > -	u_long				npages, page, nblocks, pblocks, block;
> > -	u_long				bsize = ip->i_sb->s_blocksize;
> > -	const char			*name = dp->d_name.name;
> > -	int				namelen = dp->d_name.len;
> > -
> > -	npages = dir_pages(ip);
> > -	nblocks = dir_blocks(ip);
> > -	pblocks = VXFS_BLOCK_PER_PAGE(ip->i_sb);
> > -	
> > -	for (page = 0; page < npages; page++) {
> > -		caddr_t			kaddr;
> > -		struct page		*pp;
> > -
> > -		pp = vxfs_get_page(ip->i_mapping, page);
> > -		if (IS_ERR(pp))
> > -			continue;
> > -		kaddr = (caddr_t)page_address(pp);
> > -
> > -		for (block = 0; block <= nblocks && block <= pblocks; block++) {
> > -			caddr_t			baddr, limit;
> > -			struct vxfs_dirblk	*dbp;
> > -			struct vxfs_direct	*de;
> > -
> > -			baddr = kaddr + (block * bsize);
> > -			limit = baddr + bsize - VXFS_DIRLEN(1);
> > -			
> > -			dbp = (struct vxfs_dirblk *)baddr;
> > -			de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp));
> > -
> > -			for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
> > -				if (!de->d_reclen)
> > -					break;
> > -				if (!de->d_ino)
> > -					continue;
> > -				if (vxfs_match(namelen, name, de)) {
> > -					*ppp = pp;
> > -					return (de);
> > -				}
> > +	u_long bsize = ip->i_sb->s_blocksize;
> > +	const char *name = dp->d_name.name;
> > +	int namelen = dp->d_name.len;
> > +	loff_t limit = VXFS_DIRROUND(ip->i_size);
> > +	struct vxfs_direct *de_exit = NULL;
> > +	loff_t pos = 0;
> > +
> > +
> > +	F_ENTER_V2("\"%s\" %d", name, namelen);
> > +
> > +	while (pos < limit) {
> > +		struct page *pp;
> > +		char *kaddr;
> > +		int pg_ofs = pos & ~PAGE_CACHE_MASK;
> > +
> > +		pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_CACHE_SHIFT);
> > +		if (IS_ERR(pp)) {
> > +			return NULL;
> > +		}
> > +		kaddr = (char *)page_address(pp);
> > +
> > +#ifdef DIAGNOSTIC_V2
> > +		printk("%s:%d pos %ld, lim %ld, %p\n", __FUNCTION__, __LINE__, pos, limit, kaddr);
> > +#endif
> > +		while (pg_ofs < PAGE_SIZE && pos < limit) {
> > +			struct vxfs_direct *de;
> > +
> > +			if ((pos & (bsize - 1)) < 4) {
> > +				struct vxfs_dirblk *dbp = 
> 
> White space here too
> 
> > +				    (struct vxfs_dirblk *)(kaddr + (pos & ~PAGE_CACHE_MASK ));
> > +				pos += VXFS_dirblk_ovh(dbp);
> > +				pg_ofs += VXFS_dirblk_ovh(dbp);
> > +			}
> > +			de = (struct vxfs_direct *)(kaddr + pg_ofs);
> > +
> > +#ifdef DIAGNOSTIC_V2
> > +			printk("%s:%d de=%p, pgo %d: \"%10s\", %d %d %d\n", __FUNCTION__, __LINE__,
> > +				de, pg_ofs,
> > +				de->d_name, be16_to_cpu(de->d_namelen),
> > +				be16_to_cpu(de->d_reclen), be32_to_cpu(de->d_ino));
> > +#endif
> > +			if (!de->d_reclen) {
> > +				pos += bsize - 1;
> > +				pos &= ~(bsize - 1);
> > +				break;
> > +			}
> > +
> > +			pg_ofs += be16_to_cpu(de->d_reclen);
> > +			pos += be16_to_cpu(de->d_reclen);
> > +			if (!de->d_ino) {
> > +				continue;
> > +			}
> > +
> > +			if (vxfs_match(namelen, name, de)) {
> > +				*ppp = pp;
> > +				de_exit= de; //return (de);
> > +				break;
> >  			}
> >  		}
> > -		vxfs_put_page(pp);
> > +		if (!de_exit)
> > +			vxfs_put_page(pp);
> > +		else
> > +			break;
> >  	}
> >  
> > -	return NULL;
> > +	F_EXIT_V2("\"%s\": %p", name, de_exit);
> > +	return de_exit;
> >  }
> >  
> >  /**
> > @@ -180,11 +234,10 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
> >  
> >  	de = vxfs_find_entry(dip, dp, &pp);
> >  	if (de) {
> > -		ino = de->d_ino;
> > -		kunmap(pp);
> > -		page_cache_release(pp);
> > +		ino = be32_to_cpu(de->d_ino);
> > +		vxfs_put_page(pp);
> >  	}
> > -	
> > +
> >  	return (ino);
> >  }
> >  
> > @@ -207,17 +260,17 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
> >  {
> >  	struct inode		*ip = NULL;
> >  	ino_t			ino;
> > -			 
> > +
> >  	if (dp->d_name.len > VXFS_NAMELEN)
> >  		return ERR_PTR(-ENAMETOOLONG);
> > -				 
> > +
> >  	ino = vxfs_inode_by_name(dip, dp);
> >  	if (ino) {
> >  		ip = vxfs_iget(dip->i_sb, ino);
> >  		if (IS_ERR(ip))
> >  			return ERR_CAST(ip);
> > +		d_add(dp, ip);
> >  	}
> > -	d_add(dp, ip);
> >  	return NULL;
> >  }
> >  
> > @@ -234,80 +287,95 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
> >   * Returns:
> >   *   Zero.
> >   */
> > +
> >  static int
> >  vxfs_readdir(struct file *fp, struct dir_context *ctx)
> >  {
> >  	struct inode		*ip = file_inode(fp);
> >  	struct super_block	*sbp = ip->i_sb;
> >  	u_long			bsize = sbp->s_blocksize;
> > -	u_long			page, npages, block, pblocks, nblocks, offset;
> > -	loff_t			pos;
> > +	loff_t			pos, limit;
> > +
> > +	F_ENTER_V3("pos %ld, ino %ld, size %ld", (long)ctx->pos, ip->i_ino, (long)ip->i_size);
> >  
> >  	if (ctx->pos == 0) {
> >  		if (!dir_emit_dot(fp, ctx))
> > -			return 0;
> > -		ctx->pos = 1;
> > +			goto out;
> > +		ctx->pos++;
> >  	}
> >  	if (ctx->pos == 1) {
> >  		if (!dir_emit(ctx, "..", 2, VXFS_INO(ip)->vii_dotdot, DT_DIR))
> > -			return 0;
> > -		ctx->pos = 2;
> > +			goto out;
> > +		ctx->pos++;
> >  	}
> > -	pos = ctx->pos - 2;
> > -	
> > -	if (pos > VXFS_DIRROUND(ip->i_size))
> > -		return 0;
> >  
> > -	npages = dir_pages(ip);
> > -	nblocks = dir_blocks(ip);
> > -	pblocks = VXFS_BLOCK_PER_PAGE(sbp);
> > +	limit = VXFS_DIRROUND(ip->i_size);
> > +	if (ctx->pos > limit) {
> > +//		ctx->pos = 0;
> > +		goto out;
> > +	}
> >  
> > -	page = pos >> PAGE_CACHE_SHIFT;
> > -	offset = pos & ~PAGE_CACHE_MASK;
> > -	block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks;
> > +	pos = ctx->pos & ~3L;
> >  
> > -	for (; page < npages; page++, block = 0) {
> > -		char			*kaddr;
> > -		struct page		*pp;
> > +	while (pos < limit) {
> > +		struct page *pp;
> > +		char *kaddr;
> > +		int pg_ofs = pos & ~PAGE_CACHE_MASK;
> > +		int rc = 0;
> >  
> > -		pp = vxfs_get_page(ip->i_mapping, page);
> > -		if (IS_ERR(pp))
> > -			continue;
> > +		pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_CACHE_SHIFT);
> > +		if (IS_ERR(pp)) {
> > +			return -ENOMEM;
> > +		}
> >  		kaddr = (char *)page_address(pp);
> >  
> > -		for (; block <= nblocks && block <= pblocks; block++) {
> > -			char			*baddr, *limit;
> > -			struct vxfs_dirblk	*dbp;
> > -			struct vxfs_direct	*de;
> > -
> > -			baddr = kaddr + (block * bsize);
> > -			limit = baddr + bsize - VXFS_DIRLEN(1);
> > -	
> > -			dbp = (struct vxfs_dirblk *)baddr;
> > -			de = (struct vxfs_direct *)
> > -				(offset ?
> > -				 (kaddr + offset) :
> > -				 (baddr + VXFS_DIRBLKOV(dbp)));
> > -
> > -			for (; (char *)de <= limit; de = vxfs_next_entry(de)) {
> > -				if (!de->d_reclen)
> > -					break;
> > -				if (!de->d_ino)
> > -					continue;
> > -
> > -				offset = (char *)de - kaddr;
> > -				ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
> > -				if (!dir_emit(ctx, de->d_name, de->d_namelen,
> > -					de->d_ino, DT_UNKNOWN)) {
> > -					vxfs_put_page(pp);
> > -					return 0;
> > -				}
> > +#ifdef DIAGNOSTIC_V3
> > +		printk("%s:%d pos %ld, lim %ld, %p\n", __FUNCTION__, __LINE__, pos, limit, kaddr);
> > +#endif
> > +		while (pg_ofs < PAGE_SIZE && pos < limit) {
> > +			struct vxfs_direct *de;
> > +
> > +			if ((pos & (bsize - 1)) < 4) {
> > +				struct vxfs_dirblk *dbp = 
> 
> White space
> 
> > +				    (struct vxfs_dirblk *)(kaddr + (pos & ~PAGE_CACHE_MASK ));
> > +				pos += VXFS_dirblk_ovh(dbp);
> > +				pg_ofs += VXFS_dirblk_ovh(dbp);
> > +			}
> > +			de = (struct vxfs_direct *)(kaddr + pg_ofs);
> > +
> > +#ifdef DIAGNOSTIC_V3
> > +			printk("%s:%d de=%p, pgo %d: \"%10s\", %d %d %d\n", __FUNCTION__, __LINE__,
> > +				de, pg_ofs,
> > +				de->d_name, be16_to_cpu(de->d_namelen),
> > +				be16_to_cpu(de->d_reclen), be32_to_cpu(de->d_ino));
> > +#endif
> > +			if (!de->d_reclen) {
> > +				pos += bsize - 1;
> > +				pos &= ~(bsize - 1);
> > +				break;
> > +			}
> > +
> > +			pg_ofs += be16_to_cpu(de->d_reclen);
> > +			pos += be16_to_cpu(de->d_reclen);
> > +			if (!de->d_ino) {
> > +				continue;
> > +			}
> > +
> > +			if (! (rc = dir_emit(ctx, de->d_name, be16_to_cpu(de->d_namelen),
> > +				be32_to_cpu(de->d_ino), DT_UNKNOWN))) {
> > +				// the dir entry was not submitted, so fix pos.
> > +				pos -= be16_to_cpu(de->d_reclen); 
> White space
> > +				break;
> >  			}
> > -			offset = 0;
> >  		}
> >  		vxfs_put_page(pp);
> > -		offset = 0;
> > +		if (!rc)
> > +			break;
> >  	}
> > -	ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
> > +
> > +	ctx->pos = pos | 2;
> > +
> > +out:
> > +	F_EXIT_V3("pos %ld", (long)ctx->pos);
> >  	return 0;
> >  }
> > diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
> > index 0495008..19a1cab 100644
> > --- a/fs/freevxfs/vxfs_olt.c
> > +++ b/fs/freevxfs/vxfs_olt.c
> > @@ -2,6 +2,10 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + *
> > + * 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -43,14 +47,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 = be32_to_cpu(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 = be32_to_cpu(ilistp->olt_iext[0]); 
> 
> 	White space in these lines
> 
> >  }
> >  
> >  static inline u_long
> > @@ -80,6 +84,7 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
> >  	struct buffer_head	*bp;
> >  	struct vxfs_olt		*op;
> >  	char			*oaddr, *eaddr;
> > +	u32 j;
> >  
> >  
> >  	bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
> > @@ -87,8 +92,8 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
> >  		goto fail;
> >  
> >  	op = (struct vxfs_olt *)bp->b_data;
> > -	if (op->olt_magic != VXFS_OLT_MAGIC) {
> > -		printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
> > +	if ((j = be32_to_cpu(op->olt_magic)) != VXFS_OLT_MAGIC) {
> > +		printk(KERN_NOTICE "vxfs: ivalid olt magic number %08x at +%d\n", j, infp->vsi_oltext);
> >  		goto fail;
> >  	}
> >  
> > @@ -97,19 +102,24 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
> >  	 * I've not seen any such filesystem yet and I'm lazy..  --hch
> >  	 */
> >  	if (infp->vsi_oltsize > 1) {
> > -		printk(KERN_NOTICE "vxfs: oltsize > 1 detected.\n");
> > +		printk(KERN_NOTICE "vxfs: oltsize > 1 detected (%d).\n", infp->vsi_oltsize);
> >  		printk(KERN_NOTICE "vxfs: please notify hch@xxxxxxxxxxxxx\n");
> >  		goto fail;
> >  	}
> >  
> > -	oaddr = bp->b_data + op->olt_size;
> > +	oaddr = bp->b_data + be32_to_cpu(op->olt_size);
> >  	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
> >  
> >  	while (oaddr < eaddr) {
> > -		struct vxfs_oltcommon	*ocp =
> > +		struct vxfs_oltcommon *ocp =
> >  			(struct vxfs_oltcommon *)oaddr;
> > -		
> > -		switch (ocp->olt_type) {
> > +
> > +#ifdef DIAGNOSTIC
> > +		printk(KERN_DEBUG "oltc_type %d, sz %d at +%d\n", 
> 
> 	White space
> > +			be32_to_cpu(ocp->olt_type), be32_to_cpu(ocp->olt_size), (int)(oaddr - bp->b_data));
> > +#endif
> > +
> > +		switch (be32_to_cpu(ocp->olt_type)) {
> >  		case VXFS_OLT_FSHEAD:
> >  			vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
> >  			break;
> > @@ -118,11 +128,16 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
> >  			break;
> >  		}
> >  
> > -		oaddr += ocp->olt_size;
> > +		oaddr += be32_to_cpu(ocp->olt_size);
> >  	}
> >  
> > +#ifdef DIAGNOSTIC
> > +	printk(KERN_DEBUG "olt_size %d, vsi_fshino %d, vsi_iext %ld\n",
> > +	    be32_to_cpu(op->olt_size), (u32)infp->vsi_fshino, infp->vsi_iext);
> > +#endif
> > +
> >  	brelse(bp);
> > -	return 0;
> > +	return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
> >  
> >  fail:
> >  	brelse(bp);
> > diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
> > index 7ca8c75..9fbf271 100644
> > --- a/fs/freevxfs/vxfs_super.c
> > +++ b/fs/freevxfs/vxfs_super.c
> > @@ -2,6 +2,38 @@
> >   * Copyright (c) 2000-2001 Christoph Hellwig.
> >   * All rights reserved.
> >   *
> > + * (c) 2016 Krzysztof Blaszkowski.
> > + *       Many bug fixes, improvements & tests.
> > + *
> > + * These bugs and improvements were as follows:
> > + *   - code not aware of cpu endianess and ondisk data is BE.
> > + *   - misaligned structures read from block device
> > + *   - wrong SB block number. default offset is 8kB
> > + *   - kmem_cache_alloc() objectes released with kfree()
> > + *   - inode.i_private released in evict_inode() callback.
> > + *   - refactored vxfs_readdir() and vxfs_find_entry()
> > + *
> > + * Tests were performed with image of HP 9000/779 disk (/ lvol)
> > + * Example: */
> > +// *  cksum mnt/usr/share/man/man3.Z/* 
> > +// *  cksum mnt/usr/share/doc/10.20RelNotes 
> 
> White space
> 
> > +// *  cksum mnt/usr/local/doom/*
> > +// *  cksum mnt/usr/sprockets/tools/instrument/16700/*
> > +// *  cksum mnt/usr/share/doc/*
> > +// *  cksum mnt/usr/sprockets/lib/*
> > +// *  cksum mnt/usr/sprockets/bin/*
> > +/*
> > + * Needles to say that checksums of files match these evaluated by
> > + * HP-UX B.10.20 cksum. E.g.:
> > + *  3457951056 4196020 /usr/local/doom/doom1.wad
> > + *  2527157998 35344 /usr/local/doom/doomlaunch
> > + *  2974998129 413696 /usr/local/doom/hpdoom
> > + *
> > + * The hpux_mdsetup tool project which is aimed at making possible
> > + * accessing HP-UX logical volumes by device mapper is here:
> > + *       https://sourceforge.net/projects/linux-vxfs/
> > + *
> > + *
> >   * Redistribution and use in source and binary forms, with or without
> >   * modification, are permitted provided that the following conditions
> >   * are met:
> > @@ -41,6 +73,7 @@
> >  #include <linux/stat.h>
> >  #include <linux/vfs.h>
> >  #include <linux/mount.h>
> > +#include <linux/byteorder/generic.h>
> >  
> >  #include "vxfs.h"
> >  #include "vxfs_extern.h"
> > @@ -48,7 +81,7 @@
> >  #include "vxfs_inode.h"
> >  
> >  
> > -MODULE_AUTHOR("Christoph Hellwig");
> > +MODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");
> >  MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
> >  MODULE_LICENSE("Dual BSD/GPL");
> >  
> > @@ -59,6 +92,7 @@ static int		vxfs_statfs(struct dentry *, struct kstatfs *);
> >  static int		vxfs_remount(struct super_block *, int *, char *);
> >  
> >  static const struct super_operations vxfs_super_ops = {
> > +	.destroy_inode = vxfs_destroy_inode,
> >  	.evict_inode =		vxfs_evict_inode,
> >  	.put_super =		vxfs_put_super,
> >  	.statfs =		vxfs_statfs,
> > @@ -153,6 +187,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
> >  	u_long			bsize;
> >  	struct inode *root;
> >  	int ret = -EINVAL;
> > +	int j;
> >  
> >  	sbp->s_flags |= MS_RDONLY;
> >  
> > @@ -168,7 +203,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
> >  		goto out;
> >  	}
> >  
> > -	bp = sb_bread(sbp, 1);
> > +	bp = sb_bread(sbp, 8);
> >  	if (!bp || !buffer_mapped(bp)) {
> >  		if (!silent) {
> >  			printk(KERN_WARNING
> > @@ -178,32 +213,30 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
> >  	}
> >  
> >  	rsbp = (struct vxfs_sb *)bp->b_data;
> > -	if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
> > +	if (be32_to_cpu(rsbp->vs_magic) != VXFS_SUPER_MAGIC) {
> >  		if (!silent)
> > -			printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
> > +			printk(KERN_NOTICE "vxfs: WRONG superblock magic %08x\n", rsbp->vs_magic);
> >  		goto out;
> >  	}
> >  
> > -	if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) {
> > -		printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n",
> > -		       rsbp->vs_version);
> > +	j = be32_to_cpu(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);
> > -#endif
> >  
> > -	sbp->s_magic = rsbp->vs_magic;
> > +	sbp->s_magic = be32_to_cpu(rsbp->vs_magic);
> >  	sbp->s_fs_info = infp;
> >  
> >  	infp->vsi_raw = rsbp;
> >  	infp->vsi_bp = bp;
> > -	infp->vsi_oltext = rsbp->vs_oltext[0];
> > -	infp->vsi_oltsize = rsbp->vs_oltsize;
> > +	infp->vsi_oltext = be32_to_cpu(rsbp->vs_oltext[0]);
> > +	infp->vsi_oltsize = be32_to_cpu(rsbp->vs_oltsize);
> > +
> > +	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", be32_to_cpu(rsbp->vs_version));
> >  
> > -	if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
> > +	if (!sb_set_blocksize(sbp, be32_to_cpu(rsbp->vs_bsize))) {
> >  		printk(KERN_WARNING "vxfs: unable to set final block size\n");
> >  		goto out;
> >  	}
> > @@ -229,6 +262,8 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
> >  		printk(KERN_WARNING "vxfs: unable to get root dentry.\n");
> >  		goto out_free_ilist;
> >  	}
> > +	printk(KERN_DEBUG "vxfs: blocksize: %d, oltext %d, oltsize %d\n", 
> 
> 	White space
> 
> > +	    be32_to_cpu(rsbp->vs_bsize), infp->vsi_oltext, infp->vsi_oltsize);
> >  
> >  	return 0;
> >  	
> > @@ -237,6 +272,7 @@ out_free_ilist:
> >  	vxfs_put_fake_inode(infp->vsi_ilist);
> >  	vxfs_put_fake_inode(infp->vsi_stilist);
> >  out:
> > +	printk(KERN_ERR "vxfs: mount failed %d\n", ret);
> >  	brelse(bp);
> >  	kfree(infp);
> >  	return ret;
> > @@ -264,29 +300,22 @@ MODULE_ALIAS("vxfs");
> >  static int __init
> >  vxfs_init(void)
> >  {
> > -	int rv;
> > +	int rc = vxfs_inode_info_cache(0);
> >  
> > -	vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
> > -			sizeof(struct vxfs_inode_info), 0,
> > -			SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
> > -	if (!vxfs_inode_cachep)
> > -		return -ENOMEM;
> > -	rv = register_filesystem(&vxfs_fs_type);
> > -	if (rv < 0)
> > -		kmem_cache_destroy(vxfs_inode_cachep);
> > -	return rv;
> > +	if (!rc) {
> > +		rc = register_filesystem(&vxfs_fs_type);
> > +		if (rc < 0)
> > +			vxfs_inode_info_cache(1);
> > +	}
> > +	printk(KERN_DEBUG "%s: **** %s %s rc %d\n", __FUNCTION__, __DATE__, __TIME__, rc);
> > +	return rc;
> >  }
> >  
> >  static void __exit
> >  vxfs_cleanup(void)
> >  {
> >  	unregister_filesystem(&vxfs_fs_type);
> > -	/*
> > -	 * Make sure all delayed rcu free inodes are flushed before we
> > -	 * destroy cache.
> > -	 */
> > -	rcu_barrier();
> > -	kmem_cache_destroy(vxfs_inode_cachep);
> > +	vxfs_inode_info_cache(1);
> >  }
> >  
> >  module_init(vxfs_init);
> 
> 

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