Skip to contentSkip to conversation

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

PATCH Krzysztof Błaszkowski 3 participants 21 messages May 26, 2016 – Jun 10, 2016 VFS

lore
Share & tools
lore
#0 lore raw

Hi,

So then let it roll.

Thanks

Quoted 1 line

From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 21:50:11 +0200
Subject: [PATCH 1/7] kconfig note

---
 fs/freevxfs/Kconfig |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)
fs/freevxfs/Kconfig +9 -1
index 8dc1cd5..a4c9075 100644
@@ -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.
Signature · 1 line
1.7.3.4
Quoted 1 line

From c617f6bceedc2f68c62e7432f12b59124bab34f7 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:12:05 +0200
Subject: [PATCH 2/7] cpu endian vs file system endian

---
 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(-)
fs/freevxfs/vxfs.h +24 -1
index c8a9265..5dc8949 100644
@@ -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
fs/freevxfs/vxfs_bmap.c +14 -10
index f86fd3c..95afd98 100644
@@ -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);
fs/freevxfs/vxfs_fshead.c +24 -1
index c9a6a94..6cbdde7 100644
@@ -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);
fs/freevxfs/vxfs_inode.c +59 -2

79 lines not on this page · raw message

fs/freevxfs/vxfs_inode.h +4 -4
index 240aeb1..9a2c376 100644
@@ -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
fs/freevxfs/vxfs_lookup.c +13 -2
index 99c7f0a..cea158a 100644
@@ -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;
 				}
fs/freevxfs/vxfs_olt.c +8 -7
index 0495008..6b50188 100644
@@ -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);
fs/freevxfs/vxfs_super.c +69 -28

154 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 1 line

From b95e9b749b85be347c953ce33d2b3c5dde4e56d6 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:13:20 +0200
Subject: [PATCH 3/7] missing kfree and kfree on kmem_cache obj

---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 881aa3d..0a3ff86 100644
@@ -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;
fs/freevxfs/vxfs_fshead.c +5 -3
index 6cbdde7..67ca2f9 100644
@@ -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;
 }
fs/freevxfs/vxfs_inode.c +5 -0
index 53b8757..16d8d27 100644
@@ -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);
+}
Signature · 1 line
1.7.3.4
Quoted 1 line

From e4979c6a29eb79d59d8bc2eca9acc0d2b416780f Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:15:20 +0200
Subject: [PATCH 4/7] super_operations.destroy_inode

---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 0a3ff86..4d8298b 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +12 -4
index 16d8d27..9b45ad7 100644
@@ -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);
fs/freevxfs/vxfs_super.c +1 -0
index 6a19802..11a535a 100644
@@ -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,
Signature · 1 line
1.7.3.4
Quoted 1 line

From 4a6ae0e351b6046367bbd2939547f292ed2b6e47 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:28:37 +0200
Subject: [PATCH 5/7] refactoring of vxfs_readir() and find_entry()

---
 fs/freevxfs/vxfs_lookup.c |  267 +++++++++++++++++++++------------------------
 1 files changed, 124 insertions(+), 143 deletions(-)
fs/freevxfs/vxfs_lookup.c +124 -143

321 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 1 line

From e7f68291aada1535016c767a4f5a5fcfb19a1de6 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:41:22 +0200
Subject: [PATCH 6/7] static cachep

---
 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(-)
fs/freevxfs/vxfs_extern.h +3 -1
index 4d8298b..cc43fd0 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +23 -1
index 9b45ad7..73ac417 100644
@@ -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);
+}
+
fs/freevxfs/vxfs_super.c +10 -16
index 11a535a..7579500 100644
@@ -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);
Signature · 1 line
1.7.3.4
Quoted 1 line

From 2c0008e9f2f4e62bb3e10eecad54e2a0140e0c4c Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:58:08 +0200
Subject: [PATCH 7/7] the credits

---
 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(-)
fs/freevxfs/vxfs.h +3 -0
index 5dc8949..35f56b7 100644
@@ -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:
fs/freevxfs/vxfs_fshead.c +4 -0
index 67ca2f9..44b87d0 100644
@@ -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:
fs/freevxfs/vxfs_inode.c +4 -0
index 73ac417..4c8a625 100644
@@ -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:
fs/freevxfs/vxfs_lookup.c +4 -0
index 8eacb27..173aeea 100644
@@ -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:
fs/freevxfs/vxfs_super.c +5 -1
index 7579500..bd121aa 100644
@@ -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");
 
Signature · 6 lines
1.7.3.4



-- 
Krzysztof Blaszkowski
#1 lore raw

Re: freevxfs: hp-ux support. (working) patchset 1-7/7

And it stopped rolling. Get stuck on tab to space translation. My goodness, sending patches is more complex than creating them. nightmare. .. kidding
anyway evolution's: "insert->text file" should do the job. (verified)

Quoted 1 line

From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 21:50:11 +0200
Subject: [PATCH 1/7] kconfig note

---
 fs/freevxfs/Kconfig |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)
fs/freevxfs/Kconfig +9 -1
index 8dc1cd5..a4c9075 100644
@@ -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.
Signature · 1 line
1.7.3.4
Quoted 1 line

From c617f6bceedc2f68c62e7432f12b59124bab34f7 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:12:05 +0200
Subject: [PATCH 2/7] cpu endian vs file system endian

---
 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(-)
fs/freevxfs/vxfs.h +24 -1
index c8a9265..5dc8949 100644
@@ -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
fs/freevxfs/vxfs_bmap.c +14 -10
index f86fd3c..95afd98 100644
@@ -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);
fs/freevxfs/vxfs_fshead.c +24 -1
index c9a6a94..6cbdde7 100644
@@ -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);
fs/freevxfs/vxfs_inode.c +59 -2

79 lines not on this page · raw message

fs/freevxfs/vxfs_inode.h +4 -4
index 240aeb1..9a2c376 100644
@@ -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
fs/freevxfs/vxfs_lookup.c +13 -2
index 99c7f0a..cea158a 100644
@@ -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;
 				}
fs/freevxfs/vxfs_olt.c +8 -7
index 0495008..6b50188 100644
@@ -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);
fs/freevxfs/vxfs_super.c +69 -28

154 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 1 line

From b95e9b749b85be347c953ce33d2b3c5dde4e56d6 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:13:20 +0200
Subject: [PATCH 3/7] missing kfree and kfree on kmem_cache obj

---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 881aa3d..0a3ff86 100644
@@ -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;
fs/freevxfs/vxfs_fshead.c +5 -3
index 6cbdde7..67ca2f9 100644
@@ -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;
 }
fs/freevxfs/vxfs_inode.c +5 -0
index 53b8757..16d8d27 100644
@@ -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);
+}
Signature · 1 line
1.7.3.4
Quoted 1 line

From e4979c6a29eb79d59d8bc2eca9acc0d2b416780f Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:15:20 +0200
Subject: [PATCH 4/7] super_operations.destroy_inode

---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 0a3ff86..4d8298b 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +12 -4
index 16d8d27..9b45ad7 100644
@@ -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);
fs/freevxfs/vxfs_super.c +1 -0
index 6a19802..11a535a 100644
@@ -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,
Signature · 1 line
1.7.3.4
Quoted 1 line

From 4a6ae0e351b6046367bbd2939547f292ed2b6e47 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:28:37 +0200
Subject: [PATCH 5/7] refactoring of vxfs_readir() and find_entry()

---
 fs/freevxfs/vxfs_lookup.c |  267 +++++++++++++++++++++------------------------
 1 files changed, 124 insertions(+), 143 deletions(-)
fs/freevxfs/vxfs_lookup.c +124 -143

321 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 1 line

From e7f68291aada1535016c767a4f5a5fcfb19a1de6 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:41:22 +0200
Subject: [PATCH 6/7] static cachep

---
 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(-)
fs/freevxfs/vxfs_extern.h +3 -1
index 4d8298b..cc43fd0 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +23 -1
index 9b45ad7..73ac417 100644
@@ -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);
+}
+
fs/freevxfs/vxfs_super.c +10 -16
index 11a535a..7579500 100644
@@ -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);
Signature · 1 line
1.7.3.4
Quoted 1 line

From 2c0008e9f2f4e62bb3e10eecad54e2a0140e0c4c Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 25 May 2016 22:58:08 +0200
Subject: [PATCH 7/7] the credits

---
 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(-)
fs/freevxfs/vxfs.h +3 -0
index 5dc8949..35f56b7 100644
@@ -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:
fs/freevxfs/vxfs_fshead.c +4 -0
index 67ca2f9..44b87d0 100644
@@ -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:
fs/freevxfs/vxfs_inode.c +4 -0
index 73ac417..4c8a625 100644
@@ -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:
fs/freevxfs/vxfs_lookup.c +4 -0
index 8eacb27..173aeea 100644
@@ -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:
fs/freevxfs/vxfs_super.c +5 -1
index 7579500..bd121aa 100644
@@ -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");
 
Signature · 1 line
1.7.3.4
Quoted 3 lines · Krzysztof Błaszkowski

Hi,

So then let it roll.

Signature · 1 line
Krzysztof Blaszkowski
#2 lore raw

r

In reply to Krzysztof Błaszkowski

Hi Krzysztof,

first round of reviews below:

Quoted 5 lines

Date: Wed, 25 May 2016 21:50:11 +0200
Subject: [PATCH 1/7] kconfig note

This part looks good, but I'd add a littlle more text and move it last in the series. The other patches could also use a little more descriptive text in the changelogs.

fs/freevxfs/vxfs.h struct vxfs_sb { · line 155

Quoted 10 lines
fs/freevxfs/vxfs.h +1 -1
index c8a9265..5dc8949 100644
@@ -152,7 +152,7 @@ struct vxfs_sb {
 	/*
 	 * Actually much more...
 	 */
-};
+} __packed;

Can you explain why this is added?

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 173

Quoted 10 lines
fs/freevxfs/vxfs.h +3 -0
 /*
@@ -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;
+};

Can you align these with the rest of the fields? Also where does the silent flag come from here?

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 174

Quoted 1 line
fs/freevxfs/vxfs.h +1 -0
+#define VXFS_FS32(field1, field2) fhp->field1 = fs32_to_cpu(bo, dbh->field2)

Please remove this wrapper.

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 177

Quoted 3 lines
fs/freevxfs/vxfs.h +3 -0
+#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)

and these.

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 187

Quoted 10 lines
fs/freevxfs/vxfs.h +10 -0
+	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;

I'd normally move this into a separate patch. But even if this stay in here it should be mentioned in the patch changelog.

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 192

Quoted 6 lines
fs/freevxfs/vxfs.h +2 -1
 	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);

brelse handles a null argument just fine.

Quoted 14 lines
fs/freevxfs/vxfs.h +1 -0
 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;
fs/freevxfs/vxfs_inode.c +0 -1
index 16d8d27..9b45ad7 100644
@@ -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);

fs/freevxfs/vxfs_inode.c vxfs_iget(struct super_block *sbp, ino_t ino) · line 409

Quoted 10 lines
fs/freevxfs/vxfs_inode.c +9 -0
+	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);
 }

I'd rather go for embedding the VFS inode in the VxFS inode like most modern file systems do. Take a look at alloc_inode and destroy_inode in ext2 for an example.

#3 lore raw

Re: r

Hi Christoph,

Quoted 4 lines · Christoph Hellwig

Hi Krzysztof,

first round of reviews below:

Quoted 8 lines
Quoted 5 lines

Date: Wed, 25 May 2016 21:50:11 +0200
Subject: [PATCH 1/7] kconfig note

This part looks good, but I'd add a littlle more text and move it last in the series.

okay, what would you write in this section ?
Will move the patch.

Quoted 16 lines

The other patches could also use a little more
descriptive text in the changelogs.

fs/freevxfs/vxfs.h struct vxfs_sb { · line 155

Quoted 10 lines
fs/freevxfs/vxfs.h +1 -1
index c8a9265..5dc8949 100644
@@ -152,7 +152,7 @@ struct vxfs_sb {
 	/*
 	 * Actually much more...
 	 */
-};
+} __packed;

Can you explain why this is added?

I was thinking that on-disk memory mapped structures should be "packed" especially if they contain 1 or 2 bytes fields in the middle. If the structure does not have the packed attribute then its size may be bigger than the size of similar structure (by name) used on another OS e.g. 32bit. An access to fields of such structure aligned differently (due to e.g. 64 bit compiler) will end up with data corruption.

(that's the basics, why i write this ?)

the vxfs_sb structure has u8 and u16's so usage of __pack is desired over here. the __pack will not cause any harm (because if we count all u8 and u16, they are still u32 aligned) and it will prevent from hypothetical misalignment (just in case). It is also a tip that the structure is on-disk and must be compiler alignment independent.

Quoted 13 lines

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 173

Quoted 10 lines
fs/freevxfs/vxfs.h +3 -0
 /*
@@ -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;
+};

Can you align these with the rest of the fields? Also where does the silent flag come from here?

I reckon aligning it is not necessary, because this structure is run-time, cpu endian and it lives in memory only (but storage device)

"silent" int comes from arg passed over to vxfs_fill_super() of the same name. My workaround, I do not like functions which have long arguments list. 2 args is fine, 3 - maybe too long, 4 - it must be done something, 5+ - bad day ? ;)

Quoted 10 lines

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 174

Quoted 2 lines
fs/freevxfs/vxfs.h +1 -0
+#define VXFS_FS32(field1, field2) fhp->field1 = fs32_to_cpu(bo, dbh->field2)

Please remove this wrapper.

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 177

Quoted 3 lines
fs/freevxfs/vxfs.h +3 -0
+#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)

and these.

well, this will be difficult. These macros help saving lots of typing over and over again.

although they raise checkpatch errors I will not opt-out because scope of these macros is local. These macros are not intended to be used anywhere else than functions like: dip2vip_cpy() and dbh2fhp().

I can #undef them later. Will you agree ?

Quoted 14 lines

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 187

Quoted 11 lines
fs/freevxfs/vxfs.h +10 -0
+	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;

I'd normally move this into a separate patch. But even if this stay in here it should be mentioned in the patch changelog.

indeed, that's quite important new feature.
changelog ?, where is it ?

Quoted 9 lines

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 192

Quoted 7 lines
fs/freevxfs/vxfs.h +2 -1
 	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);

brelse handles a null argument just fine.

wasn't sure so added the "if" just in case of it didn't handle. that "if" may stay there still.

Quoted 21 lines
Quoted 21 lines
fs/freevxfs/vxfs.h +1 -0
 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;
fs/freevxfs/vxfs_inode.c +6 -1
index 16d8d27..9b45ad7 100644
@@ -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);
+}
+
Quoted 8 lines

fs/freevxfs/vxfs_inode.c vxfs_iget(struct super_block *sbp, ino_t ino) · line 409

Quoted 4 lines
fs/freevxfs/vxfs_inode.c +3 -0
+void vxfs_destroy_inode(struct inode *ip)
+{
+	call_rcu(&ip->i_rcu, vxfs_i_callback);
 }

I'd rather go for embedding the VFS inode in the VxFS inode like most modern file systems do. Take a look at alloc_inode and destroy_inode in ext2 for an example.

right, and then alloc callback will be necessary. this will introduce more changes to e.g. get_fake_inode() and around this function.

Do you really want to have this "more perfect" ?

Quoted 5 lines

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

Signature · 1 line
Krzysztof Blaszkowski
#4 lore raw

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

In reply to Krzysztof Błaszkowski

Hi Carlos,

Christoph told me that you can look at these patches I prepared.

The patchset has follwing changes since previous release:
- preprocesor expanded local macros,
- merged credits patches,
- struct inode placed inside local structure vxfs_vfs_inode.

Last change is the most complex and makes an impact on e.g. read_fshead() and actually it is only one proper solution. A file system must not use destroy_inode callback without alloc_inode. if it does then inode structures will not be returned to fs/inode.c: inode_cachep.

Quoted 1 line

From 56ac335ff74706be4c3e30925d2c8c47a19eab9e Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 1/7] cpu endianess vs file system, two locations of the sb

---
 fs/freevxfs/vxfs.h        |   25 ++++++++++-
 fs/freevxfs/vxfs_bmap.c   |   24 ++++++----
 fs/freevxfs/vxfs_fshead.c |   25 ++++++++++-
 fs/freevxfs/vxfs_inode.c  |   57 +++++++++++++++++++++++-
 fs/freevxfs/vxfs_inode.h  |    8 ++--
 fs/freevxfs/vxfs_lookup.c |   15 +++++-
 fs/freevxfs/vxfs_olt.c    |   15 +++---
 fs/freevxfs/vxfs_super.c  |  108 +++++++++++++++++++++++++++++++++------------
 8 files changed, 221 insertions(+), 56 deletions(-)
fs/freevxfs/vxfs.h +24 -1
index c8a9265..5dc8949 100644
@@ -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
fs/freevxfs/vxfs_bmap.c +14 -10
index f86fd3c..95afd98 100644
@@ -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);
fs/freevxfs/vxfs_fshead.c +24 -1
index c9a6a94..05cced0 100644
@@ -60,6 +60,29 @@ vxfs_dumpfsh(struct vxfs_fsh *fhp)
 }
 #endif
 
+
+static inline void dbh2fhp(struct vxfs_fsh *fhp, void *_dbh, int bo)
+{
+ struct vxfs_fsh *dbh = (struct vxfs_fsh *)_dbh;
+
+ fhp->fsh_version = fs32_to_cpu(bo, dbh->fsh_version);
+ fhp->fsh_fsindex = fs32_to_cpu(bo, dbh->fsh_fsindex);
+ fhp->fsh_time = fs32_to_cpu(bo, dbh->fsh_time);
+ fhp->fsh_utime = fs32_to_cpu(bo, dbh->fsh_utime);
+ fhp->fsh_extop = fs32_to_cpu(bo, dbh->fsh_extop);
+ fhp->fsh_ninodes = fs32_to_cpu(bo, dbh->fsh_ninodes);
+ fhp->fsh_nau = fs32_to_cpu(bo, dbh->fsh_nau);
+ fhp->fsh_old_ilesize = fs32_to_cpu(bo, dbh->fsh_old_ilesize);
+ fhp->fsh_dflags = fs32_to_cpu(bo, dbh->fsh_dflags);
+ fhp->fsh_quota = fs32_to_cpu(bo, dbh->fsh_quota);
+ fhp->fsh_maxinode = fs32_to_cpu(bo, dbh->fsh_maxinode);
+ fhp->fsh_iauino = fs32_to_cpu(bo, dbh->fsh_iauino);
+ fhp->fsh_ilistino[0] = fs32_to_cpu(bo, dbh->fsh_ilistino[0]);
+ fhp->fsh_ilistino[1] = fs32_to_cpu(bo, dbh->fsh_ilistino[1]);
+ fhp->fsh_lctino = fs32_to_cpu(bo, dbh->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);
fs/freevxfs/vxfs_inode.c +55 -2

75 lines not on this page · raw message

fs/freevxfs/vxfs_inode.h +4 -4
index 240aeb1..9a2c376 100644
@@ -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
fs/freevxfs/vxfs_lookup.c +13 -2
index 99c7f0a..cea158a 100644
@@ -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;
 				}
fs/freevxfs/vxfs_olt.c +8 -7
index 0495008..6b50188 100644
@@ -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);
fs/freevxfs/vxfs_super.c +79 -29

164 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 1 line

From 0d0c7ed061edd846bd032fe1073d61169299a435 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 2/7] missing kfree and kfree on kmem_cache obj

---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 881aa3d..0a3ff86 100644
@@ -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;
fs/freevxfs/vxfs_fshead.c +5 -3
index 05cced0..c4c6a86 100644
@@ -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;
 }
fs/freevxfs/vxfs_inode.c +5 -0
index 86db3c2..9590f79 100644
@@ -411,3 +411,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);
+}
Signature · 1 line
1.7.3.4
Quoted 1 line

From c595f46ad63d71ac26dfc3ef23d87e372ac85426 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 3/7] super_operations.destroy_inode

---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 0a3ff86..4d8298b 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +12 -4
index 9590f79..f91a50c 100644
@@ -393,7 +393,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);
 }
 
 /**
@@ -401,17 +409,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);
fs/freevxfs/vxfs_super.c +1 -0
index 6a69eb0..500087a 100644
@@ -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,
Signature · 1 line
1.7.3.4
Quoted 1 line

From b02ffccdff5ca82922bf09cdcf1a9ea4471bbb62 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 4/7] refactoring of vxfs_readdir() and _find_entry()

---
 fs/freevxfs/vxfs_lookup.c |  267 +++++++++++++++++++++------------------------
 1 files changed, 124 insertions(+), 143 deletions(-)
fs/freevxfs/vxfs_lookup.c +124 -143

321 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 1 line

From eceb47a770b80d7f46a089f6a1744d66f0601e77 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 5/7] static inode_cachep

---
 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(-)
fs/freevxfs/vxfs_extern.h +3 -1
index 4d8298b..cc43fd0 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +23 -1
index f91a50c..1e20823 100644
@@ -41,7 +41,7 @@
 #include "vxfs_extern.h"
 
 
-struct kmem_cache		*vxfs_inode_cachep;
+static struct kmem_cache *vxfs_inode_cachep;
 
 
 #ifdef DIAGNOSTIC
@@ -424,3 +424,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);
+}
+
fs/freevxfs/vxfs_super.c +10 -16
index 500087a..9525818 100644
@@ -315,29 +315,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);
Signature · 1 line
1.7.3.4
Quoted 1 line

From 2915ed2c92dd349203070eea8970fd4fb62ba5b4 Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 6/7] struct inode embedded in vxfs_vfs_inode

struct vxfs_vfs_inode is allocated from vxfs_inode_cachep and vfs inode is initialized by inode_constructor(). sb->s_op must be set before read_fshead() otherwise 3 inodes will be allocated from common inode_cachep.

---
 fs/freevxfs/vxfs.h        |    8 ---
 fs/freevxfs/vxfs_bmap.c   |    5 +-
 fs/freevxfs/vxfs_extern.h |   15 +++---
 fs/freevxfs/vxfs_fshead.c |   48 +++++++----------
 fs/freevxfs/vxfs_inode.c  |  130 ++++++++++++++++++++-------------------------
 fs/freevxfs/vxfs_inode.h  |   20 +++++++-
 fs/freevxfs/vxfs_super.c  |   16 +++---
 7 files changed, 114 insertions(+), 128 deletions(-)
fs/freevxfs/vxfs.h +0 -8
index 5dc8949..8124a10 100644
@@ -38,7 +38,6 @@
  */
 #include <linux/types.h>
 
-
 /*
  * Data types for use with the VxFS ondisk format.
  */
@@ -270,13 +269,6 @@ enum {
 #define VXFS_ISIMMED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_IMMED)
 #define VXFS_ISTYPED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_TYPED)
 
-
-/*
- * Get filesystem private data from VFS inode.
- */
-#define VXFS_INO(ip) \
-	((struct vxfs_inode_info *)(ip)->i_private)
-
 /*
  * Get filesystem private data from VFS superblock.
  */
fs/freevxfs/vxfs_bmap.c +3 -2
index 95afd98..e39aea4 100644
@@ -97,8 +97,9 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 
 		brelse(buf);
 		return bno;
-	} else
-		printk(KERN_WARNING "no matching indir?");
+	} else {
+		printk(KERN_WARNING "%s:%d no matching indir?\n", __func__, __LINE__);
+	}
 
 	return 0;
 
fs/freevxfs/vxfs_extern.h +7 -8
index cc43fd0..9648735 100644
@@ -56,17 +56,16 @@ extern const struct inode_operations vxfs_immed_symlink_iops;
 /* vxfs_inode.c */
 extern const struct address_space_operations vxfs_immed_aops;
 extern void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
-extern struct inode *		vxfs_get_fake_inode(struct super_block *,
-					struct vxfs_inode_info *);
-extern void			vxfs_put_fake_inode(struct inode *);
-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);
+
+extern struct inode *vxfs_blkiget(struct super_block *, u_long, ino_t);
+extern struct inode *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 int vxfs_ii_cache_init(void);
 extern void vxfs_ii_cache_destroy(void);
+extern struct inode *vxfs_inode_alloc(struct super_block *sb);
 
 
 /* vxfs_lookup.c */
fs/freevxfs/vxfs_fshead.c +19 -29

90 lines not on this page · raw message

fs/freevxfs/vxfs_inode.c +57 -73

229 lines not on this page · raw message

fs/freevxfs/vxfs_inode.h +19 -1
index 9a2c376..bba04a8 100644
@@ -37,7 +37,6 @@
  * inodes of the Veritas Filesystem.
  */
 
-
 #define VXFS_ISIZE		0x100		/* Inode size */
 
 #define VXFS_NDADDR		10		/* Number of direct addrs in inode */
@@ -154,6 +153,16 @@ struct vxfs_dinode {
  */
 #define vxfs_inode_info	vxfs_dinode
 
+struct vxfs_vfs_inode {
+	struct inode ino;
+	struct vxfs_inode_info cpufs_ino;
+	/*
+	 * the cpufs_ino contains copy of on-disk inode but
+	 * it is cpu-endian formatted and it might be not aligned
+	 */
+};
+
+
 #define vii_mode	vdi_mode
 #define vii_uid		vdi_uid
 #define vii_gid		vdi_gid
@@ -177,4 +186,13 @@ struct vxfs_dinode {
 #define vii_ext4	vdi_org.ext4
 #define vii_typed	vdi_org.typed
 
+/*
+ * Get filesystem private data from VFS inode.
+ */
+static inline struct vxfs_inode_info *VXFS_INO(struct inode *i)
+{
+	return &(container_of(i, struct vxfs_vfs_inode, ino))->cpufs_ino;
+}
+
+
 #endif /* _VXFS_INODE_H_ */
fs/freevxfs/vxfs_super.c +9 -7
index 9525818..7bd76ab 100644
@@ -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 = {
+	.alloc_inode = vxfs_inode_alloc,
 	.destroy_inode = vxfs_destroy_inode,
 	.evict_inode =		vxfs_evict_inode,
 	.put_super =		vxfs_put_super,
@@ -80,9 +81,9 @@ vxfs_put_super(struct super_block *sbp)
 {
 	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
 
-	vxfs_put_fake_inode(infp->vsi_fship);
-	vxfs_put_fake_inode(infp->vsi_ilist);
-	vxfs_put_fake_inode(infp->vsi_stilist);
+	iput(infp->vsi_fship);
+	iput(infp->vsi_ilist);
+	iput(infp->vsi_stilist);
 
 	brelse(infp->vsi_bp);
 	kfree(infp);
@@ -259,17 +260,18 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 		goto out;
 	}
 
+
 	if (vxfs_read_olt(sbp, bsize)) {
 		printk(KERN_WARNING "vxfs: unable to read olt\n");
 		goto out;
 	}
 
+	sbp->s_op = &vxfs_super_ops;
 	if (vxfs_read_fshead(sbp)) {
 		printk(KERN_WARNING "vxfs: unable to read fshead\n");
 		goto out;
 	}
 
-	sbp->s_op = &vxfs_super_ops;
 	root = vxfs_iget(sbp, VXFS_ROOT_INO);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
@@ -284,9 +286,9 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 	return 0;
 	
 out_free_ilist:
-	vxfs_put_fake_inode(infp->vsi_fship);
-	vxfs_put_fake_inode(infp->vsi_ilist);
-	vxfs_put_fake_inode(infp->vsi_stilist);
+	iput(infp->vsi_fship);
+	iput(infp->vsi_ilist);
+	iput(infp->vsi_stilist);
 out:
 	brelse(infp->vsi_bp);
 	kfree(infp);
Signature · 1 line
1.7.3.4
Quoted 1 line

From ce7bce806419c15f7dad3c9a20b59318566c79ef Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 7/7] the credits

---
 fs/freevxfs/Kconfig       |   10 +++++++++-
 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 +++++-
 6 files changed, 29 insertions(+), 2 deletions(-)
fs/freevxfs/Kconfig +9 -1
index 8dc1cd5..a4c9075 100644
@@ -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.
fs/freevxfs/vxfs.h +3 -0
index 8124a10..54a1d02 100644
@@ -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:
fs/freevxfs/vxfs_fshead.c +4 -0
index b24cb8c..2fc5280 100644
@@ -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:
fs/freevxfs/vxfs_inode.c +4 -0
index ee0ca04..4d84f5d 100644
@@ -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:
fs/freevxfs/vxfs_lookup.c +4 -0
index 8eacb27..173aeea 100644
@@ -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:
fs/freevxfs/vxfs_super.c +5 -1
index 7bd76ab..964d402 100644
@@ -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");
 
Signature · 1 line
1.7.3.4
Quoted 9 lines · Krzysztof Błaszkowski

Hi,

So then let it roll.

Thanks

Quoted 1 line

From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00

2001
From: KB <[email protected]>

Signature · 1 line
Krzysztof Blaszkowski
#5 lore raw

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

Hi Krzysztof,

This is more a style review than functionality itself (although I've added a few comments in this context too).

But, for now on, please:
- Submit each patch in a single e-mail, it's much easier to review the patches in a single context, than have 7 patches and 2k lines of different contexts in a single e-mail.
- Fix the kernel style and indentation problems.

If you need help regarding sending the patches in the right format to the list, let me know off-list, since, I don't believe the list is the right place to keep discussing how to properly send patches to the list and kernel coding style stuff.
And people will be much happier reviewing properly formatted code, and different patches in single e-mails.

I've added some comments below

Quoted 46 lines · Krzysztof Błaszkowski

Hi Carlos,

Christoph told me that you can look at these patches I prepared.

The patchset has follwing changes since previous release:
- preprocesor expanded local macros,
- merged credits patches,
- struct inode placed inside local structure vxfs_vfs_inode.

Last change is the most complex and makes an impact on e.g. read_fshead() and actually it is only one proper solution. A file system must not use destroy_inode callback without alloc_inode. if it does then inode structures will not be returned to fs/inode.c: inode_cachep.

From 56ac335ff74706be4c3e30925d2c8c47a19eab9e Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 1/7] cpu endianess vs file system, two locations of the sb

---
 fs/freevxfs/vxfs.h        |   25 ++++++++++-
 fs/freevxfs/vxfs_bmap.c   |   24 ++++++----
 fs/freevxfs/vxfs_fshead.c |   25 ++++++++++-
 fs/freevxfs/vxfs_inode.c  |   57 +++++++++++++++++++++++-
 fs/freevxfs/vxfs_inode.h  |    8 ++--
 fs/freevxfs/vxfs_lookup.c |   15 +++++-
 fs/freevxfs/vxfs_olt.c    |   15 +++---
 fs/freevxfs/vxfs_super.c  |  108 +++++++++++++++++++++++++++++++++------------
 8 files changed, 221 insertions(+), 56 deletions(-)
fs/freevxfs/vxfs.h +1 -1
index c8a9265..5dc8949 100644
@@ -152,7 +152,7 @@ struct vxfs_sb {
 	/*
 	 * Actually much more...
 	 */
-};
+} __packed;
 
 
 /*

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 172

Quoted 5 lines
fs/freevxfs/vxfs.h +2 -0
@@ -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;

These definitions are still not aligned. What Christoph meant before, was indentation alignment.

Quoted 42 lines
fs/freevxfs/vxfs.h +21 -0
+};
+
+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
fs/freevxfs/vxfs_bmap.c +2 -1
index f86fd3c..95afd98 100644
@@ -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;

fs/freevxfs/vxfs_bmap.c vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) · line 135

Quoted 5 lines
fs/freevxfs/vxfs_bmap.c +1 -0
@@ -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;
 

Indentation please.

Quoted 141 lines
fs/freevxfs/vxfs_bmap.c +11 -9
 	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);
fs/freevxfs/vxfs_fshead.c +24 -1
index c9a6a94..05cced0 100644
@@ -60,6 +60,29 @@ vxfs_dumpfsh(struct vxfs_fsh *fhp)
 }
 #endif
 
+
+static inline void dbh2fhp(struct vxfs_fsh *fhp, void *_dbh, int bo)
+{
+ struct vxfs_fsh *dbh = (struct vxfs_fsh *)_dbh;
+
+ fhp->fsh_version = fs32_to_cpu(bo, dbh->fsh_version);
+ fhp->fsh_fsindex = fs32_to_cpu(bo, dbh->fsh_fsindex);
+ fhp->fsh_time = fs32_to_cpu(bo, dbh->fsh_time);
+ fhp->fsh_utime = fs32_to_cpu(bo, dbh->fsh_utime);
+ fhp->fsh_extop = fs32_to_cpu(bo, dbh->fsh_extop);
+ fhp->fsh_ninodes = fs32_to_cpu(bo, dbh->fsh_ninodes);
+ fhp->fsh_nau = fs32_to_cpu(bo, dbh->fsh_nau);
+ fhp->fsh_old_ilesize = fs32_to_cpu(bo, dbh->fsh_old_ilesize);
+ fhp->fsh_dflags = fs32_to_cpu(bo, dbh->fsh_dflags);
+ fhp->fsh_quota = fs32_to_cpu(bo, dbh->fsh_quota);
+ fhp->fsh_maxinode = fs32_to_cpu(bo, dbh->fsh_maxinode);
+ fhp->fsh_iauino = fs32_to_cpu(bo, dbh->fsh_iauino);
+ fhp->fsh_ilistino[0] = fs32_to_cpu(bo, dbh->fsh_ilistino[0]);
+ fhp->fsh_ilistino[1] = fs32_to_cpu(bo, dbh->fsh_ilistino[1]);
+ fhp->fsh_lctino = fs32_to_cpu(bo, dbh->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);
fs/freevxfs/vxfs_inode.c +39 -0
index 363e3ae..86db3c2 100644
@@ -67,6 +67,59 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
 }
 #endif
 
+static inline void dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *dip, int bo)
+{
+ int j;
+
+ vip->vdi_mode = fs32_to_cpu(bo, dip->vdi_mode);
+ vip->vdi_nlink = fs32_to_cpu(bo, dip->vdi_nlink);
+ vip->vdi_uid = fs32_to_cpu(bo, dip->vdi_uid);
+ vip->vdi_gid = fs32_to_cpu(bo, dip->vdi_gid);
+ vip->vdi_size = fs64_to_cpu(bo, dip->vdi_size);
+ vip->vdi_atime = fs32_to_cpu(bo, dip->vdi_atime);
+ vip->vdi_autime = fs32_to_cpu(bo, dip->vdi_autime);
+ vip->vdi_mtime = fs32_to_cpu(bo, dip->vdi_mtime);
+ vip->vdi_mutime = fs32_to_cpu(bo, dip->vdi_mutime);
+ vip->vdi_ctime = fs32_to_cpu(bo, dip->vdi_ctime);
+ vip->vdi_cutime = fs32_to_cpu(bo, dip->vdi_cutime);
+ vip->vdi_aflags = dip->vdi_aflags;
+ vip->vdi_orgtype = dip->vdi_orgtype;
+ vip->vdi_eopflags = fs16_to_cpu(bo, dip->vdi_eopflags);
+ vip->vdi_eopdata = fs32_to_cpu(bo, dip->vdi_eopdata);
+
+ vip->vdi_ftarea.i_regular.reserved = fs32_to_cpu(bo, dip->vdi_ftarea.i_regular.reserved);
+ vip->vdi_ftarea.i_regular.fixextsize = fs32_to_cpu(bo, dip->vdi_ftarea.i_regular.fixextsize);
+ vip->vdi_blocks = fs32_to_cpu(bo, dip->vdi_blocks);
+ vip->vdi_gen = fs32_to_cpu(bo, dip->vdi_gen);
+ vip->vdi_version = fs64_to_cpu(bo, dip->vdi_version);
+
+ switch (dip->vdi_orgtype) {
+ case VXFS_ORG_EXT4:
+  vip->vdi_org.ext4.ve4_spare = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_spare);
+  vip->vdi_org.ext4.ve4_indsize = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_indsize);
+  for (j = 0; j < 2; j++) {
+   vip->vdi_org.ext4.ve4_indir[j] = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_indir[j]);
+  }
+  for (j = 0; j < 10; j++) {
+   vip->vdi_org.ext4.ve4_direct[j].extent = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_direct[j].extent);
+   vip->vdi_org.ext4.ve4_direct[j].size = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_direct[j].size);
+  }
+  break;
+ case VXFS_ORG_IMMED:

fs/freevxfs/vxfs_inode.c vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino) · line 118

Quoted 10 lines
fs/freevxfs/vxfs_inode.c +10 -0
+  memcpy(&vip->vdi_org.immed, &dip->vdi_org.immed, sizeof(vip->vdi_org.immed));
+  break;
+ case VXFS_ORG_TYPED:
+  for (j = 0; j < 6; j++) {
+   vip->vdi_org.typed[j].vt_hdr = fs64_to_cpu(bo, dip->vdi_org.typed[j].vt_hdr);
+   vip->vdi_org.typed[j].vt_block = fs32_to_cpu(bo, dip->vdi_org.typed[j].vt_block);
+   vip->vdi_org.typed[j].vt_size = fs32_to_cpu(bo, dip->vdi_org.typed[j].vt_size);
+  }
+  break;
+ };

Please, indent this switch statement, follow the 80columns rule (i.e. lines should not have more than 80columns).

Quoted 84 lines
fs/freevxfs/vxfs_inode.c +6 -2
+
+ vip->vdi_iattrino = fs32_to_cpu(bo, dip->vdi_iattrino);
+}
+
 
 /**
  * vxfs_blkiget - find inode based on extent #
@@ -101,7 +154,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 +196,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
fs/freevxfs/vxfs_inode.h +4 -4
index 240aeb1..9a2c376 100644
@@ -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
fs/freevxfs/vxfs_lookup.c +9 -0
index 99c7f0a..cea158a 100644
@@ -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

fs/freevxfs/vxfs_lookup.c vxfs_readdir(struct file *fp, struct dir_context *ctx) · line 255

Quoted 5 lines
fs/freevxfs/vxfs_lookup.c +2 -0
@@ -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;
+

Indentation.

Quoted 124 lines
fs/freevxfs/vxfs_lookup.c +2 -2
 	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;
 				}
fs/freevxfs/vxfs_olt.c +8 -7
index 0495008..6b50188 100644
@@ -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);
fs/freevxfs/vxfs_super.c +18 -3
index 7ca8c75..6a69eb0 100644
@@ -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,53 @@ 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);

fs/freevxfs/vxfs_super.c static int vxfs_remount(struct super_block *sb, int *flags, char *data) · line 156

Quoted 10 lines
fs/freevxfs/vxfs_super.c +10 -0
+			}
+			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 %08x at +%d\n",
+					rsbp->vs_magic, blk);

Please, avoid +80 columns, you did it in the printk above, no reason to not do it here too.

fs/freevxfs/vxfs_super.c static int vxfs_remount(struct super_block *sb, int *flags, char *data) · line 163

Quoted 7 lines
fs/freevxfs/vxfs_super.c +7 -0
+			break;
+		}
+
+		rc = 0;
+		infp->vsi_raw = rsbp;
+		infp->vsi_bp = bp;
+	} while (0);

I'm not the best person to give a review here, but, I wouldn't use a do.while(0), but instead, goto error_X: statements and assign the error codes according to the conditional results, instead of re-assigning the error code if the previous code wasn't correct.
But again, a POV of another person will be better.

Quoted 20 lines
fs/freevxfs/vxfs_super.c +16 -0
+
+	if (rc) {
+		infp->vsi_raw = NULL;
+		infp->vsi_bp = NULL;
+		brelse(bp);
+	}
+
+	return rc;
+}
+
+
+static const char * const vxfs_subtypes[] = {
+	"SCO",
+	"HP-UX(be)"
+};
+
 /**
  * vxfs_read_super - read superblock into memory and initialize filesystem
  * @sbp:		VFS superblock (to fill)

fs/freevxfs/vxfs_super.c static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) · line 204

Quoted 9 lines
fs/freevxfs/vxfs_super.c +1 -1
@@ -149,10 +197,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;
 

Indentation, goo opportunity to fix the another non-indented fields too.

Quoted 93 lines
fs/freevxfs/vxfs_super.c +27 -25
 	sbp->s_flags |= MS_RDONLY;
 
@@ -162,48 +210,50 @@ 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 */
+			sbp->s_subtype = kstrdup(vxfs_subtypes[0], GFP_KERNEL);
+			break;
+		}
+
+		if (!vxfs_try_sb_magic(sbp, 8, cpu_to_be32(VXFS_SUPER_MAGIC))) {
+			infp->byte_order = BO_BE; /* HP-UX pa-risc likely */
+			sbp->s_subtype = kstrdup(vxfs_subtypes[1], GFP_KERNEL);
+			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: blocksize: %d\n", rsbp->vs_bsize);
+	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
+	printk(KERN_DEBUG "vxfs: blocksize: %d\n",
+	    fs32_to_cpu(infp->byte_order, 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 +287,7 @@ out_free_ilist:
 	vxfs_put_fake_inode(infp->vsi_ilist);
 	vxfs_put_fake_inode(infp->vsi_stilist);
 out:
-	brelse(bp);
+	brelse(infp->vsi_bp);
 	kfree(infp);
 	return ret;
 }
Signature · 6 lines
1.7.3.4

From 0d0c7ed061edd846bd032fe1073d61169299a435 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 2/7] missing kfree and kfree on kmem_cache obj

Missing kfree and kfree?

"Missing to kfree objects" sounds better IMHO

Quoted 14 lines
---
 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(-)
fs/freevxfs/vxfs_extern.h +0 -0
index 881aa3d..0a3ff86 100644

fs/freevxfs/vxfs_extern.h extern struct vxfs_inode_info * vxfs_blkiget(struct super_block *, u_long, ino_t · line 67

Quoted 4 lines
fs/freevxfs/vxfs_extern.h +1 -0
@@ -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);

Indentation

Quoted 130 lines
fs/freevxfs/vxfs_extern.h +0 -0
 /* vxfs_lookup.c */
 extern const struct inode_operations	vxfs_dir_inode_ops;
fs/freevxfs/vxfs_fshead.c +5 -3
index 05cced0..c4c6a86 100644
@@ -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;
 }
fs/freevxfs/vxfs_inode.c +5 -0
index 86db3c2..9590f79 100644
@@ -411,3 +411,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);
+}
Signature · 14 lines
1.7.3.4

From c595f46ad63d71ac26dfc3ef23d87e372ac85426 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 3/7] super_operations.destroy_inode


Signed-off-by: KB <[email protected]>
---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 0a3ff86..4d8298b 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +12 -4
index 9590f79..f91a50c 100644
@@ -393,7 +393,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);
 }
 
 /**
@@ -401,17 +409,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);
fs/freevxfs/vxfs_super.c +0 -0
index 6a69eb0..500087a 100644

fs/freevxfs/vxfs_super.c static int vxfs_statfs(struct dentry *, struct kstatfs *); · line 62

Quoted 4 lines
fs/freevxfs/vxfs_super.c +1 -0
@@ -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,

Indentation

Quoted 109 lines
fs/freevxfs/vxfs_super.c +0 -0
 	.evict_inode =		vxfs_evict_inode,
 	.put_super =		vxfs_put_super,
 	.statfs =		vxfs_statfs,
Signature · 12 lines
1.7.3.4

From b02ffccdff5ca82922bf09cdcf1a9ea4471bbb62 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 4/7] refactoring of vxfs_readdir() and _find_entry()


Signed-off-by: KB <[email protected]>
---
 fs/freevxfs/vxfs_lookup.c |  267 +++++++++++++++++++++------------------------
 1 files changed, 124 insertions(+), 143 deletions(-)
fs/freevxfs/vxfs_lookup.c +0 -77
index cea158a..8eacb27 100644
@@ -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)) {

fs/freevxfs/vxfs_lookup.c static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo) · line 89

Quoted 10 lines
fs/freevxfs/vxfs_lookup.c +7 -3
-					*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;

Indentation

fs/freevxfs/vxfs_lookup.c static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo) · line 99

Quoted 10 lines
fs/freevxfs/vxfs_lookup.c +10 -0
+
+	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;
+		}

Kernel coding style states to not use braces with single-line if conditionals.

Quoted 440 lines
fs/freevxfs/vxfs_lookup.c +107 -63
+		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;
 }
Signature · 14 lines
1.7.3.4

From eceb47a770b80d7f46a089f6a1744d66f0601e77 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 5/7] static inode_cachep


Signed-off-by: KB <[email protected]>
---
 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(-)
fs/freevxfs/vxfs_extern.h +3 -1
index 4d8298b..cc43fd0 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +23 -1
index f91a50c..1e20823 100644
@@ -41,7 +41,7 @@
 #include "vxfs_extern.h"
 
 
-struct kmem_cache		*vxfs_inode_cachep;
+static struct kmem_cache *vxfs_inode_cachep;
 
 
 #ifdef DIAGNOSTIC
@@ -424,3 +424,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);
+}
+
fs/freevxfs/vxfs_super.c +10 -16
index 500087a..9525818 100644
@@ -315,29 +315,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);
Signature · 23 lines
1.7.3.4

From 2915ed2c92dd349203070eea8970fd4fb62ba5b4 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 6/7] struct inode embedded in vxfs_vfs_inode

struct vxfs_vfs_inode is allocated from vxfs_inode_cachep
and vfs inode is initialized by inode_constructor().
sb->s_op must be set before read_fshead() otherwise 
3 inodes will be allocated from common inode_cachep.


Signed-off-by: KB <[email protected]>
---
 fs/freevxfs/vxfs.h        |    8 ---
 fs/freevxfs/vxfs_bmap.c   |    5 +-
 fs/freevxfs/vxfs_extern.h |   15 +++---
 fs/freevxfs/vxfs_fshead.c |   48 +++++++----------
 fs/freevxfs/vxfs_inode.c  |  130 ++++++++++++++++++++-------------------------
 fs/freevxfs/vxfs_inode.h  |   20 +++++++-
 fs/freevxfs/vxfs_super.c  |   16 +++---
 7 files changed, 114 insertions(+), 128 deletions(-)
fs/freevxfs/vxfs.h +0 -8
index 5dc8949..8124a10 100644
@@ -38,7 +38,6 @@
  */
 #include <linux/types.h>
 
-
 /*
  * Data types for use with the VxFS ondisk format.
  */
@@ -270,13 +269,6 @@ enum {
 #define VXFS_ISIMMED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_IMMED)
 #define VXFS_ISTYPED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_TYPED)
 
-
-/*
- * Get filesystem private data from VFS inode.
- */
-#define VXFS_INO(ip) \
-	((struct vxfs_inode_info *)(ip)->i_private)
-
 /*
  * Get filesystem private data from VFS superblock.
  */
fs/freevxfs/vxfs_bmap.c +3 -2
index 95afd98..e39aea4 100644
@@ -97,8 +97,9 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 
 		brelse(buf);
 		return bno;
-	} else
-		printk(KERN_WARNING "no matching indir?");
+	} else {
+		printk(KERN_WARNING "%s:%d no matching indir?\n", __func__, __LINE__);
+	}
 
 	return 0;
 
fs/freevxfs/vxfs_extern.h +7 -8
index cc43fd0..9648735 100644
@@ -56,17 +56,16 @@ extern const struct inode_operations vxfs_immed_symlink_iops;
 /* vxfs_inode.c */
 extern const struct address_space_operations vxfs_immed_aops;
 extern void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
-extern struct inode *		vxfs_get_fake_inode(struct super_block *,
-					struct vxfs_inode_info *);
-extern void			vxfs_put_fake_inode(struct inode *);
-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);
+
+extern struct inode *vxfs_blkiget(struct super_block *, u_long, ino_t);
+extern struct inode *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 int vxfs_ii_cache_init(void);
 extern void vxfs_ii_cache_destroy(void);
+extern struct inode *vxfs_inode_alloc(struct super_block *sb);
 
 
 /* vxfs_lookup.c */
fs/freevxfs/vxfs_fshead.c +0 -0
index c4c6a86..b24cb8c 100644

fs/freevxfs/vxfs_fshead.c vxfs_read_fshead(struct super_block *sbp) · line 135

Quoted 6 lines
fs/freevxfs/vxfs_fshead.c +2 -1
@@ -131,31 +131,26 @@ vxfs_read_fshead(struct super_block *sbp)
 {
 	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
 	struct vxfs_fsh			*pfp, *sfp;
-	struct vxfs_inode_info		*vip, *tip;
+	struct inode *ip1;
+	struct inode *ip2;

Indentation.

Quoted 153 lines
fs/freevxfs/vxfs_fshead.c +17 -28
-	vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
-	if (!vip) {
+	infp->vsi_fship = ip1 = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
+	if (IS_ERR(ip1)) {
 		printk(KERN_ERR "vxfs: unable to read fsh inode\n");
 		return -EINVAL;
 	}
-	if (!VXFS_ISFSH(vip)) {
+
+	if (!VXFS_ISFSH(VXFS_INO(ip1))) {
 		printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
-				vip->vii_mode & VXFS_TYPE_MASK); 
+				VXFS_INO(ip1)->vii_mode & VXFS_TYPE_MASK);
 		goto out_free_fship;
 	}
 
-
 #ifdef DIAGNOSTIC
 	printk("vxfs: fsh inode dump:\n");
-	vxfs_dumpi(vip, infp->vsi_fshino);
+	vxfs_dumpi(VXFS_INO(ip1), infp->vsi_fshino);
 #endif
 
-	infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
-	if (!infp->vsi_fship) {
-		printk(KERN_ERR "vxfs: unable to get fsh inode\n");
-		goto out_free_fship;
-	}
-
 	sfp = vxfs_getfsh(infp->vsi_fship, 0);
 	if (!sfp) {
 		printk(KERN_ERR "vxfs: unable to get structural fsh\n");
@@ -176,31 +171,25 @@ vxfs_read_fshead(struct super_block *sbp)
 	vxfs_dumpfsh(pfp);
 #endif
 
-	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
-	if (!tip)
-		goto out_free_pfp;
+	infp->vsi_stilist =
+		ip2 = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
 
-	infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
-	if (!infp->vsi_stilist) {
-		printk(KERN_ERR "vxfs: unable to get structural list inode\n");
-		vxfs_inode_info_free(tip);
+	if (IS_ERR(ip2)) {
 		goto out_free_pfp;
 	}
+
 	if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
 		printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n",
 				VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
 		goto out_iput_stilist;
 	}
 
-	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
-	if (!tip)
-		goto out_iput_stilist;
-	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
-	if (!infp->vsi_ilist) {
+	infp->vsi_ilist = ip2 = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
+	if (IS_ERR(ip2)) {
 		printk(KERN_ERR "vxfs: unable to get inode list inode\n");
-		vxfs_inode_info_free(tip);
 		goto out_iput_stilist;
 	}
+
 	if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
 		printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
 				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
@@ -220,9 +209,10 @@ vxfs_read_fshead(struct super_block *sbp)
  out_free_sfp:
  	kfree(sfp);
  out_iput_fship:
-	iput(infp->vsi_fship);
-	return -EINVAL;
  out_free_fship:
-	vxfs_inode_info_free(vip);
+	iput(infp->vsi_fship);
+	infp->vsi_stilist = NULL;
+	infp->vsi_ilist = NULL;
+	infp->vsi_fship = NULL;
 	return -EINVAL;
 }
fs/freevxfs/vxfs_inode.c +19 -12
index 1e20823..ee0ca04 100644
@@ -42,6 +42,7 @@
 
 
 static struct kmem_cache *vxfs_inode_cachep;
+static void vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip);
 
 
 #ifdef DIAGNOSTIC
@@ -137,35 +138,41 @@ static inline void dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *
  *  buffercache.  This function should not be used outside the
  *  read_super() method, otherwise the data may be incoherent.
  */
-struct vxfs_inode_info *
+struct inode *
 vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
 {
 	struct buffer_head		*bp;
 	u_long				block, offset;
+	struct inode *ip;
 
 	block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize);
 	offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE);
+
+	ip = new_inode(sbp);
+	if (!ip)
+		return ERR_PTR(-ENOMEM);
+
 	bp = sb_bread(sbp, block);
+	ip->i_ino = get_next_ino();
+	ip->i_mapping->a_ops = &vxfs_aops;
 
 	if (bp && buffer_mapped(bp)) {
-		struct vxfs_inode_info	*vip;
-		struct vxfs_dinode	*dip;
+		struct vxfs_inode_info	*vip = VXFS_INO(ip);
+		struct vxfs_dinode	*dip = (struct vxfs_dinode *)(bp->b_data + offset);
 
-		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
-			goto fail;
-		dip = (struct vxfs_dinode *)(bp->b_data + offset);
 		dip2vip_cpy(vip, dip, VXFS_SBI(sbp)->byte_order);
+		vxfs_iinit(ip, vip);
 #ifdef DIAGNOSTIC
 		vxfs_dumpi(vip, ino);
 #endif
-		brelse(bp);
-		return (vip);
+	} else {
+		printk(KERN_WARNING "vxfs: unable to read block %ld\n", block);
+		iput(ip);
+		ip = NULL;
 	}
-
-fail:
-	printk(KERN_WARNING "vxfs: unable to read block %ld\n", block);
 	brelse(bp);
-	return NULL;
+
+	return ip;
 }
 
 /**

fs/freevxfs/vxfs_inode.c fail: · line 192

Quoted 9 lines
fs/freevxfs/vxfs_inode.c +2 -3
@@ -180,21 +187,18 @@ fail:
  *  Returns the matching VxFS inode on success, else an error code.
  */
 static struct vxfs_inode_info *
-__vxfs_iget(ino_t ino, struct inode *ilistp)
+__vxfs_iget(struct inode *ip, struct inode *ilistp, ino_t ino)
 {
-	struct page			*pp;
-	u_long				offset;
+	struct page	*pp;

Indentation

Quoted 215 lines
fs/freevxfs/vxfs_inode.c +36 -58
+	u_long offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE;
 
-	offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE;
 	pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE);
 
 	if (!IS_ERR(pp)) {
-		struct vxfs_inode_info	*vip;
+		struct vxfs_inode_info	*vip = VXFS_INO(ip);
 		struct vxfs_dinode	*dip;
 		caddr_t			kaddr = (char *)page_address(pp);
 
-		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
-			goto fail;
 		dip = (struct vxfs_dinode *)(kaddr + offset);
 		dip2vip_cpy(vip, dip, VXFS_SBI(ilistp->i_sb)->byte_order);
 #ifdef DIAGNOSTIC
@@ -206,11 +210,6 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
 
 	printk(KERN_WARNING "vxfs: error on page %p\n", pp);
 	return ERR_CAST(pp);
-
-fail:
-	printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned long)ino);
-	vxfs_put_page(pp);
-	return ERR_PTR(-ENOMEM);
 }
 
 /**
@@ -223,13 +222,24 @@ fail:
  *  the structural inode list.
  *  Returns the matching VxFS inode on success, else a NULL pointer.
  */
-struct vxfs_inode_info *
+struct inode *
 vxfs_stiget(struct super_block *sbp, ino_t ino)
 {
-	struct vxfs_inode_info *vip;
+	struct inode *ip = new_inode(sbp);
+	struct vxfs_inode_info *ii;
 
-	vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist);
-	return IS_ERR(vip) ? NULL : vip;
+	if (!ip)
+		return NULL;
+
+	ip->i_ino = get_next_ino();
+	ip->i_mapping->a_ops = &vxfs_aops;
+	ii = __vxfs_iget(ip, VXFS_SBI(sbp)->vsi_stilist, ino);
+	if (IS_ERR(ii)) {
+		iput(ip);
+	} else {
+		vxfs_iinit(ip, ii);
+	}
+	return IS_ERR(ii) ? NULL : ip;
 }
 
 /**
@@ -297,41 +307,6 @@ vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip)
 
 }
 
-/**
- * vxfs_get_fake_inode - get fake inode structure
- * @sbp:		filesystem superblock
- * @vip:		fspriv inode
- *
- * Description:
- *  vxfs_fake_inode gets a fake inode (not in the inode hash) for a
- *  superblock, vxfs_inode pair.
- *  Returns the filled VFS inode.
- */
-struct inode *
-vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip)
-{
-	struct inode			*ip = NULL;
-
-	if ((ip = new_inode(sbp))) {
-		ip->i_ino = get_next_ino();
-		vxfs_iinit(ip, vip);
-		ip->i_mapping->a_ops = &vxfs_aops;
-	}
-	return (ip);
-}
-
-/**
- * vxfs_put_fake_inode - free faked inode
- * *ip:			VFS inode
- *
- * Description:
- *  vxfs_put_fake_inode frees all data associated with @ip.
- */
-void
-vxfs_put_fake_inode(struct inode *ip)
-{
-	iput(ip);
-}
 
 /**
  * vxfs_iget - get an inode
@@ -355,7 +330,7 @@ vxfs_iget(struct super_block *sbp, ino_t ino)
 	if (!(ip->i_state & I_NEW))
 		return ip;
 
-	vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist);
+	vip = __vxfs_iget(ip, VXFS_SBI(sbp)->vsi_ilist, ino);
 	if (IS_ERR(vip)) {
 		iget_failed(ip);
 		return ERR_CAST(vip);
@@ -393,10 +368,9 @@ 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);
-	void *priv = inode->i_private;
+	struct vxfs_vfs_inode *i = container_of(inode, struct vxfs_vfs_inode, ino);
 
-	inode->i_private = NULL;
-	kmem_cache_free(vxfs_inode_cachep, priv);
+	kmem_cache_free(vxfs_inode_cachep, i);
 }
 
 void vxfs_destroy_inode(struct inode *ip)
@@ -405,11 +379,11 @@ void vxfs_destroy_inode(struct inode *ip)
 }
 
 /**
- * vxfs_evict_inode - remove inode from main memory
+ * vxfs_evict_inode - commit inode buffers if needed, may delete on-disk inode.
  * @ip:		inode to discard.
  *
  * Description:
- *  vxfs_evict_inode() is called on the final iput
+ *  vxfs_evict_inode() may be called on the final iput.
  */
 void
 vxfs_evict_inode(struct inode *ip)
@@ -420,17 +394,27 @@ vxfs_evict_inode(struct inode *ip)
 }
 
 
-void vxfs_inode_info_free(struct vxfs_inode_info *vip)
+
+
+struct inode *vxfs_inode_alloc(struct super_block *sb)
 {
-	kmem_cache_free(vxfs_inode_cachep, vip);
+	struct vxfs_vfs_inode *i = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL);
+
+	return i ? &i->ino : NULL;
 }
 
+static void vxfs_inode_constructor(void *ptr)
+{
+	struct vxfs_vfs_inode *i = (struct vxfs_vfs_inode *) ptr;
+
+	inode_init_once(&i->ino);
+}
 
 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);
+		sizeof(struct vxfs_vfs_inode), 0,
+		SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, vxfs_inode_constructor);
 
 	return vxfs_inode_cachep ? 0 : -ENOMEM;
 }
fs/freevxfs/vxfs_inode.h +19 -1
index 9a2c376..bba04a8 100644
@@ -37,7 +37,6 @@
  * inodes of the Veritas Filesystem.
  */
 
-
 #define VXFS_ISIZE		0x100		/* Inode size */
 
 #define VXFS_NDADDR		10		/* Number of direct addrs in inode */
@@ -154,6 +153,16 @@ struct vxfs_dinode {
  */
 #define vxfs_inode_info	vxfs_dinode
 
+struct vxfs_vfs_inode {
+	struct inode ino;
+	struct vxfs_inode_info cpufs_ino;
+	/*
+	 * the cpufs_ino contains copy of on-disk inode but
+	 * it is cpu-endian formatted and it might be not aligned
+	 */
+};
+
+
 #define vii_mode	vdi_mode
 #define vii_uid		vdi_uid
 #define vii_gid		vdi_gid
@@ -177,4 +186,13 @@ struct vxfs_dinode {
 #define vii_ext4	vdi_org.ext4
 #define vii_typed	vdi_org.typed
 
+/*
+ * Get filesystem private data from VFS inode.
+ */
+static inline struct vxfs_inode_info *VXFS_INO(struct inode *i)
+{
+	return &(container_of(i, struct vxfs_vfs_inode, ino))->cpufs_ino;
+}
+
+
 #endif /* _VXFS_INODE_H_ */
fs/freevxfs/vxfs_super.c +0 -0
index 9525818..7bd76ab 100644

fs/freevxfs/vxfs_super.c static int vxfs_statfs(struct dentry *, struct kstatfs *); · line 65

Quoted 7 lines
fs/freevxfs/vxfs_super.c +1 -0
@@ -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 = {
+	.alloc_inode = vxfs_inode_alloc,
 	.destroy_inode = vxfs_destroy_inode,
 	.evict_inode =		vxfs_evict_inode,
 	.put_super =		vxfs_put_super,

Please indent everything here

Quoted 166 lines
fs/freevxfs/vxfs_super.c +8 -7
@@ -80,9 +81,9 @@ vxfs_put_super(struct super_block *sbp)
 {
 	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
 
-	vxfs_put_fake_inode(infp->vsi_fship);
-	vxfs_put_fake_inode(infp->vsi_ilist);
-	vxfs_put_fake_inode(infp->vsi_stilist);
+	iput(infp->vsi_fship);
+	iput(infp->vsi_ilist);
+	iput(infp->vsi_stilist);
 
 	brelse(infp->vsi_bp);
 	kfree(infp);
@@ -259,17 +260,18 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 		goto out;
 	}
 
+
 	if (vxfs_read_olt(sbp, bsize)) {
 		printk(KERN_WARNING "vxfs: unable to read olt\n");
 		goto out;
 	}
 
+	sbp->s_op = &vxfs_super_ops;
 	if (vxfs_read_fshead(sbp)) {
 		printk(KERN_WARNING "vxfs: unable to read fshead\n");
 		goto out;
 	}
 
-	sbp->s_op = &vxfs_super_ops;
 	root = vxfs_iget(sbp, VXFS_ROOT_INO);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
@@ -284,9 +286,9 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 	return 0;
 
 out_free_ilist:
-	vxfs_put_fake_inode(infp->vsi_fship);
-	vxfs_put_fake_inode(infp->vsi_ilist);
-	vxfs_put_fake_inode(infp->vsi_stilist);
+	iput(infp->vsi_fship);
+	iput(infp->vsi_ilist);
+	iput(infp->vsi_stilist);
 out:
 	brelse(infp->vsi_bp);
 	kfree(infp);
Signature · 17 lines
1.7.3.4

From ce7bce806419c15f7dad3c9a20b59318566c79ef Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 7/7] the credits


Signed-off-by: KB <[email protected]>
---
 fs/freevxfs/Kconfig       |   10 +++++++++-
 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 +++++-
 6 files changed, 29 insertions(+), 2 deletions(-)
fs/freevxfs/Kconfig +9 -1
index 8dc1cd5..a4c9075 100644
@@ -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.
fs/freevxfs/vxfs.h +3 -0
index 8124a10..54a1d02 100644
@@ -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:
fs/freevxfs/vxfs_fshead.c +4 -0
index b24cb8c..2fc5280 100644
@@ -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:
fs/freevxfs/vxfs_inode.c +4 -0
index ee0ca04..4d84f5d 100644
@@ -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:
fs/freevxfs/vxfs_lookup.c +4 -0
index 8eacb27..173aeea 100644
@@ -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:
fs/freevxfs/vxfs_super.c +4 -0
index 7bd76ab..964d402 100644
@@ -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:

fs/freevxfs/vxfs_super.c line 55

Quoted 5 lines
fs/freevxfs/vxfs_super.c +1 -1
@@ -48,7 +52,7 @@
 #include "vxfs_inode.h"
 
 
-MODULE_AUTHOR("Christoph Hellwig");
+MODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");

Afaict MODULE_AUTHOR is supposed to only contain the original author, and not collect all developers who actually worked on the modules, if that was the case, we would have modules with thousands of names in the MODULE_AUTHOR macro, but well, I'm not the best person to say if it's right or not :)

Quoted 21 lines
fs/freevxfs/vxfs_super.c +0 -0
 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
 MODULE_LICENSE("Dual BSD/GPL");
 
Signature · 1 line
1.7.3.4
Quoted 9 lines · Krzysztof Błaszkowski

Hi,

So then let it roll.

Thanks

Quoted 1 line

From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00

2001
From: KB <[email protected]>

Signature · 1 line
Krzysztof Blaszkowski
Signature · 1 line
Carlos
#6 lore raw

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

Hi Carlos,

Thanks for review. Will fix these things and send tomorrow morning likely. Today just can't.

Quoted 65 lines · Carlos Maiolino

Hi Krzysztof,

This is more a style review than functionality itself (although I've added a few comments in this context too).

But, for now on, please:
- Submit each patch in a single e-mail, it's much easier to review the patches in a single context, than have 7 patches and 2k lines of different contexts in a single e-mail.
- Fix the kernel style and indentation problems.

If you need help regarding sending the patches in the right format to the list, let me know off-list, since, I don't believe the list is the right place to keep discussing how to properly send patches to the list and kernel coding style stuff.
And people will be much happier reviewing properly formatted code, and different patches in single e-mails.

I've added some comments below

Quoted 44 lines · Krzysztof Błaszkowski

Hi Carlos,

Christoph told me that you can look at these patches I prepared.

The patchset has follwing changes since previous release:
- preprocesor expanded local macros,
- merged credits patches,
- struct inode placed inside local structure vxfs_vfs_inode.

Last change is the most complex and makes an impact on e.g. read_fshead() and actually it is only one proper solution. A file system must not use destroy_inode callback without alloc_inode. if it does then inode structures will not be returned to fs/inode.c: inode_cachep.

From 56ac335ff74706be4c3e30925d2c8c47a19eab9e Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 1/7] cpu endianess vs file system, two locations of the sb

---
 fs/freevxfs/vxfs.h        |   25 ++++++++++-
 fs/freevxfs/vxfs_bmap.c   |   24 ++++++----
 fs/freevxfs/vxfs_fshead.c |   25 ++++++++++-
 fs/freevxfs/vxfs_inode.c  |   57 +++++++++++++++++++++++-
 fs/freevxfs/vxfs_inode.h  |    8 ++--
 fs/freevxfs/vxfs_lookup.c |   15 +++++-
 fs/freevxfs/vxfs_olt.c    |   15 +++---
 fs/freevxfs/vxfs_super.c  |  108 +++++++++++++++++++++++++++++++++------------
 8 files changed, 221 insertions(+), 56 deletions(-)
fs/freevxfs/vxfs.h +1 -1
index c8a9265..5dc8949 100644
@@ -152,7 +152,7 @@ struct vxfs_sb {
 	/*
 	 * Actually much more...
 	 */
-};
+} __packed;
 
 
Quoted 10 lines

fs/freevxfs/vxfs.h struct vxfs_sb_info { · line 172

Quoted 7 lines
fs/freevxfs/vxfs.h +2 -0
 /*
@@ -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;

These definitions are still not aligned. What Christoph meant before, was indentation alignment.

I see, okay, so the text alignment, good enough. I dislike the old alignment because it looks bad anyway can add a few tabs.

Quoted 49 lines
Quoted 43 lines
fs/freevxfs/vxfs.h +21 -0
+};
+
+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
fs/freevxfs/vxfs_bmap.c +2 -1
index f86fd3c..95afd98 100644
@@ -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;

fs/freevxfs/vxfs_bmap.c vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) · line 135

Quoted 5 lines
fs/freevxfs/vxfs_bmap.c +1 -0
@@ -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;
 

Indentation please.

....

Quoted 147 lines
Quoted 147 lines
fs/freevxfs/vxfs_bmap.c +11 -9
 	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);
fs/freevxfs/vxfs_fshead.c +24 -1
index c9a6a94..05cced0 100644
@@ -60,6 +60,29 @@ vxfs_dumpfsh(struct vxfs_fsh *fhp)
 }
 #endif
 
+
+static inline void dbh2fhp(struct vxfs_fsh *fhp, void *_dbh, int bo)
+{
+ struct vxfs_fsh *dbh = (struct vxfs_fsh *)_dbh;
+
+ fhp->fsh_version = fs32_to_cpu(bo, dbh->fsh_version);
+ fhp->fsh_fsindex = fs32_to_cpu(bo, dbh->fsh_fsindex);
+ fhp->fsh_time = fs32_to_cpu(bo, dbh->fsh_time);
+ fhp->fsh_utime = fs32_to_cpu(bo, dbh->fsh_utime);
+ fhp->fsh_extop = fs32_to_cpu(bo, dbh->fsh_extop);
+ fhp->fsh_ninodes = fs32_to_cpu(bo, dbh->fsh_ninodes);
+ fhp->fsh_nau = fs32_to_cpu(bo, dbh->fsh_nau);
+ fhp->fsh_old_ilesize = fs32_to_cpu(bo, dbh->fsh_old_ilesize);
+ fhp->fsh_dflags = fs32_to_cpu(bo, dbh->fsh_dflags);
+ fhp->fsh_quota = fs32_to_cpu(bo, dbh->fsh_quota);
+ fhp->fsh_maxinode = fs32_to_cpu(bo, dbh->fsh_maxinode);
+ fhp->fsh_iauino = fs32_to_cpu(bo, dbh->fsh_iauino);
+ fhp->fsh_ilistino[0] = fs32_to_cpu(bo, dbh->fsh_ilistino[0]);
+ fhp->fsh_ilistino[1] = fs32_to_cpu(bo, dbh->fsh_ilistino[1]);
+ fhp->fsh_lctino = fs32_to_cpu(bo, dbh->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);
fs/freevxfs/vxfs_inode.c +44 -0
index 363e3ae..86db3c2 100644
@@ -67,6 +67,59 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
 }
 #endif
 
+static inline void dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *dip, int bo)
+{
+ int j;
+
+ vip->vdi_mode = fs32_to_cpu(bo, dip->vdi_mode);
+ vip->vdi_nlink = fs32_to_cpu(bo, dip->vdi_nlink);
+ vip->vdi_uid = fs32_to_cpu(bo, dip->vdi_uid);
+ vip->vdi_gid = fs32_to_cpu(bo, dip->vdi_gid);
+ vip->vdi_size = fs64_to_cpu(bo, dip->vdi_size);
+ vip->vdi_atime = fs32_to_cpu(bo, dip->vdi_atime);
+ vip->vdi_autime = fs32_to_cpu(bo, dip->vdi_autime);
+ vip->vdi_mtime = fs32_to_cpu(bo, dip->vdi_mtime);
+ vip->vdi_mutime = fs32_to_cpu(bo, dip->vdi_mutime);
+ vip->vdi_ctime = fs32_to_cpu(bo, dip->vdi_ctime);
+ vip->vdi_cutime = fs32_to_cpu(bo, dip->vdi_cutime);
+ vip->vdi_aflags = dip->vdi_aflags;
+ vip->vdi_orgtype = dip->vdi_orgtype;
+ vip->vdi_eopflags = fs16_to_cpu(bo, dip->vdi_eopflags);
+ vip->vdi_eopdata = fs32_to_cpu(bo, dip->vdi_eopdata);
+
+ vip->vdi_ftarea.i_regular.reserved = fs32_to_cpu(bo, dip->vdi_ftarea.i_regular.reserved);
+ vip->vdi_ftarea.i_regular.fixextsize = fs32_to_cpu(bo, dip->vdi_ftarea.i_regular.fixextsize);
+ vip->vdi_blocks = fs32_to_cpu(bo, dip->vdi_blocks);
+ vip->vdi_gen = fs32_to_cpu(bo, dip->vdi_gen);
+ vip->vdi_version = fs64_to_cpu(bo, dip->vdi_version);
+
+ switch (dip->vdi_orgtype) {
+ case VXFS_ORG_EXT4:
+  vip->vdi_org.ext4.ve4_spare = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_spare);
+  vip->vdi_org.ext4.ve4_indsize = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_indsize);
+  for (j = 0; j < 2; j++) {
+   vip->vdi_org.ext4.ve4_indir[j] = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_indir[j]);
+  }
+  for (j = 0; j < 10; j++) {
+   vip->vdi_org.ext4.ve4_direct[j].extent = fs32_to_cpu(bo, dip->vdi_org.ext4.ve4_direct[j].extent);
+   vip->vdi_org.ext4.ve4_direct[j].size = fs32_to_cpu(bo, dip->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 < 6; j++) {
+   vip->vdi_org.typed[j].vt_hdr = fs64_to_cpu(bo, dip->vdi_org.typed[j].vt_hdr);
Quoted 9 lines

fs/freevxfs/vxfs_inode.c vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino) · line 118

Quoted 5 lines
fs/freevxfs/vxfs_inode.c +5 -0
+   vip->vdi_org.typed[j].vt_block = fs32_to_cpu(bo, dip->vdi_org.typed[j].vt_block);
+   vip->vdi_org.typed[j].vt_size = fs32_to_cpu(bo, dip->vdi_org.typed[j].vt_size);
+  }
+  break;
+ };

Please, indent this switch statement, follow the 80columns rule (i.e. lines should not have more than 80columns).

okay, these were just warnings. speed limits on highways are supposed to limit a speed and there are ones who think about them as suggestions to not drive slower than .. I enjoy more the latter case.

Quoted 82 lines
Quoted 82 lines
fs/freevxfs/vxfs_inode.c +6 -2
+
+ vip->vdi_iattrino = fs32_to_cpu(bo, dip->vdi_iattrino);
+}
+
 
 /**
  * vxfs_blkiget - find inode based on extent #
@@ -101,7 +154,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 +196,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
fs/freevxfs/vxfs_inode.h +4 -4
index 240aeb1..9a2c376 100644
@@ -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
fs/freevxfs/vxfs_lookup.c +9 -0
index 99c7f0a..cea158a 100644
@@ -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
Quoted 8 lines

fs/freevxfs/vxfs_lookup.c vxfs_readdir(struct file *fp, struct dir_context *ctx) · line 255

Quoted 7 lines
fs/freevxfs/vxfs_lookup.c +2 -0
  * @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;
+

Indentation.

need to think about some clever sed syntax ..

Quoted 130 lines
Quoted 130 lines
fs/freevxfs/vxfs_lookup.c +2 -2
 	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;
 				}
fs/freevxfs/vxfs_olt.c +8 -7
index 0495008..6b50188 100644
@@ -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);
fs/freevxfs/vxfs_super.c +23 -3
index 7ca8c75..6a69eb0 100644
@@ -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,53 @@ 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;
Quoted 8 lines

fs/freevxfs/vxfs_super.c static int vxfs_remount(struct super_block *sb, int *flags, char *data) · line 156

Quoted 5 lines
fs/freevxfs/vxfs_super.c +5 -0
+		rsbp = (struct vxfs_sb *)bp->b_data;
+		if (rsbp->vs_magic != magic) {
+			if (!infp->silent)
+				printk(KERN_NOTICE "vxfs: WRONG superblock magic %08x at +%d\n",
+					rsbp->vs_magic, blk);

Please, avoid +80 columns, you did it in the printk above, no reason to not do it here too.

indeed I did. however checkpatch complained again and that was that the string was split. Daft, isn't it?

Need to know checkpatch ....ed warnings rules.

Quoted 13 lines

fs/freevxfs/vxfs_super.c static int vxfs_remount(struct super_block *sb, int *flags, char *data) · line 163

Quoted 8 lines
fs/freevxfs/vxfs_super.c +7 -0
+			break;
+		}
+
+		rc = 0;
+		infp->vsi_raw = rsbp;
+		infp->vsi_bp = bp;
+	} while (0);

I'm not the best person to give a review here, but, I wouldn't use a do.while(0), but instead, goto error_X: statements and assign the error codes according to the conditional results, instead of re-assigning the error code if the previous code wasn't correct.

some people hate gotos.

Quoted 24 lines

But again, a POV of another person will be better.

Quoted 22 lines
fs/freevxfs/vxfs_super.c +16 -0
+
+	if (rc) {
+		infp->vsi_raw = NULL;
+		infp->vsi_bp = NULL;
+		brelse(bp);
+	}
+
+	return rc;
+}
+
+
+static const char * const vxfs_subtypes[] = {
+	"SCO",
+	"HP-UX(be)"
+};
+
 /**
  * vxfs_read_super - read superblock into memory and initialize filesystem
  * @sbp:		VFS superblock (to fill)
@@ -149,10 +197,10 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 {
 	struct vxfs_sb_info	*infp;
Quoted 8 lines

fs/freevxfs/vxfs_super.c static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) · line 204

Quoted 7 lines
fs/freevxfs/vxfs_super.c +1 -1
 	struct vxfs_sb		*rsbp;
-	struct buffer_head	*bp = NULL;
 	u_long			bsize;
 	struct inode *root;
 	int ret = -EINVAL;
+	u32 j;
 

Indentation, goo opportunity to fix the another non-indented fields too.

i will hate this word shortly soon.

Quoted 90 lines
Quoted 90 lines
fs/freevxfs/vxfs_super.c +27 -25
 	sbp->s_flags |= MS_RDONLY;
 
@@ -162,48 +210,50 @@ 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 */
+			sbp->s_subtype = kstrdup(vxfs_subtypes[0], GFP_KERNEL);
+			break;
+		}
+
+		if (!vxfs_try_sb_magic(sbp, 8, cpu_to_be32(VXFS_SUPER_MAGIC))) {
+			infp->byte_order = BO_BE; /* HP-UX pa-risc likely */
+			sbp->s_subtype = kstrdup(vxfs_subtypes[1], GFP_KERNEL);
+			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: blocksize: %d\n", rsbp->vs_bsize);
+	printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
+	printk(KERN_DEBUG "vxfs: blocksize: %d\n",
+	    fs32_to_cpu(infp->byte_order, 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 +287,7 @@ out_free_ilist:
 	vxfs_put_fake_inode(infp->vsi_ilist);
 	vxfs_put_fake_inode(infp->vsi_stilist);
 out:
-	brelse(bp);
+	brelse(infp->vsi_bp);
 	kfree(infp);
 	return ret;
 }
Signature · 1 line
1.7.3.4
Quoted 8 lines
Quoted 4 lines

From 0d0c7ed061edd846bd032fe1073d61169299a435 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 2/7] missing kfree and kfree on kmem_cache obj

Missing kfree and kfree?

"Missing to kfree objects" sounds better IMHO

maybe. I meant kfree as function = noun.
as you wish.

original message should be read like this: (missing kfree) && (kfree on object allocated by kmem_cache_alloc() )

Quoted 279 lines
Quoted 14 lines
---
 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(-)
fs/freevxfs/vxfs_extern.h +0 -0
index 881aa3d..0a3ff86 100644

fs/freevxfs/vxfs_extern.h extern struct vxfs_inode_info * vxfs_blkiget(struct super_block *, u_long, ino_t · line 67

Quoted 4 lines
fs/freevxfs/vxfs_extern.h +1 -0
@@ -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);

Indentation

Quoted 130 lines
fs/freevxfs/vxfs_extern.h +0 -0
 /* vxfs_lookup.c */
 extern const struct inode_operations	vxfs_dir_inode_ops;
fs/freevxfs/vxfs_fshead.c +5 -3
index 05cced0..c4c6a86 100644
@@ -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;
 }
fs/freevxfs/vxfs_inode.c +5 -0
index 86db3c2..9590f79 100644
@@ -411,3 +411,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);
+}
Signature · 14 lines
1.7.3.4

From c595f46ad63d71ac26dfc3ef23d87e372ac85426 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 3/7] super_operations.destroy_inode


Signed-off-by: KB <[email protected]>
---
 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(-)
fs/freevxfs/vxfs_extern.h +1 -0
index 0a3ff86..4d8298b 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +12 -4
index 9590f79..f91a50c 100644
@@ -393,7 +393,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);
 }
 
 /**
@@ -401,17 +409,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);
fs/freevxfs/vxfs_super.c +0 -0
index 6a69eb0..500087a 100644

fs/freevxfs/vxfs_super.c static int vxfs_statfs(struct dentry *, struct kstatfs *); · line 62

Quoted 4 lines
fs/freevxfs/vxfs_super.c +1 -0
@@ -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,

Indentation

Quoted 109 lines
fs/freevxfs/vxfs_super.c +0 -0
 	.evict_inode =		vxfs_evict_inode,
 	.put_super =		vxfs_put_super,
 	.statfs =		vxfs_statfs,
Signature · 12 lines
1.7.3.4

From b02ffccdff5ca82922bf09cdcf1a9ea4471bbb62 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 4/7] refactoring of vxfs_readdir() and _find_entry()


Signed-off-by: KB <[email protected]>
---
 fs/freevxfs/vxfs_lookup.c |  267 +++++++++++++++++++++------------------------
 1 files changed, 124 insertions(+), 143 deletions(-)
fs/freevxfs/vxfs_lookup.c +0 -77
index cea158a..8eacb27 100644
@@ -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)) {

fs/freevxfs/vxfs_lookup.c static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo) · line 89

Quoted 10 lines
fs/freevxfs/vxfs_lookup.c +7 -3
-					*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;

Indentation

Quoted 13 lines

fs/freevxfs/vxfs_lookup.c static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo) · line 99

Quoted 10 lines
fs/freevxfs/vxfs_lookup.c +10 -0
+
+	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;
+		}

Kernel coding style states to not use braces with single-line if conditionals.

okay. have seen this warning already.

Quoted 601 lines
Quoted 441 lines
fs/freevxfs/vxfs_lookup.c +107 -63
+		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;
 }
Signature · 14 lines
1.7.3.4

From eceb47a770b80d7f46a089f6a1744d66f0601e77 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 5/7] static inode_cachep


Signed-off-by: KB <[email protected]>
---
 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(-)
fs/freevxfs/vxfs_extern.h +3 -1
index 4d8298b..cc43fd0 100644
@@ -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;
fs/freevxfs/vxfs_inode.c +23 -1
index f91a50c..1e20823 100644
@@ -41,7 +41,7 @@
 #include "vxfs_extern.h"
 
 
-struct kmem_cache		*vxfs_inode_cachep;
+static struct kmem_cache *vxfs_inode_cachep;
 
 
 #ifdef DIAGNOSTIC
@@ -424,3 +424,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);
+}
+
fs/freevxfs/vxfs_super.c +10 -16
index 500087a..9525818 100644
@@ -315,29 +315,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);
Signature · 23 lines
1.7.3.4

From 2915ed2c92dd349203070eea8970fd4fb62ba5b4 Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 6/7] struct inode embedded in vxfs_vfs_inode

struct vxfs_vfs_inode is allocated from vxfs_inode_cachep
and vfs inode is initialized by inode_constructor().
sb->s_op must be set before read_fshead() otherwise 
3 inodes will be allocated from common inode_cachep.


Signed-off-by: KB <[email protected]>
---
 fs/freevxfs/vxfs.h        |    8 ---
 fs/freevxfs/vxfs_bmap.c   |    5 +-
 fs/freevxfs/vxfs_extern.h |   15 +++---
 fs/freevxfs/vxfs_fshead.c |   48 +++++++----------
 fs/freevxfs/vxfs_inode.c  |  130 ++++++++++++++++++++-------------------------
 fs/freevxfs/vxfs_inode.h  |   20 +++++++-
 fs/freevxfs/vxfs_super.c  |   16 +++---
 7 files changed, 114 insertions(+), 128 deletions(-)
fs/freevxfs/vxfs.h +0 -8
index 5dc8949..8124a10 100644
@@ -38,7 +38,6 @@
  */
 #include <linux/types.h>
 
-
 /*
  * Data types for use with the VxFS ondisk format.
  */
@@ -270,13 +269,6 @@ enum {
 #define VXFS_ISIMMED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_IMMED)
 #define VXFS_ISTYPED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_TYPED)
 
-
-/*
- * Get filesystem private data from VFS inode.
- */
-#define VXFS_INO(ip) \
-	((struct vxfs_inode_info *)(ip)->i_private)
-
 /*
  * Get filesystem private data from VFS superblock.
  */
fs/freevxfs/vxfs_bmap.c +3 -2
index 95afd98..e39aea4 100644
@@ -97,8 +97,9 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 
 		brelse(buf);
 		return bno;
-	} else
-		printk(KERN_WARNING "no matching indir?");
+	} else {
+		printk(KERN_WARNING "%s:%d no matching indir?\n", __func__, __LINE__);
+	}
 
 	return 0;
 
fs/freevxfs/vxfs_extern.h +7 -8
index cc43fd0..9648735 100644
@@ -56,17 +56,16 @@ extern const struct inode_operations vxfs_immed_symlink_iops;
 /* vxfs_inode.c */
 extern const struct address_space_operations vxfs_immed_aops;
 extern void			vxfs_dumpi(struct vxfs_inode_info *, ino_t);
-extern struct inode *		vxfs_get_fake_inode(struct super_block *,
-					struct vxfs_inode_info *);
-extern void			vxfs_put_fake_inode(struct inode *);
-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);
+
+extern struct inode *vxfs_blkiget(struct super_block *, u_long, ino_t);
+extern struct inode *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 int vxfs_ii_cache_init(void);
 extern void vxfs_ii_cache_destroy(void);
+extern struct inode *vxfs_inode_alloc(struct super_block *sb);
 
 
 /* vxfs_lookup.c */
fs/freevxfs/vxfs_fshead.c +0 -0
index c4c6a86..b24cb8c 100644

fs/freevxfs/vxfs_fshead.c vxfs_read_fshead(struct super_block *sbp) · line 135

Quoted 6 lines
fs/freevxfs/vxfs_fshead.c +2 -1
@@ -131,31 +131,26 @@ vxfs_read_fshead(struct super_block *sbp)
 {
 	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
 	struct vxfs_fsh			*pfp, *sfp;
-	struct vxfs_inode_info		*vip, *tip;
+	struct inode *ip1;
+	struct inode *ip2;

Indentation.

Quoted 151 lines
fs/freevxfs/vxfs_fshead.c +17 -28
-	vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
-	if (!vip) {
+	infp->vsi_fship = ip1 = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
+	if (IS_ERR(ip1)) {
 		printk(KERN_ERR "vxfs: unable to read fsh inode\n");
 		return -EINVAL;
 	}
-	if (!VXFS_ISFSH(vip)) {
+
+	if (!VXFS_ISFSH(VXFS_INO(ip1))) {
 		printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
-				vip->vii_mode & VXFS_TYPE_MASK); 
+				VXFS_INO(ip1)->vii_mode & VXFS_TYPE_MASK);
 		goto out_free_fship;
 	}
 
-
 #ifdef DIAGNOSTIC
 	printk("vxfs: fsh inode dump:\n");
-	vxfs_dumpi(vip, infp->vsi_fshino);
+	vxfs_dumpi(VXFS_INO(ip1), infp->vsi_fshino);
 #endif
 
-	infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
-	if (!infp->vsi_fship) {
-		printk(KERN_ERR "vxfs: unable to get fsh inode\n");
-		goto out_free_fship;
-	}
-
 	sfp = vxfs_getfsh(infp->vsi_fship, 0);
 	if (!sfp) {
 		printk(KERN_ERR "vxfs: unable to get structural fsh\n");
@@ -176,31 +171,25 @@ vxfs_read_fshead(struct super_block *sbp)
 	vxfs_dumpfsh(pfp);
 #endif
 
-	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
-	if (!tip)
-		goto out_free_pfp;
+	infp->vsi_stilist =
+		ip2 = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
 
-	infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
-	if (!infp->vsi_stilist) {
-		printk(KERN_ERR "vxfs: unable to get structural list inode\n");
-		vxfs_inode_info_free(tip);
+	if (IS_ERR(ip2)) {
 		goto out_free_pfp;
 	}
+
 	if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
 		printk(KERN_ERR "vxfs: structural list inode is of wrong type (%x)\n",
 				VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
 		goto out_iput_stilist;
 	}
 
-	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
-	if (!tip)
-		goto out_iput_stilist;
-	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
-	if (!infp->vsi_ilist) {
+	infp->vsi_ilist = ip2 = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
+	if (IS_ERR(ip2)) {
 		printk(KERN_ERR "vxfs: unable to get inode list inode\n");
-		vxfs_inode_info_free(tip);
 		goto out_iput_stilist;
 	}
+
 	if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
 		printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
 				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
@@ -220,9 +209,10 @@ vxfs_read_fshead(struct super_block *sbp)
  out_free_sfp:
  	kfree(sfp);
  out_iput_fship:
-	iput(infp->vsi_fship);
-	return -EINVAL;
  out_free_fship:
-	vxfs_inode_info_free(vip);
+	iput(infp->vsi_fship);
+	infp->vsi_stilist = NULL;
+	infp->vsi_ilist = NULL;
+	infp->vsi_fship = NULL;
 	return -EINVAL;
 }
fs/freevxfs/vxfs_inode.c +19 -12
index 1e20823..ee0ca04 100644
@@ -42,6 +42,7 @@
 
 
 static struct kmem_cache *vxfs_inode_cachep;
+static void vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip);
 
 
 #ifdef DIAGNOSTIC
@@ -137,35 +138,41 @@ static inline void dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *
  *  buffercache.  This function should not be used outside the
  *  read_super() method, otherwise the data may be incoherent.
  */
-struct vxfs_inode_info *
+struct inode *
 vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
 {
 	struct buffer_head		*bp;
 	u_long				block, offset;
+	struct inode *ip;
 
 	block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize);
 	offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE);
+
+	ip = new_inode(sbp);
+	if (!ip)
+		return ERR_PTR(-ENOMEM);
+
 	bp = sb_bread(sbp, block);
+	ip->i_ino = get_next_ino();
+	ip->i_mapping->a_ops = &vxfs_aops;
 
 	if (bp && buffer_mapped(bp)) {
-		struct vxfs_inode_info	*vip;
-		struct vxfs_dinode	*dip;
+		struct vxfs_inode_info	*vip = VXFS_INO(ip);
+		struct vxfs_dinode	*dip = (struct vxfs_dinode *)(bp->b_data + offset);
 
-		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
-			goto fail;
-		dip = (struct vxfs_dinode *)(bp->b_data + offset);
 		dip2vip_cpy(vip, dip, VXFS_SBI(sbp)->byte_order);
+		vxfs_iinit(ip, vip);
 #ifdef DIAGNOSTIC
 		vxfs_dumpi(vip, ino);
 #endif
-		brelse(bp);
-		return (vip);
+	} else {
+		printk(KERN_WARNING "vxfs: unable to read block %ld\n", block);
+		iput(ip);
+		ip = NULL;
 	}
-
-fail:
-	printk(KERN_WARNING "vxfs: unable to read block %ld\n", block);
 	brelse(bp);
-	return NULL;
+
+	return ip;
 }
 
Quoted 12 lines

fs/freevxfs/vxfs_inode.c fail: · line 192

Quoted 11 lines
fs/freevxfs/vxfs_inode.c +2 -3
 /**
@@ -180,21 +187,18 @@ fail:
  *  Returns the matching VxFS inode on success, else an error code.
  */
 static struct vxfs_inode_info *
-__vxfs_iget(ino_t ino, struct inode *ilistp)
+__vxfs_iget(struct inode *ip, struct inode *ilistp, ino_t ino)
 {
-	struct page			*pp;
-	u_long				offset;
+	struct page	*pp;

Indentation

and i hate the "Indentation" word...

I will use "indent -kr -l 120 more switches" on everything so everything will look the same way.

Thanks

Quoted 424 lines
Quoted 216 lines
fs/freevxfs/vxfs_inode.c +36 -58
+	u_long offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE;
 
-	offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE;
 	pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE);
 
 	if (!IS_ERR(pp)) {
-		struct vxfs_inode_info	*vip;
+		struct vxfs_inode_info	*vip = VXFS_INO(ip);
 		struct vxfs_dinode	*dip;
 		caddr_t			kaddr = (char *)page_address(pp);
 
-		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
-			goto fail;
 		dip = (struct vxfs_dinode *)(kaddr + offset);
 		dip2vip_cpy(vip, dip, VXFS_SBI(ilistp->i_sb)->byte_order);
 #ifdef DIAGNOSTIC
@@ -206,11 +210,6 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
 
 	printk(KERN_WARNING "vxfs: error on page %p\n", pp);
 	return ERR_CAST(pp);
-
-fail:
-	printk(KERN_WARNING "vxfs: unable to read inode %ld\n", (unsigned long)ino);
-	vxfs_put_page(pp);
-	return ERR_PTR(-ENOMEM);
 }
 
 /**
@@ -223,13 +222,24 @@ fail:
  *  the structural inode list.
  *  Returns the matching VxFS inode on success, else a NULL pointer.
  */
-struct vxfs_inode_info *
+struct inode *
 vxfs_stiget(struct super_block *sbp, ino_t ino)
 {
-	struct vxfs_inode_info *vip;
+	struct inode *ip = new_inode(sbp);
+	struct vxfs_inode_info *ii;
 
-	vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_stilist);
-	return IS_ERR(vip) ? NULL : vip;
+	if (!ip)
+		return NULL;
+
+	ip->i_ino = get_next_ino();
+	ip->i_mapping->a_ops = &vxfs_aops;
+	ii = __vxfs_iget(ip, VXFS_SBI(sbp)->vsi_stilist, ino);
+	if (IS_ERR(ii)) {
+		iput(ip);
+	} else {
+		vxfs_iinit(ip, ii);
+	}
+	return IS_ERR(ii) ? NULL : ip;
 }
 
 /**
@@ -297,41 +307,6 @@ vxfs_iinit(struct inode *ip, struct vxfs_inode_info *vip)
 
 }
 
-/**
- * vxfs_get_fake_inode - get fake inode structure
- * @sbp:		filesystem superblock
- * @vip:		fspriv inode
- *
- * Description:
- *  vxfs_fake_inode gets a fake inode (not in the inode hash) for a
- *  superblock, vxfs_inode pair.
- *  Returns the filled VFS inode.
- */
-struct inode *
-vxfs_get_fake_inode(struct super_block *sbp, struct vxfs_inode_info *vip)
-{
-	struct inode			*ip = NULL;
-
-	if ((ip = new_inode(sbp))) {
-		ip->i_ino = get_next_ino();
-		vxfs_iinit(ip, vip);
-		ip->i_mapping->a_ops = &vxfs_aops;
-	}
-	return (ip);
-}
-
-/**
- * vxfs_put_fake_inode - free faked inode
- * *ip:			VFS inode
- *
- * Description:
- *  vxfs_put_fake_inode frees all data associated with @ip.
- */
-void
-vxfs_put_fake_inode(struct inode *ip)
-{
-	iput(ip);
-}
 
 /**
  * vxfs_iget - get an inode
@@ -355,7 +330,7 @@ vxfs_iget(struct super_block *sbp, ino_t ino)
 	if (!(ip->i_state & I_NEW))
 		return ip;
 
-	vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist);
+	vip = __vxfs_iget(ip, VXFS_SBI(sbp)->vsi_ilist, ino);
 	if (IS_ERR(vip)) {
 		iget_failed(ip);
 		return ERR_CAST(vip);
@@ -393,10 +368,9 @@ 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);
-	void *priv = inode->i_private;
+	struct vxfs_vfs_inode *i = container_of(inode, struct vxfs_vfs_inode, ino);
 
-	inode->i_private = NULL;
-	kmem_cache_free(vxfs_inode_cachep, priv);
+	kmem_cache_free(vxfs_inode_cachep, i);
 }
 
 void vxfs_destroy_inode(struct inode *ip)
@@ -405,11 +379,11 @@ void vxfs_destroy_inode(struct inode *ip)
 }
 
 /**
- * vxfs_evict_inode - remove inode from main memory
+ * vxfs_evict_inode - commit inode buffers if needed, may delete on-disk inode.
  * @ip:		inode to discard.
  *
  * Description:
- *  vxfs_evict_inode() is called on the final iput
+ *  vxfs_evict_inode() may be called on the final iput.
  */
 void
 vxfs_evict_inode(struct inode *ip)
@@ -420,17 +394,27 @@ vxfs_evict_inode(struct inode *ip)
 }
 
 
-void vxfs_inode_info_free(struct vxfs_inode_info *vip)
+
+
+struct inode *vxfs_inode_alloc(struct super_block *sb)
 {
-	kmem_cache_free(vxfs_inode_cachep, vip);
+	struct vxfs_vfs_inode *i = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL);
+
+	return i ? &i->ino : NULL;
 }
 
+static void vxfs_inode_constructor(void *ptr)
+{
+	struct vxfs_vfs_inode *i = (struct vxfs_vfs_inode *) ptr;
+
+	inode_init_once(&i->ino);
+}
 
 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);
+		sizeof(struct vxfs_vfs_inode), 0,
+		SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, vxfs_inode_constructor);
 
 	return vxfs_inode_cachep ? 0 : -ENOMEM;
 }
fs/freevxfs/vxfs_inode.h +19 -1
index 9a2c376..bba04a8 100644
@@ -37,7 +37,6 @@
  * inodes of the Veritas Filesystem.
  */
 
-
 #define VXFS_ISIZE		0x100		/* Inode size */
 
 #define VXFS_NDADDR		10		/* Number of direct addrs in inode */
@@ -154,6 +153,16 @@ struct vxfs_dinode {
  */
 #define vxfs_inode_info	vxfs_dinode
 
+struct vxfs_vfs_inode {
+	struct inode ino;
+	struct vxfs_inode_info cpufs_ino;
+	/*
+	 * the cpufs_ino contains copy of on-disk inode but
+	 * it is cpu-endian formatted and it might be not aligned
+	 */
+};
+
+
 #define vii_mode	vdi_mode
 #define vii_uid		vdi_uid
 #define vii_gid		vdi_gid
@@ -177,4 +186,13 @@ struct vxfs_dinode {
 #define vii_ext4	vdi_org.ext4
 #define vii_typed	vdi_org.typed
 
+/*
+ * Get filesystem private data from VFS inode.
+ */
+static inline struct vxfs_inode_info *VXFS_INO(struct inode *i)
+{
+	return &(container_of(i, struct vxfs_vfs_inode, ino))->cpufs_ino;
+}
+
+
 #endif /* _VXFS_INODE_H_ */
fs/freevxfs/vxfs_super.c +0 -0
index 9525818..7bd76ab 100644

fs/freevxfs/vxfs_super.c static int vxfs_statfs(struct dentry *, struct kstatfs *); · line 65

Quoted 7 lines
fs/freevxfs/vxfs_super.c +1 -0
@@ -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 = {
+	.alloc_inode = vxfs_inode_alloc,
 	.destroy_inode = vxfs_destroy_inode,
 	.evict_inode =		vxfs_evict_inode,
 	.put_super =		vxfs_put_super,

Please indent everything here

Quoted 166 lines
fs/freevxfs/vxfs_super.c +8 -7
@@ -80,9 +81,9 @@ vxfs_put_super(struct super_block *sbp)
 {
 	struct vxfs_sb_info	*infp = VXFS_SBI(sbp);
 
-	vxfs_put_fake_inode(infp->vsi_fship);
-	vxfs_put_fake_inode(infp->vsi_ilist);
-	vxfs_put_fake_inode(infp->vsi_stilist);
+	iput(infp->vsi_fship);
+	iput(infp->vsi_ilist);
+	iput(infp->vsi_stilist);
 
 	brelse(infp->vsi_bp);
 	kfree(infp);
@@ -259,17 +260,18 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 		goto out;
 	}
 
+
 	if (vxfs_read_olt(sbp, bsize)) {
 		printk(KERN_WARNING "vxfs: unable to read olt\n");
 		goto out;
 	}
 
+	sbp->s_op = &vxfs_super_ops;
 	if (vxfs_read_fshead(sbp)) {
 		printk(KERN_WARNING "vxfs: unable to read fshead\n");
 		goto out;
 	}
 
-	sbp->s_op = &vxfs_super_ops;
 	root = vxfs_iget(sbp, VXFS_ROOT_INO);
 	if (IS_ERR(root)) {
 		ret = PTR_ERR(root);
@@ -284,9 +286,9 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
 	return 0;
 
 out_free_ilist:
-	vxfs_put_fake_inode(infp->vsi_fship);
-	vxfs_put_fake_inode(infp->vsi_ilist);
-	vxfs_put_fake_inode(infp->vsi_stilist);
+	iput(infp->vsi_fship);
+	iput(infp->vsi_ilist);
+	iput(infp->vsi_stilist);
 out:
 	brelse(infp->vsi_bp);
 	kfree(infp);
Signature · 17 lines
1.7.3.4

From ce7bce806419c15f7dad3c9a20b59318566c79ef Mon Sep 17 00:00:00 2001
From: KB <[email protected]>
Date: Sat, 28 May 2016 20:55:19 +0200
Subject: [PATCH 7/7] the credits


Signed-off-by: KB <[email protected]>
---
 fs/freevxfs/Kconfig       |   10 +++++++++-
 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 +++++-
 6 files changed, 29 insertions(+), 2 deletions(-)
fs/freevxfs/Kconfig +9 -1
index 8dc1cd5..a4c9075 100644
@@ -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.
fs/freevxfs/vxfs.h +3 -0
index 8124a10..54a1d02 100644
@@ -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:
fs/freevxfs/vxfs_fshead.c +4 -0
index b24cb8c..2fc5280 100644
@@ -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:
fs/freevxfs/vxfs_inode.c +4 -0
index ee0ca04..4d84f5d 100644
@@ -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:
fs/freevxfs/vxfs_lookup.c +4 -0
index 8eacb27..173aeea 100644
@@ -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:
fs/freevxfs/vxfs_super.c +4 -0
index 7bd76ab..964d402 100644
@@ -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:

fs/freevxfs/vxfs_super.c line 55

Quoted 5 lines
fs/freevxfs/vxfs_super.c +1 -1
@@ -48,7 +52,7 @@
 #include "vxfs_inode.h"
 
 
-MODULE_AUTHOR("Christoph Hellwig");
+MODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");

Afaict MODULE_AUTHOR is supposed to only contain the original author, and not collect all developers who actually worked on the modules, if that was the case, we would have modules with thousands of names in the MODULE_AUTHOR macro, but well, I'm not the best person to say if it's right or not :)

Quoted 21 lines
fs/freevxfs/vxfs_super.c +0 -0
 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
 MODULE_LICENSE("Dual BSD/GPL");
 
Signature · 1 line
1.7.3.4
Quoted 9 lines · Krzysztof Błaszkowski

Hi,

So then let it roll.

Thanks

Quoted 1 line

From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00

2001
From: KB <[email protected]>

Signature · 1 line
Krzysztof Blaszkowski
Signature · 1 line
Krzysztof Blaszkowski
#7 lore raw

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

In reply to Krzysztof Błaszkowski

Hi Krzysztof,

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

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

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

Thanks,
Christoph

---

Quoted 1 line

From a510a0e366e8bae7f825d131ad6f6f74dd4bef01 Mon Sep 17 00:00:00 2001

From: =?UTF-8?q?Krzysztof=20B=C5=82aszkowski?= <[email protected]>
Date: Tue, 31 May 2016 08:45:13 +0200
Subject: freevxfs: handle big endian HP-UX file systems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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

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

---
 fs/freevxfs/vxfs.h        | 177 ++++++++++++++++++++++++++--------------------
 fs/freevxfs/vxfs_bmap.c   |  70 ++++++++++--------
 fs/freevxfs/vxfs_dir.h    |  17 ++---
 fs/freevxfs/vxfs_fshead.c |   5 +-
 fs/freevxfs/vxfs_fshead.h |  28 ++++----
 fs/freevxfs/vxfs_inode.c  |  31 +++++++-
 fs/freevxfs/vxfs_inode.h  | 140 +++++++++++++++++++-----------------
 fs/freevxfs/vxfs_lookup.c |  34 +++++----
 fs/freevxfs/vxfs_olt.c    |  15 ++--
 fs/freevxfs/vxfs_olt.h    |  70 +++++++++---------
 fs/freevxfs/vxfs_super.c  | 101 ++++++++++++++++++--------
 11 files changed, 409 insertions(+), 279 deletions(-)
fs/freevxfs/vxfs.h +101 -76
index c8a9265..4b561de 100644
@@ -38,13 +38,6 @@
  */
 #include <linux/types.h>
 
-
-/*
- * Data types for use with the VxFS ondisk format.
- */
-typedef	int32_t		vx_daddr_t;
-typedef int32_t		vx_ino_t;
-
 /*
  * Superblock magic number (vxfs_super->vs_magic).
  */
@@ -60,6 +53,14 @@ typedef int32_t		vx_ino_t;
  */
 #define VXFS_NEFREE		32
 
+enum vxfs_byte_order {
+	VXFS_BO_LE,
+	VXFS_BO_BE,
+};
+
+typedef __u16 __bitwise __fs16;
+typedef __u32 __bitwise __fs32;
+typedef __u64 __bitwise __fs64;
 
 /*
  * VxFS superblock (disk).
@@ -71,83 +72,83 @@ struct vxfs_sb {
 	 * Lots of this fields are no more used by version 2
 	 * and never filesystems.
 	 */
-	u_int32_t	vs_magic;		/* Magic number */
-	int32_t		vs_version;		/* VxFS version */
-	u_int32_t	vs_ctime;		/* create time - secs */
-	u_int32_t	vs_cutime;		/* create time - usecs */
-	int32_t		__unused1;		/* unused */
-	int32_t		__unused2;		/* unused */
-	vx_daddr_t	vs_old_logstart;	/* obsolete */
-	vx_daddr_t	vs_old_logend;		/* obsolete */
-	int32_t		vs_bsize;		/* block size */
-	int32_t		vs_size;		/* number of blocks */
-	int32_t		vs_dsize;		/* number of data blocks */
-	u_int32_t	vs_old_ninode;		/* obsolete */
-	int32_t		vs_old_nau;		/* obsolete */
-	int32_t		__unused3;		/* unused */
-	int32_t		vs_old_defiextsize;	/* obsolete */
-	int32_t		vs_old_ilbsize;		/* obsolete */
-	int32_t		vs_immedlen;		/* size of immediate data area */
-	int32_t		vs_ndaddr;		/* number of direct extentes */
-	vx_daddr_t	vs_firstau;		/* address of first AU */
-	vx_daddr_t	vs_emap;		/* offset of extent map in AU */
-	vx_daddr_t	vs_imap;		/* offset of inode map in AU */
-	vx_daddr_t	vs_iextop;		/* offset of ExtOp. map in AU */
-	vx_daddr_t	vs_istart;		/* offset of inode list in AU */
-	vx_daddr_t	vs_bstart;		/* offset of fdblock in AU */
-	vx_daddr_t	vs_femap;		/* aufirst + emap */
-	vx_daddr_t	vs_fimap;		/* aufirst + imap */
-	vx_daddr_t	vs_fiextop;		/* aufirst + iextop */
-	vx_daddr_t	vs_fistart;		/* aufirst + istart */
-	vx_daddr_t	vs_fbstart;		/* aufirst + bstart */
-	int32_t		vs_nindir;		/* number of entries in indir */
-	int32_t		vs_aulen;		/* length of AU in blocks */
-	int32_t		vs_auimlen;		/* length of imap in blocks */
-	int32_t		vs_auemlen;		/* length of emap in blocks */
-	int32_t		vs_auilen;		/* length of ilist in blocks */
-	int32_t		vs_aupad;		/* length of pad in blocks */
-	int32_t		vs_aublocks;		/* data blocks in AU */
-	int32_t		vs_maxtier;		/* log base 2 of aublocks */
-	int32_t		vs_inopb;		/* number of inodes per blk */
-	int32_t		vs_old_inopau;		/* obsolete */
-	int32_t		vs_old_inopilb;		/* obsolete */
-	int32_t		vs_old_ndiripau;	/* obsolete */
-	int32_t		vs_iaddrlen;		/* size of indirect addr ext. */
-	int32_t		vs_bshift;		/* log base 2 of bsize */
-	int32_t		vs_inoshift;		/* log base 2 of inobp */
-	int32_t		vs_bmask;		/* ~( bsize - 1 ) */
-	int32_t		vs_boffmask;		/* bsize - 1 */
-	int32_t		vs_old_inomask;		/* old_inopilb - 1 */
-	int32_t		vs_checksum;		/* checksum of V1 data */
+	__fs32		vs_magic;		/* Magic number */
+	__fs32		vs_version;		/* VxFS version */
+	__fs32		vs_ctime;		/* create time - secs */
+	__fs32		vs_cutime;		/* create time - usecs */
+	__fs32		__unused1;		/* unused */
+	__fs32		__unused2;		/* unused */
+	__fs32		vs_old_logstart;	/* obsolete */
+	__fs32		vs_old_logend;		/* obsolete */
+	__fs32		vs_bsize;		/* block size */
+	__fs32		vs_size;		/* number of blocks */
+	__fs32		vs_dsize;		/* number of data blocks */
+	__fs32		vs_old_ninode;		/* obsolete */
+	__fs32		vs_old_nau;		/* obsolete */
+	__fs32		__unused3;		/* unused */
+	__fs32		vs_old_defiextsize;	/* obsolete */
+	__fs32		vs_old_ilbsize;		/* obsolete */
+	__fs32		vs_immedlen;		/* size of immediate data area */
+	__fs32		vs_ndaddr;		/* number of direct extentes */
+	__fs32		vs_firstau;		/* address of first AU */
+	__fs32		vs_emap;		/* offset of extent map in AU */
+	__fs32		vs_imap;		/* offset of inode map in AU */
+	__fs32		vs_iextop;		/* offset of ExtOp. map in AU */
+	__fs32		vs_istart;		/* offset of inode list in AU */
+	__fs32		vs_bstart;		/* offset of fdblock in AU */
+	__fs32		vs_femap;		/* aufirst + emap */
+	__fs32		vs_fimap;		/* aufirst + imap */
+	__fs32		vs_fiextop;		/* aufirst + iextop */
+	__fs32		vs_fistart;		/* aufirst + istart */
+	__fs32		vs_fbstart;		/* aufirst + bstart */
+	__fs32		vs_nindir;		/* number of entries in indir */
+	__fs32		vs_aulen;		/* length of AU in blocks */
+	__fs32		vs_auimlen;		/* length of imap in blocks */
+	__fs32		vs_auemlen;		/* length of emap in blocks */
+	__fs32		vs_auilen;		/* length of ilist in blocks */
+	__fs32		vs_aupad;		/* length of pad in blocks */
+	__fs32		vs_aublocks;		/* data blocks in AU */
+	__fs32		vs_maxtier;		/* log base 2 of aublocks */
+	__fs32		vs_inopb;		/* number of inodes per blk */
+	__fs32		vs_old_inopau;		/* obsolete */
+	__fs32		vs_old_inopilb;		/* obsolete */
+	__fs32		vs_old_ndiripau;	/* obsolete */
+	__fs32		vs_iaddrlen;		/* size of indirect addr ext. */
+	__fs32		vs_bshift;		/* log base 2 of bsize */
+	__fs32		vs_inoshift;		/* log base 2 of inobp */
+	__fs32		vs_bmask;		/* ~( bsize - 1 ) */
+	__fs32		vs_boffmask;		/* bsize - 1 */
+	__fs32		vs_old_inomask;		/* old_inopilb - 1 */
+	__fs32		vs_checksum;		/* checksum of V1 data */
 	
 	/*
 	 * Version 1, writable
 	 */
-	int32_t		vs_free;		/* number of free blocks */
-	int32_t		vs_ifree;		/* number of free inodes */
-	int32_t		vs_efree[VXFS_NEFREE];	/* number of free extents by size */
-	int32_t		vs_flags;		/* flags ?!? */
-	u_int8_t	vs_mod;			/* filesystem has been changed */
-	u_int8_t	vs_clean;		/* clean FS */
-	u_int16_t	__unused4;		/* unused */
-	u_int32_t	vs_firstlogid;		/* mount time log ID */
-	u_int32_t	vs_wtime;		/* last time written - sec */
-	u_int32_t	vs_wutime;		/* last time written - usec */
-	u_int8_t	vs_fname[6];		/* FS name */
-	u_int8_t	vs_fpack[6];		/* FS pack name */
-	int32_t		vs_logversion;		/* log format version */
-	int32_t		__unused5;		/* unused */
+	__fs32		vs_free;		/* number of free blocks */
+	__fs32		vs_ifree;		/* number of free inodes */
+	__fs32		vs_efree[VXFS_NEFREE];	/* number of free extents by size */
+	__fs32		vs_flags;		/* flags ?!? */
+	__u8		vs_mod;			/* filesystem has been changed */
+	__u8		vs_clean;		/* clean FS */
+	__fs16		__unused4;		/* unused */
+	__fs32		vs_firstlogid;		/* mount time log ID */
+	__fs32		vs_wtime;		/* last time written - sec */
+	__fs32		vs_wutime;		/* last time written - usec */
+	__u8		vs_fname[6];		/* FS name */
+	__u8		vs_fpack[6];		/* FS pack name */
+	__fs32		vs_logversion;		/* log format version */
+	__u32		__unused5;		/* unused */
 	
 	/*
 	 * Version 2, Read-only
 	 */
-	vx_daddr_t	vs_oltext[2];		/* OLT extent and replica */
-	int32_t		vs_oltsize;		/* OLT extent size */
-	int32_t		vs_iauimlen;		/* size of inode map */
-	int32_t		vs_iausize;		/* size of IAU in blocks */
-	int32_t		vs_dinosize;		/* size of inode in bytes */
-	int32_t		vs_old_dniaddr;		/* indir levels per inode */
-	int32_t		vs_checksum2;		/* checksum of V2 RO */
+	__fs32		vs_oltext[2];		/* OLT extent and replica */
+	__fs32		vs_oltsize;		/* OLT extent size */
+	__fs32		vs_iauimlen;		/* size of inode map */
+	__fs32		vs_iausize;		/* size of IAU in blocks */
+	__fs32		vs_dinosize;		/* size of inode in bytes */
+	__fs32		vs_old_dniaddr;		/* indir levels per inode */
+	__fs32		vs_checksum2;		/* checksum of V2 RO */
 
 	/*
 	 * Actually much more...
@@ -168,8 +169,32 @@ struct vxfs_sb_info {
 	ino_t			vsi_fshino;	/* fileset header inode */
 	daddr_t			vsi_oltext;	/* OLT extent */
 	daddr_t			vsi_oltsize;	/* OLT size */
+	enum vxfs_byte_order	byte_order;
 };
 
+static inline u16 fs16_to_cpu(struct vxfs_sb_info *sbi, __fs16 a)
+{
+	if (sbi->byte_order == VXFS_BO_BE)
+		return be16_to_cpu((__force __be16)a);
+	else
+		return le16_to_cpu((__force __le16)a);
+}
+
+static inline u32 fs32_to_cpu(struct vxfs_sb_info *sbi, __fs32 a)
+{
+	if (sbi->byte_order == VXFS_BO_BE)
+		return be32_to_cpu((__force __be32)a);
+	else
+		return le32_to_cpu((__force __le32)a);
+}
+
+static inline u64 fs64_to_cpu(struct vxfs_sb_info *sbi, __fs64 a)
+{
+	if (sbi->byte_order == VXFS_BO_BE)
+		return be64_to_cpu((__force __be64)a);
+	else
+		return le64_to_cpu((__force __le64)a);
+}
 
 /*
  * File modes.  File types above 0xf000 are vxfs internal only, they should
fs/freevxfs/vxfs_bmap.c +42 -28

153 lines not on this page · raw message

fs/freevxfs/vxfs_dir.h +9 -8
index aaf1fb0..acc5477 100644
@@ -48,9 +48,9 @@
  * Linux driver for now.
  */
 struct vxfs_dirblk {
-	u_int16_t	d_free;		/* free space in dirblock */
-	u_int16_t	d_nhash;	/* no of hash chains */
-	u_int16_t	d_hash[1];	/* hash chain */
+	__fs16		d_free;		/* free space in dirblock */
+	__fs16		d_nhash;	/* no of hash chains */
+	__fs16		d_hash[1];	/* hash chain */
 };
 
 /*
@@ -63,10 +63,10 @@ struct vxfs_dirblk {
  * VxFS directory entry.
  */
 struct vxfs_direct {
-	vx_ino_t	d_ino;			/* inode number */
-	u_int16_t	d_reclen;		/* record length */
-	u_int16_t	d_namelen;		/* d_name length */
-	u_int16_t	d_hashnext;		/* next hash entry */
+	__fs32		d_ino;			/* inode number */
+	__fs16		d_reclen;		/* record length */
+	__fs16		d_namelen;		/* d_name length */
+	__fs16		d_hashnext;		/* next hash entry */
 	char		d_name[VXFS_NAMELEN];	/* name */
 };
 
@@ -87,6 +87,7 @@ struct vxfs_direct {
 /*
  * VXFS_DIRBLKOV is the overhead of a specific dirblock.
  */
-#define VXFS_DIRBLKOV(dbp)	((sizeof(short) * dbp->d_nhash) + 4)
+#define VXFS_DIRBLKOV(sbi, dbp)	\
+	((sizeof(short) * fs16_to_cpu(sbi, dbp->d_nhash)) + 4)
 
 #endif /* _VXFS_DIR_H_ */
fs/freevxfs/vxfs_fshead.c +3 -2
index c9a6a94..e7501cb 100644
@@ -153,7 +153,8 @@ vxfs_read_fshead(struct super_block *sbp)
 	vxfs_dumpfsh(pfp);
 #endif
 
-	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
+	tip = vxfs_blkiget(sbp, infp->vsi_iext,
+			fs32_to_cpu(infp, sfp->fsh_ilistino[0]));
 	if (!tip)
 		goto out_free_pfp;
 
@@ -169,7 +170,7 @@ vxfs_read_fshead(struct super_block *sbp)
 		goto out_iput_stilist;
 	}
 
-	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
+	tip = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0]));
 	if (!tip)
 		goto out_iput_stilist;
 	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
fs/freevxfs/vxfs_fshead.h +14 -14
index ead0d64..a786cc5 100644
@@ -42,20 +42,20 @@
  * Fileset header 
  */
 struct vxfs_fsh {
-	u_int32_t	fsh_version;		/* fileset header version */
-	u_int32_t	fsh_fsindex;		/* fileset index */
-	u_int32_t	fsh_time;		/* modification time - sec */
-	u_int32_t	fsh_utime;		/* modification time - usec */
-	u_int32_t	fsh_extop;		/* extop flags */
-	vx_ino_t	fsh_ninodes;		/* allocated inodes */
-	u_int32_t	fsh_nau;		/* number of IAUs */
-	u_int32_t	fsh_old_ilesize;	/* old size of ilist */
-	u_int32_t	fsh_dflags;		/* flags */
-	u_int32_t	fsh_quota;		/* quota limit */
-	vx_ino_t	fsh_maxinode;		/* maximum inode number */
-	vx_ino_t	fsh_iauino;		/* IAU inode */
-	vx_ino_t	fsh_ilistino[2];	/* ilist inodes */
-	vx_ino_t	fsh_lctino;		/* link count table inode */
+	__fs32		fsh_version;		/* fileset header version */
+	__fs32		fsh_fsindex;		/* fileset index */
+	__fs32		fsh_time;		/* modification time - sec */
+	__fs32		fsh_utime;		/* modification time - usec */
+	__fs32		fsh_extop;		/* extop flags */
+	__fs32		fsh_ninodes;		/* allocated inodes */
+	__fs32		fsh_nau;		/* number of IAUs */
+	__fs32		fsh_old_ilesize;	/* old size of ilist */
+	__fs32		fsh_dflags;		/* flags */
+	__fs32		fsh_quota;		/* quota limit */
+	__fs32		fsh_maxinode;		/* maximum inode number */
+	__fs32		fsh_iauino;		/* IAU inode */
+	__fs32		fsh_ilistino[2];	/* ilist inodes */
+	__fs32		fsh_lctino;		/* link count table inode */
 
 	/*
 	 * Slightly more fields follow, but they
fs/freevxfs/vxfs_inode.c +29 -2
index 3e2ccad..15de300 100644
@@ -68,6 +68,33 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
 }
 #endif
 
+static inline void dip2vip_cpy(struct vxfs_sb_info *sbi,
+		struct vxfs_inode_info *vip, struct vxfs_dinode *dip)
+{
+	vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode);
+	vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink);
+	vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid);
+	vip->vii_gid = fs32_to_cpu(sbi, dip->vdi_gid);
+	vip->vii_size = fs64_to_cpu(sbi, dip->vdi_size);
+	vip->vii_atime = fs32_to_cpu(sbi, dip->vdi_atime);
+	vip->vii_autime = fs32_to_cpu(sbi, dip->vdi_autime);
+	vip->vii_mtime = fs32_to_cpu(sbi, dip->vdi_mtime);
+	vip->vii_mutime = fs32_to_cpu(sbi, dip->vdi_mutime);
+	vip->vii_ctime = fs32_to_cpu(sbi, dip->vdi_ctime);
+	vip->vii_cutime = fs32_to_cpu(sbi, dip->vdi_cutime);
+	vip->vii_orgtype = dip->vdi_orgtype;
+
+	vip->vii_blocks = fs32_to_cpu(sbi, dip->vdi_blocks);
+	vip->vii_gen = fs32_to_cpu(sbi, dip->vdi_gen);
+
+	if (VXFS_ISDIR(vip))
+		vip->vii_dotdot = fs32_to_cpu(sbi, dip->vdi_dotdot);
+	else if (!VXFS_ISREG(vip) && !VXFS_ISLNK(vip))
+		vip->vii_rdev = fs32_to_cpu(sbi, dip->vdi_rdev);
+
+	/* don't endian swap the fields that differ by orgtype */
+	memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org));
+}
 
 /**
  * vxfs_blkiget - find inode based on extent #
@@ -102,7 +129,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
 		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
 			goto fail;
 		dip = (struct vxfs_dinode *)(bp->b_data + offset);
-		memcpy(vip, dip, sizeof(*vip));
+		dip2vip_cpy(VXFS_SBI(sbp), vip, dip);
 #ifdef DIAGNOSTIC
 		vxfs_dumpi(vip, ino);
 #endif
@@ -144,7 +171,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
 		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
 			goto fail;
 		dip = (struct vxfs_dinode *)(kaddr + offset);
-		memcpy(vip, dip, sizeof(*vip));
+		dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip);
 #ifdef DIAGNOSTIC
 		vxfs_dumpi(vip, ino);
 #endif
fs/freevxfs/vxfs_inode.h +74 -66

180 lines not on this page · raw message

fs/freevxfs/vxfs_lookup.c +22 -12
index 6d576b9..09e93b3 100644
@@ -74,9 +74,10 @@ dir_blocks(struct inode *ip)
  * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
  */
 static inline int
-vxfs_match(int len, const char * const name, struct vxfs_direct *de)
+vxfs_match(struct vxfs_sb_info *sbi, int len, const char *const name,
+		struct vxfs_direct *de)
 {
-	if (len != de->d_namelen)
+	if (len != fs16_to_cpu(sbi, de->d_namelen))
 		return 0;
 	if (!de->d_ino)
 		return 0;
@@ -84,9 +85,10 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de)
 }
 
 static inline struct vxfs_direct *
-vxfs_next_entry(struct vxfs_direct *de)
+vxfs_next_entry(struct vxfs_sb_info *sbi, struct vxfs_direct *de)
 {
-	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
+	return ((struct vxfs_direct *)
+		((char *)de + fs16_to_cpu(sbi, de->d_reclen)));
 }
 
 /**
@@ -106,6 +108,7 @@ vxfs_next_entry(struct vxfs_direct *de)
 static struct vxfs_direct *
 vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
 {
+	struct vxfs_sb_info		*sbi = VXFS_SBI(ip->i_sb);
 	u_long				npages, page, nblocks, pblocks, block;
 	u_long				bsize = ip->i_sb->s_blocksize;
 	const char			*name = dp->d_name.name;
@@ -133,14 +136,16 @@ vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
 			limit = baddr + bsize - VXFS_DIRLEN(1);
 			
 			dbp = (struct vxfs_dirblk *)baddr;
-			de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp));
+			de = (struct vxfs_direct *)
+				(baddr + VXFS_DIRBLKOV(sbi, dbp));
 
-			for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
+			for (; (caddr_t)de <= limit;
+					de = vxfs_next_entry(sbi, de)) {
 				if (!de->d_reclen)
 					break;
 				if (!de->d_ino)
 					continue;
-				if (vxfs_match(namelen, name, de)) {
+				if (vxfs_match(sbi, namelen, name, de)) {
 					*ppp = pp;
 					return (de);
 				}
@@ -173,7 +178,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
 
 	de = vxfs_find_entry(dip, dp, &pp);
 	if (de) {
-		ino = de->d_ino;
+		ino = fs32_to_cpu(VXFS_SBI(dip->i_sb), de->d_ino);
 		kunmap(pp);
 		put_page(pp);
 	}
@@ -232,10 +237,12 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 {
 	struct inode		*ip = file_inode(fp);
 	struct super_block	*sbp = ip->i_sb;
+	struct vxfs_sb_info	*sbi = VXFS_SBI(sbp);
 	u_long			bsize = sbp->s_blocksize;
 	u_long			page, npages, block, pblocks, nblocks, offset;
 	loff_t			pos;
 
+
 	if (ctx->pos == 0) {
 		if (!dir_emit_dot(fp, ctx))
 			return 0;
@@ -280,9 +287,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 			de = (struct vxfs_direct *)
 				(offset ?
 				 (kaddr + offset) :
-				 (baddr + VXFS_DIRBLKOV(dbp)));
+				 (baddr + VXFS_DIRBLKOV(sbi, dbp)));
 
-			for (; (char *)de <= limit; de = vxfs_next_entry(de)) {
+			for (; (char *)de <= limit;
+					de = vxfs_next_entry(sbi, de)) {
 				if (!de->d_reclen)
 					break;
 				if (!de->d_ino)
@@ -290,8 +298,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 
 				offset = (char *)de - kaddr;
 				ctx->pos = ((page << PAGE_SHIFT) | offset) + 2;
-				if (!dir_emit(ctx, de->d_name, de->d_namelen,
-					de->d_ino, DT_UNKNOWN)) {
+				if (!dir_emit(ctx, de->d_name,
+						fs16_to_cpu(sbi, de->d_namelen),
+						fs32_to_cpu(sbi, de->d_ino),
+						DT_UNKNOWN)) {
 					vxfs_put_page(pp);
 					return 0;
 				}
fs/freevxfs/vxfs_olt.c +7 -8
index 049500847..813da66 100644
@@ -43,14 +43,14 @@ static inline void
 vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
 {
 	BUG_ON(infp->vsi_fshino);
-	infp->vsi_fshino = fshp->olt_fsino[0];
+	infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]);
 }
 
 static inline void
 vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
 {
 	BUG_ON(infp->vsi_iext);
-	infp->vsi_iext = ilistp->olt_iext[0]; 
+	infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]);
 }
 
 static inline u_long
@@ -81,13 +81,12 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
 	struct vxfs_olt		*op;
 	char			*oaddr, *eaddr;
 
-
 	bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
 	if (!bp || !bp->b_data)
 		goto fail;
 
 	op = (struct vxfs_olt *)bp->b_data;
-	if (op->olt_magic != VXFS_OLT_MAGIC) {
+	if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) {
 		printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
 		goto fail;
 	}
@@ -102,14 +101,14 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
 		goto fail;
 	}
 
-	oaddr = bp->b_data + op->olt_size;
+	oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
 	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
 
 	while (oaddr < eaddr) {
 		struct vxfs_oltcommon	*ocp =
 			(struct vxfs_oltcommon *)oaddr;
 		
-		switch (ocp->olt_type) {
+		switch (fs32_to_cpu(infp, ocp->olt_type)) {
 		case VXFS_OLT_FSHEAD:
 			vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
 			break;
@@ -118,11 +117,11 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
 			break;
 		}
 
-		oaddr += ocp->olt_size;
+		oaddr += fs32_to_cpu(infp, ocp->olt_size);
 	}
 
 	brelse(bp);
-	return 0;
+	return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
 
 fail:
 	brelse(bp);
fs/freevxfs/vxfs_olt.h +35 -35

118 lines not on this page · raw message

fs/freevxfs/vxfs_super.c +73 -28

152 lines not on this page · raw message

Signature · 1 line
2.1.4
#8 lore raw

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

Hi Christoph,

Quoted 4 lines · Christoph Hellwig

Hi Krzysztof,

I found some time to go over the patches and spent that on the byte swap one.

Thanks.

Quoted 3 lines

I like it in general, but I'd really like to keep sparse
[1] happy to be able to static type check for it, so I reworked it a bit.

okay.

Quoted 1 line

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

many thanks.

Quoted 3 lines

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

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

Quoted 3 lines

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

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

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

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

"

vxfs_lookup.c +4 -2
@@ -298,8 +306,10 @@
 
 				offset = (char *)de - kaddr;
 				ctx->pos = ((page << PAGE_SHIFT) | offset) + 2;
-				if (!dir_emit(ctx, de->d_name, de->d_namelen,
-					de->d_ino, DT_UNKNOWN)) {
+				if (!dir_emit(ctx, de->d_name,
+						fs16_to_cpu(sbi, de->d_namelen),
+						fs32_to_cpu(sbi, de->d_ino),
+						DT_UNKNOWN)) {
 					vxfs_put_page(pp);
 					return 0;
 				}

"

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

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

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

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

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

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

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

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

If so then let me do this.

Quoted 1,225 lines

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

Thanks,
Christoph

---

Quoted 1 line

From a510a0e366e8bae7f825d131ad6f6f74dd4bef01 Mon Sep 17 00:00:00 2001

From: =?UTF-8?q?Krzysztof=20B=C5=82aszkowski?= <[email protected]>
Date: Tue, 31 May 2016 08:45:13 +0200
Subject: freevxfs: handle big endian HP-UX file systems
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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

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

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

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

Hi Krzysztof,

Quoted 6 lines

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

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

Quoted 2 lines

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

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

Quoted 5 lines

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

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

Quoted 3 lines

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

I think all readdir structures are fixed up now, please check.

Quoted 9 lines

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

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

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

Quoted 2 lines

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

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

#10 lore raw

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

Hi Christoph,

Quoted 9 lines · Christoph Hellwig

Hi Krzysztof,

Quoted 6 lines

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

Quoted 4 lines

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

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

Quoted 9 lines
Quoted 3 lines

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

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

indeed, I realized this.

Quoted 8 lines
Quoted 5 lines

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

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

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

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

Quoted 6 lines
Quoted 4 lines

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

I think all readdir structures are fixed up now, please check.

right.

Quoted 11 lines
Quoted 10 lines

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

Quoted 10 lines

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

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

Quoted 2 lines

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

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

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

Quoted 2 lines

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

Thanks. yes, the old readdir has a bug. this time my change logs are more verbose.

Signature · 1 line
Krzysztof Blaszkowski
#11 lore raw

Re: freevxfs: hp-ux support. patchset r3, 2/4

Quoted 1 line

From 01d4fc410f9a9f011eec55055b341c3aa52bfb4e Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 1 Jun 2016 09:17:13 +0200
Subject: [PATCH 2/3] inode cache mgmt

Proper inode allocation policy requires to use super_operations.alloc_inode and .destroy_inode callbacks. This solution requires file system specific inode structure to be derived from generic struct inode.
Because old approach of allocating generic inode private data is proper no longer the vxfs_blkiget()/_stiget() had to be redesigned and these functions return now the generic inode pointer. This change impacted vxfs_read_fshead() and it was also a time to fix bugs in read_fshead's error handling path like kfree(kmem_cache_alloc()) in the old code.

---
 fs/freevxfs/vxfs.h        |    8 ---
 fs/freevxfs/vxfs_bmap.c   |    5 +-
 fs/freevxfs/vxfs_extern.h |   19 +++---
 fs/freevxfs/vxfs_fshead.c |  107 ++++++++++++++------------------
 fs/freevxfs/vxfs_inode.c  |  153 +++++++++++++++++++++++++--------------------
 fs/freevxfs/vxfs_inode.h  |   16 +++++-
 fs/freevxfs/vxfs_super.c  |   43 ++++++-------
 7 files changed, 182 insertions(+), 169 deletions(-)
fs/freevxfs/vxfs.h +0 -8
index 4b561de..8b0d1a2 100644
@@ -155,7 +155,6 @@ struct vxfs_sb {
 	 */
 };
 
-
 /*
  * In core superblock filesystem private data for VxFS.
  */
@@ -272,13 +271,6 @@ enum {
 #define VXFS_ISIMMED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_IMMED)
 #define VXFS_ISTYPED(ip)	VXFS_IS_ORG((ip), VXFS_ORG_TYPED)
 
-
-/*
- * Get filesystem private data from VFS inode.
- */
-#define VXFS_INO(ip) \
-	((struct vxfs_inode_info *)(ip)->i_private)
-
 /*
  * Get filesystem private data from VFS superblock.
  */
fs/freevxfs/vxfs_bmap.c +3 -2
index 1fd41cf..333093c 100644
@@ -99,8 +99,9 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 
 		brelse(buf);
 		return bno;
-	} else
-		printk(KERN_WARNING "no matching indir?");
+	} else {
+		printk(KERN_WARNING "%s:%d no matching indir?\n", __func__, __LINE__);
+	}
 
 	return 0;
 
fs/freevxfs/vxfs_extern.h +11 -8
index 881aa3d..9648735 100644
@@ -55,15 +55,18 @@ 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 *);
-extern void			vxfs_put_fake_inode(struct inode *);
-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 struct inode *vxfs_blkiget(struct super_block *, u_long, ino_t);
+extern struct inode *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 int vxfs_ii_cache_init(void);
+extern void vxfs_ii_cache_destroy(void);
+extern struct inode *vxfs_inode_alloc(struct super_block *sb);
+
 
 /* vxfs_lookup.c */
 extern const struct inode_operations	vxfs_dir_inode_ops;
fs/freevxfs/vxfs_fshead.c +47 -60

157 lines not on this page · raw message

fs/freevxfs/vxfs_inode.c +86 -67

242 lines not on this page · raw message

fs/freevxfs/vxfs_inode.h +15 -1
index 3a29662..f372677 100644
@@ -37,7 +37,6 @@
  * inodes of the Veritas Filesystem.
  */
 
-
 #define VXFS_ISIZE		0x100		/* Inode size */
 
 #define VXFS_NDADDR		10		/* Number of direct addrs in inode */
@@ -178,6 +177,12 @@ struct vxfs_inode_info {
 	} vii_org;
 };
 
+struct vxfs_vfs_inode {
+	struct inode ino;
+	struct vxfs_inode_info cpufs_ino;
+};
+
+
 #define vii_rdev	vii_ftarea.rdev
 #define vii_dotdot	vii_ftarea.dotdot
 
@@ -185,4 +190,13 @@ struct vxfs_inode_info {
 #define vii_ext4	vii_org.ext4
 #define vii_typed	vii_org.typed
 
+/*
+ * Get filesystem private data from VFS inode.
+ */
+static inline struct vxfs_inode_info *VXFS_INO(struct inode *i)
+{
+	return &(container_of(i, struct vxfs_vfs_inode, ino))->cpufs_ino;
+}
+
+
 #endif /* _VXFS_INODE_H_ */
fs/freevxfs/vxfs_super.c +20 -23

90 lines not on this page · raw message

Signature · 1 line
1.7.3.4
Quoted 15 lines
Quoted 3 lines

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

Thanks. yes, the old readdir has a bug. this time my change logs are more verbose.

Signature · 6 lines
Krzysztof Blaszkowski

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Krzysztof Blaszkowski
#12 lore raw

Re: freevxfs: hp-ux support. patchset r3 3/4

In reply to Krzysztof Błaszkowski
Quoted 1 line

From d3f13779deb42928ad1652604b941801fd8444cd Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 1 Jun 2016 09:17:43 +0200
Subject: [PATCH 3/3] readdir fix

the patch makes algorithm of walking over directory records simple because it is linear. The idea is to evaluate page relative number, file system block number inside the mapped page, and finally current directory record offset from single index (pos or ctx->pos) advanced by size of directory record (and the length of dirblk record at beginning of every fs block). Thus the inner "for" (old code) is not necessary. Furthermore, lack of the inner for fixes the issue with accessing kaddr one block size beyond mapped page. correct "for" should look like this:
"for ( ; ... block < pblocks ; block++)" : "<" vs "<="
let's suppose pblocks is 4, thus last block would be 4 (old "for") which stands for that 5th block would be parsed and this resulted in adding some random garbage to e.g. ls output. it used to happen that some files were missing in the directory list.

anyway the "for" is no longer needed and the vxfs directory holding almost 2900 files was useful to verify the readdir().

---
 fs/freevxfs/vxfs_lookup.c |  268 +++++++++++++++++++++------------------------
 1 files changed, 125 insertions(+), 143 deletions(-)
fs/freevxfs/vxfs_lookup.c +125 -143
index 31bcebe..c9de653 100644
@@ -61,42 +61,8 @@ 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(struct vxfs_sb_info *sbi, int len, const char *const name,
-		struct vxfs_direct *de)
-{
-	if (len != fs16_to_cpu(sbi, 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_sb_info *sbi, struct vxfs_direct *de)
-{
-	return ((struct vxfs_direct *)
-		((char *)de + fs16_to_cpu(sbi, de->d_reclen)));
-}
 
 /**
  * vxfs_find_entry - find a mathing directory entry for a dentry
@@ -115,53 +81,65 @@ vxfs_next_entry(struct vxfs_sb_info *sbi, struct vxfs_direct *de)
 static struct vxfs_direct *
 vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
 {
-	struct vxfs_sb_info		*sbi = VXFS_SBI(ip->i_sb);
-	u_long				npages, page, nblocks, pblocks, block;
-	u_long				bsize = ip->i_sb->s_blocksize;
-	const char			*name = dp->d_name.name;
-	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(sbi, dbp));
-
-			for (; (caddr_t)de <= limit;
-					de = vxfs_next_entry(sbi, de)) {
-				if (!de->d_reclen)
-					break;
-				if (!de->d_ino)
-					continue;
-				if (vxfs_match(sbi, 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;
+	struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb);
+
+	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(sbi, 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(sbi, de->d_reclen);
+			pos += fs16_to_cpu(sbi, de->d_reclen);
+			if (!de->d_ino) {
+				continue;
+			}
+
+			if (namelen != fs16_to_cpu(sbi, 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;
 }
 
 /**
@@ -181,7 +159,7 @@ 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) {
@@ -189,7 +167,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
 		kunmap(pp);
 		page_cache_release(pp);
 	}
-	
+
 	return (ino);
 }
 
@@ -212,17 +190,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;
 }
 
@@ -244,80 +222,84 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
 {
 	struct inode		*ip = file_inode(fp);
 	struct super_block	*sbp = ip->i_sb;
-	struct vxfs_sb_info	*sbi = VXFS_SBI(sbp);
 	u_long			bsize = sbp->s_blocksize;
-	u_long			page, npages, block, pblocks, nblocks, offset;
-	loff_t			pos;
-
+	loff_t			pos, limit;
+	struct vxfs_sb_info	*sbi = VXFS_SBI(sbp);
 
 	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(sbi, dbp)));
-
-			for (; (char *)de <= limit;
-					de = vxfs_next_entry(sbi, 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(sbi, de->d_namelen),
-						fs32_to_cpu(sbi, 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(sbi, 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(sbi, de->d_reclen);
+			pos += fs16_to_cpu(sbi, de->d_reclen);
+			if (!de->d_ino) {
+				continue;
+			}
+
+			rc = dir_emit(ctx, de->d_name, fs16_to_cpu(sbi, de->d_namelen),
+				fs32_to_cpu(sbi, de->d_ino), DT_UNKNOWN);
+			if (!rc) {
+				/* the dir entry was not submitted, so fix pos. */
+				pos -= fs16_to_cpu(sbi, 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;
 }
+
Signature · 1 line
1.7.3.4
Quoted 12 lines

Thanks. yes, the old readdir has a bug. this time my change logs are more verbose.

Signature · 6 lines
Krzysztof Blaszkowski

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Krzysztof Blaszkowski
#13 lore raw

Re: freevxfs: hp-ux support. patchset r3 4/4

In reply to Krzysztof Błaszkowski
Quoted 1 line

From 802178068cf8bbf8a7c9c4b4efbb6a4108b1946b Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Wed, 1 Jun 2016 10:13:00 +0200
Subject: [PATCH 4/4] the credits

---
 fs/freevxfs/Kconfig       |   10 +++++++++-
 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 +++++-
 6 files changed, 29 insertions(+), 2 deletions(-)
fs/freevxfs/Kconfig +9 -1
index 8dc1cd5..a4c9075 100644
@@ -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.
fs/freevxfs/vxfs.h +3 -0
index 8b0d1a2..6f89a32 100644
@@ -2,6 +2,9 @@
  * Copyright (c) 2000-2001 Christoph Hellwig.
  * All rights reserved.
  *
+ * (c) 2016 Krzysztof Blaszkowski
+ *       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:
fs/freevxfs/vxfs_fshead.c +4 -0
index 0f3a806..dd4e394 100644
@@ -2,6 +2,10 @@
  * Copyright (c) 2000-2001 Christoph Hellwig.
  * All rights reserved.
  *
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ *       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:
fs/freevxfs/vxfs_inode.c +4 -0
index 582d652..845b881 100644
@@ -2,6 +2,10 @@
  * Copyright (c) 2000-2001 Christoph Hellwig.
  * All rights reserved.
  *
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ *       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:
fs/freevxfs/vxfs_lookup.c +4 -0
index c9de653..ab495f5 100644
@@ -2,6 +2,10 @@
  * Copyright (c) 2000-2001 Christoph Hellwig.
  * All rights reserved.
  *
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ *       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:
fs/freevxfs/vxfs_super.c +5 -1
index efa3bc2..ece9691 100644
@@ -2,6 +2,10 @@
  * Copyright (c) 2000-2001 Christoph Hellwig.
  * All rights reserved.
  *
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ *       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");
 
Signature · 1 line
1.7.3.4
Quoted 15 lines
Quoted 3 lines

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

Thanks. yes, the old readdir has a bug. this time my change logs are more verbose.

Signature · 6 lines
Krzysztof Blaszkowski

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Krzysztof Blaszkowski
#14 lore raw

Re: freevxfs: hp-ux support. patchset r3 3/4

Review

Quoted 5 lines
(quoted diff) +0 -5
-static inline u_long
-dir_pages(struct inode *inode)
-{
-	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-}

This is still against a different tree than my branch, right?

Othwrwise the readdir changes look fine minus a few very minor codingstyle issues that I'll happily fix up

Quoted 9 lines
(quoted diff) +1 -2
@@ -212,17 +190,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);
-				 

Review vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags) · line 204

Quoted 10 lines
(quoted diff) +2 -1
+
 	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;

This change is unrelated to the readdir changes, and it looks incorrect to me. If we don't find an inode for a lookup we still want to call d_add with a NULL inode - this creates a so called negative dentry, which tells the VFS to not bother looking up this file name next time.

#15 lore raw

Re: freevxfs: hp-ux support. patchset r3 3/4

Quoted 7 lines · Christoph Hellwig

Review

Quoted 5 lines
(quoted diff) +0 -5
-static inline u_long
-dir_pages(struct inode *inode)
-{
-	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-}

This is still against a different tree than my branch, right?

yes, it is.

Quoted 3 lines

Othwrwise the readdir changes look fine minus a few very minor codingstyle issues that I'll happily fix up

many thanks :)

Quoted 17 lines
Quoted 17 lines
(quoted diff) +3 -2
@@ -212,17 +190,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);
Quoted 8 lines

Review vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags) · line 204

Quoted 3 lines
(quoted diff) +0 -1
 	}
-	d_add(dp, ip);
 	return NULL;

This change is unrelated to the readdir changes, and it looks incorrect to me. If we don't find an inode for a lookup we still want to call d_add with a NULL inode - this creates a so called negative dentry, which tells the VFS to not bother looking up this file name next time.

I see. Thank you for explanation of d_add() semantics, so you are right, it was wrong change.

Quoted 4 lines

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

Signature · 1 line
Krzysztof Blaszkowski
#16 lore raw

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

In reply to Christoph Hellwig

Hi Christoph,

Quoted 11 lines · Christoph Hellwig

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

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

Quoted 2 lines

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

Please take a look at the branch above.

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

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

so .. whose patch is more accurate ?

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

Thanks,

Signature · 1 line
Krzysztof Blaszkowski
#17 lore raw

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

Quoted 6 lines · Krzysztof B??aszkowski

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

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

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

Quoted 2 lines

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

In my tree the visibility is in vxfs_super.c only. Given that the alloc/destroy methods are super operations that seems to fit better as they can have local scope, too.

#18 lore raw

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

Quoted 9 lines · Christoph Hellwig
Quoted 6 lines · Krzysztof B??aszkowski

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

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

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

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

Quoted 7 lines
Quoted 3 lines

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

In my tree the visibility is in vxfs_super.c only. Given that the alloc/destroy methods are super operations that seems to fit better as they can have local scope, too.

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

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

Signature · 1 line
Krzysztof Blaszkowski
#19 lore raw

Re: freevxfs: hp-ux support. ( 1cce17017970c07) patchset 1/4

In reply to Christoph Hellwig

Christoph,

Here are these kfree()s.

Quoted 1 line

From e82e484492af7a66b25510718783529bad345cfc Mon Sep 17 00:00:00 2001

From: KB <[email protected]>
Date: Fri, 10 Jun 2016 09:52:19 +0200
Subject: [PATCH 1/4] vxfs_read_fshead() memory leak fixed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

every successful mount two structs vxfs_fsh were not released

---
 fs/freevxfs/vxfs_fshead.c | 2 ++
 1 file changed, 2 insertions(+)
fs/freevxfs/vxfs_fshead.c +2 -0
index 69a10d6..a4610a7 100644
@@ -172,6 +172,8 @@ vxfs_read_fshead(struct super_block *sbp)
 		goto out_iput_ilist;
 	}
 
+	kfree(pfp);
+	kfree(sfp);
 	return 0;
 
  out_iput_ilist:
Signature · 1 line
2.8.3
Quoted 20 lines · Christoph Hellwig
Quoted 6 lines · Krzysztof B??aszkowski

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

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

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

Quoted 2 lines

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

In my tree the visibility is in vxfs_super.c only. Given that the alloc/destroy methods are super operations that seems to fit better as they can have local scope, too.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

Signature · 1 line
Krzysztof Blaszkowski