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); |