diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
| -rw-r--r-- | fs/xfs/xfs_vnodeops.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 00a6b7dc24a0..061e2ffdd1de 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -2366,10 +2366,15 @@ xfs_remove( | |||
| 2366 | 2366 | ||
| 2367 | namelen = VNAMELEN(dentry); | 2367 | namelen = VNAMELEN(dentry); |
| 2368 | 2368 | ||
| 2369 | if (!xfs_get_dir_entry(dentry, &ip)) { | ||
| 2370 | dm_di_mode = ip->i_d.di_mode; | ||
| 2371 | IRELE(ip); | ||
| 2372 | } | ||
| 2373 | |||
| 2369 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 2374 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { |
| 2370 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, | 2375 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, |
| 2371 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, | 2376 | DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, |
| 2372 | name, NULL, 0, 0, 0); | 2377 | name, NULL, dm_di_mode, 0, 0); |
| 2373 | if (error) | 2378 | if (error) |
| 2374 | return error; | 2379 | return error; |
| 2375 | } | 2380 | } |
| @@ -2603,8 +2608,7 @@ xfs_link( | |||
| 2603 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); | 2608 | vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); |
| 2604 | 2609 | ||
| 2605 | target_namelen = VNAMELEN(dentry); | 2610 | target_namelen = VNAMELEN(dentry); |
| 2606 | if (VN_ISDIR(src_vp)) | 2611 | ASSERT(!VN_ISDIR(src_vp)); |
| 2607 | return XFS_ERROR(EPERM); | ||
| 2608 | 2612 | ||
| 2609 | sip = xfs_vtoi(src_vp); | 2613 | sip = xfs_vtoi(src_vp); |
| 2610 | tdp = XFS_BHVTOI(target_dir_bdp); | 2614 | tdp = XFS_BHVTOI(target_dir_bdp); |
| @@ -2699,9 +2703,8 @@ xfs_link( | |||
| 2699 | xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE); | 2703 | xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE); |
| 2700 | 2704 | ||
| 2701 | error = xfs_bumplink(tp, sip); | 2705 | error = xfs_bumplink(tp, sip); |
| 2702 | if (error) { | 2706 | if (error) |
| 2703 | goto abort_return; | 2707 | goto abort_return; |
| 2704 | } | ||
| 2705 | 2708 | ||
| 2706 | /* | 2709 | /* |
| 2707 | * If this is a synchronous mount, make sure that the | 2710 | * If this is a synchronous mount, make sure that the |
| @@ -2719,9 +2722,8 @@ xfs_link( | |||
| 2719 | } | 2722 | } |
| 2720 | 2723 | ||
| 2721 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); | 2724 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); |
| 2722 | if (error) { | 2725 | if (error) |
| 2723 | goto std_return; | 2726 | goto std_return; |
| 2724 | } | ||
| 2725 | 2727 | ||
| 2726 | /* Fall through to std_return with error = 0. */ | 2728 | /* Fall through to std_return with error = 0. */ |
| 2727 | std_return: | 2729 | std_return: |
| @@ -2742,6 +2744,8 @@ std_return: | |||
| 2742 | xfs_trans_cancel(tp, cancel_flags); | 2744 | xfs_trans_cancel(tp, cancel_flags); |
| 2743 | goto std_return; | 2745 | goto std_return; |
| 2744 | } | 2746 | } |
| 2747 | |||
| 2748 | |||
| 2745 | /* | 2749 | /* |
| 2746 | * xfs_mkdir | 2750 | * xfs_mkdir |
| 2747 | * | 2751 | * |
| @@ -2996,7 +3000,7 @@ xfs_rmdir( | |||
| 2996 | int cancel_flags; | 3000 | int cancel_flags; |
| 2997 | int committed; | 3001 | int committed; |
| 2998 | bhv_vnode_t *dir_vp; | 3002 | bhv_vnode_t *dir_vp; |
| 2999 | int dm_di_mode = 0; | 3003 | int dm_di_mode = S_IFDIR; |
| 3000 | int last_cdp_link; | 3004 | int last_cdp_link; |
| 3001 | int namelen; | 3005 | int namelen; |
| 3002 | uint resblks; | 3006 | uint resblks; |
| @@ -3011,11 +3015,16 @@ xfs_rmdir( | |||
| 3011 | return XFS_ERROR(EIO); | 3015 | return XFS_ERROR(EIO); |
| 3012 | namelen = VNAMELEN(dentry); | 3016 | namelen = VNAMELEN(dentry); |
| 3013 | 3017 | ||
| 3018 | if (!xfs_get_dir_entry(dentry, &cdp)) { | ||
| 3019 | dm_di_mode = cdp->i_d.di_mode; | ||
| 3020 | IRELE(cdp); | ||
| 3021 | } | ||
| 3022 | |||
| 3014 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { | 3023 | if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { |
| 3015 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, | 3024 | error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, |
| 3016 | dir_vp, DM_RIGHT_NULL, | 3025 | dir_vp, DM_RIGHT_NULL, |
| 3017 | NULL, DM_RIGHT_NULL, | 3026 | NULL, DM_RIGHT_NULL, |
| 3018 | name, NULL, 0, 0, 0); | 3027 | name, NULL, dm_di_mode, 0, 0); |
| 3019 | if (error) | 3028 | if (error) |
| 3020 | return XFS_ERROR(error); | 3029 | return XFS_ERROR(error); |
| 3021 | } | 3030 | } |
| @@ -3835,7 +3844,9 @@ xfs_reclaim( | |||
| 3835 | XFS_MOUNT_ILOCK(mp); | 3844 | XFS_MOUNT_ILOCK(mp); |
| 3836 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | 3845 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); |
| 3837 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); | 3846 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); |
| 3847 | spin_lock(&ip->i_flags_lock); | ||
| 3838 | ip->i_flags |= XFS_IRECLAIMABLE; | 3848 | ip->i_flags |= XFS_IRECLAIMABLE; |
| 3849 | spin_unlock(&ip->i_flags_lock); | ||
| 3839 | XFS_MOUNT_IUNLOCK(mp); | 3850 | XFS_MOUNT_IUNLOCK(mp); |
| 3840 | } | 3851 | } |
| 3841 | return 0; | 3852 | return 0; |
| @@ -3860,8 +3871,10 @@ xfs_finish_reclaim( | |||
| 3860 | * us. | 3871 | * us. |
| 3861 | */ | 3872 | */ |
| 3862 | write_lock(&ih->ih_lock); | 3873 | write_lock(&ih->ih_lock); |
| 3874 | spin_lock(&ip->i_flags_lock); | ||
| 3863 | if ((ip->i_flags & XFS_IRECLAIM) || | 3875 | if ((ip->i_flags & XFS_IRECLAIM) || |
| 3864 | (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { | 3876 | (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { |
| 3877 | spin_unlock(&ip->i_flags_lock); | ||
| 3865 | write_unlock(&ih->ih_lock); | 3878 | write_unlock(&ih->ih_lock); |
| 3866 | if (locked) { | 3879 | if (locked) { |
| 3867 | xfs_ifunlock(ip); | 3880 | xfs_ifunlock(ip); |
| @@ -3870,6 +3883,7 @@ xfs_finish_reclaim( | |||
| 3870 | return 1; | 3883 | return 1; |
| 3871 | } | 3884 | } |
| 3872 | ip->i_flags |= XFS_IRECLAIM; | 3885 | ip->i_flags |= XFS_IRECLAIM; |
| 3886 | spin_unlock(&ip->i_flags_lock); | ||
| 3873 | write_unlock(&ih->ih_lock); | 3887 | write_unlock(&ih->ih_lock); |
| 3874 | 3888 | ||
| 3875 | /* | 3889 | /* |
| @@ -4273,7 +4287,7 @@ xfs_free_file_space( | |||
| 4273 | xfs_mount_t *mp; | 4287 | xfs_mount_t *mp; |
| 4274 | int nimap; | 4288 | int nimap; |
| 4275 | uint resblks; | 4289 | uint resblks; |
| 4276 | int rounding; | 4290 | uint rounding; |
| 4277 | int rt; | 4291 | int rt; |
| 4278 | xfs_fileoff_t startoffset_fsb; | 4292 | xfs_fileoff_t startoffset_fsb; |
| 4279 | xfs_trans_t *tp; | 4293 | xfs_trans_t *tp; |
| @@ -4314,8 +4328,7 @@ xfs_free_file_space( | |||
| 4314 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 4328 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ |
| 4315 | } | 4329 | } |
| 4316 | 4330 | ||
| 4317 | rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), | 4331 | rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); |
| 4318 | (__uint8_t)NBPP); | ||
| 4319 | ilen = len + (offset & (rounding - 1)); | 4332 | ilen = len + (offset & (rounding - 1)); |
| 4320 | ioffset = offset & ~(rounding - 1); | 4333 | ioffset = offset & ~(rounding - 1); |
| 4321 | if (ilen & (rounding - 1)) | 4334 | if (ilen & (rounding - 1)) |
