Commit eeacd321 authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarEric Sandeen <sandeen@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 310606b0
...@@ -2703,14 +2703,14 @@ xfs_cross_rename( ...@@ -2703,14 +2703,14 @@ xfs_cross_rename(
ip2->i_ino, ip2->i_ino,
first_block, free_list, spaceres); first_block, free_list, spaceres);
if (error) if (error)
goto out; goto out_trans_abort;
/* Swap inode number for dirent in second parent */ /* Swap inode number for dirent in second parent */
error = xfs_dir_replace(tp, dp2, name2, error = xfs_dir_replace(tp, dp2, name2,
ip1->i_ino, ip1->i_ino,
first_block, free_list, spaceres); first_block, free_list, spaceres);
if (error) if (error)
goto out; goto out_trans_abort;
/* /*
* If we're renaming one or more directories across different parents, * If we're renaming one or more directories across different parents,
...@@ -2725,16 +2725,16 @@ xfs_cross_rename( ...@@ -2725,16 +2725,16 @@ xfs_cross_rename(
dp1->i_ino, first_block, dp1->i_ino, first_block,
free_list, spaceres); free_list, spaceres);
if (error) if (error)
goto out; goto out_trans_abort;
/* transfer ip2 ".." reference to dp1 */ /* transfer ip2 ".." reference to dp1 */
if (!S_ISDIR(ip1->i_d.di_mode)) { if (!S_ISDIR(ip1->i_d.di_mode)) {
error = xfs_droplink(tp, dp2); error = xfs_droplink(tp, dp2);
if (error) if (error)
goto out; goto out_trans_abort;
error = xfs_bumplink(tp, dp1); error = xfs_bumplink(tp, dp1);
if (error) if (error)
goto out; goto out_trans_abort;
} }
/* /*
...@@ -2752,16 +2752,16 @@ xfs_cross_rename( ...@@ -2752,16 +2752,16 @@ xfs_cross_rename(
dp2->i_ino, first_block, dp2->i_ino, first_block,
free_list, spaceres); free_list, spaceres);
if (error) if (error)
goto out; goto out_trans_abort;
/* transfer ip1 ".." reference to dp2 */ /* transfer ip1 ".." reference to dp2 */
if (!S_ISDIR(ip2->i_d.di_mode)) { if (!S_ISDIR(ip2->i_d.di_mode)) {
error = xfs_droplink(tp, dp1); error = xfs_droplink(tp, dp1);
if (error) if (error)
goto out; goto out_trans_abort;
error = xfs_bumplink(tp, dp2); error = xfs_bumplink(tp, dp2);
if (error) if (error)
goto out; goto out_trans_abort;
} }
/* /*
...@@ -2789,7 +2789,11 @@ xfs_cross_rename( ...@@ -2789,7 +2789,11 @@ xfs_cross_rename(
} }
xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE); xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
out: return xfs_finish_rename(tp, free_list);
out_trans_abort:
xfs_bmap_cancel(free_list);
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
return error; return error;
} }
...@@ -2820,6 +2824,9 @@ xfs_rename( ...@@ -2820,6 +2824,9 @@ xfs_rename(
trace_xfs_rename(src_dp, target_dp, src_name, target_name); trace_xfs_rename(src_dp, target_dp, src_name, target_name);
if ((flags & RENAME_EXCHANGE) && !target_ip)
return -EINVAL;
new_parent = (src_dp != target_dp); new_parent = (src_dp != target_dp);
src_is_directory = S_ISDIR(src_ip->i_d.di_mode); src_is_directory = S_ISDIR(src_ip->i_d.di_mode);
...@@ -2877,17 +2884,11 @@ xfs_rename( ...@@ -2877,17 +2884,11 @@ xfs_rename(
xfs_bmap_init(&free_list, &first_block); xfs_bmap_init(&free_list, &first_block);
/* /* RENAME_EXCHANGE is unique from here on. */
* Handle RENAME_EXCHANGE flags if (flags & RENAME_EXCHANGE)
*/ return xfs_cross_rename(tp, src_dp, src_name, src_ip,
if (flags & RENAME_EXCHANGE) { target_dp, target_name, target_ip,
error = xfs_cross_rename(tp, src_dp, src_name, src_ip, &free_list, &first_block, spaceres);
target_dp, target_name, target_ip,
&free_list, &first_block, spaceres);
if (error)
goto out_trans_abort;
return xfs_finish_rename(tp, &free_list);
}
/* /*
* Set up the target. * Set up the target.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment