diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 92 |
1 files changed, 25 insertions, 67 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1377c868f3f4..58bfe629b933 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -104,7 +104,7 @@ xfs_open( | |||
| 104 | * If it's a directory with any blocks, read-ahead block 0 | 104 | * If it's a directory with any blocks, read-ahead block 0 |
| 105 | * as we're almost certain to have the next operation be a read there. | 105 | * as we're almost certain to have the next operation be a read there. |
| 106 | */ | 106 | */ |
| 107 | if (vp->v_type == VDIR && ip->i_d.di_nextents > 0) { | 107 | if (VN_ISDIR(vp) && ip->i_d.di_nextents > 0) { |
| 108 | mode = xfs_ilock_map_shared(ip); | 108 | mode = xfs_ilock_map_shared(ip); |
| 109 | if (ip->i_d.di_nextents > 0) | 109 | if (ip->i_d.di_nextents > 0) |
| 110 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); | 110 | (void)xfs_da_reada_buf(NULL, ip, 0, XFS_DATA_FORK); |
| @@ -163,18 +163,21 @@ xfs_getattr( | |||
| 163 | /* | 163 | /* |
| 164 | * Copy from in-core inode. | 164 | * Copy from in-core inode. |
| 165 | */ | 165 | */ |
| 166 | vap->va_type = vp->v_type; | 166 | vap->va_mode = ip->i_d.di_mode; |
| 167 | vap->va_mode = ip->i_d.di_mode & MODEMASK; | ||
| 168 | vap->va_uid = ip->i_d.di_uid; | 167 | vap->va_uid = ip->i_d.di_uid; |
| 169 | vap->va_gid = ip->i_d.di_gid; | 168 | vap->va_gid = ip->i_d.di_gid; |
| 170 | vap->va_projid = ip->i_d.di_projid; | 169 | vap->va_projid = ip->i_d.di_projid; |
| 171 | 170 | ||
| 172 | /* | 171 | /* |
| 173 | * Check vnode type block/char vs. everything else. | 172 | * Check vnode type block/char vs. everything else. |
| 174 | * Do it with bitmask because that's faster than looking | ||
| 175 | * for multiple values individually. | ||
| 176 | */ | 173 | */ |
| 177 | if (((1 << vp->v_type) & ((1<<VBLK) | (1<<VCHR))) == 0) { | 174 | switch (ip->i_d.di_mode & S_IFMT) { |
| 175 | case S_IFBLK: | ||
| 176 | case S_IFCHR: | ||
| 177 | vap->va_rdev = ip->i_df.if_u2.if_rdev; | ||
| 178 | vap->va_blocksize = BLKDEV_IOSIZE; | ||
| 179 | break; | ||
| 180 | default: | ||
| 178 | vap->va_rdev = 0; | 181 | vap->va_rdev = 0; |
| 179 | 182 | ||
| 180 | if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | 183 | if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { |
| @@ -224,9 +227,7 @@ xfs_getattr( | |||
| 224 | (ip->i_d.di_extsize << mp->m_sb.sb_blocklog) : | 227 | (ip->i_d.di_extsize << mp->m_sb.sb_blocklog) : |
| 225 | (mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog); | 228 | (mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog); |
| 226 | } | 229 | } |
| 227 | } else { | 230 | break; |
| 228 | vap->va_rdev = ip->i_df.if_u2.if_rdev; | ||
| 229 | vap->va_blocksize = BLKDEV_IOSIZE; | ||
| 230 | } | 231 | } |
| 231 | 232 | ||
| 232 | vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec; | 233 | vap->va_atime.tv_sec = ip->i_d.di_atime.t_sec; |
| @@ -468,7 +469,7 @@ xfs_setattr( | |||
| 468 | m |= S_ISGID; | 469 | m |= S_ISGID; |
| 469 | #if 0 | 470 | #if 0 |
| 470 | /* Linux allows this, Irix doesn't. */ | 471 | /* Linux allows this, Irix doesn't. */ |
| 471 | if ((vap->va_mode & S_ISVTX) && vp->v_type != VDIR) | 472 | if ((vap->va_mode & S_ISVTX) && !VN_ISDIR(vp)) |
| 472 | m |= S_ISVTX; | 473 | m |= S_ISVTX; |
| 473 | #endif | 474 | #endif |
| 474 | if (m && !capable(CAP_FSETID)) | 475 | if (m && !capable(CAP_FSETID)) |
| @@ -546,10 +547,10 @@ xfs_setattr( | |||
| 546 | goto error_return; | 547 | goto error_return; |
| 547 | } | 548 | } |
| 548 | 549 | ||
| 549 | if (vp->v_type == VDIR) { | 550 | if (VN_ISDIR(vp)) { |
| 550 | code = XFS_ERROR(EISDIR); | 551 | code = XFS_ERROR(EISDIR); |
| 551 | goto error_return; | 552 | goto error_return; |
| 552 | } else if (vp->v_type != VREG) { | 553 | } else if (!VN_ISREG(vp)) { |
| 553 | code = XFS_ERROR(EINVAL); | 554 | code = XFS_ERROR(EINVAL); |
| 554 | goto error_return; | 555 | goto error_return; |
| 555 | } | 556 | } |
| @@ -1567,7 +1568,7 @@ xfs_release( | |||
| 1567 | vp = BHV_TO_VNODE(bdp); | 1568 | vp = BHV_TO_VNODE(bdp); |
| 1568 | ip = XFS_BHVTOI(bdp); | 1569 | ip = XFS_BHVTOI(bdp); |
| 1569 | 1570 | ||
| 1570 | if ((vp->v_type != VREG) || (ip->i_d.di_mode == 0)) { | 1571 | if (!VN_ISREG(vp) || (ip->i_d.di_mode == 0)) { |
| 1571 | return 0; | 1572 | return 0; |
| 1572 | } | 1573 | } |
| 1573 | 1574 | ||
| @@ -1895,7 +1896,7 @@ xfs_create( | |||
| 1895 | dp = XFS_BHVTOI(dir_bdp); | 1896 | dp = XFS_BHVTOI(dir_bdp); |
| 1896 | mp = dp->i_mount; | 1897 | mp = dp->i_mount; |
| 1897 | 1898 | ||
| 1898 | dm_di_mode = vap->va_mode|VTTOIF(vap->va_type); | 1899 | dm_di_mode = vap->va_mode; |
| 1899 | namelen = VNAMELEN(dentry); | 1900 | namelen = VNAMELEN(dentry); |
| 1900 | 1901 | ||
| 1901 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { | 1902 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { |
| @@ -1973,8 +1974,7 @@ xfs_create( | |||
| 1973 | (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen))) | 1974 | (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen))) |
| 1974 | goto error_return; | 1975 | goto error_return; |
| 1975 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; | 1976 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; |
| 1976 | error = xfs_dir_ialloc(&tp, dp, | 1977 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, |
| 1977 | MAKEIMODE(vap->va_type,vap->va_mode), 1, | ||
| 1978 | rdev, credp, prid, resblks > 0, | 1978 | rdev, credp, prid, resblks > 0, |
| 1979 | &ip, &committed); | 1979 | &ip, &committed); |
| 1980 | if (error) { | 1980 | if (error) { |
| @@ -2620,7 +2620,7 @@ xfs_link( | |||
| 2620 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); | 2620 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); |
| 2621 | 2621 | ||
| 2622 | target_namelen = VNAMELEN(dentry); | 2622 | target_namelen = VNAMELEN(dentry); |
| 2623 | if (src_vp->v_type == VDIR) | 2623 | if (VN_ISDIR(src_vp)) |
| 2624 | return XFS_ERROR(EPERM); | 2624 | return XFS_ERROR(EPERM); |
| 2625 | 2625 | ||
| 2626 | src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); | 2626 | src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops); |
| @@ -2805,7 +2805,7 @@ xfs_mkdir( | |||
| 2805 | 2805 | ||
| 2806 | tp = NULL; | 2806 | tp = NULL; |
| 2807 | dp_joined_to_trans = B_FALSE; | 2807 | dp_joined_to_trans = B_FALSE; |
| 2808 | dm_di_mode = vap->va_mode|VTTOIF(vap->va_type); | 2808 | dm_di_mode = vap->va_mode; |
| 2809 | 2809 | ||
| 2810 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { | 2810 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_CREATE)) { |
| 2811 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, | 2811 | error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE, |
| @@ -2879,8 +2879,7 @@ xfs_mkdir( | |||
| 2879 | /* | 2879 | /* |
| 2880 | * create the directory inode. | 2880 | * create the directory inode. |
| 2881 | */ | 2881 | */ |
| 2882 | error = xfs_dir_ialloc(&tp, dp, | 2882 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 2, |
| 2883 | MAKEIMODE(vap->va_type,vap->va_mode), 2, | ||
| 2884 | 0, credp, prid, resblks > 0, | 2883 | 0, credp, prid, resblks > 0, |
| 2885 | &cdp, NULL); | 2884 | &cdp, NULL); |
| 2886 | if (error) { | 2885 | if (error) { |
| @@ -3650,7 +3649,7 @@ xfs_rwlock( | |||
| 3650 | vnode_t *vp; | 3649 | vnode_t *vp; |
| 3651 | 3650 | ||
| 3652 | vp = BHV_TO_VNODE(bdp); | 3651 | vp = BHV_TO_VNODE(bdp); |
| 3653 | if (vp->v_type == VDIR) | 3652 | if (VN_ISDIR(vp)) |
| 3654 | return 1; | 3653 | return 1; |
| 3655 | ip = XFS_BHVTOI(bdp); | 3654 | ip = XFS_BHVTOI(bdp); |
| 3656 | if (locktype == VRWLOCK_WRITE) { | 3655 | if (locktype == VRWLOCK_WRITE) { |
| @@ -3681,7 +3680,7 @@ xfs_rwunlock( | |||
| 3681 | vnode_t *vp; | 3680 | vnode_t *vp; |
| 3682 | 3681 | ||
| 3683 | vp = BHV_TO_VNODE(bdp); | 3682 | vp = BHV_TO_VNODE(bdp); |
| 3684 | if (vp->v_type == VDIR) | 3683 | if (VN_ISDIR(vp)) |
| 3685 | return; | 3684 | return; |
| 3686 | ip = XFS_BHVTOI(bdp); | 3685 | ip = XFS_BHVTOI(bdp); |
| 3687 | if (locktype == VRWLOCK_WRITE) { | 3686 | if (locktype == VRWLOCK_WRITE) { |
| @@ -3847,51 +3846,10 @@ xfs_reclaim( | |||
| 3847 | return 0; | 3846 | return 0; |
| 3848 | } | 3847 | } |
| 3849 | 3848 | ||
| 3850 | if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) { | 3849 | vn_iowait(vp); |
| 3851 | if (ip->i_d.di_size > 0) { | ||
| 3852 | /* | ||
| 3853 | * Flush and invalidate any data left around that is | ||
| 3854 | * a part of this file. | ||
| 3855 | * | ||
| 3856 | * Get the inode's i/o lock so that buffers are pushed | ||
| 3857 | * out while holding the proper lock. We can't hold | ||
| 3858 | * the inode lock here since flushing out buffers may | ||
| 3859 | * cause us to try to get the lock in xfs_strategy(). | ||
| 3860 | * | ||
| 3861 | * We don't have to call remapf() here, because there | ||
| 3862 | * cannot be any mapped file references to this vnode | ||
| 3863 | * since it is being reclaimed. | ||
| 3864 | */ | ||
| 3865 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
| 3866 | |||
| 3867 | /* | ||
| 3868 | * If we hit an IO error, we need to make sure that the | ||
| 3869 | * buffer and page caches of file data for | ||
| 3870 | * the file are tossed away. We don't want to use | ||
| 3871 | * VOP_FLUSHINVAL_PAGES here because we don't want dirty | ||
| 3872 | * pages to stay attached to the vnode, but be | ||
| 3873 | * marked P_BAD. pdflush/vnode_pagebad | ||
| 3874 | * hates that. | ||
| 3875 | */ | ||
| 3876 | if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { | ||
| 3877 | VOP_FLUSHINVAL_PAGES(vp, 0, -1, FI_NONE); | ||
| 3878 | } else { | ||
| 3879 | VOP_TOSS_PAGES(vp, 0, -1, FI_NONE); | ||
| 3880 | } | ||
| 3881 | 3850 | ||
| 3882 | ASSERT(VN_CACHED(vp) == 0); | 3851 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); |
| 3883 | ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || | 3852 | ASSERT(VN_CACHED(vp) == 0); |
| 3884 | ip->i_delayed_blks == 0); | ||
| 3885 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
| 3886 | } else if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { | ||
| 3887 | /* | ||
| 3888 | * di_size field may not be quite accurate if we're | ||
| 3889 | * shutting down. | ||
| 3890 | */ | ||
| 3891 | VOP_TOSS_PAGES(vp, 0, -1, FI_NONE); | ||
| 3892 | ASSERT(VN_CACHED(vp) == 0); | ||
| 3893 | } | ||
| 3894 | } | ||
| 3895 | 3853 | ||
| 3896 | /* If we have nothing to flush with this inode then complete the | 3854 | /* If we have nothing to flush with this inode then complete the |
| 3897 | * teardown now, otherwise break the link between the xfs inode | 3855 | * teardown now, otherwise break the link between the xfs inode |
| @@ -4567,7 +4525,7 @@ xfs_change_file_space( | |||
| 4567 | /* | 4525 | /* |
| 4568 | * must be a regular file and have write permission | 4526 | * must be a regular file and have write permission |
| 4569 | */ | 4527 | */ |
| 4570 | if (vp->v_type != VREG) | 4528 | if (!VN_ISREG(vp)) |
| 4571 | return XFS_ERROR(EINVAL); | 4529 | return XFS_ERROR(EINVAL); |
| 4572 | 4530 | ||
| 4573 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 4531 | xfs_ilock(ip, XFS_ILOCK_SHARED); |
