From: Alex Kiernan Fix handling of device inodes on Solaris x86 filesystems, add support for large dev_t against Solaris UFS filesystems. Signed-off-by: Andrew Morton --- 25-akpm/fs/ufs/inode.c | 4 +-- 25-akpm/fs/ufs/namei.c | 4 +-- 25-akpm/fs/ufs/util.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 25-akpm/fs/ufs/util.h | 2 + 4 files changed, 59 insertions(+), 4 deletions(-) diff -puN fs/ufs/inode.c~solaris-ufs-fix fs/ufs/inode.c --- 25/fs/ufs/inode.c~solaris-ufs-fix Wed Oct 20 15:05:00 2004 +++ 25-akpm/fs/ufs/inode.c Wed Oct 20 15:05:00 2004 @@ -629,7 +629,7 @@ void ufs_read_inode (struct inode * inod } } else init_special_inode(inode, inode->i_mode, - old_decode_dev(fs32_to_cpu(sb, ufsi->i_u1.i_data[0]))); + ufs_get_inode_dev(sb, ufsi)); brelse (bh); @@ -705,7 +705,7 @@ ufs2_inode : } } else /* TODO : here ...*/ init_special_inode(inode, inode->i_mode, - old_decode_dev(fs32_to_cpu(sb, ufsi->i_u1.i_data[0]))); + ufs_get_inode_dev(sb, ufsi)); brelse(bh); diff -puN fs/ufs/namei.c~solaris-ufs-fix fs/ufs/namei.c --- 25/fs/ufs/namei.c~solaris-ufs-fix Wed Oct 20 15:05:00 2004 +++ 25-akpm/fs/ufs/namei.c Wed Oct 20 15:05:00 2004 @@ -30,6 +30,7 @@ #include #include #include "swab.h" /* will go away - see comment in mknod() */ +#include "util.h" /* #undef UFS_NAMEI_DEBUG @@ -125,8 +126,7 @@ static int ufs_mknod (struct inode * dir if (!IS_ERR(inode)) { init_special_inode(inode, mode, rdev); /* NOTE: that'll go when we get wide dev_t */ - UFS_I(inode)->i_u1.i_data[0] = cpu_to_fs32(inode->i_sb, - old_encode_dev(rdev)); + ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev); mark_inode_dirty(inode); lock_kernel(); err = ufs_add_nondir(dentry, inode); diff -puN fs/ufs/util.c~solaris-ufs-fix fs/ufs/util.c --- 25/fs/ufs/util.c~solaris-ufs-fix Wed Oct 20 15:05:00 2004 +++ 25-akpm/fs/ufs/util.c Wed Oct 20 15:05:00 2004 @@ -202,3 +202,56 @@ void _ubh_memcpyubh_(struct ufs_sb_priva bhno++; } } + +dev_t +ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi) +{ + __fs32 fs32; + dev_t dev; + + if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) + fs32 = ufsi->i_u1.i_data[1]; + else + fs32 = ufsi->i_u1.i_data[0]; + fs32 = fs32_to_cpu(sb, fs32); + switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { + case UFS_ST_SUNx86: + case UFS_ST_SUN: + if ((fs32 & 0xffff0000) == 0 || + (fs32 & 0xffff0000) == 0xffff0000) + dev = old_decode_dev(fs32 & 0x7fff); + else + dev = MKDEV(sysv_major(fs32), sysv_minor(fs32)); + break; + + default: + dev = old_decode_dev(fs32); + break; + } + return dev; +} + +void +ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev) +{ + __fs32 fs32; + + switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) { + case UFS_ST_SUNx86: + case UFS_ST_SUN: + fs32 = sysv_encode_dev(dev); + if ((fs32 & 0xffff8000) == 0) { + fs32 = old_encode_dev(dev); + } + break; + + default: + fs32 = old_encode_dev(dev); + break; + } + fs32 = cpu_to_fs32(sb, fs32); + if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86) + ufsi->i_u1.i_data[1] = fs32; + else + ufsi->i_u1.i_data[0] = fs32; +} diff -puN fs/ufs/util.h~solaris-ufs-fix fs/ufs/util.h --- 25/fs/ufs/util.h~solaris-ufs-fix Wed Oct 20 15:05:00 2004 +++ 25-akpm/fs/ufs/util.h Wed Oct 20 15:05:00 2004 @@ -223,6 +223,8 @@ ufs_set_inode_gid(struct super_block *sb inode->ui_u1.oldids.ui_sgid = cpu_to_fs16(sb, value); } +extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); +extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); /* * These functions manipulate ufs buffers _