diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 63 |
1 files changed, 4 insertions, 59 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 2ebfc60097d1..70702a60b4bb 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -2162,20 +2162,6 @@ xfs_remove( | |||
2162 | return error; | 2162 | return error; |
2163 | } | 2163 | } |
2164 | 2164 | ||
2165 | /* | ||
2166 | * We need to get a reference to ip before we get our log | ||
2167 | * reservation. The reason for this is that we cannot call | ||
2168 | * xfs_iget for an inode for which we do not have a reference | ||
2169 | * once we've acquired a log reservation. This is because the | ||
2170 | * inode we are trying to get might be in xfs_inactive going | ||
2171 | * for a log reservation. Since we'll have to wait for the | ||
2172 | * inactive code to complete before returning from xfs_iget, | ||
2173 | * we need to make sure that we don't have log space reserved | ||
2174 | * when we call xfs_iget. Instead we get an unlocked reference | ||
2175 | * to the inode before getting our log reservation. | ||
2176 | */ | ||
2177 | IHOLD(ip); | ||
2178 | |||
2179 | xfs_itrace_entry(ip); | 2165 | xfs_itrace_entry(ip); |
2180 | xfs_itrace_ref(ip); | 2166 | xfs_itrace_ref(ip); |
2181 | 2167 | ||
@@ -2184,7 +2170,6 @@ xfs_remove( | |||
2184 | error = XFS_QM_DQATTACH(mp, ip, 0); | 2170 | error = XFS_QM_DQATTACH(mp, ip, 0); |
2185 | if (error) { | 2171 | if (error) { |
2186 | REMOVE_DEBUG_TRACE(__LINE__); | 2172 | REMOVE_DEBUG_TRACE(__LINE__); |
2187 | IRELE(ip); | ||
2188 | goto std_return; | 2173 | goto std_return; |
2189 | } | 2174 | } |
2190 | 2175 | ||
@@ -2211,7 +2196,6 @@ xfs_remove( | |||
2211 | ASSERT(error != ENOSPC); | 2196 | ASSERT(error != ENOSPC); |
2212 | REMOVE_DEBUG_TRACE(__LINE__); | 2197 | REMOVE_DEBUG_TRACE(__LINE__); |
2213 | xfs_trans_cancel(tp, 0); | 2198 | xfs_trans_cancel(tp, 0); |
2214 | IRELE(ip); | ||
2215 | return error; | 2199 | return error; |
2216 | } | 2200 | } |
2217 | 2201 | ||
@@ -2219,7 +2203,6 @@ xfs_remove( | |||
2219 | if (error) { | 2203 | if (error) { |
2220 | REMOVE_DEBUG_TRACE(__LINE__); | 2204 | REMOVE_DEBUG_TRACE(__LINE__); |
2221 | xfs_trans_cancel(tp, cancel_flags); | 2205 | xfs_trans_cancel(tp, cancel_flags); |
2222 | IRELE(ip); | ||
2223 | goto std_return; | 2206 | goto std_return; |
2224 | } | 2207 | } |
2225 | 2208 | ||
@@ -2227,6 +2210,7 @@ xfs_remove( | |||
2227 | * At this point, we've gotten both the directory and the entry | 2210 | * At this point, we've gotten both the directory and the entry |
2228 | * inodes locked. | 2211 | * inodes locked. |
2229 | */ | 2212 | */ |
2213 | IHOLD(ip); | ||
2230 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2214 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2231 | 2215 | ||
2232 | IHOLD(dp); | 2216 | IHOLD(dp); |
@@ -2260,12 +2244,6 @@ xfs_remove( | |||
2260 | link_zero = (ip)->i_d.di_nlink==0; | 2244 | link_zero = (ip)->i_d.di_nlink==0; |
2261 | 2245 | ||
2262 | /* | 2246 | /* |
2263 | * Take an extra ref on the inode so that it doesn't | ||
2264 | * go to xfs_inactive() from within the commit. | ||
2265 | */ | ||
2266 | IHOLD(ip); | ||
2267 | |||
2268 | /* | ||
2269 | * If this is a synchronous mount, make sure that the | 2247 | * If this is a synchronous mount, make sure that the |
2270 | * remove transaction goes to disk before returning to | 2248 | * remove transaction goes to disk before returning to |
2271 | * the user. | 2249 | * the user. |
@@ -2281,10 +2259,8 @@ xfs_remove( | |||
2281 | } | 2259 | } |
2282 | 2260 | ||
2283 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2261 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
2284 | if (error) { | 2262 | if (error) |
2285 | IRELE(ip); | ||
2286 | goto std_return; | 2263 | goto std_return; |
2287 | } | ||
2288 | 2264 | ||
2289 | /* | 2265 | /* |
2290 | * If we are using filestreams, kill the stream association. | 2266 | * If we are using filestreams, kill the stream association. |
@@ -2296,7 +2272,6 @@ xfs_remove( | |||
2296 | xfs_filestream_deassociate(ip); | 2272 | xfs_filestream_deassociate(ip); |
2297 | 2273 | ||
2298 | xfs_itrace_exit(ip); | 2274 | xfs_itrace_exit(ip); |
2299 | IRELE(ip); | ||
2300 | 2275 | ||
2301 | /* Fall through to std_return with error = 0 */ | 2276 | /* Fall through to std_return with error = 0 */ |
2302 | std_return: | 2277 | std_return: |
@@ -2325,8 +2300,6 @@ xfs_remove( | |||
2325 | cancel_flags |= XFS_TRANS_ABORT; | 2300 | cancel_flags |= XFS_TRANS_ABORT; |
2326 | xfs_trans_cancel(tp, cancel_flags); | 2301 | xfs_trans_cancel(tp, cancel_flags); |
2327 | 2302 | ||
2328 | IRELE(ip); | ||
2329 | |||
2330 | goto std_return; | 2303 | goto std_return; |
2331 | } | 2304 | } |
2332 | 2305 | ||
@@ -2698,7 +2671,6 @@ xfs_rmdir( | |||
2698 | struct xfs_name *name, | 2671 | struct xfs_name *name, |
2699 | xfs_inode_t *cdp) | 2672 | xfs_inode_t *cdp) |
2700 | { | 2673 | { |
2701 | bhv_vnode_t *dir_vp = XFS_ITOV(dp); | ||
2702 | xfs_mount_t *mp = dp->i_mount; | 2674 | xfs_mount_t *mp = dp->i_mount; |
2703 | xfs_trans_t *tp; | 2675 | xfs_trans_t *tp; |
2704 | int error; | 2676 | int error; |
@@ -2724,27 +2696,12 @@ xfs_rmdir( | |||
2724 | } | 2696 | } |
2725 | 2697 | ||
2726 | /* | 2698 | /* |
2727 | * We need to get a reference to cdp before we get our log | ||
2728 | * reservation. The reason for this is that we cannot call | ||
2729 | * xfs_iget for an inode for which we do not have a reference | ||
2730 | * once we've acquired a log reservation. This is because the | ||
2731 | * inode we are trying to get might be in xfs_inactive going | ||
2732 | * for a log reservation. Since we'll have to wait for the | ||
2733 | * inactive code to complete before returning from xfs_iget, | ||
2734 | * we need to make sure that we don't have log space reserved | ||
2735 | * when we call xfs_iget. Instead we get an unlocked reference | ||
2736 | * to the inode before getting our log reservation. | ||
2737 | */ | ||
2738 | IHOLD(cdp); | ||
2739 | |||
2740 | /* | ||
2741 | * Get the dquots for the inodes. | 2699 | * Get the dquots for the inodes. |
2742 | */ | 2700 | */ |
2743 | error = XFS_QM_DQATTACH(mp, dp, 0); | 2701 | error = XFS_QM_DQATTACH(mp, dp, 0); |
2744 | if (!error) | 2702 | if (!error) |
2745 | error = XFS_QM_DQATTACH(mp, cdp, 0); | 2703 | error = XFS_QM_DQATTACH(mp, cdp, 0); |
2746 | if (error) { | 2704 | if (error) { |
2747 | IRELE(cdp); | ||
2748 | REMOVE_DEBUG_TRACE(__LINE__); | 2705 | REMOVE_DEBUG_TRACE(__LINE__); |
2749 | goto std_return; | 2706 | goto std_return; |
2750 | } | 2707 | } |
@@ -2771,7 +2728,6 @@ xfs_rmdir( | |||
2771 | if (error) { | 2728 | if (error) { |
2772 | ASSERT(error != ENOSPC); | 2729 | ASSERT(error != ENOSPC); |
2773 | cancel_flags = 0; | 2730 | cancel_flags = 0; |
2774 | IRELE(cdp); | ||
2775 | goto error_return; | 2731 | goto error_return; |
2776 | } | 2732 | } |
2777 | XFS_BMAP_INIT(&free_list, &first_block); | 2733 | XFS_BMAP_INIT(&free_list, &first_block); |
@@ -2785,14 +2741,13 @@ xfs_rmdir( | |||
2785 | error = xfs_lock_dir_and_entry(dp, cdp); | 2741 | error = xfs_lock_dir_and_entry(dp, cdp); |
2786 | if (error) { | 2742 | if (error) { |
2787 | xfs_trans_cancel(tp, cancel_flags); | 2743 | xfs_trans_cancel(tp, cancel_flags); |
2788 | IRELE(cdp); | ||
2789 | goto std_return; | 2744 | goto std_return; |
2790 | } | 2745 | } |
2791 | 2746 | ||
2747 | IHOLD(dp); | ||
2792 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 2748 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
2793 | VN_HOLD(dir_vp); | ||
2794 | 2749 | ||
2795 | xfs_itrace_ref(cdp); | 2750 | IHOLD(cdp); |
2796 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); | 2751 | xfs_trans_ijoin(tp, cdp, XFS_ILOCK_EXCL); |
2797 | 2752 | ||
2798 | ASSERT(cdp->i_d.di_nlink >= 2); | 2753 | ASSERT(cdp->i_d.di_nlink >= 2); |
@@ -2846,12 +2801,6 @@ xfs_rmdir( | |||
2846 | last_cdp_link = (cdp)->i_d.di_nlink==0; | 2801 | last_cdp_link = (cdp)->i_d.di_nlink==0; |
2847 | 2802 | ||
2848 | /* | 2803 | /* |
2849 | * Take an extra ref on the child vnode so that it | ||
2850 | * does not go to xfs_inactive() from within the commit. | ||
2851 | */ | ||
2852 | IHOLD(cdp); | ||
2853 | |||
2854 | /* | ||
2855 | * If this is a synchronous mount, make sure that the | 2804 | * If this is a synchronous mount, make sure that the |
2856 | * rmdir transaction goes to disk before returning to | 2805 | * rmdir transaction goes to disk before returning to |
2857 | * the user. | 2806 | * the user. |
@@ -2865,19 +2814,15 @@ xfs_rmdir( | |||
2865 | xfs_bmap_cancel(&free_list); | 2814 | xfs_bmap_cancel(&free_list); |
2866 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | | 2815 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | |
2867 | XFS_TRANS_ABORT)); | 2816 | XFS_TRANS_ABORT)); |
2868 | IRELE(cdp); | ||
2869 | goto std_return; | 2817 | goto std_return; |
2870 | } | 2818 | } |
2871 | 2819 | ||
2872 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 2820 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
2873 | if (error) { | 2821 | if (error) { |
2874 | IRELE(cdp); | ||
2875 | goto std_return; | 2822 | goto std_return; |
2876 | } | 2823 | } |
2877 | 2824 | ||
2878 | 2825 | ||
2879 | IRELE(cdp); | ||
2880 | |||
2881 | /* Fall through to std_return with error = 0 or the errno | 2826 | /* Fall through to std_return with error = 0 or the errno |
2882 | * from xfs_trans_commit. */ | 2827 | * from xfs_trans_commit. */ |
2883 | std_return: | 2828 | std_return: |