diff options
| -rw-r--r-- | fs/xfs/xfs_inode.c | 59 |
1 files changed, 26 insertions, 33 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index d0a98bafcbac..426dbf7d094a 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -2788,7 +2788,7 @@ xfs_rename( | |||
| 2788 | int error; | 2788 | int error; |
| 2789 | xfs_bmap_free_t free_list; | 2789 | xfs_bmap_free_t free_list; |
| 2790 | xfs_fsblock_t first_block; | 2790 | xfs_fsblock_t first_block; |
| 2791 | int cancel_flags; | 2791 | int cancel_flags = 0; |
| 2792 | int committed; | 2792 | int committed; |
| 2793 | xfs_inode_t *inodes[__XFS_SORT_INODES]; | 2793 | xfs_inode_t *inodes[__XFS_SORT_INODES]; |
| 2794 | int num_inodes = __XFS_SORT_INODES; | 2794 | int num_inodes = __XFS_SORT_INODES; |
| @@ -2802,28 +2802,23 @@ xfs_rename( | |||
| 2802 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, NULL, | 2802 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, NULL, |
| 2803 | inodes, &num_inodes); | 2803 | inodes, &num_inodes); |
| 2804 | 2804 | ||
| 2805 | xfs_bmap_init(&free_list, &first_block); | ||
| 2806 | tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); | 2805 | tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); |
| 2807 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
| 2808 | spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len); | 2806 | spaceres = XFS_RENAME_SPACE_RES(mp, target_name->len); |
| 2809 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0); | 2807 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, spaceres, 0); |
| 2810 | if (error == -ENOSPC) { | 2808 | if (error == -ENOSPC) { |
| 2811 | spaceres = 0; | 2809 | spaceres = 0; |
| 2812 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0); | 2810 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_rename, 0, 0); |
| 2813 | } | 2811 | } |
| 2814 | if (error) { | 2812 | if (error) |
| 2815 | xfs_trans_cancel(tp, 0); | 2813 | goto out_trans_cancel; |
| 2816 | goto std_return; | 2814 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; |
| 2817 | } | ||
| 2818 | 2815 | ||
| 2819 | /* | 2816 | /* |
| 2820 | * Attach the dquots to the inodes | 2817 | * Attach the dquots to the inodes |
| 2821 | */ | 2818 | */ |
| 2822 | error = xfs_qm_vop_rename_dqattach(inodes); | 2819 | error = xfs_qm_vop_rename_dqattach(inodes); |
| 2823 | if (error) { | 2820 | if (error) |
| 2824 | xfs_trans_cancel(tp, cancel_flags); | 2821 | goto out_trans_cancel; |
| 2825 | goto std_return; | ||
| 2826 | } | ||
| 2827 | 2822 | ||
| 2828 | /* | 2823 | /* |
| 2829 | * Lock all the participating inodes. Depending upon whether | 2824 | * Lock all the participating inodes. Depending upon whether |
| @@ -2853,9 +2848,11 @@ xfs_rename( | |||
| 2853 | if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | 2848 | if (unlikely((target_dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && |
| 2854 | (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) { | 2849 | (xfs_get_projid(target_dp) != xfs_get_projid(src_ip)))) { |
| 2855 | error = -EXDEV; | 2850 | error = -EXDEV; |
| 2856 | goto error_return; | 2851 | goto out_trans_cancel; |
| 2857 | } | 2852 | } |
| 2858 | 2853 | ||
| 2854 | xfs_bmap_init(&free_list, &first_block); | ||
| 2855 | |||
| 2859 | /* | 2856 | /* |
| 2860 | * Handle RENAME_EXCHANGE flags | 2857 | * Handle RENAME_EXCHANGE flags |
| 2861 | */ | 2858 | */ |
| @@ -2864,7 +2861,7 @@ xfs_rename( | |||
| 2864 | target_dp, target_name, target_ip, | 2861 | target_dp, target_name, target_ip, |
| 2865 | &free_list, &first_block, spaceres); | 2862 | &free_list, &first_block, spaceres); |
| 2866 | if (error) | 2863 | if (error) |
| 2867 | goto abort_return; | 2864 | goto out_trans_abort; |
| 2868 | goto finish_rename; | 2865 | goto finish_rename; |
| 2869 | } | 2866 | } |
| 2870 | 2867 | ||
| @@ -2879,7 +2876,7 @@ xfs_rename( | |||
| 2879 | if (!spaceres) { | 2876 | if (!spaceres) { |
| 2880 | error = xfs_dir_canenter(tp, target_dp, target_name); | 2877 | error = xfs_dir_canenter(tp, target_dp, target_name); |
| 2881 | if (error) | 2878 | if (error) |
| 2882 | goto error_return; | 2879 | goto out_trans_cancel; |
| 2883 | } | 2880 | } |
| 2884 | /* | 2881 | /* |
| 2885 | * If target does not exist and the rename crosses | 2882 | * If target does not exist and the rename crosses |
| @@ -2890,9 +2887,9 @@ xfs_rename( | |||
| 2890 | src_ip->i_ino, &first_block, | 2887 | src_ip->i_ino, &first_block, |
| 2891 | &free_list, spaceres); | 2888 | &free_list, spaceres); |
| 2892 | if (error == -ENOSPC) | 2889 | if (error == -ENOSPC) |
| 2893 | goto error_return; | 2890 | goto out_bmap_cancel; |
| 2894 | if (error) | 2891 | if (error) |
| 2895 | goto abort_return; | 2892 | goto out_trans_abort; |
| 2896 | 2893 | ||
| 2897 | xfs_trans_ichgtime(tp, target_dp, | 2894 | xfs_trans_ichgtime(tp, target_dp, |
| 2898 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 2895 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| @@ -2900,7 +2897,7 @@ xfs_rename( | |||
| 2900 | if (new_parent && src_is_directory) { | 2897 | if (new_parent && src_is_directory) { |
| 2901 | error = xfs_bumplink(tp, target_dp); | 2898 | error = xfs_bumplink(tp, target_dp); |
| 2902 | if (error) | 2899 | if (error) |
| 2903 | goto abort_return; | 2900 | goto out_trans_abort; |
| 2904 | } | 2901 | } |
| 2905 | } else { /* target_ip != NULL */ | 2902 | } else { /* target_ip != NULL */ |
| 2906 | /* | 2903 | /* |
| @@ -2915,7 +2912,7 @@ xfs_rename( | |||
| 2915 | if (!(xfs_dir_isempty(target_ip)) || | 2912 | if (!(xfs_dir_isempty(target_ip)) || |
| 2916 | (target_ip->i_d.di_nlink > 2)) { | 2913 | (target_ip->i_d.di_nlink > 2)) { |
| 2917 | error = -EEXIST; | 2914 | error = -EEXIST; |
| 2918 | goto error_return; | 2915 | goto out_trans_cancel; |
| 2919 | } | 2916 | } |
| 2920 | } | 2917 | } |
| 2921 | 2918 | ||
| @@ -2932,7 +2929,7 @@ xfs_rename( | |||
| 2932 | src_ip->i_ino, | 2929 | src_ip->i_ino, |
| 2933 | &first_block, &free_list, spaceres); | 2930 | &first_block, &free_list, spaceres); |
| 2934 | if (error) | 2931 | if (error) |
| 2935 | goto abort_return; | 2932 | goto out_trans_abort; |
| 2936 | 2933 | ||
| 2937 | xfs_trans_ichgtime(tp, target_dp, | 2934 | xfs_trans_ichgtime(tp, target_dp, |
| 2938 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 2935 | XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| @@ -2943,7 +2940,7 @@ xfs_rename( | |||
| 2943 | */ | 2940 | */ |
| 2944 | error = xfs_droplink(tp, target_ip); | 2941 | error = xfs_droplink(tp, target_ip); |
| 2945 | if (error) | 2942 | if (error) |
| 2946 | goto abort_return; | 2943 | goto out_trans_abort; |
| 2947 | 2944 | ||
| 2948 | if (src_is_directory) { | 2945 | if (src_is_directory) { |
| 2949 | /* | 2946 | /* |
| @@ -2951,7 +2948,7 @@ xfs_rename( | |||
| 2951 | */ | 2948 | */ |
| 2952 | error = xfs_droplink(tp, target_ip); | 2949 | error = xfs_droplink(tp, target_ip); |
| 2953 | if (error) | 2950 | if (error) |
| 2954 | goto abort_return; | 2951 | goto out_trans_abort; |
| 2955 | } | 2952 | } |
| 2956 | } /* target_ip != NULL */ | 2953 | } /* target_ip != NULL */ |
| 2957 | 2954 | ||
| @@ -2968,7 +2965,7 @@ xfs_rename( | |||
| 2968 | &first_block, &free_list, spaceres); | 2965 | &first_block, &free_list, spaceres); |
| 2969 | ASSERT(error != -EEXIST); | 2966 | ASSERT(error != -EEXIST); |
| 2970 | if (error) | 2967 | if (error) |
| 2971 | goto abort_return; | 2968 | goto out_trans_abort; |
| 2972 | } | 2969 | } |
| 2973 | 2970 | ||
| 2974 | /* | 2971 | /* |
| @@ -2994,13 +2991,13 @@ xfs_rename( | |||
| 2994 | */ | 2991 | */ |
| 2995 | error = xfs_droplink(tp, src_dp); | 2992 | error = xfs_droplink(tp, src_dp); |
| 2996 | if (error) | 2993 | if (error) |
| 2997 | goto abort_return; | 2994 | goto out_trans_abort; |
| 2998 | } | 2995 | } |
| 2999 | 2996 | ||
| 3000 | error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, | 2997 | error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino, |
| 3001 | &first_block, &free_list, spaceres); | 2998 | &first_block, &free_list, spaceres); |
| 3002 | if (error) | 2999 | if (error) |
| 3003 | goto abort_return; | 3000 | goto out_trans_abort; |
| 3004 | 3001 | ||
| 3005 | xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 3002 | xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 3006 | xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE); | 3003 | xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE); |
| @@ -3018,12 +3015,8 @@ finish_rename: | |||
| 3018 | } | 3015 | } |
| 3019 | 3016 | ||
| 3020 | error = xfs_bmap_finish(&tp, &free_list, &committed); | 3017 | error = xfs_bmap_finish(&tp, &free_list, &committed); |
| 3021 | if (error) { | 3018 | if (error) |
| 3022 | xfs_bmap_cancel(&free_list); | 3019 | goto out_trans_abort; |
| 3023 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | | ||
| 3024 | XFS_TRANS_ABORT)); | ||
| 3025 | goto std_return; | ||
| 3026 | } | ||
| 3027 | 3020 | ||
| 3028 | /* | 3021 | /* |
| 3029 | * trans_commit will unlock src_ip, target_ip & decrement | 3022 | * trans_commit will unlock src_ip, target_ip & decrement |
| @@ -3031,12 +3024,12 @@ finish_rename: | |||
| 3031 | */ | 3024 | */ |
| 3032 | return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 3025 | return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
| 3033 | 3026 | ||
| 3034 | abort_return: | 3027 | out_trans_abort: |
| 3035 | cancel_flags |= XFS_TRANS_ABORT; | 3028 | cancel_flags |= XFS_TRANS_ABORT; |
| 3036 | error_return: | 3029 | out_bmap_cancel: |
| 3037 | xfs_bmap_cancel(&free_list); | 3030 | xfs_bmap_cancel(&free_list); |
| 3031 | out_trans_cancel: | ||
| 3038 | xfs_trans_cancel(tp, cancel_flags); | 3032 | xfs_trans_cancel(tp, cancel_flags); |
| 3039 | std_return: | ||
| 3040 | return error; | 3033 | return error; |
| 3041 | } | 3034 | } |
| 3042 | 3035 | ||
