]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
freevxfs: handle big endian HP-UX file systems
authorKrzysztof Błaszkowski <kb@sysmikro.com.pl>
Tue, 31 May 2016 06:45:13 +0000 (08:45 +0200)
committerChristoph Hellwig <hch@lst.de>
Wed, 1 Jun 2016 07:01:28 +0000 (09:01 +0200)
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@sysmikro.com.pl>
[hch: make spare happy]
Signed-off-by: Christoph Hellwig <hch@lst.de>
fs/freevxfs/vxfs.h
fs/freevxfs/vxfs_bmap.c
fs/freevxfs/vxfs_dir.h
fs/freevxfs/vxfs_fshead.c
fs/freevxfs/vxfs_fshead.h
fs/freevxfs/vxfs_inode.c
fs/freevxfs/vxfs_inode.h
fs/freevxfs/vxfs_lookup.c
fs/freevxfs/vxfs_olt.c
fs/freevxfs/vxfs_olt.h
fs/freevxfs/vxfs_super.c

index c8a92652612aad1352ba491b50a165624ceaba7a..4b561ded5eb1761689e619dc7d033f33c634f69b 100644 (file)
  */
 #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
index f86fd3cacd5ab77f6741ce9fcb1dc2d8ee746c01..1fd41cf98b9fce33ffaf318a3a1c0abde5edfd0f 100644 (file)
@@ -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 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
 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:
index aaf1fb098639553fc6ad7a8d6c9e0ccd7162a9ce..acc5477b3f2325242788801afff810fb5736fe4f 100644 (file)
@@ -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_ */
index c9a6a94e58e9cd289ea14a689d9344c7e291bdd4..e7501cb85321f105b31ec2704ae8531c3c9e74ec 100644 (file)
@@ -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);
index ead0d640c18144fdbcb348e2ec1b4ff25f05c969..a786cc55509c8291b20a227a4de9aa17f1641cab 100644 (file)
  * 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
index 3e2ccade61edb4e4a9a7d27d9229d5ed37175dbc..15de300a3ac6e6a05ea64b8e35642f1c25f41ab5 100644 (file)
@@ -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
index 240aeb11263fac0919f47bde21dd4f009715fba8..93d01148e5db61982e21fc6f4290ece290cbcd66 100644 (file)
@@ -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,38 @@ 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 {
+       __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_ */
index 6d576b97f2c8ff9abcda09e58ccc55a088e78f2f..09e93b3a1582c6dc12c3f0f78771285e6918a76a 100644 (file)
@@ -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;
                                }
index 0495008479034b2f0828609272ee2716341aed9b..813da66851510b92786a2b201bf627a58bdaa524 100644 (file)
@@ -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);
index b7b3af50261583f3c0f86b7fdc4328a0f833bd11..0c0b0c9fa5579b4b54ccb67c5bf3b214916ac767 100644 (file)
@@ -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_ */
index 7ca8c75d50d3fdc5f9079599465e04f99058d45d..6124091b4fdb8f7ff3a9baad2a20a03caa3b4c54 100644 (file)
@@ -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 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
        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;
 }