diff options
author | Krzysztof Błaszkowski <kb@sysmikro.com.pl> | 2016-05-31 09:45:13 +0300 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2016-06-01 10:01:28 +0300 |
commit | 0d83f7fc83f77d1cc8395b9e851325d8cc1892e3 (patch) | |
tree | 9cfc6aef0a098884097fd37bb413639e8e76f461 /fs/freevxfs/vxfs_lookup.c | |
parent | 6b15d6650c5301ce023d8df0cc3a60b1a76d377e (diff) | |
download | linux-0d83f7fc83f77d1cc8395b9e851325d8cc1892e3.tar.xz |
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>
Diffstat (limited to 'fs/freevxfs/vxfs_lookup.c')
-rw-r--r-- | fs/freevxfs/vxfs_lookup.c | 34 |
1 files changed, 22 insertions, 12 deletions
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) * 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; } |