aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-03-24 23:08:07 -0400
committerDave Chinner <david@fromorbit.com>2015-03-24 23:08:07 -0400
commiteeacd3217b8fa8143f5dc27ded405790c74f01e8 (patch)
treeed74419ea4aa2b4825a5f48ee9585aad860808ef /fs/xfs/xfs_inode.c
parent310606b0c7e385e9dd3533d168413ad2c579d961 (diff)
xfs: make xfs_cross_rename() complete fully
Now that xfs_finish_rename() exists, there is no reason for xfs_cross_rename() to return to xfs_rename() to finish off the rename transaction. Drive the completion code into xfs_cross_rename() and handle all errors there so as to simplify the xfs_rename() code. Further, push the rename exchange target_ip check to early in the rename code so as to make the error handling easy and obviously correct. 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/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c3fe00cb19e4..b376ebe5fad9 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2703,14 +2703,14 @@ xfs_cross_rename(
2703 ip2->i_ino, 2703 ip2->i_ino,
2704 first_block, free_list, spaceres); 2704 first_block, free_list, spaceres);
2705 if (error) 2705 if (error)
2706 goto out; 2706 goto out_trans_abort;
2707 2707
2708 /* Swap inode number for dirent in second parent */ 2708 /* Swap inode number for dirent in second parent */
2709 error = xfs_dir_replace(tp, dp2, name2, 2709 error = xfs_dir_replace(tp, dp2, name2,
2710 ip1->i_ino, 2710 ip1->i_ino,
2711 first_block, free_list, spaceres); 2711 first_block, free_list, spaceres);
2712 if (error) 2712 if (error)
2713 goto out; 2713 goto out_trans_abort;
2714 2714
2715 /* 2715 /*
2716 * If we're renaming one or more directories across different parents, 2716 * If we're renaming one or more directories across different parents,
@@ -2725,16 +2725,16 @@ xfs_cross_rename(
2725 dp1->i_ino, first_block, 2725 dp1->i_ino, first_block,
2726 free_list, spaceres); 2726 free_list, spaceres);
2727 if (error) 2727 if (error)
2728 goto out; 2728 goto out_trans_abort;
2729 2729
2730 /* transfer ip2 ".." reference to dp1 */ 2730 /* transfer ip2 ".." reference to dp1 */
2731 if (!S_ISDIR(ip1->i_d.di_mode)) { 2731 if (!S_ISDIR(ip1->i_d.di_mode)) {
2732 error = xfs_droplink(tp, dp2); 2732 error = xfs_droplink(tp, dp2);
2733 if (error) 2733 if (error)
2734 goto out; 2734 goto out_trans_abort;
2735 error = xfs_bumplink(tp, dp1); 2735 error = xfs_bumplink(tp, dp1);
2736 if (error) 2736 if (error)
2737 goto out; 2737 goto out_trans_abort;
2738 } 2738 }
2739 2739
2740 /* 2740 /*
@@ -2752,16 +2752,16 @@ xfs_cross_rename(
2752 dp2->i_ino, first_block, 2752 dp2->i_ino, first_block,
2753 free_list, spaceres); 2753 free_list, spaceres);
2754 if (error) 2754 if (error)
2755 goto out; 2755 goto out_trans_abort;
2756 2756
2757 /* transfer ip1 ".." reference to dp2 */ 2757 /* transfer ip1 ".." reference to dp2 */
2758 if (!S_ISDIR(ip2->i_d.di_mode)) { 2758 if (!S_ISDIR(ip2->i_d.di_mode)) {
2759 error = xfs_droplink(tp, dp1); 2759 error = xfs_droplink(tp, dp1);
2760 if (error) 2760 if (error)
2761 goto out; 2761 goto out_trans_abort;
2762 error = xfs_bumplink(tp, dp2); 2762 error = xfs_bumplink(tp, dp2);
2763 if (error) 2763 if (error)
2764 goto out; 2764 goto out_trans_abort;
2765 } 2765 }
2766 2766
2767 /* 2767 /*
@@ -2789,7 +2789,11 @@ xfs_cross_rename(
2789 } 2789 }
2790 xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 2790 xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2791 xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE); 2791 xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
2792out: 2792 return xfs_finish_rename(tp, free_list);
2793
2794out_trans_abort:
2795 xfs_bmap_cancel(free_list);
2796 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
2793 return error; 2797 return error;
2794} 2798}
2795 2799
@@ -2820,6 +2824,9 @@ xfs_rename(
2820 2824
2821 trace_xfs_rename(src_dp, target_dp, src_name, target_name); 2825 trace_xfs_rename(src_dp, target_dp, src_name, target_name);
2822 2826
2827 if ((flags & RENAME_EXCHANGE) && !target_ip)
2828 return -EINVAL;
2829
2823 new_parent = (src_dp != target_dp); 2830 new_parent = (src_dp != target_dp);
2824 src_is_directory = S_ISDIR(src_ip->i_d.di_mode); 2831 src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
2825 2832
@@ -2877,17 +2884,11 @@ xfs_rename(
2877 2884
2878 xfs_bmap_init(&free_list, &first_block); 2885 xfs_bmap_init(&free_list, &first_block);
2879 2886
2880 /* 2887 /* RENAME_EXCHANGE is unique from here on. */
2881 * Handle RENAME_EXCHANGE flags 2888 if (flags & RENAME_EXCHANGE)
2882 */ 2889 return xfs_cross_rename(tp, src_dp, src_name, src_ip,
2883 if (flags & RENAME_EXCHANGE) { 2890 target_dp, target_name, target_ip,
2884 error = xfs_cross_rename(tp, src_dp, src_name, src_ip, 2891 &free_list, &first_block, spaceres);
2885 target_dp, target_name, target_ip,
2886 &free_list, &first_block, spaceres);
2887 if (error)
2888 goto out_trans_abort;
2889 return xfs_finish_rename(tp, &free_list);
2890 }
2891 2892
2892 /* 2893 /*
2893 * Set up the target. 2894 * Set up the target.