Hi Christoph, On Tue, 2016-05-31 at 05:25 -0700, Christoph Hellwig wrote: > Hi Krzysztof, > > I found some time to go over the patches and spent that on the byte > swap one. Thanks. > I like it in general, but I'd really like to keep sparse > [1] happy to be able to static type check for it, so I reworked it > a bit. okay. > I also used that as an opportunity to write a proper changelog, many thanks. > xpand your full name in the signed off line and fix up small deviations > from the Linux coding style. > once again thanks. yes, I will look at this further soon. > Can you check if this patch works for you and you are fine with it? > If so I'd like to commit it to a git tree and then work relative to it > for the other patches. I can check but here are my remarks: the dip2vip_cpy() does partial byte-swap from file system endian to cpu endian, so the union uses fs native endianess and this raises difficulty of using struct vxfs_inode_info to yet another level. Is this a good practice ? (apart from a benefit like some minor speed gain) Are there any real benefits from marking anything "bitwise" except that it is just another type ? I reckon that this is just reworked my 0001 patch and one of chunks does not apply to lookup.c " --- vxfs_lookup.c +++ vxfs_lookup.c @@ -298,8 +306,10 @@ offset = (char *)de - kaddr; ctx->pos = ((page << PAGE_SHIFT) | offset) + 2; - if (!dir_emit(ctx, de->d_name, de->d_namelen, - de->d_ino, DT_UNKNOWN)) { + if (!dir_emit(ctx, de->d_name, + fs16_to_cpu(sbi, de->d_namelen), + fs32_to_cpu(sbi, de->d_ino), + DT_UNKNOWN)) { vxfs_put_page(pp); return 0; } " because for some strange reason the patch uses "PAGE_SHIFT" while original lookup.c from 3.16 or 3.18 kernels uses PAGE_CACHE_SHIFT but 4.6 kernel. so the patch below does not apply cleanly to source from 3.x kernels. I use 3.16, double checked latest 3.18. Anyway because readdir() is not aware of fs endianess (because 0004 patch is not in there) the hp-ux tests will fail with some general protection fault very likely. I am almost sure that this patch stands also for that patch 6/7 will have to be changed heavily because it will not apply. I can't see also patches which fix these obvious bugs like freeing kmem_cache_alloc() objects with kfree. Even worse is releasing inode->i_private from the "evict_inode" callback. This leads to dangling objects in vxfs's kmem_cache when the fs is unmounted. Destroying cache on module unload causes kmem_cache_destroy to complain about it and after a few tries ((module load, mount, some ops on mountpoint, unmount, unload) x few times) hard lockup is inevitable. A fix is to utilize the "destroy_inode" callback however this will lead to memory leaks to fs/inode.c cache. So it is partial fix. A proper fix is to use both "alloc_inode" and "destroy_inode" callbacks but this stands for that the vxfs inode structure must inherit generic struct inode and the patch 0006 addresses this. This is what, I think, is right in this situation: you put big effort to split vxfs_dinfo from vxfs_inode_info, which was on "to do", fs endian fields are marked bitwise. This work should not be wasted and I think that it is wise to modify remaining patches to your "0001" and I can do this. It is pointless to give a try to that patch only below because of readdir() and inode_cachep issue. (and wrong error handling: kfree(kmem_cache_alloc()), small memory leak in fshead.c - these are minors despite of that look bad) Do you think other patches should be updated with regard to the patch you sent ? If so then let me do this. > > [1] See Documentation/sparse.txt in the kernel tree for instructions > > Thanks, > Christoph > > --- > >From a510a0e366e8bae7f825d131ad6f6f74dd4bef01 Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Krzysztof=20B=C5=82aszkowski?= <kb@xxxxxxxxxxxxxxx> > Date: Tue, 31 May 2016 08:45:13 +0200 > Subject: freevxfs: handle big endian HP-UX file systems > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > To support VxFS filesystems from HP-UX on x86 systems we need to > implement byte swapping, and to keep support for Unixware filesystems > it needs to be the complicated dual-endian kind ala sysvfs. > > To do this properly we have to split the on disk and in-core inode > so that we can keep the in-core one in native endianness. All other > structures are byteswapped on demand. > > Signed-off-by: Krzysztof Błaszkowski <kb@xxxxxxxxxxxxxxx> > [hch: make spare happy] > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > --- > fs/freevxfs/vxfs.h | 177 ++++++++++++++++++++++++++-------------------- > fs/freevxfs/vxfs_bmap.c | 70 ++++++++++-------- > fs/freevxfs/vxfs_dir.h | 17 ++--- > fs/freevxfs/vxfs_fshead.c | 5 +- > fs/freevxfs/vxfs_fshead.h | 28 ++++---- > fs/freevxfs/vxfs_inode.c | 31 +++++++- > fs/freevxfs/vxfs_inode.h | 140 +++++++++++++++++++----------------- > fs/freevxfs/vxfs_lookup.c | 34 +++++---- > fs/freevxfs/vxfs_olt.c | 15 ++-- > fs/freevxfs/vxfs_olt.h | 70 +++++++++--------- > fs/freevxfs/vxfs_super.c | 101 ++++++++++++++++++-------- > 11 files changed, 409 insertions(+), 279 deletions(-) > > diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h > index c8a9265..4b561de 100644 > --- a/fs/freevxfs/vxfs.h > +++ b/fs/freevxfs/vxfs.h > @@ -38,13 +38,6 @@ > */ > #include <linux/types.h> > > - > -/* > - * Data types for use with the VxFS ondisk format. > - */ > -typedef int32_t vx_daddr_t; > -typedef int32_t vx_ino_t; > - > /* > * Superblock magic number (vxfs_super->vs_magic). > */ > @@ -60,6 +53,14 @@ typedef int32_t vx_ino_t; > */ > #define VXFS_NEFREE 32 > > +enum vxfs_byte_order { > + VXFS_BO_LE, > + VXFS_BO_BE, > +}; > + > +typedef __u16 __bitwise __fs16; > +typedef __u32 __bitwise __fs32; > +typedef __u64 __bitwise __fs64; > > /* > * VxFS superblock (disk). > @@ -71,83 +72,83 @@ struct vxfs_sb { > * Lots of this fields are no more used by version 2 > * and never filesystems. > */ > - u_int32_t vs_magic; /* Magic number */ > - int32_t vs_version; /* VxFS version */ > - u_int32_t vs_ctime; /* create time - secs */ > - u_int32_t vs_cutime; /* create time - usecs */ > - int32_t __unused1; /* unused */ > - int32_t __unused2; /* unused */ > - vx_daddr_t vs_old_logstart; /* obsolete */ > - vx_daddr_t vs_old_logend; /* obsolete */ > - int32_t vs_bsize; /* block size */ > - int32_t vs_size; /* number of blocks */ > - int32_t vs_dsize; /* number of data blocks */ > - u_int32_t vs_old_ninode; /* obsolete */ > - int32_t vs_old_nau; /* obsolete */ > - int32_t __unused3; /* unused */ > - int32_t vs_old_defiextsize; /* obsolete */ > - int32_t vs_old_ilbsize; /* obsolete */ > - int32_t vs_immedlen; /* size of immediate data area */ > - int32_t vs_ndaddr; /* number of direct extentes */ > - vx_daddr_t vs_firstau; /* address of first AU */ > - vx_daddr_t vs_emap; /* offset of extent map in AU */ > - vx_daddr_t vs_imap; /* offset of inode map in AU */ > - vx_daddr_t vs_iextop; /* offset of ExtOp. map in AU */ > - vx_daddr_t vs_istart; /* offset of inode list in AU */ > - vx_daddr_t vs_bstart; /* offset of fdblock in AU */ > - vx_daddr_t vs_femap; /* aufirst + emap */ > - vx_daddr_t vs_fimap; /* aufirst + imap */ > - vx_daddr_t vs_fiextop; /* aufirst + iextop */ > - vx_daddr_t vs_fistart; /* aufirst + istart */ > - vx_daddr_t vs_fbstart; /* aufirst + bstart */ > - int32_t vs_nindir; /* number of entries in indir */ > - int32_t vs_aulen; /* length of AU in blocks */ > - int32_t vs_auimlen; /* length of imap in blocks */ > - int32_t vs_auemlen; /* length of emap in blocks */ > - int32_t vs_auilen; /* length of ilist in blocks */ > - int32_t vs_aupad; /* length of pad in blocks */ > - int32_t vs_aublocks; /* data blocks in AU */ > - int32_t vs_maxtier; /* log base 2 of aublocks */ > - int32_t vs_inopb; /* number of inodes per blk */ > - int32_t vs_old_inopau; /* obsolete */ > - int32_t vs_old_inopilb; /* obsolete */ > - int32_t vs_old_ndiripau; /* obsolete */ > - int32_t vs_iaddrlen; /* size of indirect addr ext. */ > - int32_t vs_bshift; /* log base 2 of bsize */ > - int32_t vs_inoshift; /* log base 2 of inobp */ > - int32_t vs_bmask; /* ~( bsize - 1 ) */ > - int32_t vs_boffmask; /* bsize - 1 */ > - int32_t vs_old_inomask; /* old_inopilb - 1 */ > - int32_t vs_checksum; /* checksum of V1 data */ > + __fs32 vs_magic; /* Magic number */ > + __fs32 vs_version; /* VxFS version */ > + __fs32 vs_ctime; /* create time - secs */ > + __fs32 vs_cutime; /* create time - usecs */ > + __fs32 __unused1; /* unused */ > + __fs32 __unused2; /* unused */ > + __fs32 vs_old_logstart; /* obsolete */ > + __fs32 vs_old_logend; /* obsolete */ > + __fs32 vs_bsize; /* block size */ > + __fs32 vs_size; /* number of blocks */ > + __fs32 vs_dsize; /* number of data blocks */ > + __fs32 vs_old_ninode; /* obsolete */ > + __fs32 vs_old_nau; /* obsolete */ > + __fs32 __unused3; /* unused */ > + __fs32 vs_old_defiextsize; /* obsolete */ > + __fs32 vs_old_ilbsize; /* obsolete */ > + __fs32 vs_immedlen; /* size of immediate data area */ > + __fs32 vs_ndaddr; /* number of direct extentes */ > + __fs32 vs_firstau; /* address of first AU */ > + __fs32 vs_emap; /* offset of extent map in AU */ > + __fs32 vs_imap; /* offset of inode map in AU */ > + __fs32 vs_iextop; /* offset of ExtOp. map in AU */ > + __fs32 vs_istart; /* offset of inode list in AU */ > + __fs32 vs_bstart; /* offset of fdblock in AU */ > + __fs32 vs_femap; /* aufirst + emap */ > + __fs32 vs_fimap; /* aufirst + imap */ > + __fs32 vs_fiextop; /* aufirst + iextop */ > + __fs32 vs_fistart; /* aufirst + istart */ > + __fs32 vs_fbstart; /* aufirst + bstart */ > + __fs32 vs_nindir; /* number of entries in indir */ > + __fs32 vs_aulen; /* length of AU in blocks */ > + __fs32 vs_auimlen; /* length of imap in blocks */ > + __fs32 vs_auemlen; /* length of emap in blocks */ > + __fs32 vs_auilen; /* length of ilist in blocks */ > + __fs32 vs_aupad; /* length of pad in blocks */ > + __fs32 vs_aublocks; /* data blocks in AU */ > + __fs32 vs_maxtier; /* log base 2 of aublocks */ > + __fs32 vs_inopb; /* number of inodes per blk */ > + __fs32 vs_old_inopau; /* obsolete */ > + __fs32 vs_old_inopilb; /* obsolete */ > + __fs32 vs_old_ndiripau; /* obsolete */ > + __fs32 vs_iaddrlen; /* size of indirect addr ext. */ > + __fs32 vs_bshift; /* log base 2 of bsize */ > + __fs32 vs_inoshift; /* log base 2 of inobp */ > + __fs32 vs_bmask; /* ~( bsize - 1 ) */ > + __fs32 vs_boffmask; /* bsize - 1 */ > + __fs32 vs_old_inomask; /* old_inopilb - 1 */ > + __fs32 vs_checksum; /* checksum of V1 data */ > > /* > * Version 1, writable > */ > - int32_t vs_free; /* number of free blocks */ > - int32_t vs_ifree; /* number of free inodes */ > - int32_t vs_efree[VXFS_NEFREE]; /* number of free extents by size */ > - int32_t vs_flags; /* flags ?!? */ > - u_int8_t vs_mod; /* filesystem has been changed */ > - u_int8_t vs_clean; /* clean FS */ > - u_int16_t __unused4; /* unused */ > - u_int32_t vs_firstlogid; /* mount time log ID */ > - u_int32_t vs_wtime; /* last time written - sec */ > - u_int32_t vs_wutime; /* last time written - usec */ > - u_int8_t vs_fname[6]; /* FS name */ > - u_int8_t vs_fpack[6]; /* FS pack name */ > - int32_t vs_logversion; /* log format version */ > - int32_t __unused5; /* unused */ > + __fs32 vs_free; /* number of free blocks */ > + __fs32 vs_ifree; /* number of free inodes */ > + __fs32 vs_efree[VXFS_NEFREE]; /* number of free extents by size */ > + __fs32 vs_flags; /* flags ?!? */ > + __u8 vs_mod; /* filesystem has been changed */ > + __u8 vs_clean; /* clean FS */ > + __fs16 __unused4; /* unused */ > + __fs32 vs_firstlogid; /* mount time log ID */ > + __fs32 vs_wtime; /* last time written - sec */ > + __fs32 vs_wutime; /* last time written - usec */ > + __u8 vs_fname[6]; /* FS name */ > + __u8 vs_fpack[6]; /* FS pack name */ > + __fs32 vs_logversion; /* log format version */ > + __u32 __unused5; /* unused */ > > /* > * Version 2, Read-only > */ > - vx_daddr_t vs_oltext[2]; /* OLT extent and replica */ > - int32_t vs_oltsize; /* OLT extent size */ > - int32_t vs_iauimlen; /* size of inode map */ > - int32_t vs_iausize; /* size of IAU in blocks */ > - int32_t vs_dinosize; /* size of inode in bytes */ > - int32_t vs_old_dniaddr; /* indir levels per inode */ > - int32_t vs_checksum2; /* checksum of V2 RO */ > + __fs32 vs_oltext[2]; /* OLT extent and replica */ > + __fs32 vs_oltsize; /* OLT extent size */ > + __fs32 vs_iauimlen; /* size of inode map */ > + __fs32 vs_iausize; /* size of IAU in blocks */ > + __fs32 vs_dinosize; /* size of inode in bytes */ > + __fs32 vs_old_dniaddr; /* indir levels per inode */ > + __fs32 vs_checksum2; /* checksum of V2 RO */ > > /* > * Actually much more... > @@ -168,8 +169,32 @@ struct vxfs_sb_info { > ino_t vsi_fshino; /* fileset header inode */ > daddr_t vsi_oltext; /* OLT extent */ > daddr_t vsi_oltsize; /* OLT size */ > + enum vxfs_byte_order byte_order; > }; > > +static inline u16 fs16_to_cpu(struct vxfs_sb_info *sbi, __fs16 a) > +{ > + if (sbi->byte_order == VXFS_BO_BE) > + return be16_to_cpu((__force __be16)a); > + else > + return le16_to_cpu((__force __le16)a); > +} > + > +static inline u32 fs32_to_cpu(struct vxfs_sb_info *sbi, __fs32 a) > +{ > + if (sbi->byte_order == VXFS_BO_BE) > + return be32_to_cpu((__force __be32)a); > + else > + return le32_to_cpu((__force __le32)a); > +} > + > +static inline u64 fs64_to_cpu(struct vxfs_sb_info *sbi, __fs64 a) > +{ > + if (sbi->byte_order == VXFS_BO_BE) > + return be64_to_cpu((__force __be64)a); > + else > + return le64_to_cpu((__force __le64)a); > +} > > /* > * File modes. File types above 0xf000 are vxfs internal only, they should > diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c > index f86fd3c..1fd41cf 100644 > --- a/fs/freevxfs/vxfs_bmap.c > +++ b/fs/freevxfs/vxfs_bmap.c > @@ -68,8 +68,9 @@ vxfs_bmap_ext4(struct inode *ip, long bn) > { > struct super_block *sb = ip->i_sb; > struct vxfs_inode_info *vip = VXFS_INO(ip); > + struct vxfs_sb_info *sbi = VXFS_SBI(sb); > unsigned long bsize = sb->s_blocksize; > - u32 indsize = vip->vii_ext4.ve4_indsize; > + u32 indsize = fs32_to_cpu(sbi, vip->vii_ext4.ve4_indsize); > int i; > > if (indsize > sb->s_blocksize) > @@ -77,22 +78,24 @@ vxfs_bmap_ext4(struct inode *ip, long bn) > > for (i = 0; i < VXFS_NDADDR; i++) { > struct direct *d = vip->vii_ext4.ve4_direct + i; > - if (bn >= 0 && bn < d->size) > - return (bn + d->extent); > - bn -= d->size; > + if (bn >= 0 && bn < fs32_to_cpu(sbi, d->size)) > + return (bn + fs32_to_cpu(sbi, d->extent)); > + bn -= fs32_to_cpu(sbi, d->size); > } > > if ((bn / (indsize * indsize * bsize / 4)) == 0) { > struct buffer_head *buf; > daddr_t bno; > - u32 *indir; > + __fs32 *indir; > > - buf = sb_bread(sb, vip->vii_ext4.ve4_indir[0]); > + buf = sb_bread(sb, > + fs32_to_cpu(sbi, vip->vii_ext4.ve4_indir[0])); > if (!buf || !buffer_mapped(buf)) > goto fail_buf; > > - indir = (u32 *)buf->b_data; > - bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize); > + indir = (__fs32 *)buf->b_data; > + bno = fs32_to_cpu(sbi, indir[(bn / indsize) % (indsize * bn)]) + > + (bn % indsize); > > brelse(buf); > return bno; > @@ -127,6 +130,7 @@ fail_buf: > static daddr_t > vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) > { > + struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb); > struct buffer_head *bp = NULL; > daddr_t pblock = 0; > int i; > @@ -142,24 +146,27 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) > > typ = ((struct vxfs_typed *)bp->b_data) + > (i % VXFS_TYPED_PER_BLOCK(ip->i_sb)); > - off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK); > + off = fs64_to_cpu(sbi, typ->vt_hdr) & VXFS_TYPED_OFFSETMASK; > > if (block < off) { > brelse(bp); > continue; > } > > - switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) { > + switch ((u_int32_t)(fs64_to_cpu(sbi, typ->vt_hdr) >> > + VXFS_TYPED_TYPESHIFT)) { > case VXFS_TYPED_INDIRECT: > - pblock = vxfs_bmap_indir(ip, typ->vt_block, > - typ->vt_size, block - off); > + pblock = vxfs_bmap_indir(ip, > + fs32_to_cpu(sbi, typ->vt_block), > + fs32_to_cpu(sbi, typ->vt_size), > + block - off); > if (pblock == -2) > break; > goto out; > case VXFS_TYPED_DATA: > - if ((block - off) >= typ->vt_size) > + if ((block - off) >= fs32_to_cpu(sbi, typ->vt_size)) > break; > - pblock = (typ->vt_block + block - off); > + pblock = fs32_to_cpu(sbi, typ->vt_block) + block - off; > goto out; > case VXFS_TYPED_INDIRECT_DEV4: > case VXFS_TYPED_DATA_DEV4: { > @@ -167,13 +174,15 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) > (struct vxfs_typed_dev4 *)typ; > > printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n"); > - printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n", > - (unsigned long long) typ4->vd4_block, > - (unsigned long long) typ4->vd4_size, > - typ4->vd4_dev); > + printk(KERN_INFO "block: %llu\tsize: %lld\tdev: %d\n", > + fs64_to_cpu(sbi, typ4->vd4_block), > + fs64_to_cpu(sbi, typ4->vd4_size), > + fs32_to_cpu(sbi, typ4->vd4_dev)); > goto fail; > } > default: > + printk(KERN_ERR "%s:%d vt_hdr %llu\n", __func__, > + __LINE__, fs64_to_cpu(sbi, typ->vt_hdr)); > BUG(); > } > brelse(bp); > @@ -201,28 +210,33 @@ static daddr_t > vxfs_bmap_typed(struct inode *ip, long iblock) > { > struct vxfs_inode_info *vip = VXFS_INO(ip); > + struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb); > daddr_t pblock = 0; > int i; > > for (i = 0; i < VXFS_NTYPED; i++) { > struct vxfs_typed *typ = vip->vii_org.typed + i; > - int64_t off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK); > + u64 hdr = fs64_to_cpu(sbi, typ->vt_hdr); > + int64_t off = (hdr & VXFS_TYPED_OFFSETMASK); > > #ifdef DIAGNOSTIC > vxfs_typdump(typ); > #endif > if (iblock < off) > continue; > - switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) { > + switch ((u32)(hdr >> VXFS_TYPED_TYPESHIFT)) { > case VXFS_TYPED_INDIRECT: > - pblock = vxfs_bmap_indir(ip, typ->vt_block, > - typ->vt_size, iblock - off); > + pblock = vxfs_bmap_indir(ip, > + fs32_to_cpu(sbi, typ->vt_block), > + fs32_to_cpu(sbi, typ->vt_size), > + iblock - off); > if (pblock == -2) > break; > return (pblock); > case VXFS_TYPED_DATA: > - if ((iblock - off) < typ->vt_size) > - return (typ->vt_block + iblock - off); > + if ((iblock - off) < fs32_to_cpu(sbi, typ->vt_size)) > + return (fs32_to_cpu(sbi, typ->vt_block) + > + iblock - off); > break; > case VXFS_TYPED_INDIRECT_DEV4: > case VXFS_TYPED_DATA_DEV4: { > @@ -230,10 +244,10 @@ vxfs_bmap_typed(struct inode *ip, long iblock) > (struct vxfs_typed_dev4 *)typ; > > printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n"); > - printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n", > - (unsigned long long) typ4->vd4_block, > - (unsigned long long) typ4->vd4_size, > - typ4->vd4_dev); > + printk(KERN_INFO "block: %llu\tsize: %lld\tdev: %d\n", > + fs64_to_cpu(sbi, typ4->vd4_block), > + fs64_to_cpu(sbi, typ4->vd4_size), > + fs32_to_cpu(sbi, typ4->vd4_dev)); > return 0; > } > default: > diff --git a/fs/freevxfs/vxfs_dir.h b/fs/freevxfs/vxfs_dir.h > index aaf1fb0..acc5477 100644 > --- a/fs/freevxfs/vxfs_dir.h > +++ b/fs/freevxfs/vxfs_dir.h > @@ -48,9 +48,9 @@ > * Linux driver for now. > */ > struct vxfs_dirblk { > - u_int16_t d_free; /* free space in dirblock */ > - u_int16_t d_nhash; /* no of hash chains */ > - u_int16_t d_hash[1]; /* hash chain */ > + __fs16 d_free; /* free space in dirblock */ > + __fs16 d_nhash; /* no of hash chains */ > + __fs16 d_hash[1]; /* hash chain */ > }; > > /* > @@ -63,10 +63,10 @@ struct vxfs_dirblk { > * VxFS directory entry. > */ > struct vxfs_direct { > - vx_ino_t d_ino; /* inode number */ > - u_int16_t d_reclen; /* record length */ > - u_int16_t d_namelen; /* d_name length */ > - u_int16_t d_hashnext; /* next hash entry */ > + __fs32 d_ino; /* inode number */ > + __fs16 d_reclen; /* record length */ > + __fs16 d_namelen; /* d_name length */ > + __fs16 d_hashnext; /* next hash entry */ > char d_name[VXFS_NAMELEN]; /* name */ > }; > > @@ -87,6 +87,7 @@ struct vxfs_direct { > /* > * VXFS_DIRBLKOV is the overhead of a specific dirblock. > */ > -#define VXFS_DIRBLKOV(dbp) ((sizeof(short) * dbp->d_nhash) + 4) > +#define VXFS_DIRBLKOV(sbi, dbp) \ > + ((sizeof(short) * fs16_to_cpu(sbi, dbp->d_nhash)) + 4) > > #endif /* _VXFS_DIR_H_ */ > diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c > index c9a6a94..e7501cb 100644 > --- a/fs/freevxfs/vxfs_fshead.c > +++ b/fs/freevxfs/vxfs_fshead.c > @@ -153,7 +153,8 @@ vxfs_read_fshead(struct super_block *sbp) > vxfs_dumpfsh(pfp); > #endif > > - tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]); > + tip = vxfs_blkiget(sbp, infp->vsi_iext, > + fs32_to_cpu(infp, sfp->fsh_ilistino[0])); > if (!tip) > goto out_free_pfp; > > @@ -169,7 +170,7 @@ vxfs_read_fshead(struct super_block *sbp) > goto out_iput_stilist; > } > > - tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]); > + tip = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0])); > if (!tip) > goto out_iput_stilist; > infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip); > diff --git a/fs/freevxfs/vxfs_fshead.h b/fs/freevxfs/vxfs_fshead.h > index ead0d64..a786cc5 100644 > --- a/fs/freevxfs/vxfs_fshead.h > +++ b/fs/freevxfs/vxfs_fshead.h > @@ -42,20 +42,20 @@ > * Fileset header > */ > struct vxfs_fsh { > - u_int32_t fsh_version; /* fileset header version */ > - u_int32_t fsh_fsindex; /* fileset index */ > - u_int32_t fsh_time; /* modification time - sec */ > - u_int32_t fsh_utime; /* modification time - usec */ > - u_int32_t fsh_extop; /* extop flags */ > - vx_ino_t fsh_ninodes; /* allocated inodes */ > - u_int32_t fsh_nau; /* number of IAUs */ > - u_int32_t fsh_old_ilesize; /* old size of ilist */ > - u_int32_t fsh_dflags; /* flags */ > - u_int32_t fsh_quota; /* quota limit */ > - vx_ino_t fsh_maxinode; /* maximum inode number */ > - vx_ino_t fsh_iauino; /* IAU inode */ > - vx_ino_t fsh_ilistino[2]; /* ilist inodes */ > - vx_ino_t fsh_lctino; /* link count table inode */ > + __fs32 fsh_version; /* fileset header version */ > + __fs32 fsh_fsindex; /* fileset index */ > + __fs32 fsh_time; /* modification time - sec */ > + __fs32 fsh_utime; /* modification time - usec */ > + __fs32 fsh_extop; /* extop flags */ > + __fs32 fsh_ninodes; /* allocated inodes */ > + __fs32 fsh_nau; /* number of IAUs */ > + __fs32 fsh_old_ilesize; /* old size of ilist */ > + __fs32 fsh_dflags; /* flags */ > + __fs32 fsh_quota; /* quota limit */ > + __fs32 fsh_maxinode; /* maximum inode number */ > + __fs32 fsh_iauino; /* IAU inode */ > + __fs32 fsh_ilistino[2]; /* ilist inodes */ > + __fs32 fsh_lctino; /* link count table inode */ > > /* > * Slightly more fields follow, but they > diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c > index 3e2ccad..15de300 100644 > --- a/fs/freevxfs/vxfs_inode.c > +++ b/fs/freevxfs/vxfs_inode.c > @@ -68,6 +68,33 @@ vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino) > } > #endif > > +static inline void dip2vip_cpy(struct vxfs_sb_info *sbi, > + struct vxfs_inode_info *vip, struct vxfs_dinode *dip) > +{ > + vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode); > + vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink); > + vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid); > + vip->vii_gid = fs32_to_cpu(sbi, dip->vdi_gid); > + vip->vii_size = fs64_to_cpu(sbi, dip->vdi_size); > + vip->vii_atime = fs32_to_cpu(sbi, dip->vdi_atime); > + vip->vii_autime = fs32_to_cpu(sbi, dip->vdi_autime); > + vip->vii_mtime = fs32_to_cpu(sbi, dip->vdi_mtime); > + vip->vii_mutime = fs32_to_cpu(sbi, dip->vdi_mutime); > + vip->vii_ctime = fs32_to_cpu(sbi, dip->vdi_ctime); > + vip->vii_cutime = fs32_to_cpu(sbi, dip->vdi_cutime); > + vip->vii_orgtype = dip->vdi_orgtype; > + > + vip->vii_blocks = fs32_to_cpu(sbi, dip->vdi_blocks); > + vip->vii_gen = fs32_to_cpu(sbi, dip->vdi_gen); > + > + if (VXFS_ISDIR(vip)) > + vip->vii_dotdot = fs32_to_cpu(sbi, dip->vdi_dotdot); > + else if (!VXFS_ISREG(vip) && !VXFS_ISLNK(vip)) > + vip->vii_rdev = fs32_to_cpu(sbi, dip->vdi_rdev); > + > + /* don't endian swap the fields that differ by orgtype */ > + memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org)); > +} > > /** > * vxfs_blkiget - find inode based on extent # > @@ -102,7 +129,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) > if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) > goto fail; > dip = (struct vxfs_dinode *)(bp->b_data + offset); > - memcpy(vip, dip, sizeof(*vip)); > + dip2vip_cpy(VXFS_SBI(sbp), vip, dip); > #ifdef DIAGNOSTIC > vxfs_dumpi(vip, ino); > #endif > @@ -144,7 +171,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) > if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) > goto fail; > dip = (struct vxfs_dinode *)(kaddr + offset); > - memcpy(vip, dip, sizeof(*vip)); > + dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip); > #ifdef DIAGNOSTIC > vxfs_dumpi(vip, ino); > #endif > diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h > index 240aeb1..3a29662 100644 > --- a/fs/freevxfs/vxfs_inode.h > +++ b/fs/freevxfs/vxfs_inode.h > @@ -66,74 +66,74 @@ enum { > * Data stored immediately in the inode. > */ > struct vxfs_immed { > - u_int8_t vi_immed[VXFS_NIMMED]; > + __u8 vi_immed[VXFS_NIMMED]; > }; > > struct vxfs_ext4 { > - u_int32_t ve4_spare; /* ?? */ > - u_int32_t ve4_indsize; /* Indirect extent size */ > - vx_daddr_t ve4_indir[VXFS_NIADDR]; /* Indirect extents */ > + __fs32 ve4_spare; /* ?? */ > + __fs32 ve4_indsize; /* Indirect extent size */ > + __fs32 ve4_indir[VXFS_NIADDR]; /* Indirect extents */ > struct direct { /* Direct extents */ > - vx_daddr_t extent; /* Extent number */ > - int32_t size; /* Size of extent */ > + __fs32 extent; /* Extent number */ > + __fs32 size; /* Size of extent */ > } ve4_direct[VXFS_NDADDR]; > }; > > struct vxfs_typed { > - u_int64_t vt_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */ > - vx_daddr_t vt_block; /* Extent block */ > - int32_t vt_size; /* Size in blocks */ > + __fs64 vt_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */ > + __fs32 vt_block; /* Extent block */ > + __fs32 vt_size; /* Size in blocks */ > }; > > struct vxfs_typed_dev4 { > - u_int64_t vd4_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */ > - u_int64_t vd4_block; /* Extent block */ > - u_int64_t vd4_size; /* Size in blocks */ > - int32_t vd4_dev; /* Device ID */ > - u_int32_t __pad1; > + __fs64 vd4_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */ > + __fs64 vd4_block; /* Extent block */ > + __fs64 vd4_size; /* Size in blocks */ > + __fs32 vd4_dev; /* Device ID */ > + __u8 __pad1; > }; > > /* > * The inode as contained on the physical device. > */ > struct vxfs_dinode { > - int32_t vdi_mode; > - u_int32_t vdi_nlink; /* Link count */ > - u_int32_t vdi_uid; /* UID */ > - u_int32_t vdi_gid; /* GID */ > - u_int64_t vdi_size; /* Inode size in bytes */ > - u_int32_t vdi_atime; /* Last time accessed - sec */ > - u_int32_t vdi_autime; /* Last time accessed - usec */ > - u_int32_t vdi_mtime; /* Last modify time - sec */ > - u_int32_t vdi_mutime; /* Last modify time - usec */ > - u_int32_t vdi_ctime; /* Create time - sec */ > - u_int32_t vdi_cutime; /* Create time - usec */ > - u_int8_t vdi_aflags; /* Allocation flags */ > - u_int8_t vdi_orgtype; /* Organisation type */ > - u_int16_t vdi_eopflags; > - u_int32_t vdi_eopdata; > + __fs32 vdi_mode; > + __fs32 vdi_nlink; /* Link count */ > + __fs32 vdi_uid; /* UID */ > + __fs32 vdi_gid; /* GID */ > + __fs64 vdi_size; /* Inode size in bytes */ > + __fs32 vdi_atime; /* Last time accessed - sec */ > + __fs32 vdi_autime; /* Last time accessed - usec */ > + __fs32 vdi_mtime; /* Last modify time - sec */ > + __fs32 vdi_mutime; /* Last modify time - usec */ > + __fs32 vdi_ctime; /* Create time - sec */ > + __fs32 vdi_cutime; /* Create time - usec */ > + __u8 vdi_aflags; /* Allocation flags */ > + __u8 vdi_orgtype; /* Organisation type */ > + __fs16 vdi_eopflags; > + __fs32 vdi_eopdata; > union { > - u_int32_t rdev; > - u_int32_t dotdot; > + __fs32 rdev; > + __fs32 dotdot; > struct { > - u_int32_t reserved; > - u_int32_t fixextsize; > + __u32 reserved; > + __fs32 fixextsize; > } i_regular; > struct { > - u_int32_t matchino; > - u_int32_t fsetindex; > + __fs32 matchino; > + __fs32 fsetindex; > } i_vxspec; > - u_int64_t align; > + __u64 align; > } vdi_ftarea; > - u_int32_t vdi_blocks; /* How much blocks does inode occupy */ > - u_int32_t vdi_gen; /* Inode generation */ > - u_int64_t vdi_version; /* Version */ > + __fs32 vdi_blocks; /* How much blocks does inode occupy */ > + __fs32 vdi_gen; /* Inode generation */ > + __fs64 vdi_version; /* Version */ > union { > struct vxfs_immed immed; > struct vxfs_ext4 ext4; > struct vxfs_typed typed[VXFS_NTYPED]; > } vdi_org; > - u_int32_t vdi_iattrino; > + __fs32 vdi_iattrino; > }; > > #define vdi_rdev vdi_ftarea.rdev > @@ -149,32 +149,40 @@ struct vxfs_dinode { > > /* > * The inode as represented in the main memory. > - * > - * TBD: This should become a separate structure... > */ > -#define vxfs_inode_info vxfs_dinode > - > -#define vii_mode vdi_mode > -#define vii_uid vdi_uid > -#define vii_gid vdi_gid > -#define vii_nlink vdi_nlink > -#define vii_size vdi_size > -#define vii_atime vdi_atime > -#define vii_ctime vdi_ctime > -#define vii_mtime vdi_mtime > -#define vii_blocks vdi_blocks > -#define vii_org vdi_org > -#define vii_orgtype vdi_orgtype > -#define vii_gen vdi_gen > - > -#define vii_rdev vdi_ftarea.rdev > -#define vii_dotdot vdi_ftarea.dotdot > -#define vii_fixextsize vdi_ftarea.regular.fixextsize > -#define vii_matchino vdi_ftarea.vxspec.matchino > -#define vii_fsetindex vdi_ftarea.vxspec.fsetindex > - > -#define vii_immed vdi_org.immed > -#define vii_ext4 vdi_org.ext4 > -#define vii_typed vdi_org.typed > +struct vxfs_inode_info { > + struct inode vfs_inode; > + > + __u32 vii_mode; > + __u32 vii_nlink; /* Link count */ > + __u32 vii_uid; /* UID */ > + __u32 vii_gid; /* GID */ > + __u64 vii_size; /* Inode size in bytes */ > + __u32 vii_atime; /* Last time accessed - sec */ > + __u32 vii_autime; /* Last time accessed - usec */ > + __u32 vii_mtime; /* Last modify time - sec */ > + __u32 vii_mutime; /* Last modify time - usec */ > + __u32 vii_ctime; /* Create time - sec */ > + __u32 vii_cutime; /* Create time - usec */ > + __u8 vii_orgtype; /* Organisation type */ > + union { > + __u32 rdev; > + __u32 dotdot; > + } vii_ftarea; > + __u32 vii_blocks; /* How much blocks does inode occupy */ > + __u32 vii_gen; /* Inode generation */ > + union { > + struct vxfs_immed immed; > + struct vxfs_ext4 ext4; > + struct vxfs_typed typed[VXFS_NTYPED]; > + } vii_org; > +}; > + > +#define vii_rdev vii_ftarea.rdev > +#define vii_dotdot vii_ftarea.dotdot > + > +#define vii_immed vii_org.immed > +#define vii_ext4 vii_org.ext4 > +#define vii_typed vii_org.typed > > #endif /* _VXFS_INODE_H_ */ > diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c > index 6d576b9..09e93b3 100644 > --- a/fs/freevxfs/vxfs_lookup.c > +++ b/fs/freevxfs/vxfs_lookup.c > @@ -74,9 +74,10 @@ dir_blocks(struct inode *ip) > * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller. > */ > static inline int > -vxfs_match(int len, const char * const name, struct vxfs_direct *de) > +vxfs_match(struct vxfs_sb_info *sbi, int len, const char *const name, > + struct vxfs_direct *de) > { > - if (len != de->d_namelen) > + if (len != fs16_to_cpu(sbi, de->d_namelen)) > return 0; > if (!de->d_ino) > return 0; > @@ -84,9 +85,10 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de) > } > > static inline struct vxfs_direct * > -vxfs_next_entry(struct vxfs_direct *de) > +vxfs_next_entry(struct vxfs_sb_info *sbi, struct vxfs_direct *de) > { > - return ((struct vxfs_direct *)((char*)de + de->d_reclen)); > + return ((struct vxfs_direct *) > + ((char *)de + fs16_to_cpu(sbi, de->d_reclen))); > } > > /** > @@ -106,6 +108,7 @@ vxfs_next_entry(struct vxfs_direct *de) > static struct vxfs_direct * > vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp) > { > + struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb); > u_long npages, page, nblocks, pblocks, block; > u_long bsize = ip->i_sb->s_blocksize; > const char *name = dp->d_name.name; > @@ -133,14 +136,16 @@ vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp) > limit = baddr + bsize - VXFS_DIRLEN(1); > > dbp = (struct vxfs_dirblk *)baddr; > - de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp)); > + de = (struct vxfs_direct *) > + (baddr + VXFS_DIRBLKOV(sbi, dbp)); > > - for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) { > + for (; (caddr_t)de <= limit; > + de = vxfs_next_entry(sbi, de)) { > if (!de->d_reclen) > break; > if (!de->d_ino) > continue; > - if (vxfs_match(namelen, name, de)) { > + if (vxfs_match(sbi, namelen, name, de)) { > *ppp = pp; > return (de); > } > @@ -173,7 +178,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp) > > de = vxfs_find_entry(dip, dp, &pp); > if (de) { > - ino = de->d_ino; > + ino = fs32_to_cpu(VXFS_SBI(dip->i_sb), de->d_ino); > kunmap(pp); > put_page(pp); > } > @@ -232,10 +237,12 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx) > { > struct inode *ip = file_inode(fp); > struct super_block *sbp = ip->i_sb; > + struct vxfs_sb_info *sbi = VXFS_SBI(sbp); > u_long bsize = sbp->s_blocksize; > u_long page, npages, block, pblocks, nblocks, offset; > loff_t pos; > > + > if (ctx->pos == 0) { > if (!dir_emit_dot(fp, ctx)) > return 0; > @@ -280,9 +287,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx) > de = (struct vxfs_direct *) > (offset ? > (kaddr + offset) : > - (baddr + VXFS_DIRBLKOV(dbp))); > + (baddr + VXFS_DIRBLKOV(sbi, dbp))); > > - for (; (char *)de <= limit; de = vxfs_next_entry(de)) { > + for (; (char *)de <= limit; > + de = vxfs_next_entry(sbi, de)) { > if (!de->d_reclen) > break; > if (!de->d_ino) > @@ -290,8 +298,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx) > > offset = (char *)de - kaddr; > ctx->pos = ((page << PAGE_SHIFT) | offset) + 2; > - if (!dir_emit(ctx, de->d_name, de->d_namelen, > - de->d_ino, DT_UNKNOWN)) { > + if (!dir_emit(ctx, de->d_name, > + fs16_to_cpu(sbi, de->d_namelen), > + fs32_to_cpu(sbi, de->d_ino), > + DT_UNKNOWN)) { > vxfs_put_page(pp); > return 0; > } > diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c > index 049500847..813da66 100644 > --- a/fs/freevxfs/vxfs_olt.c > +++ b/fs/freevxfs/vxfs_olt.c > @@ -43,14 +43,14 @@ static inline void > vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) > { > BUG_ON(infp->vsi_fshino); > - infp->vsi_fshino = fshp->olt_fsino[0]; > + infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]); > } > > static inline void > vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) > { > BUG_ON(infp->vsi_iext); > - infp->vsi_iext = ilistp->olt_iext[0]; > + infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]); > } > > static inline u_long > @@ -81,13 +81,12 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize) > struct vxfs_olt *op; > char *oaddr, *eaddr; > > - > bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize)); > if (!bp || !bp->b_data) > goto fail; > > op = (struct vxfs_olt *)bp->b_data; > - if (op->olt_magic != VXFS_OLT_MAGIC) { > + if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) { > printk(KERN_NOTICE "vxfs: ivalid olt magic number\n"); > goto fail; > } > @@ -102,14 +101,14 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize) > goto fail; > } > > - oaddr = bp->b_data + op->olt_size; > + oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size); > eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize); > > while (oaddr < eaddr) { > struct vxfs_oltcommon *ocp = > (struct vxfs_oltcommon *)oaddr; > > - switch (ocp->olt_type) { > + switch (fs32_to_cpu(infp, ocp->olt_type)) { > case VXFS_OLT_FSHEAD: > vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp); > break; > @@ -118,11 +117,11 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize) > break; > } > > - oaddr += ocp->olt_size; > + oaddr += fs32_to_cpu(infp, ocp->olt_size); > } > > brelse(bp); > - return 0; > + return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL; > > fail: > brelse(bp); > diff --git a/fs/freevxfs/vxfs_olt.h b/fs/freevxfs/vxfs_olt.h > index b7b3af5..0c0b0c9 100644 > --- a/fs/freevxfs/vxfs_olt.h > +++ b/fs/freevxfs/vxfs_olt.h > @@ -63,83 +63,83 @@ enum { > * the initial inode list, the fileset header or the device configuration. > */ > struct vxfs_olt { > - u_int32_t olt_magic; /* magic number */ > - u_int32_t olt_size; /* size of this entry */ > - u_int32_t olt_checksum; /* checksum of extent */ > - u_int32_t __unused1; /* ??? */ > - u_int32_t olt_mtime; /* time of last mod. (sec) */ > - u_int32_t olt_mutime; /* time of last mod. (usec) */ > - u_int32_t olt_totfree; /* free space in OLT extent */ > - vx_daddr_t olt_extents[2]; /* addr of this extent, replica */ > - u_int32_t olt_esize; /* size of this extent */ > - vx_daddr_t olt_next[2]; /* addr of next extent, replica */ > - u_int32_t olt_nsize; /* size of next extent */ > - u_int32_t __unused2; /* align to 8 byte boundary */ > + __fs32 olt_magic; /* magic number */ > + __fs32 olt_size; /* size of this entry */ > + __fs32 olt_checksum; /* checksum of extent */ > + __u32 __unused1; /* ??? */ > + __fs32 olt_mtime; /* time of last mod. (sec) */ > + __fs32 olt_mutime; /* time of last mod. (usec) */ > + __fs32 olt_totfree; /* free space in OLT extent */ > + __fs32 olt_extents[2]; /* addr of this extent, replica */ > + __fs32 olt_esize; /* size of this extent */ > + __fs32 olt_next[2]; /* addr of next extent, replica */ > + __fs32 olt_nsize; /* size of next extent */ > + __u32 __unused2; /* align to 8 byte boundary */ > }; > > /* > * VxFS common OLT entry (on disk). > */ > struct vxfs_oltcommon { > - u_int32_t olt_type; /* type of this record */ > - u_int32_t olt_size; /* size of this record */ > + __fs32 olt_type; /* type of this record */ > + __fs32 olt_size; /* size of this record */ > }; > > /* > * VxFS free OLT entry (on disk). > */ > struct vxfs_oltfree { > - u_int32_t olt_type; /* type of this record */ > - u_int32_t olt_fsize; /* size of this free record */ > + __fs32 olt_type; /* type of this record */ > + __fs32 olt_fsize; /* size of this free record */ > }; > > /* > * VxFS initial-inode list (on disk). > */ > struct vxfs_oltilist { > - u_int32_t olt_type; /* type of this record */ > - u_int32_t olt_size; /* size of this record */ > - vx_ino_t olt_iext[2]; /* initial inode list, replica */ > + __fs32 olt_type; /* type of this record */ > + __fs32 olt_size; /* size of this record */ > + __fs32 olt_iext[2]; /* initial inode list, replica */ > }; > > /* > * Current Usage Table > */ > struct vxfs_oltcut { > - u_int32_t olt_type; /* type of this record */ > - u_int32_t olt_size; /* size of this record */ > - vx_ino_t olt_cutino; /* inode of current usage table */ > - u_int32_t __pad; /* unused, 8 byte align */ > + __fs32 olt_type; /* type of this record */ > + __fs32 olt_size; /* size of this record */ > + __fs32 olt_cutino; /* inode of current usage table */ > + __u8 __pad; /* unused, 8 byte align */ > }; > > /* > * Inodes containing Superblock, Intent log and OLTs > */ > struct vxfs_oltsb { > - u_int32_t olt_type; /* type of this record */ > - u_int32_t olt_size; /* size of this record */ > - vx_ino_t olt_sbino; /* inode of superblock file */ > - u_int32_t __unused1; /* ??? */ > - vx_ino_t olt_logino[2]; /* inode of log file,replica */ > - vx_ino_t olt_oltino[2]; /* inode of OLT, replica */ > + __fs32 olt_type; /* type of this record */ > + __fs32 olt_size; /* size of this record */ > + __fs32 olt_sbino; /* inode of superblock file */ > + __u32 __unused1; /* ??? */ > + __fs32 olt_logino[2]; /* inode of log file,replica */ > + __fs32 olt_oltino[2]; /* inode of OLT, replica */ > }; > > /* > * Inode containing device configuration + it's replica > */ > struct vxfs_oltdev { > - u_int32_t olt_type; /* type of this record */ > - u_int32_t olt_size; /* size of this record */ > - vx_ino_t olt_devino[2]; /* inode of device config files */ > + __fs32 olt_type; /* type of this record */ > + __fs32 olt_size; /* size of this record */ > + __fs32 olt_devino[2]; /* inode of device config files */ > }; > > /* > * Fileset header > */ > struct vxfs_oltfshead { > - u_int32_t olt_type; /* type number */ > - u_int32_t olt_size; /* size of this record */ > - vx_ino_t olt_fsino[2]; /* inodes of fileset header */ > + __fs32 olt_type; /* type number */ > + __fs32 olt_size; /* size of this record */ > + __fs32 olt_fsino[2]; /* inodes of fileset header */ > }; > > #endif /* _VXFS_OLT_H_ */ > diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c > index 7ca8c75..6124091 100644 > --- a/fs/freevxfs/vxfs_super.c > +++ b/fs/freevxfs/vxfs_super.c > @@ -109,14 +109,15 @@ static int > vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp) > { > struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb); > + struct vxfs_sb *raw_sb = infp->vsi_raw; > > bufp->f_type = VXFS_SUPER_MAGIC; > bufp->f_bsize = dentry->d_sb->s_blocksize; > - bufp->f_blocks = infp->vsi_raw->vs_dsize; > - bufp->f_bfree = infp->vsi_raw->vs_free; > + bufp->f_blocks = fs32_to_cpu(infp, raw_sb->vs_dsize); > + bufp->f_bfree = fs32_to_cpu(infp, raw_sb->vs_free); > bufp->f_bavail = 0; > bufp->f_files = 0; > - bufp->f_ffree = infp->vsi_raw->vs_ifree; > + bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree); > bufp->f_namelen = VXFS_NAMELEN; > > return 0; > @@ -129,6 +130,50 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data) > return 0; > } > > + > +static int vxfs_try_sb_magic(struct super_block *sbp, int silent, > + unsigned blk, __fs32 magic) > +{ > + struct buffer_head *bp; > + struct vxfs_sb *rsbp; > + struct vxfs_sb_info *infp = VXFS_SBI(sbp); > + int rc = -ENOMEM; > + > + bp = sb_bread(sbp, blk); > + do { > + if (!bp || !buffer_mapped(bp)) { > + if (!silent) { > + printk(KERN_WARNING > + "vxfs: unable to read disk superblock at %u\n", > + blk); > + } > + break; > + } > + > + rc = -EINVAL; > + rsbp = (struct vxfs_sb *)bp->b_data; > + if (rsbp->vs_magic != magic) { > + if (!silent) > + printk(KERN_NOTICE > + "vxfs: WRONG superblock magic %08x at %u\n", > + rsbp->vs_magic, blk); > + break; > + } > + > + rc = 0; > + infp->vsi_raw = rsbp; > + infp->vsi_bp = bp; > + } while (0); > + > + if (rc) { > + infp->vsi_raw = NULL; > + infp->vsi_bp = NULL; > + brelse(bp); > + } > + > + return rc; > +} > + > /** > * vxfs_read_super - read superblock into memory and initialize filesystem > * @sbp: VFS superblock (to fill) > @@ -149,10 +194,10 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) > { > struct vxfs_sb_info *infp; > struct vxfs_sb *rsbp; > - struct buffer_head *bp = NULL; > u_long bsize; > struct inode *root; > int ret = -EINVAL; > + u32 j; > > sbp->s_flags |= MS_RDONLY; > > @@ -168,42 +213,42 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) > goto out; > } > > - bp = sb_bread(sbp, 1); > - if (!bp || !buffer_mapped(bp)) { > - if (!silent) { > - printk(KERN_WARNING > - "vxfs: unable to read disk superblock\n"); > - } > - goto out; > - } > + sbp->s_fs_info = infp; > > - rsbp = (struct vxfs_sb *)bp->b_data; > - if (rsbp->vs_magic != VXFS_SUPER_MAGIC) { > + if (!vxfs_try_sb_magic(sbp, silent, 1, > + (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) { > + /* Unixware, x86 */ > + infp->byte_order = VXFS_BO_LE; > + } else if (!vxfs_try_sb_magic(sbp, silent, 8, > + (__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) { > + /* HP-UX, parisc */ > + infp->byte_order = VXFS_BO_BE; > + } else { > if (!silent) > - printk(KERN_NOTICE "vxfs: WRONG superblock magic\n"); > + printk(KERN_NOTICE "vxfs: can't find superblock.\n"); > goto out; > } > > - if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) { > - printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", > - rsbp->vs_version); > + rsbp = infp->vsi_raw; > + j = fs32_to_cpu(infp, rsbp->vs_version); > + if ((j < 2 || j > 4) && !silent) { > + printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j); > goto out; > } > > #ifdef DIAGNOSTIC > - printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", rsbp->vs_version); > - printk(KERN_DEBUG "vxfs: blocksize: %d\n", rsbp->vs_bsize); > + printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j); > + printk(KERN_DEBUG "vxfs: blocksize: %d\n", > + fs32_to_cpu(infp, rsbp->vs_bsize)); > #endif > > - sbp->s_magic = rsbp->vs_magic; > - sbp->s_fs_info = infp; > + sbp->s_magic = fs32_to_cpu(infp, rsbp->vs_magic); > > - infp->vsi_raw = rsbp; > - infp->vsi_bp = bp; > - infp->vsi_oltext = rsbp->vs_oltext[0]; > - infp->vsi_oltsize = rsbp->vs_oltsize; > + infp->vsi_oltext = fs32_to_cpu(infp, rsbp->vs_oltext[0]); > + infp->vsi_oltsize = fs32_to_cpu(infp, rsbp->vs_oltsize); > > - if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) { > + j = fs32_to_cpu(infp, rsbp->vs_bsize); > + if (!sb_set_blocksize(sbp, j)) { > printk(KERN_WARNING "vxfs: unable to set final block size\n"); > goto out; > } > @@ -237,7 +282,7 @@ out_free_ilist: > vxfs_put_fake_inode(infp->vsi_ilist); > vxfs_put_fake_inode(infp->vsi_stilist); > out: > - brelse(bp); > + brelse(infp->vsi_bp); > kfree(infp); > return ret; > } -- Krzysztof Blaszkowski -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html