From: "Krzysztof Błaszkowski" <kb@sysmikro.com.pl>
To: Christoph Hellwig <hch@infradead.org>,
Carlos Maiolino <cmaiolino@redhat.com>
Cc: linux-fsdevel@vger.kernel.org
Subject: freevxfs
Date: Wed, 25 May 2016 23:27:27 +0200 [thread overview]
Message-ID: <1464211647.25693.27.camel@linux-q3cb.site> (raw)
[-- Attachment #1: Type: text/plain, Size: 593 bytes --]
Hi,
Please find included patchset which addresses all major features we have
discussed (unless I forgot about something).
I verified correctness of operation with my regression tests and HP-UX's
vxfs image. No difference spotted. However I can't do this with SCO
image because I do not have such. I reckon that it is highly possible
that SCO image will work as usual because the only difference is data
endianess and offset of super block.
I included for reference these scripts just in case one is curious.
(chksum8-sorted.log comes from hp-ux's cksum)
Regards,
--
Krzysztof Blaszkowski
[-- Attachment #2: 0001-kconfig-note.patch --]
[-- Type: text/x-patch, Size: 1615 bytes --]
>From 3d3b4e1ed5df014ae191e0566ff86a17d7d9ac05 Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 21:50:11 +0200
Subject: [PATCH 1/7] kconfig note
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/Kconfig | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/fs/freevxfs/Kconfig b/fs/freevxfs/Kconfig
index 8dc1cd5..a4c9075 100644
--- a/fs/freevxfs/Kconfig
+++ b/fs/freevxfs/Kconfig
@@ -5,12 +5,20 @@ config VXFS_FS
FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
file system format. VERITAS VxFS(TM) is the standard file system
of SCO UnixWare (and possibly others) and optionally available
- for Sunsoft Solaris, HP-UX and many other operating systems.
+ for Sunsoft Solaris, HP-UX and many other operating systems. However
+ these particular OS implementations of vxfs may differ in on-disk
+ data endianess and/or superblock offset. The vxfs module has been
+ tested with SCO UnixWare and HP-UX B.10.20 (pa-risc 1.1 arch.)
Currently only readonly access is supported.
NOTE: the file system type as used by mount(1), mount(2) and
fstab(5) is 'vxfs' as it describes the file system format, not
the actual driver.
+ There is a userspace utility for HP-UX logical volumes which makes
+ creating HP-UX logical volumes easy from HP-UX disk block device file
+ or regular file with image of the disk. See:
+ https://sourceforge.net/projects/linux-vxfs/
+
To compile this as a module, choose M here: the module will be
called freevxfs. If unsure, say N.
--
1.7.3.4
[-- Attachment #3: 0002-cpu-endian-vs-file-system-endian.patch --]
[-- Type: text/x-patch, Size: 17532 bytes --]
>From c617f6bceedc2f68c62e7432f12b59124bab34f7 Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 22:12:05 +0200
Subject: [PATCH 2/7] cpu endian vs file system endian
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/vxfs.h | 25 +++++++++++-
fs/freevxfs/vxfs_bmap.c | 24 ++++++-----
fs/freevxfs/vxfs_fshead.c | 25 +++++++++++-
fs/freevxfs/vxfs_inode.c | 61 +++++++++++++++++++++++++++-
fs/freevxfs/vxfs_inode.h | 8 ++--
fs/freevxfs/vxfs_lookup.c | 15 ++++++-
fs/freevxfs/vxfs_olt.c | 15 ++++---
fs/freevxfs/vxfs_super.c | 97 ++++++++++++++++++++++++++++++++-------------
8 files changed, 215 insertions(+), 55 deletions(-)
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
index c8a9265..5dc8949 100644
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -152,7 +152,7 @@ struct vxfs_sb {
/*
* Actually much more...
*/
-};
+} __packed;
/*
@@ -168,9 +168,32 @@ struct vxfs_sb_info {
ino_t vsi_fshino; /* fileset header inode */
daddr_t vsi_oltext; /* OLT extent */
daddr_t vsi_oltsize; /* OLT size */
+ int byte_order;
+ int silent;
+};
+
+enum {
+ BO_LE = 1,
+ BO_BE
};
+static inline u32 fs32_to_cpu(int bo, u32 a)
+{
+ return (bo == BO_BE) ? be32_to_cpu(a) : le32_to_cpu(a);
+}
+
+static inline u16 fs16_to_cpu(int bo, u16 a)
+{
+ return (bo == BO_BE) ? be16_to_cpu(a) : le16_to_cpu(a);
+}
+
+static inline u64 fs64_to_cpu(int bo, u64 a)
+{
+ return (bo == BO_BE) ? be64_to_cpu(a) : le64_to_cpu(a);
+}
+
+
/*
* File modes. File types above 0xf000 are vxfs internal only, they should
* not be passed back to higher levels of the system. vxfs file types must
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
index f86fd3c..95afd98 100644
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -92,7 +92,8 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
goto fail_buf;
indir = (u32 *)buf->b_data;
- bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize);
+ bno = fs32_to_cpu(VXFS_SBI(sb)->byte_order,
+ indir[(bn/indsize) % (indsize*bn)]) + (bn % indsize);
brelse(buf);
return bno;
@@ -130,6 +131,7 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
struct buffer_head *bp = NULL;
daddr_t pblock = 0;
int i;
+ int bo = VXFS_SBI(ip->i_sb)->byte_order;
for (i = 0; i < size * VXFS_TYPED_PER_BLOCK(ip->i_sb); i++) {
struct vxfs_typed *typ;
@@ -142,24 +144,24 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
typ = ((struct vxfs_typed *)bp->b_data) +
(i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
- off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK);
+ off = fs64_to_cpu(bo, typ->vt_hdr) & VXFS_TYPED_OFFSETMASK;
if (block < off) {
brelse(bp);
continue;
}
- switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) {
+ switch ((u_int32_t)(fs64_to_cpu(bo, typ->vt_hdr) >> VXFS_TYPED_TYPESHIFT)) {
case VXFS_TYPED_INDIRECT:
- pblock = vxfs_bmap_indir(ip, typ->vt_block,
- typ->vt_size, block - off);
+ pblock = vxfs_bmap_indir(ip, fs32_to_cpu(bo, typ->vt_block),
+ fs32_to_cpu(bo, typ->vt_size), block - off);
if (pblock == -2)
break;
goto out;
case VXFS_TYPED_DATA:
- if ((block - off) >= typ->vt_size)
+ if ((block - off) >= fs32_to_cpu(bo, typ->vt_size))
break;
- pblock = (typ->vt_block + block - off);
+ pblock = fs32_to_cpu(bo, typ->vt_block) + block - off;
goto out;
case VXFS_TYPED_INDIRECT_DEV4:
case VXFS_TYPED_DATA_DEV4: {
@@ -168,12 +170,14 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n",
- (unsigned long long) typ4->vd4_block,
- (unsigned long long) typ4->vd4_size,
- typ4->vd4_dev);
+ (unsigned long long) fs64_to_cpu(bo, typ4->vd4_block),
+ (unsigned long long) fs64_to_cpu(bo, typ4->vd4_size),
+ fs32_to_cpu(bo, typ4->vd4_dev));
goto fail;
}
default:
+ printk(KERN_ERR "%s:%d vt_hdr %llu\n", __func__, __LINE__,
+ fs64_to_cpu(bo, typ->vt_hdr));
BUG();
}
brelse(bp);
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index c9a6a94..6cbdde7 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -60,6 +60,29 @@ vxfs_dumpfsh(struct vxfs_fsh *fhp)
}
#endif
+#define VXFS_FS32(field1, field2) fhp->field1 = fs32_to_cpu(bo, dbh->field2)
+static inline void dbh2fhp(struct vxfs_fsh *fhp, void *_dbh, int bo)
+{
+ struct vxfs_fsh *dbh = (struct vxfs_fsh *)_dbh;
+
+ VXFS_FS32(fsh_version, fsh_version);
+ VXFS_FS32(fsh_fsindex, fsh_fsindex);
+ VXFS_FS32(fsh_time, fsh_time);
+ VXFS_FS32(fsh_utime, fsh_utime);
+ VXFS_FS32(fsh_extop, fsh_extop);
+ VXFS_FS32(fsh_ninodes, fsh_ninodes);
+ VXFS_FS32(fsh_nau, fsh_nau);
+ VXFS_FS32(fsh_old_ilesize, fsh_old_ilesize);
+ VXFS_FS32(fsh_dflags, fsh_dflags);
+ VXFS_FS32(fsh_quota, fsh_quota);
+ VXFS_FS32(fsh_maxinode, fsh_maxinode);
+ VXFS_FS32(fsh_iauino, fsh_iauino);
+ VXFS_FS32(fsh_ilistino[0], fsh_ilistino[0]);
+ VXFS_FS32(fsh_ilistino[1], fsh_ilistino[1]);
+ VXFS_FS32(fsh_lctino, fsh_lctino);
+}
+
+
/**
* vxfs_getfsh - read fileset header into memory
* @ip: the (fake) fileset header inode
@@ -83,7 +106,7 @@ vxfs_getfsh(struct inode *ip, int which)
if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
goto out;
- memcpy(fhp, bp->b_data, sizeof(*fhp));
+ dbh2fhp(fhp, bp->b_data, VXFS_SBI(ip->i_sb)->byte_order);
put_bh(bp);
return (fhp);
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 363e3ae..53b8757 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -67,6 +67,63 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino)
}
#endif
+#define VXFS_FS32(field1, field2) vip->field1 = fs32_to_cpu(bo, dip->field2)
+#define VXFS_FS64(field1, field2) vip->field1 = fs64_to_cpu(bo, dip->field2)
+#define VXFS_FS16(field1, field2) vip->field1 = fs16_to_cpu(bo, dip->field2)
+
+static inline void dip2vip_cpy(struct vxfs_inode_info *vip, struct vxfs_dinode *dip, int bo)
+{
+ int j;
+
+ VXFS_FS32(vdi_mode, vdi_mode);
+ VXFS_FS32(vdi_nlink, vdi_nlink);
+ VXFS_FS32(vdi_uid, vdi_uid);
+ VXFS_FS32(vdi_gid, vdi_gid);
+ VXFS_FS64(vdi_size, vdi_size);
+ VXFS_FS32(vdi_atime, vdi_atime);
+ VXFS_FS32(vdi_autime, vdi_autime);
+ VXFS_FS32(vdi_mtime, vdi_mtime);
+ VXFS_FS32(vdi_mutime, vdi_mutime);
+ VXFS_FS32(vdi_ctime, vdi_ctime);
+ VXFS_FS32(vdi_cutime, vdi_cutime);
+ vip->vdi_aflags = dip->vdi_aflags;
+ vip->vdi_orgtype = dip->vdi_orgtype;
+ VXFS_FS16(vdi_eopflags, vdi_eopflags);
+ VXFS_FS32(vdi_eopdata, vdi_eopdata);
+
+ VXFS_FS32(vdi_ftarea.i_regular.reserved, vdi_ftarea.i_regular.reserved);
+ VXFS_FS32(vdi_ftarea.i_regular.fixextsize, vdi_ftarea.i_regular.fixextsize);
+ VXFS_FS32(vdi_blocks, vdi_blocks);
+ VXFS_FS32(vdi_gen, vdi_gen);
+ VXFS_FS64(vdi_version, vdi_version);
+
+ switch (dip->vdi_orgtype) {
+ case VXFS_ORG_EXT4:
+ VXFS_FS32(vdi_org.ext4.ve4_spare, vdi_org.ext4.ve4_spare);
+ VXFS_FS32(vdi_org.ext4.ve4_indsize, vdi_org.ext4.ve4_indsize);
+ for (j = 0; j < VXFS_NIADDR; j++) {
+ VXFS_FS32(vdi_org.ext4.ve4_indir[j], vdi_org.ext4.ve4_indir[j]);
+ }
+ for (j = 0; j < VXFS_NDADDR; j++) {
+ VXFS_FS32(vdi_org.ext4.ve4_direct[j].extent, vdi_org.ext4.ve4_direct[j].extent);
+ VXFS_FS32(vdi_org.ext4.ve4_direct[j].size, vdi_org.ext4.ve4_direct[j].size);
+ }
+ break;
+ case VXFS_ORG_IMMED:
+ memcpy(&vip->vdi_org.immed, &dip->vdi_org.immed, sizeof(vip->vdi_org.immed));
+ break;
+ case VXFS_ORG_TYPED:
+ for (j = 0; j < VXFS_NTYPED; j++) {
+ VXFS_FS64(vdi_org.typed[j].vt_hdr, vdi_org.typed[j].vt_hdr);
+ VXFS_FS32(vdi_org.typed[j].vt_block, vdi_org.typed[j].vt_block);
+ VXFS_FS32(vdi_org.typed[j].vt_size, vdi_org.typed[j].vt_size);
+ }
+ break;
+ };
+
+ VXFS_FS32(vdi_iattrino, vdi_iattrino);
+}
+
/**
* vxfs_blkiget - find inode based on extent #
@@ -101,7 +158,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
goto fail;
dip = (struct vxfs_dinode *)(bp->b_data + offset);
- memcpy(vip, dip, sizeof(*vip));
+ dip2vip_cpy(vip, dip, VXFS_SBI(sbp)->byte_order);
#ifdef DIAGNOSTIC
vxfs_dumpi(vip, ino);
#endif
@@ -143,7 +200,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
goto fail;
dip = (struct vxfs_dinode *)(kaddr + offset);
- memcpy(vip, dip, sizeof(*vip));
+ dip2vip_cpy(vip, dip, VXFS_SBI(ilistp->i_sb)->byte_order);
#ifdef DIAGNOSTIC
vxfs_dumpi(vip, ino);
#endif
diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h
index 240aeb1..9a2c376 100644
--- a/fs/freevxfs/vxfs_inode.h
+++ b/fs/freevxfs/vxfs_inode.h
@@ -77,13 +77,13 @@ struct vxfs_ext4 {
vx_daddr_t extent; /* Extent number */
int32_t size; /* Size of extent */
} ve4_direct[VXFS_NDADDR];
-};
+} __packed;
struct vxfs_typed {
u_int64_t vt_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
vx_daddr_t vt_block; /* Extent block */
int32_t vt_size; /* Size in blocks */
-};
+} __packed;
struct vxfs_typed_dev4 {
u_int64_t vd4_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
@@ -91,7 +91,7 @@ struct vxfs_typed_dev4 {
u_int64_t vd4_size; /* Size in blocks */
int32_t vd4_dev; /* Device ID */
u_int32_t __pad1;
-};
+} __packed;
/*
* The inode as contained on the physical device.
@@ -134,7 +134,7 @@ struct vxfs_dinode {
struct vxfs_typed typed[VXFS_NTYPED];
} vdi_org;
u_int32_t vdi_iattrino;
-};
+} __packed;
#define vdi_rdev vdi_ftarea.rdev
#define vdi_dotdot vdi_ftarea.dotdot
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 99c7f0a..cea158a 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -96,6 +96,15 @@ vxfs_next_entry(struct vxfs_direct *de)
return ((struct vxfs_direct *)((char*)de + de->d_reclen));
}
+/*
+ * VXFS_dirblk_ovh is the overhead of a specific dirblock.
+ */
+static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo)
+{
+ return (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
+}
+
+
/**
* vxfs_find_entry - find a mathing directory entry for a dentry
* @ip: directory inode
@@ -242,6 +251,8 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
u_long bsize = sbp->s_blocksize;
u_long page, npages, block, pblocks, nblocks, offset;
loff_t pos;
+ int bo = VXFS_SBI(sbp)->byte_order;
+
if (ctx->pos == 0) {
if (!dir_emit_dot(fp, ctx))
@@ -297,8 +308,8 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
offset = (char *)de - kaddr;
ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
- if (!dir_emit(ctx, de->d_name, de->d_namelen,
- de->d_ino, DT_UNKNOWN)) {
+ if (!dir_emit(ctx, de->d_name, fs16_to_cpu(bo, de->d_namelen),
+ fs32_to_cpu(bo, de->d_ino), DT_UNKNOWN)) {
vxfs_put_page(pp);
return 0;
}
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 0495008..6b50188 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -43,14 +43,14 @@ static inline void
vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
{
BUG_ON(infp->vsi_fshino);
- infp->vsi_fshino = fshp->olt_fsino[0];
+ infp->vsi_fshino = fs32_to_cpu(infp->byte_order, fshp->olt_fsino[0]);
}
static inline void
vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
{
BUG_ON(infp->vsi_iext);
- infp->vsi_iext = ilistp->olt_iext[0];
+ infp->vsi_iext = fs32_to_cpu(infp->byte_order, ilistp->olt_iext[0]);
}
static inline u_long
@@ -80,6 +80,7 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
struct buffer_head *bp;
struct vxfs_olt *op;
char *oaddr, *eaddr;
+ int bo = infp->byte_order;
bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
@@ -87,7 +88,7 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
goto fail;
op = (struct vxfs_olt *)bp->b_data;
- if (op->olt_magic != VXFS_OLT_MAGIC) {
+ if (fs32_to_cpu(bo, op->olt_magic) != VXFS_OLT_MAGIC) {
printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
goto fail;
}
@@ -102,14 +103,14 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
goto fail;
}
- oaddr = bp->b_data + op->olt_size;
+ oaddr = bp->b_data + fs32_to_cpu(bo, op->olt_size);
eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
while (oaddr < eaddr) {
struct vxfs_oltcommon *ocp =
(struct vxfs_oltcommon *)oaddr;
- switch (ocp->olt_type) {
+ switch (fs32_to_cpu(bo, ocp->olt_type)) {
case VXFS_OLT_FSHEAD:
vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
break;
@@ -118,11 +119,11 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
break;
}
- oaddr += ocp->olt_size;
+ oaddr += fs32_to_cpu(bo, ocp->olt_size);
}
brelse(bp);
- return 0;
+ return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
fail:
brelse(bp);
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 7ca8c75..6a19802 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -109,14 +109,15 @@ static int
vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
{
struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb);
+ struct vxfs_sb *raw_sb = infp->vsi_raw;
bufp->f_type = VXFS_SUPER_MAGIC;
bufp->f_bsize = dentry->d_sb->s_blocksize;
- bufp->f_blocks = infp->vsi_raw->vs_dsize;
- bufp->f_bfree = infp->vsi_raw->vs_free;
+ bufp->f_blocks = fs32_to_cpu(infp->byte_order, raw_sb->vs_dsize);
+ bufp->f_bfree = fs32_to_cpu(infp->byte_order, raw_sb->vs_free);
bufp->f_bavail = 0;
bufp->f_files = 0;
- bufp->f_ffree = infp->vsi_raw->vs_ifree;
+ bufp->f_ffree = fs32_to_cpu(infp->byte_order, raw_sb->vs_ifree);
bufp->f_namelen = VXFS_NAMELEN;
return 0;
@@ -129,6 +130,46 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data)
return 0;
}
+
+static int vxfs_try_sb_magic(struct super_block *sbp, int blk, u32 magic)
+{
+ struct buffer_head *bp;
+ struct vxfs_sb *rsbp;
+ struct vxfs_sb_info *infp = VXFS_SBI(sbp);
+ int rc = -ENOMEM;
+
+ bp = sb_bread(sbp, blk);
+ do {
+ if (!bp || !buffer_mapped(bp)) {
+ if (!infp->silent) {
+ printk(KERN_WARNING "vxfs: unable to read"
+ " disk superblock at %d\n", blk);
+ }
+ break;
+ }
+
+ rc = -EINVAL;
+ rsbp = (struct vxfs_sb *)bp->b_data;
+ if (rsbp->vs_magic != magic) {
+ if (!infp->silent)
+ printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
+ break;
+ }
+
+ rc = 0;
+ infp->vsi_raw = rsbp;
+ infp->vsi_bp = bp;
+ } while (0);
+
+ if (rc) {
+ infp->vsi_raw = NULL;
+ infp->vsi_bp = NULL;
+ brelse(bp);
+ }
+
+ return rc;
+}
+
/**
* vxfs_read_super - read superblock into memory and initialize filesystem
* @sbp: VFS superblock (to fill)
@@ -149,10 +190,10 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
{
struct vxfs_sb_info *infp;
struct vxfs_sb *rsbp;
- struct buffer_head *bp = NULL;
u_long bsize;
struct inode *root;
int ret = -EINVAL;
+ u32 j;
sbp->s_flags |= MS_RDONLY;
@@ -162,48 +203,47 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
return -ENOMEM;
}
+ infp->silent = silent;
bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
if (!bsize) {
printk(KERN_WARNING "vxfs: unable to set blocksize\n");
goto out;
}
- bp = sb_bread(sbp, 1);
- if (!bp || !buffer_mapped(bp)) {
- if (!silent) {
- printk(KERN_WARNING
- "vxfs: unable to read disk superblock\n");
+ sbp->s_fs_info = infp;
+ do {
+ if (!vxfs_try_sb_magic(sbp, 1, cpu_to_le32(VXFS_SUPER_MAGIC))) {
+ infp->byte_order = BO_LE; /* SCO */
+ break;
+ }
+
+ if (!vxfs_try_sb_magic(sbp, 8, cpu_to_be32(VXFS_SUPER_MAGIC))) {
+ infp->byte_order = BO_BE; /* HP-UX pa-risc likely */
+ break;
}
- goto out;
- }
- rsbp = (struct vxfs_sb *)bp->b_data;
- if (rsbp->vs_magic != VXFS_SUPER_MAGIC) {
- if (!silent)
- printk(KERN_NOTICE "vxfs: WRONG superblock magic\n");
goto out;
- }
+ } while (0);
- if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) {
- printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n",
- rsbp->vs_version);
+ rsbp = infp->vsi_raw;
+ j = fs32_to_cpu(infp->byte_order, rsbp->vs_version);
+ if ((j < 2 || j > 4) && !silent) {
+ printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j);
goto out;
}
#ifdef DIAGNOSTIC
- printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", rsbp->vs_version);
+ printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
printk(KERN_DEBUG "vxfs: blocksize: %d\n", rsbp->vs_bsize);
#endif
- sbp->s_magic = rsbp->vs_magic;
- sbp->s_fs_info = infp;
+ sbp->s_magic = fs32_to_cpu(infp->byte_order, rsbp->vs_magic);
- infp->vsi_raw = rsbp;
- infp->vsi_bp = bp;
- infp->vsi_oltext = rsbp->vs_oltext[0];
- infp->vsi_oltsize = rsbp->vs_oltsize;
+ infp->vsi_oltext = fs32_to_cpu(infp->byte_order, rsbp->vs_oltext[0]);
+ infp->vsi_oltsize = fs32_to_cpu(infp->byte_order, rsbp->vs_oltsize);
- if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) {
+ j = fs32_to_cpu(infp->byte_order, rsbp->vs_bsize);
+ if (!sb_set_blocksize(sbp, j)) {
printk(KERN_WARNING "vxfs: unable to set final block size\n");
goto out;
}
@@ -237,7 +277,8 @@ out_free_ilist:
vxfs_put_fake_inode(infp->vsi_ilist);
vxfs_put_fake_inode(infp->vsi_stilist);
out:
- brelse(bp);
+ if (infp->vsi_bp)
+ brelse(infp->vsi_bp);
kfree(infp);
return ret;
}
--
1.7.3.4
[-- Attachment #4: 0003-missing-kfree-and-kfree-on-kmem_cache-obj.patch --]
[-- Type: text/x-patch, Size: 2605 bytes --]
>From b95e9b749b85be347c953ce33d2b3c5dde4e56d6 Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 22:13:20 +0200
Subject: [PATCH 3/7] missing kfree and kfree on kmem_cache obj
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/vxfs_extern.h | 1 +
fs/freevxfs/vxfs_fshead.c | 8 +++++---
fs/freevxfs/vxfs_inode.c | 5 +++++
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index 881aa3d..0a3ff86 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -64,6 +64,7 @@ extern struct vxfs_inode_info * vxfs_blkiget(struct super_block *, u_long, ino_t
extern struct vxfs_inode_info * vxfs_stiget(struct super_block *, ino_t);
extern struct inode * vxfs_iget(struct super_block *, ino_t);
extern void vxfs_evict_inode(struct inode *);
+extern void vxfs_inode_info_free(struct vxfs_inode_info *vip);
/* vxfs_lookup.c */
extern const struct inode_operations vxfs_dir_inode_ops;
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index 6cbdde7..67ca2f9 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -183,7 +183,7 @@ vxfs_read_fshead(struct super_block *sbp)
infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
if (!infp->vsi_stilist) {
printk(KERN_ERR "vxfs: unable to get structural list inode\n");
- kfree(tip);
+ vxfs_inode_info_free(tip);
goto out_free_pfp;
}
if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
@@ -198,7 +198,7 @@ vxfs_read_fshead(struct super_block *sbp)
infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
if (!infp->vsi_ilist) {
printk(KERN_ERR "vxfs: unable to get inode list inode\n");
- kfree(tip);
+ vxfs_inode_info_free(tip);
goto out_iput_stilist;
}
if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
@@ -206,6 +206,8 @@ vxfs_read_fshead(struct super_block *sbp)
VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
goto out_iput_ilist;
}
+ kfree(pfp);
+ kfree(sfp);
return 0;
@@ -221,6 +223,6 @@ vxfs_read_fshead(struct super_block *sbp)
iput(infp->vsi_fship);
return -EINVAL;
out_free_fship:
- kfree(vip);
+ vxfs_inode_info_free(vip);
return -EINVAL;
}
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 53b8757..16d8d27 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -415,3 +415,8 @@ vxfs_evict_inode(struct inode *ip)
clear_inode(ip);
call_rcu(&ip->i_rcu, vxfs_i_callback);
}
+
+void vxfs_inode_info_free(struct vxfs_inode_info *vip)
+{
+ kmem_cache_free(vxfs_inode_cachep, vip);
+}
--
1.7.3.4
[-- Attachment #5: 0004-super_operations.destroy_inode.patch --]
[-- Type: text/x-patch, Size: 2645 bytes --]
>From e4979c6a29eb79d59d8bc2eca9acc0d2b416780f Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 22:15:20 +0200
Subject: [PATCH 4/7] super_operations.destroy_inode
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/vxfs_extern.h | 1 +
fs/freevxfs/vxfs_inode.c | 16 ++++++++++++----
fs/freevxfs/vxfs_super.c | 1 +
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index 0a3ff86..4d8298b 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -65,6 +65,7 @@ extern struct vxfs_inode_info * vxfs_stiget(struct super_block *, ino_t);
extern struct inode * vxfs_iget(struct super_block *, ino_t);
extern void vxfs_evict_inode(struct inode *);
extern void vxfs_inode_info_free(struct vxfs_inode_info *vip);
+extern void vxfs_destroy_inode(struct inode *ip);
/* vxfs_lookup.c */
extern const struct inode_operations vxfs_dir_inode_ops;
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 16d8d27..9b45ad7 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -397,7 +397,15 @@ vxfs_iget(struct super_block *sbp, ino_t ino)
static void vxfs_i_callback(struct rcu_head *head)
{
struct inode *inode = container_of(head, struct inode, i_rcu);
- kmem_cache_free(vxfs_inode_cachep, inode->i_private);
+ void *priv = inode->i_private;
+
+ inode->i_private = NULL;
+ kmem_cache_free(vxfs_inode_cachep, priv);
+}
+
+void vxfs_destroy_inode(struct inode *ip)
+{
+ call_rcu(&ip->i_rcu, vxfs_i_callback);
}
/**
@@ -405,17 +413,17 @@ static void vxfs_i_callback(struct rcu_head *head)
* @ip: inode to discard.
*
* Description:
- * vxfs_evict_inode() is called on the final iput and frees the private
- * inode area.
+ * vxfs_evict_inode() is called on the final iput
*/
void
vxfs_evict_inode(struct inode *ip)
{
truncate_inode_pages_final(&ip->i_data);
+ invalidate_inode_buffers(ip);
clear_inode(ip);
- call_rcu(&ip->i_rcu, vxfs_i_callback);
}
+
void vxfs_inode_info_free(struct vxfs_inode_info *vip)
{
kmem_cache_free(vxfs_inode_cachep, vip);
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 6a19802..11a535a 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -59,6 +59,7 @@ static int vxfs_statfs(struct dentry *, struct kstatfs *);
static int vxfs_remount(struct super_block *, int *, char *);
static const struct super_operations vxfs_super_ops = {
+ .destroy_inode = vxfs_destroy_inode,
.evict_inode = vxfs_evict_inode,
.put_super = vxfs_put_super,
.statfs = vxfs_statfs,
--
1.7.3.4
[-- Attachment #6: 0005-refactoring-of-vxfs_readir-and-find_entry.patch --]
[-- Type: text/x-patch, Size: 8246 bytes --]
>From 4a6ae0e351b6046367bbd2939547f292ed2b6e47 Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 22:28:37 +0200
Subject: [PATCH 5/7] refactoring of vxfs_readir() and find_entry()
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/vxfs_lookup.c | 267 +++++++++++++++++++++------------------------
1 files changed, 124 insertions(+), 143 deletions(-)
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index cea158a..8eacb27 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -61,48 +61,6 @@ const struct file_operations vxfs_dir_operations = {
.iterate = vxfs_readdir,
};
-
-static inline u_long
-dir_pages(struct inode *inode)
-{
- return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-}
-
-static inline u_long
-dir_blocks(struct inode *ip)
-{
- u_long bsize = ip->i_sb->s_blocksize;
- return (ip->i_size + bsize - 1) & ~(bsize - 1);
-}
-
-/*
- * NOTE! unlike strncmp, vxfs_match returns 1 for success, 0 for failure.
- *
- * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
- */
-static inline int
-vxfs_match(int len, const char * const name, struct vxfs_direct *de)
-{
- if (len != de->d_namelen)
- return 0;
- if (!de->d_ino)
- return 0;
- return !memcmp(name, de->d_name, len);
-}
-
-static inline struct vxfs_direct *
-vxfs_next_entry(struct vxfs_direct *de)
-{
- return ((struct vxfs_direct *)((char*)de + de->d_reclen));
-}
-
-/*
- * VXFS_dirblk_ovh is the overhead of a specific dirblock.
- */
-static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo)
-{
- return (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
-}
/**
@@ -122,50 +80,65 @@ static inline u_long VXFS_dirblk_ovh(struct vxfs_dirblk *dbp, int bo)
static struct vxfs_direct *
vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
{
- u_long npages, page, nblocks, pblocks, block;
- u_long bsize = ip->i_sb->s_blocksize;
- const char *name = dp->d_name.name;
- int namelen = dp->d_name.len;
-
- npages = dir_pages(ip);
- nblocks = dir_blocks(ip);
- pblocks = VXFS_BLOCK_PER_PAGE(ip->i_sb);
-
- for (page = 0; page < npages; page++) {
- caddr_t kaddr;
- struct page *pp;
-
- pp = vxfs_get_page(ip->i_mapping, page);
- if (IS_ERR(pp))
- continue;
- kaddr = (caddr_t)page_address(pp);
-
- for (block = 0; block <= nblocks && block <= pblocks; block++) {
- caddr_t baddr, limit;
- struct vxfs_dirblk *dbp;
- struct vxfs_direct *de;
-
- baddr = kaddr + (block * bsize);
- limit = baddr + bsize - VXFS_DIRLEN(1);
-
- dbp = (struct vxfs_dirblk *)baddr;
- de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp));
-
- for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) {
- if (!de->d_reclen)
- break;
- if (!de->d_ino)
- continue;
- if (vxfs_match(namelen, name, de)) {
- *ppp = pp;
- return (de);
- }
+ u_long bsize = ip->i_sb->s_blocksize;
+ const char *name = dp->d_name.name;
+ int namelen = dp->d_name.len;
+ loff_t limit = VXFS_DIRROUND(ip->i_size);
+ struct vxfs_direct *de_exit = NULL;
+ loff_t pos = 0;
+ int bo = VXFS_SBI(ip->i_sb)->byte_order;
+
+ while (pos < limit) {
+ struct page *pp;
+ char *kaddr;
+ int pg_ofs = pos & ~PAGE_CACHE_MASK;
+
+ pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_CACHE_SHIFT);
+ if (IS_ERR(pp)) {
+ return NULL;
+ }
+ kaddr = (char *)page_address(pp);
+
+ while (pg_ofs < PAGE_SIZE && pos < limit) {
+ struct vxfs_direct *de;
+
+ if ((pos & (bsize - 1)) < 4) {
+ struct vxfs_dirblk *dbp =
+ (struct vxfs_dirblk *)(kaddr + (pos & ~PAGE_CACHE_MASK));
+ int overhead = (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
+
+ pos += overhead;
+ pg_ofs += overhead;
+ }
+ de = (struct vxfs_direct *)(kaddr + pg_ofs);
+
+ if (!de->d_reclen) {
+ pos += bsize - 1;
+ pos &= ~(bsize - 1);
+ break;
+ }
+
+ pg_ofs += fs16_to_cpu(bo, de->d_reclen);
+ pos += fs16_to_cpu(bo, de->d_reclen);
+ if (!de->d_ino) {
+ continue;
+ }
+
+ if (namelen != fs16_to_cpu(bo, de->d_namelen))
+ continue;
+ if (!memcmp(name, de->d_name, namelen)) {
+ *ppp = pp;
+ de_exit = de;
+ break;
}
}
- vxfs_put_page(pp);
+ if (!de_exit)
+ vxfs_put_page(pp);
+ else
+ break;
}
- return NULL;
+ return de_exit;
}
/**
@@ -185,15 +158,17 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
{
struct vxfs_direct *de;
struct page *pp;
- ino_t ino = 0;
+ ino_t ino = 0;
de = vxfs_find_entry(dip, dp, &pp);
if (de) {
- ino = de->d_ino;
+ int bo = VXFS_SBI(dip->i_sb)->byte_order;
+
+ ino = fs32_to_cpu(bo, de->d_ino);
kunmap(pp);
page_cache_release(pp);
}
-
+
return (ino);
}
@@ -225,8 +200,8 @@ vxfs_lookup(struct inode *dip, struct dentry *dp, unsigned int flags)
ip = vxfs_iget(dip->i_sb, ino);
if (IS_ERR(ip))
return ERR_CAST(ip);
+ d_add(dp, ip);
}
- d_add(dp, ip);
return NULL;
}
@@ -249,76 +224,82 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
struct inode *ip = file_inode(fp);
struct super_block *sbp = ip->i_sb;
u_long bsize = sbp->s_blocksize;
- u_long page, npages, block, pblocks, nblocks, offset;
- loff_t pos;
+ loff_t pos, limit;
int bo = VXFS_SBI(sbp)->byte_order;
-
if (ctx->pos == 0) {
if (!dir_emit_dot(fp, ctx))
- return 0;
- ctx->pos = 1;
+ goto out;
+ ctx->pos++;
}
if (ctx->pos == 1) {
if (!dir_emit(ctx, "..", 2, VXFS_INO(ip)->vii_dotdot, DT_DIR))
- return 0;
- ctx->pos = 2;
+ goto out;
+ ctx->pos++;
+ }
+
+ limit = VXFS_DIRROUND(ip->i_size);
+ if (ctx->pos > limit) {
+#if 0
+ ctx->pos = 0;
+#endif
+ goto out;
}
- pos = ctx->pos - 2;
-
- if (pos > VXFS_DIRROUND(ip->i_size))
- return 0;
-
- npages = dir_pages(ip);
- nblocks = dir_blocks(ip);
- pblocks = VXFS_BLOCK_PER_PAGE(sbp);
-
- page = pos >> PAGE_CACHE_SHIFT;
- offset = pos & ~PAGE_CACHE_MASK;
- block = (u_long)(pos >> sbp->s_blocksize_bits) % pblocks;
-
- for (; page < npages; page++, block = 0) {
- char *kaddr;
- struct page *pp;
-
- pp = vxfs_get_page(ip->i_mapping, page);
- if (IS_ERR(pp))
- continue;
+
+ pos = ctx->pos & ~3L;
+
+ while (pos < limit) {
+ struct page *pp;
+ char *kaddr;
+ int pg_ofs = pos & ~PAGE_CACHE_MASK;
+ int rc = 0;
+
+ pp = vxfs_get_page(ip->i_mapping, pos >> PAGE_CACHE_SHIFT);
+ if (IS_ERR(pp)) {
+ return -ENOMEM;
+ }
kaddr = (char *)page_address(pp);
- for (; block <= nblocks && block <= pblocks; block++) {
- char *baddr, *limit;
- struct vxfs_dirblk *dbp;
- struct vxfs_direct *de;
-
- baddr = kaddr + (block * bsize);
- limit = baddr + bsize - VXFS_DIRLEN(1);
-
- dbp = (struct vxfs_dirblk *)baddr;
- de = (struct vxfs_direct *)
- (offset ?
- (kaddr + offset) :
- (baddr + VXFS_DIRBLKOV(dbp)));
-
- for (; (char *)de <= limit; de = vxfs_next_entry(de)) {
- if (!de->d_reclen)
- break;
- if (!de->d_ino)
- continue;
-
- offset = (char *)de - kaddr;
- ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
- if (!dir_emit(ctx, de->d_name, fs16_to_cpu(bo, de->d_namelen),
- fs32_to_cpu(bo, de->d_ino), DT_UNKNOWN)) {
- vxfs_put_page(pp);
- return 0;
- }
+ while (pg_ofs < PAGE_SIZE && pos < limit) {
+ struct vxfs_direct *de;
+
+ if ((pos & (bsize - 1)) < 4) {
+ struct vxfs_dirblk *dbp =
+ (struct vxfs_dirblk *)(kaddr + (pos & ~PAGE_CACHE_MASK));
+ int overhead = (sizeof(short) * fs16_to_cpu(bo, dbp->d_nhash)) + 4;
+
+ pos += overhead;
+ pg_ofs += overhead;
+ }
+ de = (struct vxfs_direct *)(kaddr + pg_ofs);
+
+ if (!de->d_reclen) {
+ pos += bsize - 1;
+ pos &= ~(bsize - 1);
+ break;
+ }
+
+ pg_ofs += fs16_to_cpu(bo, de->d_reclen);
+ pos += fs16_to_cpu(bo, de->d_reclen);
+ if (!de->d_ino) {
+ continue;
+ }
+
+ rc = dir_emit(ctx, de->d_name, fs16_to_cpu(bo, de->d_namelen),
+ fs32_to_cpu(bo, de->d_ino), DT_UNKNOWN);
+ if (!rc) {
+ /* the dir entry was not submitted, so fix pos. */
+ pos -= fs16_to_cpu(bo, de->d_reclen);
+ break;
}
- offset = 0;
}
vxfs_put_page(pp);
- offset = 0;
+ if (!rc)
+ break;
}
- ctx->pos = ((page << PAGE_CACHE_SHIFT) | offset) + 2;
+
+ ctx->pos = pos | 2;
+
+out:
return 0;
}
--
1.7.3.4
[-- Attachment #7: 0006-static-cachep.patch --]
[-- Type: text/x-patch, Size: 3331 bytes --]
>From e7f68291aada1535016c767a4f5a5fcfb19a1de6 Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 22:41:22 +0200
Subject: [PATCH 6/7] static cachep
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/vxfs_extern.h | 4 +++-
fs/freevxfs/vxfs_inode.c | 24 +++++++++++++++++++++++-
fs/freevxfs/vxfs_super.c | 26 ++++++++++----------------
3 files changed, 36 insertions(+), 18 deletions(-)
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index 4d8298b..cc43fd0 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -55,7 +55,6 @@ extern const struct inode_operations vxfs_immed_symlink_iops;
/* vxfs_inode.c */
extern const struct address_space_operations vxfs_immed_aops;
-extern struct kmem_cache *vxfs_inode_cachep;
extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t);
extern struct inode * vxfs_get_fake_inode(struct super_block *,
struct vxfs_inode_info *);
@@ -66,6 +65,9 @@ extern struct inode * vxfs_iget(struct super_block *, ino_t);
extern void vxfs_evict_inode(struct inode *);
extern void vxfs_inode_info_free(struct vxfs_inode_info *vip);
extern void vxfs_destroy_inode(struct inode *ip);
+extern int vxfs_ii_cache_init(void);
+extern void vxfs_ii_cache_destroy(void);
+
/* vxfs_lookup.c */
extern const struct inode_operations vxfs_dir_inode_ops;
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 9b45ad7..73ac417 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -41,7 +41,7 @@
#include "vxfs_extern.h"
-struct kmem_cache *vxfs_inode_cachep;
+static struct kmem_cache *vxfs_inode_cachep;
#ifdef DIAGNOSTIC
@@ -428,3 +428,25 @@ void vxfs_inode_info_free(struct vxfs_inode_info *vip)
{
kmem_cache_free(vxfs_inode_cachep, vip);
}
+
+
+int vxfs_ii_cache_init(void)
+{
+ vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
+ sizeof(struct vxfs_inode_info), 0,
+ SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
+
+ return vxfs_inode_cachep ? 0 : -ENOMEM;
+}
+
+
+void vxfs_ii_cache_destroy(void)
+{
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
+ kmem_cache_destroy(vxfs_inode_cachep);
+}
+
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 11a535a..7579500 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -306,29 +306,23 @@ MODULE_ALIAS("vxfs");
static int __init
vxfs_init(void)
{
- int rv;
+ int rc = vxfs_ii_cache_init();
- vxfs_inode_cachep = kmem_cache_create("vxfs_inode",
- sizeof(struct vxfs_inode_info), 0,
- SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
- if (!vxfs_inode_cachep)
- return -ENOMEM;
- rv = register_filesystem(&vxfs_fs_type);
- if (rv < 0)
- kmem_cache_destroy(vxfs_inode_cachep);
- return rv;
+ if (!rc) {
+ rc = register_filesystem(&vxfs_fs_type);
+ if (rc < 0)
+ vxfs_ii_cache_destroy();
+ }
+ printk(KERN_DEBUG "%s: **** %s %s rc %d\n", __func__, __DATE__, __TIME__, rc);
+
+ return rc;
}
static void __exit
vxfs_cleanup(void)
{
unregister_filesystem(&vxfs_fs_type);
- /*
- * Make sure all delayed rcu free inodes are flushed before we
- * destroy cache.
- */
- rcu_barrier();
- kmem_cache_destroy(vxfs_inode_cachep);
+ vxfs_ii_cache_destroy();
}
module_init(vxfs_init);
--
1.7.3.4
[-- Attachment #8: 0007-the-credits.patch --]
[-- Type: text/x-patch, Size: 3314 bytes --]
>From 2c0008e9f2f4e62bb3e10eecad54e2a0140e0c4c Mon Sep 17 00:00:00 2001
From: KB <kb@sysmikro.com.pl>
Date: Wed, 25 May 2016 22:58:08 +0200
Subject: [PATCH 7/7] the credits
Signed-off-by: KB <kb@sysmikro.com.pl>
---
fs/freevxfs/vxfs.h | 3 +++
fs/freevxfs/vxfs_fshead.c | 4 ++++
fs/freevxfs/vxfs_inode.c | 4 ++++
fs/freevxfs/vxfs_lookup.c | 4 ++++
fs/freevxfs/vxfs_super.c | 6 +++++-
5 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
index 5dc8949..35f56b7 100644
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -2,6 +2,9 @@
* Copyright (c) 2000-2001 Christoph Hellwig.
* All rights reserved.
*
+ * (c) 2016 Krzysztof Blaszkowski
+ * Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index 67ca2f9..44b87d0 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -2,6 +2,10 @@
* Copyright (c) 2000-2001 Christoph Hellwig.
* All rights reserved.
*
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ * Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 73ac417..4c8a625 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -2,6 +2,10 @@
* Copyright (c) 2000-2001 Christoph Hellwig.
* All rights reserved.
*
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ * Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 8eacb27..173aeea 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -2,6 +2,10 @@
* Copyright (c) 2000-2001 Christoph Hellwig.
* All rights reserved.
*
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ * Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 7579500..bd121aa 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -2,6 +2,10 @@
* Copyright (c) 2000-2001 Christoph Hellwig.
* All rights reserved.
*
+ *
+ * (c) 2016 Krzysztof Blaszkowski
+ * Many bug fixes, improvements & tests with HP-UX B.10.20 (pa-risc)
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -48,7 +52,7 @@
#include "vxfs_inode.h"
-MODULE_AUTHOR("Christoph Hellwig");
+MODULE_AUTHOR("Christoph Hellwig, Krzysztof Blaszkowski");
MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
MODULE_LICENSE("Dual BSD/GPL");
--
1.7.3.4
[-- Attachment #9: Check.sh --]
[-- Type: application/x-shellscript, Size: 180 bytes --]
[-- Attachment #10: cksum8-sorted.log --]
[-- Type: text/x-log, Size: 5629 bytes --]
3531594148 32829 /usr/sprockets/bin/bw_map
3973234498 518896 /usr/sprockets/bin/cifslist
3973234498 518896 /usr/sprockets/bin/cifslogout
4171014129 518904 /usr/sprockets/bin/cifsmount
4171014129 518904 /usr/sprockets/bin/cifsumount
256627809 1171456 /usr/sprockets/bin/convert
4193697053 242843 /usr/sprockets/bin/createLicensingFiles
2780783712 51 /usr/sprockets/bin/createSprocFile
3285775584 825 /usr/sprockets/bin/dcexec
4073641898 94 /usr/sprockets/bin/defaultResources
4039074287 6610 /usr/sprockets/bin/disableNIS
313350104 20480 /usr/sprockets/bin/dos2ux
1872597524 65536 /usr/sprockets/bin/doschmod
1872597524 65536 /usr/sprockets/bin/doscp
1872597524 65536 /usr/sprockets/bin/dosdf
1872597524 65536 /usr/sprockets/bin/doslib
1872597524 65536 /usr/sprockets/bin/dosll
1872597524 65536 /usr/sprockets/bin/dosls
1872597524 65536 /usr/sprockets/bin/dosmkdir
1872597524 65536 /usr/sprockets/bin/dosrm
1872597524 65536 /usr/sprockets/bin/dosrmdir
1968087462 7112 /usr/sprockets/bin/enableNIS
3282246790 360 /usr/sprockets/bin/endexec
2151751185 553 /usr/sprockets/bin/endsession
3927613487 1115 /usr/sprockets/bin/env_var_sub
3738550324 157 /usr/sprockets/bin/format_dos
3888232633 172649 /usr/sprockets/bin/fppv
2279585942 466 /usr/sprockets/bin/getHostname
2946778792 5648 /usr/sprockets/bin/getSharedConnections
3306388627 20480 /usr/sprockets/bin/ibmsync
3041502972 28781 /usr/sprockets/bin/ipconfig700
3113659230 391815 /usr/sprockets/bin/kpp
908094753 24630 /usr/sprockets/bin/kxst
1329462070 36864 /usr/sprockets/bin/lanload
1015322628 36947 /usr/sprockets/bin/listener
486757159 339968 /usr/sprockets/bin/lmgrd
2620320940 339968 /usr/sprockets/bin/lmutil
951644065 243039 /usr/sprockets/bin/mattrib
951644065 243039 /usr/sprockets/bin/mbadblocks
951644065 243039 /usr/sprockets/bin/mcd
3650177936 951 /usr/sprockets/bin/mcheck
514586869 56 /usr/sprockets/bin/mcomp
951644065 243039 /usr/sprockets/bin/mcopy
951644065 243039 /usr/sprockets/bin/mdel
951644065 243039 /usr/sprockets/bin/mdeltree
951644065 243039 /usr/sprockets/bin/mdir
951644065 243039 /usr/sprockets/bin/mformat
951644065 243039 /usr/sprockets/bin/minfo
951644065 243039 /usr/sprockets/bin/mlabel
951644065 243039 /usr/sprockets/bin/mmd
951644065 243039 /usr/sprockets/bin/mmount
951644065 243039 /usr/sprockets/bin/mmove
951644065 243039 /usr/sprockets/bin/mpartition
662030829 1478557 /usr/sprockets/bin/mpv
951644065 243039 /usr/sprockets/bin/mrd
951644065 243039 /usr/sprockets/bin/mread
951644065 243039 /usr/sprockets/bin/mren
3443865238 32829 /usr/sprockets/bin/msgintcpt
951644065 243039 /usr/sprockets/bin/mtools
951644065 243039 /usr/sprockets/bin/mtoolstest
951644065 243039 /usr/sprockets/bin/mtype
951644065 243039 /usr/sprockets/bin/mwrite
1915353244 82 /usr/sprockets/bin/mxtar
951644065 243039 /usr/sprockets/bin/mzip
2033389047 379158 /usr/sprockets/bin/nmbd
1043940798 32843 /usr/sprockets/bin/nsbuild
421327339 32843 /usr/sprockets/bin/nsdump
2156955828 32843 /usr/sprockets/bin/nsquery
1030470949 28737 /usr/sprockets/bin/pciinfo
889541250 61560 /usr/sprockets/bin/pcipeek
1431205578 28737 /usr/sprockets/bin/pciprog
3351126604 126976 /usr/sprockets/bin/pkunzip
3351126604 126976 /usr/sprockets/bin/pkzip
2166142790 53390 /usr/sprockets/bin/probeload
694305221 41144 /usr/sprockets/bin/progflash
1141035887 445257 /usr/sprockets/bin/pv
974426301 3882 /usr/sprockets/bin/runnetscape
1879287959 1801 /usr/sprockets/bin/running
2273866242 74107 /usr/sprockets/bin/runroot
2616587298 79 /usr/sprockets/bin/runTouch
4222109660 875 /usr/sprockets/bin/samba
1912440105 24633 /usr/sprockets/bin/sbscrsvr
2558012300 3904 /usr/sprockets/bin/screensaverControl
4256537430 1780 /usr/sprockets/bin/sd-set_parms
1151924416 688 /usr/sprockets/bin/sendSignal
2744646624 32829 /usr/sprockets/bin/sessionDisallow
1227674200 1346161 /usr/sprockets/bin/sessionMgr
3332668870 98791 /usr/sprockets/bin/sessionWrapper
1477797090 82487 /usr/sprockets/bin/setlight
3759253613 1122 /usr/sprockets/bin/sharity
3313588847 3448000 /usr/sprockets/bin/sharityd
1569390236 24630 /usr/sprockets/bin/shmLock
3791448153 317300 /usr/sprockets/bin/smbclient
1018298877 506532 /usr/sprockets/bin/smbd
4009501079 45140 /usr/sprockets/bin/smtpclient
991996913 144424 /usr/sprockets/bin/starhw
3124681867 4311 /usr/sprockets/bin/startVNC
1468091312 919 /usr/sprockets/bin/startVNCviewer
304853428 1994350 /usr/sprockets/bin/sw_admin
304853428 1994350 /usr/sprockets/bin/sw_autoinstall
1455142555 123406 /usr/sprockets/bin/sw_copyfdset
2157175922 111102 /usr/sprockets/bin/sw_depot2bin
304853428 1994350 /usr/sprockets/bin/sw_install
304853428 1994350 /usr/sprockets/bin/sw_list
1842505403 7100 /usr/sprockets/bin/sw_makefdset
304853428 1994350 /usr/sprockets/bin/sw_remove
1743298644 2342 /usr/sprockets/bin/sw_rmprevious
1582083858 20548 /usr/sprockets/bin/sw_vendorfdset
178332129 1794 /usr/sprockets/bin/sysInfo
3657811479 1574 /usr/sprockets/bin/tgz
4018370132 36951 /usr/sprockets/bin/tp_license
1649141155 11843 /usr/sprockets/bin/updsharitycfg
2980018004 20480 /usr/sprockets/bin/ux2dos
3745508150 1318 /usr/sprockets/bin/uz
1348652714 32864 /usr/sprockets/bin/vncpasswd
4059637159 12757 /usr/sprockets/bin/vncserver
4128771573 366263 /usr/sprockets/bin/vncviewer
285011189 1526819 /usr/sprockets/bin/vp
589630079 387 /usr/sprockets/bin/vpexit
528762950 1132 /usr/sprockets/bin/xcopy
1793380080 521816 /usr/sprockets/bin/xscreensaver
24739470 145832 /usr/sprockets/bin/xscreensaver-command
4079099643 2167483 /usr/sprockets/bin/Xvnc
49651643 41091 /usr/sprockets/bin/yakdebug
2578809639 127914 /usr/sprockets/bin/yakhw
306877946 189649 /usr/sprockets/bin/yakserver
[-- Attachment #11: Test3d.sh --]
[-- Type: application/x-shellscript, Size: 923 bytes --]
next reply other threads:[~2016-05-25 21:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-25 21:27 Krzysztof Błaszkowski [this message]
2016-05-26 11:50 ` freevxfs Carlos Maiolino
2016-05-26 14:44 ` freevxfs Krzysztof Błaszkowski
-- strict thread matches above, loose matches on Subject: below --
2016-05-22 15:13 freevxfs Krzysztof Błaszkowski
2016-05-23 8:23 ` freevxfs Carlos Maiolino
2016-05-24 11:50 ` freevxfs Krzysztof Błaszkowski
2016-05-23 8:36 ` freevxfs Christoph Hellwig
2016-05-24 8:48 ` freevxfs Krzysztof Błaszkowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1464211647.25693.27.camel@linux-q3cb.site \
--to=kb@sysmikro.com.pl \
--cc=cmaiolino@redhat.com \
--cc=hch@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.