Commit 0d83f7fc authored by Krzysztof Błaszkowski's avatar Krzysztof Błaszkowski Committed by Christoph Hellwig

freevxfs: handle big endian HP-UX file systems

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: default avatarKrzysztof Błaszkowski <kb@sysmikro.com.pl>
[hch: make spare happy]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 6b15d665
......@@ -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
......
......@@ -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:
......
......@@ -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_ */
......@@ -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);
......
......@@ -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
......
......@@ -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
......
......@@ -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_ */
......@@ -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)