aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Błaszkowski <kb@sysmikro.com.pl>2016-05-31 02:45:13 -0400
committerChristoph Hellwig <hch@lst.de>2016-06-01 03:01:28 -0400
commit0d83f7fc83f77d1cc8395b9e851325d8cc1892e3 (patch)
tree9cfc6aef0a098884097fd37bb413639e8e76f461
parent6b15d6650c5301ce023d8df0cc3a60b1a76d377e (diff)
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: Krzysztof Błaszkowski <kb@sysmikro.com.pl> [hch: make spare happy] Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--fs/freevxfs/vxfs.h177
-rw-r--r--fs/freevxfs/vxfs_bmap.c70
-rw-r--r--fs/freevxfs/vxfs_dir.h17
-rw-r--r--fs/freevxfs/vxfs_fshead.c5
-rw-r--r--fs/freevxfs/vxfs_fshead.h28
-rw-r--r--fs/freevxfs/vxfs_inode.c31
-rw-r--r--fs/freevxfs/vxfs_inode.h138
-rw-r--r--fs/freevxfs/vxfs_lookup.c34
-rw-r--r--fs/freevxfs/vxfs_olt.c15
-rw-r--r--fs/freevxfs/vxfs_olt.h70
-rw-r--r--fs/freevxfs/vxfs_super.c101
11 files changed, 407 insertions, 279 deletions
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
index c8a92652612a..4b561ded5eb1 100644
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -38,13 +38,6 @@
38 */ 38 */
39#include <linux/types.h> 39#include <linux/types.h>
40 40
41
42/*
43 * Data types for use with the VxFS ondisk format.
44 */
45typedef int32_t vx_daddr_t;
46typedef int32_t vx_ino_t;
47
48/* 41/*
49 * Superblock magic number (vxfs_super->vs_magic). 42 * Superblock magic number (vxfs_super->vs_magic).
50 */ 43 */
@@ -60,6 +53,14 @@ typedef int32_t vx_ino_t;
60 */ 53 */
61#define VXFS_NEFREE 32 54#define VXFS_NEFREE 32
62 55
56enum vxfs_byte_order {
57 VXFS_BO_LE,
58 VXFS_BO_BE,
59};
60
61typedef __u16 __bitwise __fs16;
62typedef __u32 __bitwise __fs32;
63typedef __u64 __bitwise __fs64;
63 64
64/* 65/*
65 * VxFS superblock (disk). 66 * VxFS superblock (disk).
@@ -71,83 +72,83 @@ struct vxfs_sb {
71 * Lots of this fields are no more used by version 2 72 * Lots of this fields are no more used by version 2
72 * and never filesystems. 73 * and never filesystems.
73 */ 74 */
74 u_int32_t vs_magic; /* Magic number */ 75 __fs32 vs_magic; /* Magic number */
75 int32_t vs_version; /* VxFS version */ 76 __fs32 vs_version; /* VxFS version */
76 u_int32_t vs_ctime; /* create time - secs */ 77 __fs32 vs_ctime; /* create time - secs */
77 u_int32_t vs_cutime; /* create time - usecs */ 78 __fs32 vs_cutime; /* create time - usecs */
78 int32_t __unused1; /* unused */ 79 __fs32 __unused1; /* unused */
79 int32_t __unused2; /* unused */ 80 __fs32 __unused2; /* unused */
80 vx_daddr_t vs_old_logstart; /* obsolete */ 81 __fs32 vs_old_logstart; /* obsolete */
81 vx_daddr_t vs_old_logend; /* obsolete */ 82 __fs32 vs_old_logend; /* obsolete */
82 int32_t vs_bsize; /* block size */ 83 __fs32 vs_bsize; /* block size */
83 int32_t vs_size; /* number of blocks */ 84 __fs32 vs_size; /* number of blocks */
84 int32_t vs_dsize; /* number of data blocks */ 85 __fs32 vs_dsize; /* number of data blocks */
85 u_int32_t vs_old_ninode; /* obsolete */ 86 __fs32 vs_old_ninode; /* obsolete */
86 int32_t vs_old_nau; /* obsolete */ 87 __fs32 vs_old_nau; /* obsolete */
87 int32_t __unused3; /* unused */ 88 __fs32 __unused3; /* unused */
88 int32_t vs_old_defiextsize; /* obsolete */ 89 __fs32 vs_old_defiextsize; /* obsolete */
89 int32_t vs_old_ilbsize; /* obsolete */ 90 __fs32 vs_old_ilbsize; /* obsolete */
90 int32_t vs_immedlen; /* size of immediate data area */ 91 __fs32 vs_immedlen; /* size of immediate data area */
91 int32_t vs_ndaddr; /* number of direct extentes */ 92 __fs32 vs_ndaddr; /* number of direct extentes */
92 vx_daddr_t vs_firstau; /* address of first AU */ 93 __fs32 vs_firstau; /* address of first AU */
93 vx_daddr_t vs_emap; /* offset of extent map in AU */ 94 __fs32 vs_emap; /* offset of extent map in AU */
94 vx_daddr_t vs_imap; /* offset of inode map in AU */ 95 __fs32 vs_imap; /* offset of inode map in AU */
95 vx_daddr_t vs_iextop; /* offset of ExtOp. map in AU */ 96 __fs32 vs_iextop; /* offset of ExtOp. map in AU */
96 vx_daddr_t vs_istart; /* offset of inode list in AU */ 97 __fs32 vs_istart; /* offset of inode list in AU */
97 vx_daddr_t vs_bstart; /* offset of fdblock in AU */ 98 __fs32 vs_bstart; /* offset of fdblock in AU */
98 vx_daddr_t vs_femap; /* aufirst + emap */ 99 __fs32 vs_femap; /* aufirst + emap */
99 vx_daddr_t vs_fimap; /* aufirst + imap */ 100 __fs32 vs_fimap; /* aufirst + imap */
100 vx_daddr_t vs_fiextop; /* aufirst + iextop */ 101 __fs32 vs_fiextop; /* aufirst + iextop */
101 vx_daddr_t vs_fistart; /* aufirst + istart */ 102 __fs32 vs_fistart; /* aufirst + istart */
102 vx_daddr_t vs_fbstart; /* aufirst + bstart */ 103 __fs32 vs_fbstart; /* aufirst + bstart */
103 int32_t vs_nindir; /* number of entries in indir */ 104 __fs32 vs_nindir; /* number of entries in indir */
104 int32_t vs_aulen; /* length of AU in blocks */ 105 __fs32 vs_aulen; /* length of AU in blocks */
105 int32_t vs_auimlen; /* length of imap in blocks */ 106 __fs32 vs_auimlen; /* length of imap in blocks */
106 int32_t vs_auemlen; /* length of emap in blocks */ 107 __fs32 vs_auemlen; /* length of emap in blocks */
107 int32_t vs_auilen; /* length of ilist in blocks */ 108 __fs32 vs_auilen; /* length of ilist in blocks */
108 int32_t vs_aupad; /* length of pad in blocks */ 109 __fs32 vs_aupad; /* length of pad in blocks */
109 int32_t vs_aublocks; /* data blocks in AU */ 110 __fs32 vs_aublocks; /* data blocks in AU */
110 int32_t vs_maxtier; /* log base 2 of aublocks */ 111 __fs32 vs_maxtier; /* log base 2 of aublocks */
111 int32_t vs_inopb; /* number of inodes per blk */ 112 __fs32 vs_inopb; /* number of inodes per blk */
112 int32_t vs_old_inopau; /* obsolete */ 113 __fs32 vs_old_inopau; /* obsolete */
113 int32_t vs_old_inopilb; /* obsolete */ 114 __fs32 vs_old_inopilb; /* obsolete */
114 int32_t vs_old_ndiripau; /* obsolete */ 115 __fs32 vs_old_ndiripau; /* obsolete */
115 int32_t vs_iaddrlen; /* size of indirect addr ext. */ 116 __fs32 vs_iaddrlen; /* size of indirect addr ext. */
116 int32_t vs_bshift; /* log base 2 of bsize */ 117 __fs32 vs_bshift; /* log base 2 of bsize */
117 int32_t vs_inoshift; /* log base 2 of inobp */ 118 __fs32 vs_inoshift; /* log base 2 of inobp */
118 int32_t vs_bmask; /* ~( bsize - 1 ) */ 119 __fs32 vs_bmask; /* ~( bsize - 1 ) */
119 int32_t vs_boffmask; /* bsize - 1 */ 120 __fs32 vs_boffmask; /* bsize - 1 */
120 int32_t vs_old_inomask; /* old_inopilb - 1 */ 121 __fs32 vs_old_inomask; /* old_inopilb - 1 */
121 int32_t vs_checksum; /* checksum of V1 data */ 122 __fs32 vs_checksum; /* checksum of V1 data */
122 123
123 /* 124 /*
124 * Version 1, writable 125 * Version 1, writable
125 */ 126 */
126 int32_t vs_free; /* number of free blocks */ 127 __fs32 vs_free; /* number of free blocks */
127 int32_t vs_ifree; /* number of free inodes */ 128 __fs32 vs_ifree; /* number of free inodes */
128 int32_t vs_efree[VXFS_NEFREE]; /* number of free extents by size */ 129 __fs32 vs_efree[VXFS_NEFREE]; /* number of free extents by size */
129 int32_t vs_flags; /* flags ?!? */ 130 __fs32 vs_flags; /* flags ?!? */
130 u_int8_t vs_mod; /* filesystem has been changed */ 131 __u8 vs_mod; /* filesystem has been changed */
131 u_int8_t vs_clean; /* clean FS */ 132 __u8 vs_clean; /* clean FS */
132 u_int16_t __unused4; /* unused */ 133 __fs16 __unused4; /* unused */
133 u_int32_t vs_firstlogid; /* mount time log ID */ 134 __fs32 vs_firstlogid; /* mount time log ID */
134 u_int32_t vs_wtime; /* last time written - sec */ 135 __fs32 vs_wtime; /* last time written - sec */
135 u_int32_t vs_wutime; /* last time written - usec */ 136 __fs32 vs_wutime; /* last time written - usec */
136 u_int8_t vs_fname[6]; /* FS name */ 137 __u8 vs_fname[6]; /* FS name */
137 u_int8_t vs_fpack[6]; /* FS pack name */ 138 __u8 vs_fpack[6]; /* FS pack name */
138 int32_t vs_logversion; /* log format version */ 139 __fs32 vs_logversion; /* log format version */
139 int32_t __unused5; /* unused */ 140 __u32 __unused5; /* unused */
140 141
141 /* 142 /*
142 * Version 2, Read-only 143 * Version 2, Read-only
143 */ 144 */
144 vx_daddr_t vs_oltext[2]; /* OLT extent and replica */ 145 __fs32 vs_oltext[2]; /* OLT extent and replica */
145 int32_t vs_oltsize; /* OLT extent size */ 146 __fs32 vs_oltsize; /* OLT extent size */
146 int32_t vs_iauimlen; /* size of inode map */ 147 __fs32 vs_iauimlen; /* size of inode map */
147 int32_t vs_iausize; /* size of IAU in blocks */ 148 __fs32 vs_iausize; /* size of IAU in blocks */
148 int32_t vs_dinosize; /* size of inode in bytes */ 149 __fs32 vs_dinosize; /* size of inode in bytes */
149 int32_t vs_old_dniaddr; /* indir levels per inode */ 150 __fs32 vs_old_dniaddr; /* indir levels per inode */
150 int32_t vs_checksum2; /* checksum of V2 RO */ 151 __fs32 vs_checksum2; /* checksum of V2 RO */
151 152
152 /* 153 /*
153 * Actually much more... 154 * Actually much more...
@@ -168,8 +169,32 @@ struct vxfs_sb_info {
168 ino_t vsi_fshino; /* fileset header inode */ 169 ino_t vsi_fshino; /* fileset header inode */
169 daddr_t vsi_oltext; /* OLT extent */ 170 daddr_t vsi_oltext; /* OLT extent */
170 daddr_t vsi_oltsize; /* OLT size */ 171 daddr_t vsi_oltsize; /* OLT size */
172 enum vxfs_byte_order byte_order;
171}; 173};
172 174
175static inline u16 fs16_to_cpu(struct vxfs_sb_info *sbi, __fs16 a)
176{
177 if (sbi->byte_order == VXFS_BO_BE)
178 return be16_to_cpu((__force __be16)a);
179 else
180 return le16_to_cpu((__force __le16)a);
181}
182
183static inline u32 fs32_to_cpu(struct vxfs_sb_info *sbi, __fs32 a)
184{
185 if (sbi->byte_order == VXFS_BO_BE)
186 return be32_to_cpu((__force __be32)a);
187 else
188 return le32_to_cpu((__force __le32)a);
189}
190
191static inline u64 fs64_to_cpu(struct vxfs_sb_info *sbi, __fs64 a)
192{
193 if (sbi->byte_order == VXFS_BO_BE)
194 return be64_to_cpu((__force __be64)a);
195 else
196 return le64_to_cpu((__force __le64)a);
197}
173 198
174/* 199/*
175 * File modes. File types above 0xf000 are vxfs internal only, they should 200 * 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 f86fd3cacd5a..1fd41cf98b9f 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)
68{ 68{
69 struct super_block *sb = ip->i_sb; 69 struct super_block *sb = ip->i_sb;
70 struct vxfs_inode_info *vip = VXFS_INO(ip); 70 struct vxfs_inode_info *vip = VXFS_INO(ip);
71 struct vxfs_sb_info *sbi = VXFS_SBI(sb);
71 unsigned long bsize = sb->s_blocksize; 72 unsigned long bsize = sb->s_blocksize;
72 u32 indsize = vip->vii_ext4.ve4_indsize; 73 u32 indsize = fs32_to_cpu(sbi, vip->vii_ext4.ve4_indsize);
73 int i; 74 int i;
74 75
75 if (indsize > sb->s_blocksize) 76 if (indsize > sb->s_blocksize)
@@ -77,22 +78,24 @@ vxfs_bmap_ext4(struct inode *ip, long bn)
77 78
78 for (i = 0; i < VXFS_NDADDR; i++) { 79 for (i = 0; i < VXFS_NDADDR; i++) {
79 struct direct *d = vip->vii_ext4.ve4_direct + i; 80 struct direct *d = vip->vii_ext4.ve4_direct + i;
80 if (bn >= 0 && bn < d->size) 81 if (bn >= 0 && bn < fs32_to_cpu(sbi, d->size))
81 return (bn + d->extent); 82 return (bn + fs32_to_cpu(sbi, d->extent));
82 bn -= d->size; 83 bn -= fs32_to_cpu(sbi, d->size);
83 } 84 }
84 85
85 if ((bn / (indsize * indsize * bsize / 4)) == 0) { 86 if ((bn / (indsize * indsize * bsize / 4)) == 0) {
86 struct buffer_head *buf; 87 struct buffer_head *buf;
87 daddr_t bno; 88 daddr_t bno;
88 u32 *indir; 89 __fs32 *indir;
89 90
90 buf = sb_bread(sb, vip->vii_ext4.ve4_indir[0]); 91 buf = sb_bread(sb,
92 fs32_to_cpu(sbi, vip->vii_ext4.ve4_indir[0]));
91 if (!buf || !buffer_mapped(buf)) 93 if (!buf || !buffer_mapped(buf))
92 goto fail_buf; 94 goto fail_buf;
93 95
94 indir = (u32 *)buf->b_data; 96 indir = (__fs32 *)buf->b_data;
95 bno = indir[(bn/indsize) % (indsize*bn)] + (bn%indsize); 97 bno = fs32_to_cpu(sbi, indir[(bn / indsize) % (indsize * bn)]) +
98 (bn % indsize);
96 99
97 brelse(buf); 100 brelse(buf);
98 return bno; 101 return bno;
@@ -127,6 +130,7 @@ fail_buf:
127static daddr_t 130static daddr_t
128vxfs_bmap_indir(struct inode *ip, long indir, int size, long block) 131vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
129{ 132{
133 struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb);
130 struct buffer_head *bp = NULL; 134 struct buffer_head *bp = NULL;
131 daddr_t pblock = 0; 135 daddr_t pblock = 0;
132 int i; 136 int i;
@@ -142,24 +146,27 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
142 146
143 typ = ((struct vxfs_typed *)bp->b_data) + 147 typ = ((struct vxfs_typed *)bp->b_data) +
144 (i % VXFS_TYPED_PER_BLOCK(ip->i_sb)); 148 (i % VXFS_TYPED_PER_BLOCK(ip->i_sb));
145 off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK); 149 off = fs64_to_cpu(sbi, typ->vt_hdr) & VXFS_TYPED_OFFSETMASK;
146 150
147 if (block < off) { 151 if (block < off) {
148 brelse(bp); 152 brelse(bp);
149 continue; 153 continue;
150 } 154 }
151 155
152 switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) { 156 switch ((u_int32_t)(fs64_to_cpu(sbi, typ->vt_hdr) >>
157 VXFS_TYPED_TYPESHIFT)) {
153 case VXFS_TYPED_INDIRECT: 158 case VXFS_TYPED_INDIRECT:
154 pblock = vxfs_bmap_indir(ip, typ->vt_block, 159 pblock = vxfs_bmap_indir(ip,
155 typ->vt_size, block - off); 160 fs32_to_cpu(sbi, typ->vt_block),
161 fs32_to_cpu(sbi, typ->vt_size),
162 block - off);
156 if (pblock == -2) 163 if (pblock == -2)
157 break; 164 break;
158 goto out; 165 goto out;
159 case VXFS_TYPED_DATA: 166 case VXFS_TYPED_DATA:
160 if ((block - off) >= typ->vt_size) 167 if ((block - off) >= fs32_to_cpu(sbi, typ->vt_size))
161 break; 168 break;
162 pblock = (typ->vt_block + block - off); 169 pblock = fs32_to_cpu(sbi, typ->vt_block) + block - off;
163 goto out; 170 goto out;
164 case VXFS_TYPED_INDIRECT_DEV4: 171 case VXFS_TYPED_INDIRECT_DEV4:
165 case VXFS_TYPED_DATA_DEV4: { 172 case VXFS_TYPED_DATA_DEV4: {
@@ -167,13 +174,15 @@ vxfs_bmap_indir(struct inode *ip, long indir, int size, long block)
167 (struct vxfs_typed_dev4 *)typ; 174 (struct vxfs_typed_dev4 *)typ;
168 175
169 printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n"); 176 printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
170 printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n", 177 printk(KERN_INFO "block: %llu\tsize: %lld\tdev: %d\n",
171 (unsigned long long) typ4->vd4_block, 178 fs64_to_cpu(sbi, typ4->vd4_block),
172 (unsigned long long) typ4->vd4_size, 179 fs64_to_cpu(sbi, typ4->vd4_size),
173 typ4->vd4_dev); 180 fs32_to_cpu(sbi, typ4->vd4_dev));
174 goto fail; 181 goto fail;
175 } 182 }
176 default: 183 default:
184 printk(KERN_ERR "%s:%d vt_hdr %llu\n", __func__,
185 __LINE__, fs64_to_cpu(sbi, typ->vt_hdr));
177 BUG(); 186 BUG();
178 } 187 }
179 brelse(bp); 188 brelse(bp);
@@ -201,28 +210,33 @@ static daddr_t
201vxfs_bmap_typed(struct inode *ip, long iblock) 210vxfs_bmap_typed(struct inode *ip, long iblock)
202{ 211{
203 struct vxfs_inode_info *vip = VXFS_INO(ip); 212 struct vxfs_inode_info *vip = VXFS_INO(ip);
213 struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb);
204 daddr_t pblock = 0; 214 daddr_t pblock = 0;
205 int i; 215 int i;
206 216
207 for (i = 0; i < VXFS_NTYPED; i++) { 217 for (i = 0; i < VXFS_NTYPED; i++) {
208 struct vxfs_typed *typ = vip->vii_org.typed + i; 218 struct vxfs_typed *typ = vip->vii_org.typed + i;
209 int64_t off = (typ->vt_hdr & VXFS_TYPED_OFFSETMASK); 219 u64 hdr = fs64_to_cpu(sbi, typ->vt_hdr);
220 int64_t off = (hdr & VXFS_TYPED_OFFSETMASK);
210 221
211#ifdef DIAGNOSTIC 222#ifdef DIAGNOSTIC
212 vxfs_typdump(typ); 223 vxfs_typdump(typ);
213#endif 224#endif
214 if (iblock < off) 225 if (iblock < off)
215 continue; 226 continue;
216 switch ((u_int32_t)(typ->vt_hdr >> VXFS_TYPED_TYPESHIFT)) { 227 switch ((u32)(hdr >> VXFS_TYPED_TYPESHIFT)) {
217 case VXFS_TYPED_INDIRECT: 228 case VXFS_TYPED_INDIRECT:
218 pblock = vxfs_bmap_indir(ip, typ->vt_block, 229 pblock = vxfs_bmap_indir(ip,
219 typ->vt_size, iblock - off); 230 fs32_to_cpu(sbi, typ->vt_block),
231 fs32_to_cpu(sbi, typ->vt_size),
232 iblock - off);
220 if (pblock == -2) 233 if (pblock == -2)
221 break; 234 break;
222 return (pblock); 235 return (pblock);
223 case VXFS_TYPED_DATA: 236 case VXFS_TYPED_DATA:
224 if ((iblock - off) < typ->vt_size) 237 if ((iblock - off) < fs32_to_cpu(sbi, typ->vt_size))
225 return (typ->vt_block + iblock - off); 238 return (fs32_to_cpu(sbi, typ->vt_block) +
239 iblock - off);
226 break; 240 break;
227 case VXFS_TYPED_INDIRECT_DEV4: 241 case VXFS_TYPED_INDIRECT_DEV4:
228 case VXFS_TYPED_DATA_DEV4: { 242 case VXFS_TYPED_DATA_DEV4: {
@@ -230,10 +244,10 @@ vxfs_bmap_typed(struct inode *ip, long iblock)
230 (struct vxfs_typed_dev4 *)typ; 244 (struct vxfs_typed_dev4 *)typ;
231 245
232 printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n"); 246 printk(KERN_INFO "\n\nTYPED_DEV4 detected!\n");
233 printk(KERN_INFO "block: %Lu\tsize: %Ld\tdev: %d\n", 247 printk(KERN_INFO "block: %llu\tsize: %lld\tdev: %d\n",
234 (unsigned long long) typ4->vd4_block, 248 fs64_to_cpu(sbi, typ4->vd4_block),
235 (unsigned long long) typ4->vd4_size, 249 fs64_to_cpu(sbi, typ4->vd4_size),
236 typ4->vd4_dev); 250 fs32_to_cpu(sbi, typ4->vd4_dev));
237 return 0; 251 return 0;
238 } 252 }
239 default: 253 default:
diff --git a/fs/freevxfs/vxfs_dir.h b/fs/freevxfs/vxfs_dir.h
index aaf1fb098639..acc5477b3f23 100644
--- a/fs/freevxfs/vxfs_dir.h
+++ b/fs/freevxfs/vxfs_dir.h
@@ -48,9 +48,9 @@
48 * Linux driver for now. 48 * Linux driver for now.
49 */ 49 */
50struct vxfs_dirblk { 50struct vxfs_dirblk {
51 u_int16_t d_free; /* free space in dirblock */ 51 __fs16 d_free; /* free space in dirblock */
52 u_int16_t d_nhash; /* no of hash chains */ 52 __fs16 d_nhash; /* no of hash chains */
53 u_int16_t d_hash[1]; /* hash chain */ 53 __fs16 d_hash[1]; /* hash chain */
54}; 54};
55 55
56/* 56/*
@@ -63,10 +63,10 @@ struct vxfs_dirblk {
63 * VxFS directory entry. 63 * VxFS directory entry.
64 */ 64 */
65struct vxfs_direct { 65struct vxfs_direct {
66 vx_ino_t d_ino; /* inode number */ 66 __fs32 d_ino; /* inode number */
67 u_int16_t d_reclen; /* record length */ 67 __fs16 d_reclen; /* record length */
68 u_int16_t d_namelen; /* d_name length */ 68 __fs16 d_namelen; /* d_name length */
69 u_int16_t d_hashnext; /* next hash entry */ 69 __fs16 d_hashnext; /* next hash entry */
70 char d_name[VXFS_NAMELEN]; /* name */ 70 char d_name[VXFS_NAMELEN]; /* name */
71}; 71};
72 72
@@ -87,6 +87,7 @@ struct vxfs_direct {
87/* 87/*
88 * VXFS_DIRBLKOV is the overhead of a specific dirblock. 88 * VXFS_DIRBLKOV is the overhead of a specific dirblock.
89 */ 89 */
90#define VXFS_DIRBLKOV(dbp) ((sizeof(short) * dbp->d_nhash) + 4) 90#define VXFS_DIRBLKOV(sbi, dbp) \
91 ((sizeof(short) * fs16_to_cpu(sbi, dbp->d_nhash)) + 4)
91 92
92#endif /* _VXFS_DIR_H_ */ 93#endif /* _VXFS_DIR_H_ */
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
index c9a6a94e58e9..e7501cb85321 100644
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -153,7 +153,8 @@ vxfs_read_fshead(struct super_block *sbp)
153 vxfs_dumpfsh(pfp); 153 vxfs_dumpfsh(pfp);
154#endif 154#endif
155 155
156 tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]); 156 tip = vxfs_blkiget(sbp, infp->vsi_iext,
157 fs32_to_cpu(infp, sfp->fsh_ilistino[0]));
157 if (!tip) 158 if (!tip)
158 goto out_free_pfp; 159 goto out_free_pfp;
159 160
@@ -169,7 +170,7 @@ vxfs_read_fshead(struct super_block *sbp)
169 goto out_iput_stilist; 170 goto out_iput_stilist;
170 } 171 }
171 172
172 tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]); 173 tip = vxfs_stiget(sbp, fs32_to_cpu(infp, pfp->fsh_ilistino[0]));
173 if (!tip) 174 if (!tip)
174 goto out_iput_stilist; 175 goto out_iput_stilist;
175 infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip); 176 infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
diff --git a/fs/freevxfs/vxfs_fshead.h b/fs/freevxfs/vxfs_fshead.h
index ead0d640c181..a786cc55509c 100644
--- a/fs/freevxfs/vxfs_fshead.h
+++ b/fs/freevxfs/vxfs_fshead.h
@@ -42,20 +42,20 @@
42 * Fileset header 42 * Fileset header
43 */ 43 */
44struct vxfs_fsh { 44struct vxfs_fsh {
45 u_int32_t fsh_version; /* fileset header version */ 45 __fs32 fsh_version; /* fileset header version */
46 u_int32_t fsh_fsindex; /* fileset index */ 46 __fs32 fsh_fsindex; /* fileset index */
47 u_int32_t fsh_time; /* modification time - sec */ 47 __fs32 fsh_time; /* modification time - sec */
48 u_int32_t fsh_utime; /* modification time - usec */ 48 __fs32 fsh_utime; /* modification time - usec */
49 u_int32_t fsh_extop; /* extop flags */ 49 __fs32 fsh_extop; /* extop flags */
50 vx_ino_t fsh_ninodes; /* allocated inodes */ 50 __fs32 fsh_ninodes; /* allocated inodes */
51 u_int32_t fsh_nau; /* number of IAUs */ 51 __fs32 fsh_nau; /* number of IAUs */
52 u_int32_t fsh_old_ilesize; /* old size of ilist */ 52 __fs32 fsh_old_ilesize; /* old size of ilist */
53 u_int32_t fsh_dflags; /* flags */ 53 __fs32 fsh_dflags; /* flags */
54 u_int32_t fsh_quota; /* quota limit */ 54 __fs32 fsh_quota; /* quota limit */
55 vx_ino_t fsh_maxinode; /* maximum inode number */ 55 __fs32 fsh_maxinode; /* maximum inode number */
56 vx_ino_t fsh_iauino; /* IAU inode */ 56 __fs32 fsh_iauino; /* IAU inode */
57 vx_ino_t fsh_ilistino[2]; /* ilist inodes */ 57 __fs32 fsh_ilistino[2]; /* ilist inodes */
58 vx_ino_t fsh_lctino; /* link count table inode */ 58 __fs32 fsh_lctino; /* link count table inode */
59 59
60 /* 60 /*
61 * Slightly more fields follow, but they 61 * Slightly more fields follow, but they
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 3e2ccade61ed..15de300a3ac6 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)
68} 68}
69#endif 69#endif
70 70
71static inline void dip2vip_cpy(struct vxfs_sb_info *sbi,
72 struct vxfs_inode_info *vip, struct vxfs_dinode *dip)
73{
74 vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode);
75 vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink);
76 vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid);
77 vip->vii_gid = fs32_to_cpu(sbi, dip->vdi_gid);
78 vip->vii_size = fs64_to_cpu(sbi, dip->vdi_size);
79 vip->vii_atime = fs32_to_cpu(sbi, dip->vdi_atime);
80 vip->vii_autime = fs32_to_cpu(sbi, dip->vdi_autime);
81 vip->vii_mtime = fs32_to_cpu(sbi, dip->vdi_mtime);
82 vip->vii_mutime = fs32_to_cpu(sbi, dip->vdi_mutime);
83 vip->vii_ctime = fs32_to_cpu(sbi, dip->vdi_ctime);
84 vip->vii_cutime = fs32_to_cpu(sbi, dip->vdi_cutime);
85 vip->vii_orgtype = dip->vdi_orgtype;
86
87 vip->vii_blocks = fs32_to_cpu(sbi, dip->vdi_blocks);
88 vip->vii_gen = fs32_to_cpu(sbi, dip->vdi_gen);
89
90 if (VXFS_ISDIR(vip))
91 vip->vii_dotdot = fs32_to_cpu(sbi, dip->vdi_dotdot);
92 else if (!VXFS_ISREG(vip) && !VXFS_ISLNK(vip))
93 vip->vii_rdev = fs32_to_cpu(sbi, dip->vdi_rdev);
94
95 /* don't endian swap the fields that differ by orgtype */
96 memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org));
97}
71 98
72/** 99/**
73 * vxfs_blkiget - find inode based on extent # 100 * vxfs_blkiget - find inode based on extent #
@@ -102,7 +129,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
102 if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) 129 if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
103 goto fail; 130 goto fail;
104 dip = (struct vxfs_dinode *)(bp->b_data + offset); 131 dip = (struct vxfs_dinode *)(bp->b_data + offset);
105 memcpy(vip, dip, sizeof(*vip)); 132 dip2vip_cpy(VXFS_SBI(sbp), vip, dip);
106#ifdef DIAGNOSTIC 133#ifdef DIAGNOSTIC
107 vxfs_dumpi(vip, ino); 134 vxfs_dumpi(vip, ino);
108#endif 135#endif
@@ -144,7 +171,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp)
144 if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) 171 if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL)))
145 goto fail; 172 goto fail;
146 dip = (struct vxfs_dinode *)(kaddr + offset); 173 dip = (struct vxfs_dinode *)(kaddr + offset);
147 memcpy(vip, dip, sizeof(*vip)); 174 dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip);
148#ifdef DIAGNOSTIC 175#ifdef DIAGNOSTIC
149 vxfs_dumpi(vip, ino); 176 vxfs_dumpi(vip, ino);
150#endif 177#endif
diff --git a/fs/freevxfs/vxfs_inode.h b/fs/freevxfs/vxfs_inode.h
index 240aeb11263f..93d01148e5db 100644
--- a/fs/freevxfs/vxfs_inode.h
+++ b/fs/freevxfs/vxfs_inode.h
@@ -66,74 +66,74 @@ enum {
66 * Data stored immediately in the inode. 66 * Data stored immediately in the inode.
67 */ 67 */
68struct vxfs_immed { 68struct vxfs_immed {
69 u_int8_t vi_immed[VXFS_NIMMED]; 69 __u8 vi_immed[VXFS_NIMMED];
70}; 70};
71 71
72struct vxfs_ext4 { 72struct vxfs_ext4 {
73 u_int32_t ve4_spare; /* ?? */ 73 __fs32 ve4_spare; /* ?? */
74 u_int32_t ve4_indsize; /* Indirect extent size */ 74 __fs32 ve4_indsize; /* Indirect extent size */
75 vx_daddr_t ve4_indir[VXFS_NIADDR]; /* Indirect extents */ 75 __fs32 ve4_indir[VXFS_NIADDR]; /* Indirect extents */
76 struct direct { /* Direct extents */ 76 struct direct { /* Direct extents */
77 vx_daddr_t extent; /* Extent number */ 77 __fs32 extent; /* Extent number */
78 int32_t size; /* Size of extent */ 78 __fs32 size; /* Size of extent */
79 } ve4_direct[VXFS_NDADDR]; 79 } ve4_direct[VXFS_NDADDR];
80}; 80};
81 81
82struct vxfs_typed { 82struct vxfs_typed {
83 u_int64_t vt_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */ 83 __fs64 vt_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
84 vx_daddr_t vt_block; /* Extent block */ 84 __fs32 vt_block; /* Extent block */
85 int32_t vt_size; /* Size in blocks */ 85 __fs32 vt_size; /* Size in blocks */
86}; 86};
87 87
88struct vxfs_typed_dev4 { 88struct vxfs_typed_dev4 {
89 u_int64_t vd4_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */ 89 __fs64 vd4_hdr; /* Header, 0xTTOOOOOOOOOOOOOO; T=type,O=offs */
90 u_int64_t vd4_block; /* Extent block */ 90 __fs64 vd4_block; /* Extent block */
91 u_int64_t vd4_size; /* Size in blocks */ 91 __fs64 vd4_size; /* Size in blocks */
92 int32_t vd4_dev; /* Device ID */ 92 __fs32 vd4_dev; /* Device ID */
93 u_int32_t __pad1; 93 __u8 __pad1;
94}; 94};
95 95
96/* 96/*
97 * The inode as contained on the physical device. 97 * The inode as contained on the physical device.
98 */ 98 */
99struct vxfs_dinode { 99struct vxfs_dinode {
100 int32_t vdi_mode; 100 __fs32 vdi_mode;
101 u_int32_t vdi_nlink; /* Link count */ 101 __fs32 vdi_nlink; /* Link count */
102 u_int32_t vdi_uid; /* UID */ 102 __fs32 vdi_uid; /* UID */
103 u_int32_t vdi_gid; /* GID */ 103 __fs32 vdi_gid; /* GID */
104 u_int64_t vdi_size; /* Inode size in bytes */ 104 __fs64 vdi_size; /* Inode size in bytes */
105 u_int32_t vdi_atime; /* Last time accessed - sec */ 105 __fs32 vdi_atime; /* Last time accessed - sec */
106 u_int32_t vdi_autime; /* Last time accessed - usec */ 106 __fs32 vdi_autime; /* Last time accessed - usec */
107 u_int32_t vdi_mtime; /* Last modify time - sec */ 107 __fs32 vdi_mtime; /* Last modify time - sec */
108 u_int32_t vdi_mutime; /* Last modify time - usec */ 108 __fs32 vdi_mutime; /* Last modify time - usec */
109 u_int32_t vdi_ctime; /* Create time - sec */ 109 __fs32 vdi_ctime; /* Create time - sec */
110 u_int32_t vdi_cutime; /* Create time - usec */ 110 __fs32 vdi_cutime; /* Create time - usec */
111 u_int8_t vdi_aflags; /* Allocation flags */ 111 __u8 vdi_aflags; /* Allocation flags */
112 u_int8_t vdi_orgtype; /* Organisation type */ 112 __u8 vdi_orgtype; /* Organisation type */
113 u_int16_t vdi_eopflags; 113 __fs16 vdi_eopflags;
114 u_int32_t vdi_eopdata; 114 __fs32 vdi_eopdata;
115 union { 115 union {
116 u_int32_t rdev; 116 __fs32 rdev;
117 u_int32_t dotdot; 117 __fs32 dotdot;
118 struct { 118 struct {
119 u_int32_t reserved; 119 __u32 reserved;
120 u_int32_t fixextsize; 120 __fs32 fixextsize;
121 } i_regular; 121 } i_regular;
122 struct { 122 struct {
123 u_int32_t matchino; 123 __fs32 matchino;
124 u_int32_t fsetindex; 124 __fs32 fsetindex;
125 } i_vxspec; 125 } i_vxspec;
126 u_int64_t align; 126 __u64 align;
127 } vdi_ftarea; 127 } vdi_ftarea;
128 u_int32_t vdi_blocks; /* How much blocks does inode occupy */ 128 __fs32 vdi_blocks; /* How much blocks does inode occupy */
129 u_int32_t vdi_gen; /* Inode generation */ 129 __fs32 vdi_gen; /* Inode generation */
130 u_int64_t vdi_version; /* Version */ 130 __fs64 vdi_version; /* Version */
131 union { 131 union {
132 struct vxfs_immed immed; 132 struct vxfs_immed immed;
133 struct vxfs_ext4 ext4; 133 struct vxfs_ext4 ext4;
134 struct vxfs_typed typed[VXFS_NTYPED]; 134 struct vxfs_typed typed[VXFS_NTYPED];
135 } vdi_org; 135 } vdi_org;
136 u_int32_t vdi_iattrino; 136 __fs32 vdi_iattrino;
137}; 137};
138 138
139#define vdi_rdev vdi_ftarea.rdev 139#define vdi_rdev vdi_ftarea.rdev
@@ -149,32 +149,38 @@ struct vxfs_dinode {
149 149
150/* 150/*
151 * The inode as represented in the main memory. 151 * The inode as represented in the main memory.
152 *
153 * TBD: This should become a separate structure...
154 */ 152 */
155#define vxfs_inode_info vxfs_dinode 153struct vxfs_inode_info {
156 154 __u32 vii_mode;
157#define vii_mode vdi_mode 155 __u32 vii_nlink; /* Link count */
158#define vii_uid vdi_uid 156 __u32 vii_uid; /* UID */
159#define vii_gid vdi_gid 157 __u32 vii_gid; /* GID */
160#define vii_nlink vdi_nlink 158 __u64 vii_size; /* Inode size in bytes */
161#define vii_size vdi_size 159 __u32 vii_atime; /* Last time accessed - sec */
162#define vii_atime vdi_atime 160 __u32 vii_autime; /* Last time accessed - usec */
163#define vii_ctime vdi_ctime 161 __u32 vii_mtime; /* Last modify time - sec */
164#define vii_mtime vdi_mtime 162 __u32 vii_mutime; /* Last modify time - usec */
165#define vii_blocks vdi_blocks 163 __u32 vii_ctime; /* Create time - sec */
166#define vii_org vdi_org 164 __u32 vii_cutime; /* Create time - usec */
167#define vii_orgtype vdi_orgtype 165 __u8 vii_orgtype; /* Organisation type */
168#define vii_gen vdi_gen 166 union {
169 167 __u32 rdev;
170#define vii_rdev vdi_ftarea.rdev 168 __u32 dotdot;
171#define vii_dotdot vdi_ftarea.dotdot 169 } vii_ftarea;
172#define vii_fixextsize vdi_ftarea.regular.fixextsize 170 __u32 vii_blocks; /* How much blocks does inode occupy */
173#define vii_matchino vdi_ftarea.vxspec.matchino 171 __u32 vii_gen; /* Inode generation */
174#define vii_fsetindex vdi_ftarea.vxspec.fsetindex 172 union {
175 173 struct vxfs_immed immed;
176#define vii_immed vdi_org.immed 174 struct vxfs_ext4 ext4;
177#define vii_ext4 vdi_org.ext4 175 struct vxfs_typed typed[VXFS_NTYPED];
178#define vii_typed vdi_org.typed 176 } vii_org;
177};
178
179#define vii_rdev vii_ftarea.rdev
180#define vii_dotdot vii_ftarea.dotdot
181
182#define vii_immed vii_org.immed
183#define vii_ext4 vii_org.ext4
184#define vii_typed vii_org.typed
179 185
180#endif /* _VXFS_INODE_H_ */ 186#endif /* _VXFS_INODE_H_ */
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
index 6d576b97f2c8..09e93b3a1582 100644
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -74,9 +74,10 @@ dir_blocks(struct inode *ip)
74 * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller. 74 * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
75 */ 75 */
76static inline int 76static inline int
77vxfs_match(int len, const char * const name, struct vxfs_direct *de) 77vxfs_match(struct vxfs_sb_info *sbi, int len, const char *const name,
78 struct vxfs_direct *de)
78{ 79{
79 if (len != de->d_namelen) 80 if (len != fs16_to_cpu(sbi, de->d_namelen))
80 return 0; 81 return 0;
81 if (!de->d_ino) 82 if (!de->d_ino)
82 return 0; 83 return 0;
@@ -84,9 +85,10 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de)
84} 85}
85 86
86static inline struct vxfs_direct * 87static inline struct vxfs_direct *
87vxfs_next_entry(struct vxfs_direct *de) 88vxfs_next_entry(struct vxfs_sb_info *sbi, struct vxfs_direct *de)
88{ 89{
89 return ((struct vxfs_direct *)((char*)de + de->d_reclen)); 90 return ((struct vxfs_direct *)
91 ((char *)de + fs16_to_cpu(sbi, de->d_reclen)));
90} 92}
91 93
92/** 94/**
@@ -106,6 +108,7 @@ vxfs_next_entry(struct vxfs_direct *de)
106static struct vxfs_direct * 108static struct vxfs_direct *
107vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp) 109vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
108{ 110{
111 struct vxfs_sb_info *sbi = VXFS_SBI(ip->i_sb);
109 u_long npages, page, nblocks, pblocks, block; 112 u_long npages, page, nblocks, pblocks, block;
110 u_long bsize = ip->i_sb->s_blocksize; 113 u_long bsize = ip->i_sb->s_blocksize;
111 const char *name = dp->d_name.name; 114 const char *name = dp->d_name.name;
@@ -133,14 +136,16 @@ vxfs_find_entry(struct inode *ip, struct dentry *dp, struct page **ppp)
133 limit = baddr + bsize - VXFS_DIRLEN(1); 136 limit = baddr + bsize - VXFS_DIRLEN(1);
134 137
135 dbp = (struct vxfs_dirblk *)baddr; 138 dbp = (struct vxfs_dirblk *)baddr;
136 de = (struct vxfs_direct *)(baddr + VXFS_DIRBLKOV(dbp)); 139 de = (struct vxfs_direct *)
140 (baddr + VXFS_DIRBLKOV(sbi, dbp));
137 141
138 for (; (caddr_t)de <= limit; de = vxfs_next_entry(de)) { 142 for (; (caddr_t)de <= limit;
143 de = vxfs_next_entry(sbi, de)) {
139 if (!de->d_reclen) 144 if (!de->d_reclen)
140 break; 145 break;
141 if (!de->d_ino) 146 if (!de->d_ino)
142 continue; 147 continue;
143 if (vxfs_match(namelen, name, de)) { 148 if (vxfs_match(sbi, namelen, name, de)) {
144 *ppp = pp; 149 *ppp = pp;
145 return (de); 150 return (de);
146 } 151 }
@@ -173,7 +178,7 @@ vxfs_inode_by_name(struct inode *dip, struct dentry *dp)
173 178
174 de = vxfs_find_entry(dip, dp, &pp); 179 de = vxfs_find_entry(dip, dp, &pp);
175 if (de) { 180 if (de) {
176 ino = de->d_ino; 181 ino = fs32_to_cpu(VXFS_SBI(dip->i_sb), de->d_ino);
177 kunmap(pp); 182 kunmap(pp);
178 put_page(pp); 183 put_page(pp);
179 } 184 }
@@ -232,10 +237,12 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
232{ 237{
233 struct inode *ip = file_inode(fp); 238 struct inode *ip = file_inode(fp);
234 struct super_block *sbp = ip->i_sb; 239 struct super_block *sbp = ip->i_sb;
240 struct vxfs_sb_info *sbi = VXFS_SBI(sbp);
235 u_long bsize = sbp->s_blocksize; 241 u_long bsize = sbp->s_blocksize;
236 u_long page, npages, block, pblocks, nblocks, offset; 242 u_long page, npages, block, pblocks, nblocks, offset;
237 loff_t pos; 243 loff_t pos;
238 244
245
239 if (ctx->pos == 0) { 246 if (ctx->pos == 0) {
240 if (!dir_emit_dot(fp, ctx)) 247 if (!dir_emit_dot(fp, ctx))
241 return 0; 248 return 0;
@@ -280,9 +287,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
280 de = (struct vxfs_direct *) 287 de = (struct vxfs_direct *)
281 (offset ? 288 (offset ?
282 (kaddr + offset) : 289 (kaddr + offset) :
283 (baddr + VXFS_DIRBLKOV(dbp))); 290 (baddr + VXFS_DIRBLKOV(sbi, dbp)));
284 291
285 for (; (char *)de <= limit; de = vxfs_next_entry(de)) { 292 for (; (char *)de <= limit;
293 de = vxfs_next_entry(sbi, de)) {
286 if (!de->d_reclen) 294 if (!de->d_reclen)
287 break; 295 break;
288 if (!de->d_ino) 296 if (!de->d_ino)
@@ -290,8 +298,10 @@ vxfs_readdir(struct file *fp, struct dir_context *ctx)
290 298
291 offset = (char *)de - kaddr; 299 offset = (char *)de - kaddr;
292 ctx->pos = ((page << PAGE_SHIFT) | offset) + 2; 300 ctx->pos = ((page << PAGE_SHIFT) | offset) + 2;
293 if (!dir_emit(ctx, de->d_name, de->d_namelen, 301 if (!dir_emit(ctx, de->d_name,
294 de->d_ino, DT_UNKNOWN)) { 302 fs16_to_cpu(sbi, de->d_namelen),
303 fs32_to_cpu(sbi, de->d_ino),
304 DT_UNKNOWN)) {
295 vxfs_put_page(pp); 305 vxfs_put_page(pp);
296 return 0; 306 return 0;
297 } 307 }
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 049500847903..813da6685151 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -43,14 +43,14 @@ static inline void
43vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) 43vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
44{ 44{
45 BUG_ON(infp->vsi_fshino); 45 BUG_ON(infp->vsi_fshino);
46 infp->vsi_fshino = fshp->olt_fsino[0]; 46 infp->vsi_fshino = fs32_to_cpu(infp, fshp->olt_fsino[0]);
47} 47}
48 48
49static inline void 49static inline void
50vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) 50vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
51{ 51{
52 BUG_ON(infp->vsi_iext); 52 BUG_ON(infp->vsi_iext);
53 infp->vsi_iext = ilistp->olt_iext[0]; 53 infp->vsi_iext = fs32_to_cpu(infp, ilistp->olt_iext[0]);
54} 54}
55 55
56static inline u_long 56static inline u_long
@@ -81,13 +81,12 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
81 struct vxfs_olt *op; 81 struct vxfs_olt *op;
82 char *oaddr, *eaddr; 82 char *oaddr, *eaddr;
83 83
84
85 bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize)); 84 bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
86 if (!bp || !bp->b_data) 85 if (!bp || !bp->b_data)
87 goto fail; 86 goto fail;
88 87
89 op = (struct vxfs_olt *)bp->b_data; 88 op = (struct vxfs_olt *)bp->b_data;
90 if (op->olt_magic != VXFS_OLT_MAGIC) { 89 if (fs32_to_cpu(infp, op->olt_magic) != VXFS_OLT_MAGIC) {
91 printk(KERN_NOTICE "vxfs: ivalid olt magic number\n"); 90 printk(KERN_NOTICE "vxfs: ivalid olt magic number\n");
92 goto fail; 91 goto fail;
93 } 92 }
@@ -102,14 +101,14 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
102 goto fail; 101 goto fail;
103 } 102 }
104 103
105 oaddr = bp->b_data + op->olt_size; 104 oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
106 eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize); 105 eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
107 106
108 while (oaddr < eaddr) { 107 while (oaddr < eaddr) {
109 struct vxfs_oltcommon *ocp = 108 struct vxfs_oltcommon *ocp =
110 (struct vxfs_oltcommon *)oaddr; 109 (struct vxfs_oltcommon *)oaddr;
111 110
112 switch (ocp->olt_type) { 111 switch (fs32_to_cpu(infp, ocp->olt_type)) {
113 case VXFS_OLT_FSHEAD: 112 case VXFS_OLT_FSHEAD:
114 vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp); 113 vxfs_get_fshead((struct vxfs_oltfshead *)oaddr, infp);
115 break; 114 break;
@@ -118,11 +117,11 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
118 break; 117 break;
119 } 118 }
120 119
121 oaddr += ocp->olt_size; 120 oaddr += fs32_to_cpu(infp, ocp->olt_size);
122 } 121 }
123 122
124 brelse(bp); 123 brelse(bp);
125 return 0; 124 return (infp->vsi_fshino && infp->vsi_iext) ? 0 : -EINVAL;
126 125
127fail: 126fail:
128 brelse(bp); 127 brelse(bp);
diff --git a/fs/freevxfs/vxfs_olt.h b/fs/freevxfs/vxfs_olt.h
index b7b3af502615..0c0b0c9fa557 100644
--- a/fs/freevxfs/vxfs_olt.h
+++ b/fs/freevxfs/vxfs_olt.h
@@ -63,83 +63,83 @@ enum {
63 * the initial inode list, the fileset header or the device configuration. 63 * the initial inode list, the fileset header or the device configuration.
64 */ 64 */
65struct vxfs_olt { 65struct vxfs_olt {
66 u_int32_t olt_magic; /* magic number */ 66 __fs32 olt_magic; /* magic number */
67 u_int32_t olt_size; /* size of this entry */ 67 __fs32 olt_size; /* size of this entry */
68 u_int32_t olt_checksum; /* checksum of extent */ 68 __fs32 olt_checksum; /* checksum of extent */
69 u_int32_t __unused1; /* ??? */ 69 __u32 __unused1; /* ??? */
70 u_int32_t olt_mtime; /* time of last mod. (sec) */ 70 __fs32 olt_mtime; /* time of last mod. (sec) */
71 u_int32_t olt_mutime; /* time of last mod. (usec) */ 71 __fs32 olt_mutime; /* time of last mod. (usec) */
72 u_int32_t olt_totfree; /* free space in OLT extent */ 72 __fs32 olt_totfree; /* free space in OLT extent */
73 vx_daddr_t olt_extents[2]; /* addr of this extent, replica */ 73 __fs32 olt_extents[2]; /* addr of this extent, replica */
74 u_int32_t olt_esize; /* size of this extent */ 74 __fs32 olt_esize; /* size of this extent */
75 vx_daddr_t olt_next[2]; /* addr of next extent, replica */ 75 __fs32 olt_next[2]; /* addr of next extent, replica */
76 u_int32_t olt_nsize; /* size of next extent */ 76 __fs32 olt_nsize; /* size of next extent */
77 u_int32_t __unused2; /* align to 8 byte boundary */ 77 __u32 __unused2; /* align to 8 byte boundary */
78}; 78};
79 79
80/* 80/*
81 * VxFS common OLT entry (on disk). 81 * VxFS common OLT entry (on disk).
82 */ 82 */
83struct vxfs_oltcommon { 83struct vxfs_oltcommon {
84 u_int32_t olt_type; /* type of this record */ 84 __fs32 olt_type; /* type of this record */
85 u_int32_t olt_size; /* size of this record */ 85 __fs32 olt_size; /* size of this record */
86}; 86};
87 87
88/* 88/*
89 * VxFS free OLT entry (on disk). 89 * VxFS free OLT entry (on disk).
90 */ 90 */
91struct vxfs_oltfree { 91struct vxfs_oltfree {
92 u_int32_t olt_type; /* type of this record */ 92 __fs32 olt_type; /* type of this record */
93 u_int32_t olt_fsize; /* size of this free record */ 93 __fs32 olt_fsize; /* size of this free record */
94}; 94};
95 95
96/* 96/*
97 * VxFS initial-inode list (on disk). 97 * VxFS initial-inode list (on disk).
98 */ 98 */
99struct vxfs_oltilist { 99struct vxfs_oltilist {
100 u_int32_t olt_type; /* type of this record */ 100 __fs32 olt_type; /* type of this record */
101 u_int32_t olt_size; /* size of this record */ 101 __fs32 olt_size; /* size of this record */
102 vx_ino_t olt_iext[2]; /* initial inode list, replica */ 102 __fs32 olt_iext[2]; /* initial inode list, replica */
103}; 103};
104 104
105/* 105/*
106 * Current Usage Table 106 * Current Usage Table
107 */ 107 */
108struct vxfs_oltcut { 108struct vxfs_oltcut {
109 u_int32_t olt_type; /* type of this record */ 109 __fs32 olt_type; /* type of this record */
110 u_int32_t olt_size; /* size of this record */ 110 __fs32 olt_size; /* size of this record */
111 vx_ino_t olt_cutino; /* inode of current usage table */ 111 __fs32 olt_cutino; /* inode of current usage table */
112 u_int32_t __pad; /* unused, 8 byte align */ 112 __u8 __pad; /* unused, 8 byte align */
113}; 113};
114 114
115/* 115/*
116 * Inodes containing Superblock, Intent log and OLTs 116 * Inodes containing Superblock, Intent log and OLTs
117 */ 117 */
118struct vxfs_oltsb { 118struct vxfs_oltsb {
119 u_int32_t olt_type; /* type of this record */ 119 __fs32 olt_type; /* type of this record */
120 u_int32_t olt_size; /* size of this record */ 120 __fs32 olt_size; /* size of this record */
121 vx_ino_t olt_sbino; /* inode of superblock file */ 121 __fs32 olt_sbino; /* inode of superblock file */
122 u_int32_t __unused1; /* ??? */ 122 __u32 __unused1; /* ??? */
123 vx_ino_t olt_logino[2]; /* inode of log file,replica */ 123 __fs32 olt_logino[2]; /* inode of log file,replica */
124 vx_ino_t olt_oltino[2]; /* inode of OLT, replica */ 124 __fs32 olt_oltino[2]; /* inode of OLT, replica */
125}; 125};
126 126
127/* 127/*
128 * Inode containing device configuration + it's replica 128 * Inode containing device configuration + it's replica
129 */ 129 */
130struct vxfs_oltdev { 130struct vxfs_oltdev {
131 u_int32_t olt_type; /* type of this record */ 131 __fs32 olt_type; /* type of this record */
132 u_int32_t olt_size; /* size of this record */ 132 __fs32 olt_size; /* size of this record */
133 vx_ino_t olt_devino[2]; /* inode of device config files */ 133 __fs32 olt_devino[2]; /* inode of device config files */
134}; 134};
135 135
136/* 136/*
137 * Fileset header 137 * Fileset header
138 */ 138 */
139struct vxfs_oltfshead { 139struct vxfs_oltfshead {
140 u_int32_t olt_type; /* type number */ 140 __fs32 olt_type; /* type number */
141 u_int32_t olt_size; /* size of this record */ 141 __fs32 olt_size; /* size of this record */
142 vx_ino_t olt_fsino[2]; /* inodes of fileset header */ 142 __fs32 olt_fsino[2]; /* inodes of fileset header */
143}; 143};
144 144
145#endif /* _VXFS_OLT_H_ */ 145#endif /* _VXFS_OLT_H_ */
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 7ca8c75d50d3..6124091b4fdb 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -109,14 +109,15 @@ static int
109vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp) 109vxfs_statfs(struct dentry *dentry, struct kstatfs *bufp)
110{ 110{
111 struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb); 111 struct vxfs_sb_info *infp = VXFS_SBI(dentry->d_sb);
112 struct vxfs_sb *raw_sb = infp->vsi_raw;
112 113
113 bufp->f_type = VXFS_SUPER_MAGIC; 114 bufp->f_type = VXFS_SUPER_MAGIC;
114 bufp->f_bsize = dentry->d_sb->s_blocksize; 115 bufp->f_bsize = dentry->d_sb->s_blocksize;
115 bufp->f_blocks = infp->vsi_raw->vs_dsize; 116 bufp->f_blocks = fs32_to_cpu(infp, raw_sb->vs_dsize);
116 bufp->f_bfree = infp->vsi_raw->vs_free; 117 bufp->f_bfree = fs32_to_cpu(infp, raw_sb->vs_free);
117 bufp->f_bavail = 0; 118 bufp->f_bavail = 0;
118 bufp->f_files = 0; 119 bufp->f_files = 0;
119 bufp->f_ffree = infp->vsi_raw->vs_ifree; 120 bufp->f_ffree = fs32_to_cpu(infp, raw_sb->vs_ifree);
120 bufp->f_namelen = VXFS_NAMELEN; 121 bufp->f_namelen = VXFS_NAMELEN;
121 122
122 return 0; 123 return 0;
@@ -129,6 +130,50 @@ static int vxfs_remount(struct super_block *sb, int *flags, char *data)
129 return 0; 130 return 0;
130} 131}
131 132
133
134static int vxfs_try_sb_magic(struct super_block *sbp, int silent,
135 unsigned blk, __fs32 magic)
136{
137 struct buffer_head *bp;
138 struct vxfs_sb *rsbp;
139 struct vxfs_sb_info *infp = VXFS_SBI(sbp);
140 int rc = -ENOMEM;
141
142 bp = sb_bread(sbp, blk);
143 do {
144 if (!bp || !buffer_mapped(bp)) {
145 if (!silent) {
146 printk(KERN_WARNING
147 "vxfs: unable to read disk superblock at %u\n",
148 blk);
149 }
150 break;
151 }
152
153 rc = -EINVAL;
154 rsbp = (struct vxfs_sb *)bp->b_data;
155 if (rsbp->vs_magic != magic) {
156 if (!silent)
157 printk(KERN_NOTICE
158 "vxfs: WRONG superblock magic %08x at %u\n",
159 rsbp->vs_magic, blk);
160 break;
161 }
162
163 rc = 0;
164 infp->vsi_raw = rsbp;
165 infp->vsi_bp = bp;
166 } while (0);
167
168 if (rc) {
169 infp->vsi_raw = NULL;
170 infp->vsi_bp = NULL;
171 brelse(bp);
172 }
173
174 return rc;
175}
176
132/** 177/**
133 * vxfs_read_super - read superblock into memory and initialize filesystem 178 * vxfs_read_super - read superblock into memory and initialize filesystem
134 * @sbp: VFS superblock (to fill) 179 * @sbp: VFS superblock (to fill)
@@ -149,10 +194,10 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
149{ 194{
150 struct vxfs_sb_info *infp; 195 struct vxfs_sb_info *infp;
151 struct vxfs_sb *rsbp; 196 struct vxfs_sb *rsbp;
152 struct buffer_head *bp = NULL;
153 u_long bsize; 197 u_long bsize;
154 struct inode *root; 198 struct inode *root;
155 int ret = -EINVAL; 199 int ret = -EINVAL;
200 u32 j;
156 201
157 sbp->s_flags |= MS_RDONLY; 202 sbp->s_flags |= MS_RDONLY;
158 203
@@ -168,42 +213,42 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
168 goto out; 213 goto out;
169 } 214 }
170 215
171 bp = sb_bread(sbp, 1); 216 sbp->s_fs_info = infp;
172 if (!bp || !buffer_mapped(bp)) {
173 if (!silent) {
174 printk(KERN_WARNING
175 "vxfs: unable to read disk superblock\n");
176 }
177 goto out;
178 }
179 217
180 rsbp = (struct vxfs_sb *)bp->b_data; 218 if (!vxfs_try_sb_magic(sbp, silent, 1,
181 if (rsbp->vs_magic != VXFS_SUPER_MAGIC) { 219 (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
220 /* Unixware, x86 */
221 infp->byte_order = VXFS_BO_LE;
222 } else if (!vxfs_try_sb_magic(sbp, silent, 8,
223 (__force __fs32)cpu_to_be32(VXFS_SUPER_MAGIC))) {
224 /* HP-UX, parisc */
225 infp->byte_order = VXFS_BO_BE;
226 } else {
182 if (!silent) 227 if (!silent)
183 printk(KERN_NOTICE "vxfs: WRONG superblock magic\n"); 228 printk(KERN_NOTICE "vxfs: can't find superblock.\n");
184 goto out; 229 goto out;
185 } 230 }
186 231
187 if ((rsbp->vs_version < 2 || rsbp->vs_version > 4) && !silent) { 232 rsbp = infp->vsi_raw;
188 printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", 233 j = fs32_to_cpu(infp, rsbp->vs_version);
189 rsbp->vs_version); 234 if ((j < 2 || j > 4) && !silent) {
235 printk(KERN_NOTICE "vxfs: unsupported VxFS version (%d)\n", j);
190 goto out; 236 goto out;
191 } 237 }
192 238
193#ifdef DIAGNOSTIC 239#ifdef DIAGNOSTIC
194 printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", rsbp->vs_version); 240 printk(KERN_DEBUG "vxfs: supported VxFS version (%d)\n", j);
195 printk(KERN_DEBUG "vxfs: blocksize: %d\n", rsbp->vs_bsize); 241 printk(KERN_DEBUG "vxfs: blocksize: %d\n",
242 fs32_to_cpu(infp, rsbp->vs_bsize));
196#endif 243#endif
197 244
198 sbp->s_magic = rsbp->vs_magic; 245 sbp->s_magic = fs32_to_cpu(infp, rsbp->vs_magic);
199 sbp->s_fs_info = infp;
200 246
201 infp->vsi_raw = rsbp; 247 infp->vsi_oltext = fs32_to_cpu(infp, rsbp->vs_oltext[0]);
202 infp->vsi_bp = bp; 248 infp->vsi_oltsize = fs32_to_cpu(infp, rsbp->vs_oltsize);
203 infp->vsi_oltext = rsbp->vs_oltext[0];
204 infp->vsi_oltsize = rsbp->vs_oltsize;
205 249
206 if (!sb_set_blocksize(sbp, rsbp->vs_bsize)) { 250 j = fs32_to_cpu(infp, rsbp->vs_bsize);
251 if (!sb_set_blocksize(sbp, j)) {
207 printk(KERN_WARNING "vxfs: unable to set final block size\n"); 252 printk(KERN_WARNING "vxfs: unable to set final block size\n");
208 goto out; 253 goto out;
209 } 254 }
@@ -237,7 +282,7 @@ out_free_ilist:
237 vxfs_put_fake_inode(infp->vsi_ilist); 282 vxfs_put_fake_inode(infp->vsi_ilist);
238 vxfs_put_fake_inode(infp->vsi_stilist); 283 vxfs_put_fake_inode(infp->vsi_stilist);
239out: 284out:
240 brelse(bp); 285 brelse(infp->vsi_bp);
241 kfree(infp); 286 kfree(infp);
242 return ret; 287 return ret;
243} 288}