int cancel_flags;
int committed;
xfs_inode_t *inodes[4];
- int target_ip_dropped = 0; /* dropped target_ip link? */
int spaceres;
- int target_link_zero = 0;
int num_inodes;
xfs_itrace_entry(src_dp);
xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip,
inodes, &num_inodes);
- IHOLD(src_ip);
- if (target_ip)
- IHOLD(target_ip);
-
XFS_BMAP_INIT(&free_list, &first_block);
tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME);
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
}
if (error) {
xfs_trans_cancel(tp, 0);
- goto rele_return;
+ goto std_return;
}
/*
*/
if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) {
xfs_trans_cancel(tp, cancel_flags);
- goto rele_return;
+ goto std_return;
}
/*
error = XFS_ERROR(EXDEV);
xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
xfs_trans_cancel(tp, cancel_flags);
- goto rele_return;
+ goto std_return;
}
/*
*/
IHOLD(src_dp);
xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
+
if (new_parent) {
IHOLD(target_dp);
xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
}
- if ((src_ip != src_dp) && (src_ip != target_dp)) {
- xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
- }
- if ((target_ip != NULL) &&
- (target_ip != src_ip) &&
- (target_ip != src_dp) &&
- (target_ip != target_dp)) {
+
+ IHOLD(src_ip);
+ xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
+
+ if (target_ip) {
+ IHOLD(target_ip);
xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
}
error = xfs_droplink(tp, target_ip);
if (error)
goto abort_return;
- target_ip_dropped = 1;
if (src_is_directory) {
/*
if (error)
goto abort_return;
}
-
- /* Do this test while we still hold the locks */
- target_link_zero = (target_ip)->i_d.di_nlink==0;
-
} /* target_ip != NULL */
/*
xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
}
- /*
- * If there was a target inode, take an extra reference on
- * it here so that it doesn't go to xfs_inactive() from
- * within the commit.
- */
- if (target_ip != NULL) {
- IHOLD(target_ip);
- }
-
/*
* If this is a synchronous mount, make sure that the
* rename transaction goes to disk before returning to
xfs_trans_set_sync(tp);
}
- /*
- * Take refs. for vop_link_removed calls below. No need to worry
- * about directory refs. because the caller holds them.
- *
- * Do holds before the xfs_bmap_finish since it might rele them down
- * to zero.
- */
-
- if (target_ip_dropped)
- IHOLD(target_ip);
- IHOLD(src_ip);
-
error = xfs_bmap_finish(&tp, &free_list, &committed);
if (error) {
xfs_bmap_cancel(&free_list);
xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES |
XFS_TRANS_ABORT));
- if (target_ip != NULL) {
- IRELE(target_ip);
- }
- if (target_ip_dropped) {
- IRELE(target_ip);
- }
- IRELE(src_ip);
goto std_return;
}
* the vnode references.
*/
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
- if (target_ip != NULL)
- IRELE(target_ip);
- /*
- * Let interposed file systems know about removed links.
- */
- if (target_ip_dropped)
- IRELE(target_ip);
-
- IRELE(src_ip);
/* Fall through to std_return with error = 0 or errno from
* xfs_trans_commit */
xfs_bmap_cancel(&free_list);
xfs_trans_cancel(tp, cancel_flags);
goto std_return;
-
- rele_return:
- IRELE(src_ip);
- if (target_ip != NULL) {
- IRELE(target_ip);
- }
- goto std_return;
}