diff options
author | Dave Chinner <dchinner@redhat.com> | 2015-03-24 23:05:43 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2015-03-24 23:05:43 -0400 |
commit | 445883e8133975fe8d555610c70c1c4c501f0bf8 (patch) | |
tree | 6f1ecf9746c65f6c31a0060812d8cf6f1df90c74 /fs/xfs | |
parent | 95afcf5c7bca93fb84d260f70c304f35ef4c3114 (diff) |
xfs: cleanup xfs_rename error handling
The jump labels are ambiguous and unclear and some of the error
paths are used inconsistently. Rules for error jumps are:
- use out_trans_cancel for unmodified transaction context
- use out_bmap_cancel on ENOSPC errors
- use out_trans_abort when transaction is likely to be dirty.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-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 | ||