Re: freevxfs

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

 



On Wed, May 25, 2016 at 11:27:27PM +0200, Krzysztof Błaszkowski wrote:
> Hi,
> 
> Please find included patchset which addresses all major features we have
> discussed (unless I forgot about something).
> 

Hi Krzysztof,

please send the patches one-by one, inlined in the e-mail message, not attached
to the e-mail, mainly all of them attached to a single message.

You can use git send-email to send the patches.

See: Documentation/SubmittingPatches

Cheers

> I verified correctness of operation with my regression tests and HP-UX's
> vxfs image. No difference spotted. However I can't do this with SCO
> image because I do not have such. I reckon that it is highly possible
> that SCO image will work as usual because the only difference is data
> endianess and offset of super block.
> 
> I included for reference these scripts just in case one is curious.
> (chksum8-sorted.log comes from hp-ux's cksum)
> 
> Regards,
> -- 
> Krzysztof Blaszkowski

> From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 21:50:11 +0200
> Subject: [PATCH 1/7] kconfig note
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/Kconfig |   10 +++++++++-
>  1 files changed, 9 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/freevxfs/Kconfig b/fs/freevxfs/Kconfig
> index 8dc1cd5..a4c9075 100644
> --- a/fs/freevxfs/Kconfig
> +++ b/fs/freevxfs/Kconfig
> @@ -5,12 +5,20 @@ config VXFS_FS
>  	  FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
>  	  file system format.  VERITAS VxFS(TM) is the standard file system
>  	  of SCO UnixWare (and possibly others) and optionally available
> -	  for Sunsoft Solaris, HP-UX and many other operating systems.
> +	  for Sunsoft Solaris, HP-UX and many other operating systems. However
> +	  these particular OS implementations of vxfs may differ in on-disk
> +	  data endianess and/or superblock offset. The vxfs module has been 
> +	  tested with SCO UnixWare and HP-UX B.10.20 (pa-risc 1.1 arch.)
>  	  Currently only readonly access is supported.
>  
>  	  NOTE: the file system type as used by mount(1), mount(2) and
>  	  fstab(5) is 'vxfs' as it describes the file system format, not
>  	  the actual driver.
>  
> +	  There is a userspace utility for HP-UX logical volumes which makes 
> +	  creating HP-UX logical volumes easy from HP-UX disk block device file 
> +	  or regular file with image of the disk. See:
> +	         https://sourceforge.net/projects/linux-vxfs/
> +
>  	  To compile this as a module, choose M here: the module will be
>  	  called freevxfs.  If unsure, say N.
> -- 
> 1.7.3.4
> 

> From c617f6bceedc2f68c62e7432f12b59124bab34f7 Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 22:12:05 +0200
> Subject: [PATCH 2/7] cpu endian vs file system endian
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/vxfs.h        |   25 +++++++++++-
>  fs/freevxfs/vxfs_bmap.c   |   24 ++++++-----
>  fs/freevxfs/vxfs_fshead.c |   25 +++++++++++-
>  fs/freevxfs/vxfs_inode.c  |   61 +++++++++++++++++++++++++++-
>  fs/freevxfs/vxfs_inode.h  |    8 ++--
>  fs/freevxfs/vxfs_lookup.c |   15 ++++++-
>  fs/freevxfs/vxfs_olt.c    |   15 ++++---
>  fs/freevxfs/vxfs_super.c  |   97 ++++++++++++++++++++++++++++++++-------------
>  8 files changed, 215 insertions(+), 55 deletions(-)
> 
> diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
> index c8a9265..5dc8949 100644
> --- a/fs/freevxfs/vxfs.h
> +++ b/fs/freevxfs/vxfs.h
> @@ -152,7 +152,7 @@ struct vxfs_sb {
>  	/*
>  	 * Actually much more...
>  	 */
> -};
> +} __packed;
>  
>  
>  /*
> @@ -168,9 +168,32 @@ struct vxfs_sb_info {
>  	ino_t			vsi_fshino;	/* fileset header inode */
>  	daddr_t			vsi_oltext;	/* OLT extent */
>  	daddr_t			vsi_oltsize;	/* OLT size */
> +	int byte_order;
> +	int silent;
> +};
> +
> +enum {
> +	BO_LE = 1,
> +	BO_BE
>  };
>  
>  
> +static inline u32 fs32_to_cpu(int bo, u32 a)
> +{
> +	return (bo == BO_BE) ? be32_to_cpu(a) : le32_to_cpu(a);
> +}
> +
> +static inline u16 fs16_to_cpu(int bo, u16 a)
> +{
> +	return (bo == BO_BE) ? be16_to_cpu(a) : le16_to_cpu(a);
> +}
> +
> +static inline u64 fs64_to_cpu(int bo, u64 a)
> +{
> +	return (bo == BO_BE) ? be64_to_cpu(a) : le64_to_cpu(a);
> +}
> +
> +
>  /*
>   * File modes.  File types above 0xf000 are vxfs internal only, they should
>   * not be passed back to higher levels of the system.  vxfs file types must
> diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
> index f86fd3c..95afd98 100644
> --- a/fs/freevxfs/vxfs_bmap.c
> +++ b/fs/freevxfs/vxfs_bmap.c
> @@ -92,7 +92,8 @@ 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 = fs32_to_cpu(VXFS_SBI(sb)->byte_order,
> +		    indir[(bn/indsize) % (indsize*bn)]) + (bn % indsize);
>  
>  		brelse(buf);
>  		return bno;
> @@ -130,6 +131,7 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
>  	struct buffer_head		*bp = NULL;
>  	daddr_t				pblock = 0;
>  	int				i;
> +	int bo = VXFS_SBI(ip->i_sb)->byte_order;
>  
>  	for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
>  		struct vxfs_typed	*typ;
> @@ -142,24 +144,24 @@ 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(bo, 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(bo, 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(bo, typ->vt_block),
> +					fs32_to_cpu(bo, 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(bo, typ->vt_size))
>  				break;
> -			pblock = (typ->vt_block + block - off);
> +			pblock = fs32_to_cpu(bo, typ->vt_block) + block - off;
>  			goto out;
>  		case VXFS_TYPED_INDIRECT_DEV4:
>  		case VXFS_TYPED_DATA_DEV4: {
> @@ -168,12 +170,14 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
>  
>  			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);
> +			       (unsigned long long) fs64_to_cpu(bo, typ4->vd4_block),
> +			       (unsigned long long) fs64_to_cpu(bo, typ4->vd4_size),
> +			       fs32_to_cpu(bo, typ4->vd4_dev));
>  			goto fail;
>  		}
>  		default:
> +			printk(KERN_ERR "%s:%d vt_hdr %llu\n", __func__, __LINE__,
> +			    fs64_to_cpu(bo, typ->vt_hdr));
>  			BUG();
>  		}
>  		brelse(bp);
> diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
> index c9a6a94..6cbdde7 100644
> --- a/fs/freevxfs/vxfs_fshead.c
> +++ b/fs/freevxfs/vxfs_fshead.c
> @@ -60,6 +60,29 @@ vxfs_dumpfsh(struct vxfs_fsh *fhp)
>  }
>  #endif
>  
> +#define VXFS_FS32(field1, field2) fhp->field1 = fs32_to_cpu(bo, dbh->field2)
> +static inline void dbh2fhp(struct vxfs_fsh *fhp, void *_dbh, int bo)
> +{
> +	struct vxfs_fsh *dbh = (struct vxfs_fsh *)_dbh;
> +
> +	VXFS_FS32(fsh_version, fsh_version);
> +	VXFS_FS32(fsh_fsindex, fsh_fsindex);
> +	VXFS_FS32(fsh_time, fsh_time);
> +	VXFS_FS32(fsh_utime, fsh_utime);
> +	VXFS_FS32(fsh_extop, fsh_extop);
> +	VXFS_FS32(fsh_ninodes, fsh_ninodes);
> +	VXFS_FS32(fsh_nau, fsh_nau);
> +	VXFS_FS32(fsh_old_ilesize, fsh_old_ilesize);
> +	VXFS_FS32(fsh_dflags, fsh_dflags);
> +	VXFS_FS32(fsh_quota, fsh_quota);
> +	VXFS_FS32(fsh_maxinode, fsh_maxinode);
> +	VXFS_FS32(fsh_iauino, fsh_iauino);
> +	VXFS_FS32(fsh_ilistino[0], fsh_ilistino[0]);
> +	VXFS_FS32(fsh_ilistino[1], fsh_ilistino[1]);
> +	VXFS_FS32(fsh_lctino, fsh_lctino);
> +}
> +
> +
>  /**
>   * vxfs_getfsh - read fileset header into memory
>   * @ip:		the (fake) fileset header inode
> @@ -83,7 +106,7 @@ 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, VXFS_SBI(ip->i_sb)->byte_order);
>  
>  		put_bh(bp);
>  		return (fhp);
> diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
> index 363e3ae..53b8757 100644
> --- a/fs/freevxfs/vxfs_inode.c
> +++ b/fs/freevxfs/vxfs_inode.c
> @@ -67,6 +67,63 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
>  }
>  #endif
>  
> +#define VXFS_FS32(field1, field2) vip->field1 = fs32_to_cpu(bo, dip->field2)
> +#define VXFS_FS64(field1, field2) vip->field1 = fs64_to_cpu(bo, dip->field2)
> +#define VXFS_FS16(field1, field2) vip->field1 = fs16_to_cpu(bo, dip->field2)
> +
> +static inline void dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *dip, int bo)
> +{
> +	int j;
> +
> +	VXFS_FS32(vdi_mode, vdi_mode);
> +	VXFS_FS32(vdi_nlink, vdi_nlink);
> +	VXFS_FS32(vdi_uid, vdi_uid);
> +	VXFS_FS32(vdi_gid, vdi_gid);
> +	VXFS_FS64(vdi_size, vdi_size);
> +	VXFS_FS32(vdi_atime, vdi_atime);
> +	VXFS_FS32(vdi_autime, vdi_autime);
> +	VXFS_FS32(vdi_mtime, vdi_mtime);
> +	VXFS_FS32(vdi_mutime, vdi_mutime);
> +	VXFS_FS32(vdi_ctime, vdi_ctime);
> +	VXFS_FS32(vdi_cutime, vdi_cutime);
> +	vip->vdi_aflags = dip->vdi_aflags;
> +	vip->vdi_orgtype = dip->vdi_orgtype;
> +	VXFS_FS16(vdi_eopflags, vdi_eopflags);
> +	VXFS_FS32(vdi_eopdata, vdi_eopdata);
> +
> +	VXFS_FS32(vdi_ftarea.i_regular.reserved, vdi_ftarea.i_regular.reserved);
> +	VXFS_FS32(vdi_ftarea.i_regular.fixextsize, vdi_ftarea.i_regular.fixextsize);
> +	VXFS_FS32(vdi_blocks, vdi_blocks);
> +	VXFS_FS32(vdi_gen, vdi_gen);
> +	VXFS_FS64(vdi_version, vdi_version);
> +
> +	switch (dip->vdi_orgtype) {
> +	case VXFS_ORG_EXT4:
> +		VXFS_FS32(vdi_org.ext4.ve4_spare, vdi_org.ext4.ve4_spare);
> +		VXFS_FS32(vdi_org.ext4.ve4_indsize, vdi_org.ext4.ve4_indsize);
> +		for (j = 0; j < VXFS_NIADDR; j++) {
> +			VXFS_FS32(vdi_org.ext4.ve4_indir[j], vdi_org.ext4.ve4_indir[j]);
> +		}
> +		for (j = 0; j < VXFS_NDADDR; j++) {
> +			VXFS_FS32(vdi_org.ext4.ve4_direct[j].extent, vdi_org.ext4.ve4_direct[j].extent);
> +			VXFS_FS32(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_FS64(vdi_org.typed[j].vt_hdr, vdi_org.typed[j].vt_hdr);
> +			VXFS_FS32(vdi_org.typed[j].vt_block, vdi_org.typed[j].vt_block);
> +			VXFS_FS32(vdi_org.typed[j].vt_size, vdi_org.typed[j].vt_size);
> +		}
> +		break;
> +	};
> +
> +	VXFS_FS32(vdi_iattrino, vdi_iattrino);
> +}
> +
>  
>  /**
>   * vxfs_blkiget - find inode based on extent #
> @@ -101,7 +158,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, VXFS_SBI(sbp)->byte_order);
>  #ifdef DIAGNOSTIC
>  		vxfs_dumpi(vip, ino);
>  #endif
> @@ -143,7 +200,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, VXFS_SBI(ilistp->i_sb)->byte_order);
>  #ifdef DIAGNOSTIC
>  		vxfs_dumpi(vip, ino);
>  #endif
> diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h
> index 240aeb1..9a2c376 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];
> -};
> +} __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 */
> -};
> +} __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;
> -};
> +} __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;
> -};
> +} __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..cea158a 100644
> --- a/fs/freevxfs/vxfs_lookup.c
> +++ b/fs/freevxfs/vxfs_lookup.c
> @@ -96,6 +96,15 @@ vxfs_next_entry(struct vxfs_direct *de)
>  	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
>  }
>  
> +/*
> + * VXFS_dirblk_ovh is the overhead of a specific dirblock.
> + */
> +static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo)
> +{
> +	return (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
> +}
> +
> +
>  /**
>   * vxfs_find_entry - find a mathing directory entry for a dentry
>   * @ip:		directory inode
> @@ -242,6 +251,8 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
>  	u_long			bsize = sbp->s_blocksize;
>  	u_long			page, npages, block, pblocks, nblocks, offset;
>  	loff_t			pos;
> +	int bo = VXFS_SBI(sbp)->byte_order;
> +
>  
>  	if (ctx->pos == 0) {
>  		if (!dir_emit_dot(fp, ctx))
> @@ -297,8 +308,8 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
>  
>  				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)) {
> +				if (!dir_emit(ctx, de->d_name, fs16_to_cpu(bo, de->d_namelen),
> +					fs32_to_cpu(bo, 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 0495008..6b50188 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->byte_order, 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->byte_order, ilistp->olt_iext[0]);
>  }
>  
>  static inline u_long
> @@ -80,6 +80,7 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
>  	struct buffer_head	*bp;
>  	struct vxfs_olt		*op;
>  	char			*oaddr, *eaddr;
> +	int bo = infp->byte_order;
>  
>  
>  	bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
> @@ -87,7 +88,7 @@ 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) {
> +	if (fs32_to_cpu(bo, op->olt_magic) != VXFS_OLT_MAGIC) {
>  		printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
>  		goto fail;
>  	}
> @@ -102,14 +103,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(bo, 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(bo, ocp->olt_type)) {
>  		case VXFS_OLT_FSHEAD:
>  			vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
>  			break;
> @@ -118,11 +119,11 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
>  			break;
>  		}
>  
> -		oaddr += ocp->olt_size;
> +		oaddr += fs32_to_cpu(bo, 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_super.c b/fs/freevxfs/vxfs_super.c
> index 7ca8c75..6a19802 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->byte_order, raw_sb->vs_dsize);
> +	bufp->f_bfree = fs32_to_cpu(infp->byte_order, 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->byte_order, raw_sb->vs_ifree);
>  	bufp->f_namelen = VXFS_NAMELEN;
>  
>  	return 0;
> @@ -129,6 +130,46 @@ 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 blk, u32 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 (!infp->silent) {
> +				printk(KERN_WARNING "vxfs: unable to read"
> +				    " disk superblock at %d\n", blk);
> +			}
> +			break;
> +		}
> +
> +		rc = -EINVAL;
> +		rsbp = (struct vxfs_sb *)bp->b_data;
> +		if (rsbp->vs_magic != magic) {
> +			if (!infp->silent)
> +				printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
> +			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 +190,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;
>  
> @@ -162,48 +203,47 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
>  		return -ENOMEM;
>  	}
>  
> +	infp->silent = silent;
>  	bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
>  	if (!bsize) {
>  		printk(KERN_WARNING "vxfs: unable to set blocksize\n");
>  		goto out;
>  	}
>  
> -	bp = sb_bread(sbp, 1);
> -	if (!bp || !buffer_mapped(bp)) {
> -		if (!silent) {
> -			printk(KERN_WARNING
> -				"vxfs: unable to read disk superblock\n");
> +	sbp->s_fs_info = infp;
> +	do {
> +		if (!vxfs_try_sb_magic(sbp, 1, cpu_to_le32(VXFS_SUPER_MAGIC))) {
> +			infp->byte_order = BO_LE; /* SCO */
> +			break;
> +		}
> +
> +		if (!vxfs_try_sb_magic(sbp, 8, cpu_to_be32(VXFS_SUPER_MAGIC))) {
> +			infp->byte_order = BO_BE; /* HP-UX pa-risc likely */
> +			break;
>  		}
> -		goto out;
> -	}
>  
> -	rsbp = (struct vxfs_sb *)bp->b_data;
> -	if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
> -		if (!silent)
> -			printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
>  		goto out;
> -	}
> +	} while (0);
>  
> -	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->byte_order, 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: supported VxFS version (%d)\n", j);
>  	printk(KERN_DEBUG "vxfs: blocksize: %d\n", rsbp->vs_bsize);
>  #endif
>  
> -	sbp->s_magic = rsbp->vs_magic;
> -	sbp->s_fs_info = infp;
> +	sbp->s_magic = fs32_to_cpu(infp->byte_order, 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->byte_order, rsbp->vs_oltext[0]);
> +	infp->vsi_oltsize = fs32_to_cpu(infp->byte_order, rsbp->vs_oltsize);
>  
> -	if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
> +	j = fs32_to_cpu(infp->byte_order, rsbp->vs_bsize);
> +	if (!sb_set_blocksize(sbp, j)) {
>  		printk(KERN_WARNING "vxfs: unable to set final block size\n");
>  		goto out;
>  	}
> @@ -237,7 +277,8 @@ out_free_ilist:
>  	vxfs_put_fake_inode(infp->vsi_ilist);
>  	vxfs_put_fake_inode(infp->vsi_stilist);
>  out:
> -	brelse(bp);
> +	if (infp->vsi_bp)
> +		brelse(infp->vsi_bp);
>  	kfree(infp);
>  	return ret;
>  }
> -- 
> 1.7.3.4
> 

> From b95e9b749b85be347c953ce33d2b3c5dde4e56d6 Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 22:13:20 +0200
> Subject: [PATCH 3/7] missing kfree and kfree on kmem_cache obj
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/vxfs_extern.h |    1 +
>  fs/freevxfs/vxfs_fshead.c |    8 +++++---
>  fs/freevxfs/vxfs_inode.c  |    5 +++++
>  3 files changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
> index 881aa3d..0a3ff86 100644
> --- a/fs/freevxfs/vxfs_extern.h
> +++ b/fs/freevxfs/vxfs_extern.h
> @@ -64,6 +64,7 @@ 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_inode_info_free(struct vxfs_inode_info *vip);
>  
>  /* 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 6cbdde7..67ca2f9 100644
> --- a/fs/freevxfs/vxfs_fshead.c
> +++ b/fs/freevxfs/vxfs_fshead.c
> @@ -183,7 +183,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))) {
> @@ -198,7 +198,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))) {
> @@ -206,6 +206,8 @@ vxfs_read_fshead(struct super_block *sbp)
>  				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
>  		goto out_iput_ilist;
>  	}
> +	kfree(pfp);
> +	kfree(sfp);
>  
>  	return 0;
>  
> @@ -221,6 +223,6 @@ vxfs_read_fshead(struct super_block *sbp)
>  	iput(infp->vsi_fship);
>  	return -EINVAL;
>   out_free_fship:
> - 	kfree(vip);
> +	vxfs_inode_info_free(vip);
>  	return -EINVAL;
>  }
> diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
> index 53b8757..16d8d27 100644
> --- a/fs/freevxfs/vxfs_inode.c
> +++ b/fs/freevxfs/vxfs_inode.c
> @@ -415,3 +415,8 @@ vxfs_evict_inode(struct inode *ip)
>  	clear_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);
> +}
> -- 
> 1.7.3.4
> 

> From e4979c6a29eb79d59d8bc2eca9acc0d2b416780f Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 22:15:20 +0200
> Subject: [PATCH 4/7] super_operations.destroy_inode
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/vxfs_extern.h |    1 +
>  fs/freevxfs/vxfs_inode.c  |   16 ++++++++++++----
>  fs/freevxfs/vxfs_super.c  |    1 +
>  3 files changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
> index 0a3ff86..4d8298b 100644
> --- a/fs/freevxfs/vxfs_extern.h
> +++ b/fs/freevxfs/vxfs_extern.h
> @@ -65,6 +65,7 @@ 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_inode_info_free(struct vxfs_inode_info *vip);
> +extern void vxfs_destroy_inode(struct inode *ip);
>  
>  /* vxfs_lookup.c */
>  extern const struct inode_operations	vxfs_dir_inode_ops;
> diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
> index 16d8d27..9b45ad7 100644
> --- a/fs/freevxfs/vxfs_inode.c
> +++ b/fs/freevxfs/vxfs_inode.c
> @@ -397,7 +397,15 @@ 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;
> +	kmem_cache_free(vxfs_inode_cachep, priv);
> +}
> +
> +void vxfs_destroy_inode(struct inode *ip)
> +{
> +	call_rcu(&ip->i_rcu, vxfs_i_callback);
>  }
>  
>  /**
> @@ -405,17 +413,17 @@ static void vxfs_i_callback(struct rcu_head *head)
>   * @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);
>  }
>  
> +
>  void vxfs_inode_info_free(struct vxfs_inode_info *vip)
>  {
>  	kmem_cache_free(vxfs_inode_cachep, vip);
> diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
> index 6a19802..11a535a 100644
> --- a/fs/freevxfs/vxfs_super.c
> +++ b/fs/freevxfs/vxfs_super.c
> @@ -59,6 +59,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,
> -- 
> 1.7.3.4
> 

> From 4a6ae0e351b6046367bbd2939547f292ed2b6e47 Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 22:28:37 +0200
> Subject: [PATCH 5/7] refactoring of vxfs_readir() and find_entry()
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/vxfs_lookup.c |  267 +++++++++++++++++++++------------------------
>  1 files changed, 124 insertions(+), 143 deletions(-)
> 
> diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
> index cea158a..8eacb27 100644
> --- a/fs/freevxfs/vxfs_lookup.c
> +++ b/fs/freevxfs/vxfs_lookup.c
> @@ -61,48 +61,6 @@ const struct file_operations vxfs_dir_operations = {
>  	.iterate =		vxfs_readdir,
>  };
>  
> - 
> -static inline u_long
> -dir_pages(struct inode *inode)
> -{
> -	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
> -}
> - 
> -static inline u_long
> -dir_blocks(struct inode *ip)
> -{
> -	u_long			bsize = ip->i_sb->s_blocksize;
> -	return (ip->i_size + bsize - 1) & ~(bsize - 1);
> -}
> -
> -/*
> - * NOTE! unlike strncmp, vxfs_match returns 1 for success, 0 for failure.
> - *
> - * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
> - */
> -static inline int
> -vxfs_match(int len, const char * const name, struct vxfs_direct *de)
> -{
> -	if (len != de->d_namelen)
> -		return 0;
> -	if (!de->d_ino)
> -		return 0;
> -	return !memcmp(name, de->d_name, len);
> -}
> -
> -static inline struct vxfs_direct *
> -vxfs_next_entry(struct vxfs_direct *de)
> -{
> -	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
> -}
> -
> -/*
> - * VXFS_dirblk_ovh is the overhead of a specific dirblock.
> - */
> -static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo)
> -{
> -	return (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
> -}
>  
>  
>  /**
> @@ -122,50 +80,65 @@ static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo)
>  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;
> +	int bo = VXFS_SBI(ip->i_sb)->byte_order;
> +
> +	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);
> +
> +		while (pg_ofs < PAGE_SIZE && pos < limit) {
> +			struct vxfs_direct *de;
> +
> +			if ((pos & (bsize - 1)) < 4) {
> +				struct vxfs_dirblk *dbp =
> +				    (struct vxfs_dirblk *)(kaddr + (pos & ~PAGE_CACHE_MASK));
> +				int overhead = (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
> +
> +				pos += overhead;
> +				pg_ofs += overhead;
> +			}
> +			de = (struct vxfs_direct *)(kaddr + pg_ofs);
> +
> +			if (!de->d_reclen) {
> +				pos += bsize - 1;
> +				pos &= ~(bsize - 1);
> +				break;
> +			}
> +
> +			pg_ofs += fs16_to_cpu(bo, de->d_reclen);
> +			pos += fs16_to_cpu(bo, de->d_reclen);
> +			if (!de->d_ino) {
> +				continue;
> +			}
> +
> +			if (namelen != fs16_to_cpu(bo, de->d_namelen))
> +				continue;
> +			if (!memcmp(name, de->d_name, namelen)) {
> +				*ppp = pp;
> +				de_exit = de;
> +				break;
>  			}
>  		}
> -		vxfs_put_page(pp);
> +		if (!de_exit)
> +			vxfs_put_page(pp);
> +		else
> +			break;
>  	}
>  
> -	return NULL;
> +	return de_exit;
>  }
>  
>  /**
> @@ -185,15 +158,17 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
>  {
>  	struct vxfs_direct		*de;
>  	struct page			*pp;
> -	ino_t				ino = 0;
> +	ino_t ino = 0;
>  
>  	de = vxfs_find_entry(dip, dp, &pp);
>  	if (de) {
> -		ino = de->d_ino;
> +		int bo = VXFS_SBI(dip->i_sb)->byte_order;
> +
> +		ino = fs32_to_cpu(bo, de->d_ino);
>  		kunmap(pp);
>  		page_cache_release(pp);
>  	}
> -	
> +
>  	return (ino);
>  }
>  
> @@ -225,8 +200,8 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
>  		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;
>  }
>  
> @@ -249,76 +224,82 @@ 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;
>  	int bo = VXFS_SBI(sbp)->byte_order;
>  
> -
>  	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++;
> +	}
> +
> +	limit = VXFS_DIRROUND(ip->i_size);
> +	if (ctx->pos > limit) {
> +#if 0
> +		ctx->pos = 0;
> +#endif
> +		goto out;
>  	}
> -	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);
> -
> -	page = pos >> PAGE_CACHE_SHIFT;
> -	offset = pos & ~PAGE_CACHE_MASK;
> -	block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks;
> -
> -	for (; page < npages; page++, block = 0) {
> -		char			*kaddr;
> -		struct page		*pp;
> -
> -		pp = vxfs_get_page(ip->i_mapping, page);
> -		if (IS_ERR(pp))
> -			continue;
> +
> +	pos = ctx->pos & ~3L;
> +
> +	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, 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, fs16_to_cpu(bo, de->d_namelen),
> -					fs32_to_cpu(bo, de->d_ino), DT_UNKNOWN)) {
> -					vxfs_put_page(pp);
> -					return 0;
> -				}
> +		while (pg_ofs < PAGE_SIZE && pos < limit) {
> +			struct vxfs_direct *de;
> +
> +			if ((pos & (bsize - 1)) < 4) {
> +				struct vxfs_dirblk *dbp =
> +				    (struct vxfs_dirblk *)(kaddr + (pos & ~PAGE_CACHE_MASK));
> +				int overhead = (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
> +
> +				pos += overhead;
> +				pg_ofs += overhead;
> +			}
> +			de = (struct vxfs_direct *)(kaddr + pg_ofs);
> +
> +			if (!de->d_reclen) {
> +				pos += bsize - 1;
> +				pos &= ~(bsize - 1);
> +				break;
> +			}
> +
> +			pg_ofs += fs16_to_cpu(bo, de->d_reclen);
> +			pos += fs16_to_cpu(bo, de->d_reclen);
> +			if (!de->d_ino) {
> +				continue;
> +			}
> +
> +			rc = dir_emit(ctx, de->d_name, fs16_to_cpu(bo, de->d_namelen),
> +				fs32_to_cpu(bo, de->d_ino), DT_UNKNOWN);
> +			if (!rc) {
> +				/* the dir entry was not submitted, so fix pos. */
> +				pos -= fs16_to_cpu(bo, de->d_reclen);
> +				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:
>  	return 0;
>  }
> -- 
> 1.7.3.4
> 

> From e7f68291aada1535016c767a4f5a5fcfb19a1de6 Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 22:41:22 +0200
> Subject: [PATCH 6/7] static cachep
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/vxfs_extern.h |    4 +++-
>  fs/freevxfs/vxfs_inode.c  |   24 +++++++++++++++++++++++-
>  fs/freevxfs/vxfs_super.c  |   26 ++++++++++----------------
>  3 files changed, 36 insertions(+), 18 deletions(-)
> 
> diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
> index 4d8298b..cc43fd0 100644
> --- a/fs/freevxfs/vxfs_extern.h
> +++ b/fs/freevxfs/vxfs_extern.h
> @@ -55,7 +55,6 @@ 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 void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
>  extern struct inode *		vxfs_get_fake_inode(struct super_block *,
>  					struct vxfs_inode_info *);
> @@ -66,6 +65,9 @@ extern struct inode *		vxfs_iget(struct super_block *, ino_t);
>  extern void			vxfs_evict_inode(struct inode *);
>  extern void vxfs_inode_info_free(struct vxfs_inode_info *vip);
>  extern void vxfs_destroy_inode(struct inode *ip);
> +extern int vxfs_ii_cache_init(void);
> +extern void vxfs_ii_cache_destroy(void);
> +
>  
>  /* vxfs_lookup.c */
>  extern const struct inode_operations	vxfs_dir_inode_ops;
> diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
> index 9b45ad7..73ac417 100644
> --- a/fs/freevxfs/vxfs_inode.c
> +++ b/fs/freevxfs/vxfs_inode.c
> @@ -41,7 +41,7 @@
>  #include "vxfs_extern.h"
>  
>  
> -struct kmem_cache		*vxfs_inode_cachep;
> +static struct kmem_cache *vxfs_inode_cachep;
>  
>  
>  #ifdef DIAGNOSTIC
> @@ -428,3 +428,25 @@ void vxfs_inode_info_free(struct vxfs_inode_info *vip)
>  {
>  	kmem_cache_free(vxfs_inode_cachep, vip);
>  }
> +
> +
> +int vxfs_ii_cache_init(void)
> +{
> +	vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
> +		sizeof(struct vxfs_inode_info), 0,
> +		SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
> +
> +	return vxfs_inode_cachep ? 0 : -ENOMEM;
> +}
> +
> +
> +void vxfs_ii_cache_destroy(void)
> +{
> +	/*
> +	 * Make sure all delayed rcu free inodes are flushed before we
> +	 * destroy cache.
> +	 */
> +	rcu_barrier();
> +	kmem_cache_destroy(vxfs_inode_cachep);
> +}
> +
> diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
> index 11a535a..7579500 100644
> --- a/fs/freevxfs/vxfs_super.c
> +++ b/fs/freevxfs/vxfs_super.c
> @@ -306,29 +306,23 @@ MODULE_ALIAS("vxfs");
>  static int __init
>  vxfs_init(void)
>  {
> -	int rv;
> +	int rc = vxfs_ii_cache_init();
>  
> -	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_ii_cache_destroy();
> +	}
> +	printk(KERN_DEBUG "%s: **** %s %s rc %d\n", __func__, __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_ii_cache_destroy();
>  }
>  
>  module_init(vxfs_init);
> -- 
> 1.7.3.4
> 

> From 2c0008e9f2f4e62bb3e10eecad54e2a0140e0c4c Mon Sep 17 00:00:00 2001
> From: KB <kb@xxxxxxxxxxxxxxx>
> Date: Wed, 25 May 2016 22:58:08 +0200
> Subject: [PATCH 7/7] the credits
> 
> 
> Signed-off-by: KB <kb@xxxxxxxxxxxxxxx>
> ---
>  fs/freevxfs/vxfs.h        |    3 +++
>  fs/freevxfs/vxfs_fshead.c |    4 ++++
>  fs/freevxfs/vxfs_inode.c  |    4 ++++
>  fs/freevxfs/vxfs_lookup.c |    4 ++++
>  fs/freevxfs/vxfs_super.c  |    6 +++++-
>  5 files changed, 20 insertions(+), 1 deletions(-)
> 
> diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
> index 5dc8949..35f56b7 100644
> --- a/fs/freevxfs/vxfs.h
> +++ b/fs/freevxfs/vxfs.h
> @@ -2,6 +2,9 @@
>   * Copyright (c) 2000-2001 Christoph Hellwig.
>   * All rights reserved.
>   *
> + * (c) 2016 Krzysztof Blaszkowski
> + *       Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
> + *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
>   * are met:
> diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
> index 67ca2f9..44b87d0 100644
> --- a/fs/freevxfs/vxfs_fshead.c
> +++ b/fs/freevxfs/vxfs_fshead.c
> @@ -2,6 +2,10 @@
>   * Copyright (c) 2000-2001 Christoph Hellwig.
>   * All rights reserved.
>   *
> + *
> + * (c) 2016 Krzysztof Blaszkowski
> + *       Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
> + *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
>   * are met:
> diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
> index 73ac417..4c8a625 100644
> --- a/fs/freevxfs/vxfs_inode.c
> +++ b/fs/freevxfs/vxfs_inode.c
> @@ -2,6 +2,10 @@
>   * Copyright (c) 2000-2001 Christoph Hellwig.
>   * All rights reserved.
>   *
> + *
> + * (c) 2016 Krzysztof Blaszkowski
> + *       Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
> + *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
>   * are met:
> diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
> index 8eacb27..173aeea 100644
> --- a/fs/freevxfs/vxfs_lookup.c
> +++ b/fs/freevxfs/vxfs_lookup.c
> @@ -2,6 +2,10 @@
>   * Copyright (c) 2000-2001 Christoph Hellwig.
>   * All rights reserved.
>   *
> + *
> + * (c) 2016 Krzysztof Blaszkowski
> + *       Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
> + *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
>   * are met:
> diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
> index 7579500..bd121aa 100644
> --- a/fs/freevxfs/vxfs_super.c
> +++ b/fs/freevxfs/vxfs_super.c
> @@ -2,6 +2,10 @@
>   * Copyright (c) 2000-2001 Christoph Hellwig.
>   * All rights reserved.
>   *
> + *
> + * (c) 2016 Krzysztof Blaszkowski
> + *       Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
> + *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
>   * are met:
> @@ -48,7 +52,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");
>  
> -- 
> 1.7.3.4
> 


> 3531594148 32829 /usr/sprockets/bin/bw_map
> 3973234498 518896 /usr/sprockets/bin/cifslist
> 3973234498 518896 /usr/sprockets/bin/cifslogout
> 4171014129 518904 /usr/sprockets/bin/cifsmount
> 4171014129 518904 /usr/sprockets/bin/cifsumount
> 256627809 1171456 /usr/sprockets/bin/convert
> 4193697053 242843 /usr/sprockets/bin/createLicensingFiles
> 2780783712 51 /usr/sprockets/bin/createSprocFile
> 3285775584 825 /usr/sprockets/bin/dcexec
> 4073641898 94 /usr/sprockets/bin/defaultResources
> 4039074287 6610 /usr/sprockets/bin/disableNIS
> 313350104 20480 /usr/sprockets/bin/dos2ux
> 1872597524 65536 /usr/sprockets/bin/doschmod
> 1872597524 65536 /usr/sprockets/bin/doscp
> 1872597524 65536 /usr/sprockets/bin/dosdf
> 1872597524 65536 /usr/sprockets/bin/doslib
> 1872597524 65536 /usr/sprockets/bin/dosll
> 1872597524 65536 /usr/sprockets/bin/dosls
> 1872597524 65536 /usr/sprockets/bin/dosmkdir
> 1872597524 65536 /usr/sprockets/bin/dosrm
> 1872597524 65536 /usr/sprockets/bin/dosrmdir
> 1968087462 7112 /usr/sprockets/bin/enableNIS
> 3282246790 360 /usr/sprockets/bin/endexec
> 2151751185 553 /usr/sprockets/bin/endsession
> 3927613487 1115 /usr/sprockets/bin/env_var_sub
> 3738550324 157 /usr/sprockets/bin/format_dos
> 3888232633 172649 /usr/sprockets/bin/fppv
> 2279585942 466 /usr/sprockets/bin/getHostname
> 2946778792 5648 /usr/sprockets/bin/getSharedConnections
> 3306388627 20480 /usr/sprockets/bin/ibmsync
> 3041502972 28781 /usr/sprockets/bin/ipconfig700
> 3113659230 391815 /usr/sprockets/bin/kpp
> 908094753 24630 /usr/sprockets/bin/kxst
> 1329462070 36864 /usr/sprockets/bin/lanload
> 1015322628 36947 /usr/sprockets/bin/listener
> 486757159 339968 /usr/sprockets/bin/lmgrd
> 2620320940 339968 /usr/sprockets/bin/lmutil
> 951644065 243039 /usr/sprockets/bin/mattrib
> 951644065 243039 /usr/sprockets/bin/mbadblocks
> 951644065 243039 /usr/sprockets/bin/mcd
> 3650177936 951 /usr/sprockets/bin/mcheck
> 514586869 56 /usr/sprockets/bin/mcomp
> 951644065 243039 /usr/sprockets/bin/mcopy
> 951644065 243039 /usr/sprockets/bin/mdel
> 951644065 243039 /usr/sprockets/bin/mdeltree
> 951644065 243039 /usr/sprockets/bin/mdir
> 951644065 243039 /usr/sprockets/bin/mformat
> 951644065 243039 /usr/sprockets/bin/minfo
> 951644065 243039 /usr/sprockets/bin/mlabel
> 951644065 243039 /usr/sprockets/bin/mmd
> 951644065 243039 /usr/sprockets/bin/mmount
> 951644065 243039 /usr/sprockets/bin/mmove
> 951644065 243039 /usr/sprockets/bin/mpartition
> 662030829 1478557 /usr/sprockets/bin/mpv
> 951644065 243039 /usr/sprockets/bin/mrd
> 951644065 243039 /usr/sprockets/bin/mread
> 951644065 243039 /usr/sprockets/bin/mren
> 3443865238 32829 /usr/sprockets/bin/msgintcpt
> 951644065 243039 /usr/sprockets/bin/mtools
> 951644065 243039 /usr/sprockets/bin/mtoolstest
> 951644065 243039 /usr/sprockets/bin/mtype
> 951644065 243039 /usr/sprockets/bin/mwrite
> 1915353244 82 /usr/sprockets/bin/mxtar
> 951644065 243039 /usr/sprockets/bin/mzip
> 2033389047 379158 /usr/sprockets/bin/nmbd
> 1043940798 32843 /usr/sprockets/bin/nsbuild
> 421327339 32843 /usr/sprockets/bin/nsdump
> 2156955828 32843 /usr/sprockets/bin/nsquery
> 1030470949 28737 /usr/sprockets/bin/pciinfo
> 889541250 61560 /usr/sprockets/bin/pcipeek
> 1431205578 28737 /usr/sprockets/bin/pciprog
> 3351126604 126976 /usr/sprockets/bin/pkunzip
> 3351126604 126976 /usr/sprockets/bin/pkzip
> 2166142790 53390 /usr/sprockets/bin/probeload
> 694305221 41144 /usr/sprockets/bin/progflash
> 1141035887 445257 /usr/sprockets/bin/pv
> 974426301 3882 /usr/sprockets/bin/runnetscape
> 1879287959 1801 /usr/sprockets/bin/running
> 2273866242 74107 /usr/sprockets/bin/runroot
> 2616587298 79 /usr/sprockets/bin/runTouch
> 4222109660 875 /usr/sprockets/bin/samba
> 1912440105 24633 /usr/sprockets/bin/sbscrsvr
> 2558012300 3904 /usr/sprockets/bin/screensaverControl
> 4256537430 1780 /usr/sprockets/bin/sd-set_parms
> 1151924416 688 /usr/sprockets/bin/sendSignal
> 2744646624 32829 /usr/sprockets/bin/sessionDisallow
> 1227674200 1346161 /usr/sprockets/bin/sessionMgr
> 3332668870 98791 /usr/sprockets/bin/sessionWrapper
> 1477797090 82487 /usr/sprockets/bin/setlight
> 3759253613 1122 /usr/sprockets/bin/sharity
> 3313588847 3448000 /usr/sprockets/bin/sharityd
> 1569390236 24630 /usr/sprockets/bin/shmLock
> 3791448153 317300 /usr/sprockets/bin/smbclient
> 1018298877 506532 /usr/sprockets/bin/smbd
> 4009501079 45140 /usr/sprockets/bin/smtpclient
> 991996913 144424 /usr/sprockets/bin/starhw
> 3124681867 4311 /usr/sprockets/bin/startVNC
> 1468091312 919 /usr/sprockets/bin/startVNCviewer
> 304853428 1994350 /usr/sprockets/bin/sw_admin
> 304853428 1994350 /usr/sprockets/bin/sw_autoinstall
> 1455142555 123406 /usr/sprockets/bin/sw_copyfdset
> 2157175922 111102 /usr/sprockets/bin/sw_depot2bin
> 304853428 1994350 /usr/sprockets/bin/sw_install
> 304853428 1994350 /usr/sprockets/bin/sw_list
> 1842505403 7100 /usr/sprockets/bin/sw_makefdset
> 304853428 1994350 /usr/sprockets/bin/sw_remove
> 1743298644 2342 /usr/sprockets/bin/sw_rmprevious
> 1582083858 20548 /usr/sprockets/bin/sw_vendorfdset
> 178332129 1794 /usr/sprockets/bin/sysInfo
> 3657811479 1574 /usr/sprockets/bin/tgz
> 4018370132 36951 /usr/sprockets/bin/tp_license
> 1649141155 11843 /usr/sprockets/bin/updsharitycfg
> 2980018004 20480 /usr/sprockets/bin/ux2dos
> 3745508150 1318 /usr/sprockets/bin/uz
> 1348652714 32864 /usr/sprockets/bin/vncpasswd
> 4059637159 12757 /usr/sprockets/bin/vncserver
> 4128771573 366263 /usr/sprockets/bin/vncviewer
> 285011189 1526819 /usr/sprockets/bin/vp
> 589630079 387 /usr/sprockets/bin/vpexit
> 528762950 1132 /usr/sprockets/bin/xcopy
> 1793380080 521816 /usr/sprockets/bin/xscreensaver
> 24739470 145832 /usr/sprockets/bin/xscreensaver-command
> 4079099643 2167483 /usr/sprockets/bin/Xvnc
> 49651643 41091 /usr/sprockets/bin/yakdebug
> 2578809639 127914 /usr/sprockets/bin/yakhw
> 306877946 189649 /usr/sprockets/bin/yakserver



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