From: viro@www.linux.org.uk Similar fix for UFS; touching device node (and they have 32bit dev_t) ends up killing upper 16 bits, which makes for very unhappy *BSD, since that turns /dev/ad0s1 into alias of /dev/ad0. Again, for now we store on-disk value in private part of inode and use it instead of ->i_rdev in ->write_inode(). fs/ufs/inode.c | 16 ++++++++-------- fs/ufs/namei.c | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff -puN fs/ufs/inode.c~large-dev_t-2nd-12 fs/ufs/inode.c --- 25/fs/ufs/inode.c~large-dev_t-2nd-12 2003-09-05 00:50:10.000000000 -0700 +++ 25-akpm/fs/ufs/inode.c 2003-09-05 00:50:10.000000000 -0700 @@ -475,6 +475,7 @@ void ufs_read_inode (struct inode * inod struct ufs_sb_private_info * uspi; struct ufs_inode * ufs_inode; struct buffer_head * bh; + mode_t mode; unsigned i; unsigned flags; @@ -500,7 +501,7 @@ void ufs_read_inode (struct inode * inod /* * Copy data to the in-core inode. */ - inode->i_mode = fs16_to_cpu(sb, ufs_inode->ui_mode); + inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode); inode->i_nlink = fs16_to_cpu(sb, ufs_inode->ui_nlink); if (inode->i_nlink == 0) ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino); @@ -527,9 +528,7 @@ void ufs_read_inode (struct inode * inod ufsi->i_oeftflag = fs32_to_cpu(sb, ufs_inode->ui_u3.ui_sun.ui_oeftflag); ufsi->i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - ; - else if (inode->i_blocks) { + if (S_ISCHR(mode) || S_ISBLK(mode) || inode->i_blocks) { for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) ufsi->i_u1.i_data[i] = ufs_inode->ui_u2.ui_addr.ui_db[i]; } @@ -555,7 +554,7 @@ void ufs_read_inode (struct inode * inod } } else init_special_inode(inode, inode->i_mode, - fs32_to_cpu(sb, ufs_inode->ui_u2.ui_addr.ui_db[0])); + old_decode_dev(fs32_to_cpu(sb, ufsi->i_u1.i_data[0]))); brelse (bh); @@ -618,9 +617,10 @@ static int ufs_update_inode(struct inode ufs_inode->ui_u3.ui_sun.ui_oeftflag = cpu_to_fs32(sb, ufsi->i_oeftflag); } - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) - ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); - else if (inode->i_blocks) { + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { + /* ufs_inode->ui_u2.ui_addr.ui_db[0] = cpu_to_fs32(sb, inode->i_rdev); */ + ufs_inode->ui_u2.ui_addr.ui_db[0] = ufsi->i_u1.i_data[0]; + } else if (inode->i_blocks) { for (i = 0; i < (UFS_NDADDR + UFS_NINDIR); i++) ufs_inode->ui_u2.ui_addr.ui_db[i] = ufsi->i_u1.i_data[i]; } diff -puN fs/ufs/namei.c~large-dev_t-2nd-12 fs/ufs/namei.c --- 25/fs/ufs/namei.c~large-dev_t-2nd-12 2003-09-05 00:50:10.000000000 -0700 +++ 25-akpm/fs/ufs/namei.c 2003-09-05 00:50:10.000000000 -0700 @@ -29,6 +29,7 @@ #include #include #include +#include "swab.h" /* will go away - see comment in mknod() */ #undef UFS_NAMEI_DEBUG @@ -115,6 +116,9 @@ static int ufs_mknod (struct inode * dir int err = PTR_ERR(inode); 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)); mark_inode_dirty(inode); lock_kernel(); err = ufs_add_nondir(dentry, inode); _