|
@@ -1310,7 +1310,7 @@ xfs_create(
|
|
|
error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
|
|
|
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
|
|
|
if (error)
|
|
|
- goto std_return;
|
|
|
+ return error;
|
|
|
|
|
|
if (is_dir) {
|
|
|
rdev = 0;
|
|
@@ -1389,12 +1389,6 @@ xfs_create(
|
|
|
goto out_trans_abort;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * At this point, we've gotten a newly allocated inode.
|
|
|
- * It is locked (and joined to the transaction).
|
|
|
- */
|
|
|
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
|
|
-
|
|
|
/*
|
|
|
* Now we join the directory inode to the transaction. We do not do it
|
|
|
* earlier because xfs_dir_ialloc might commit the previous transaction
|
|
@@ -1440,22 +1434,13 @@ xfs_create(
|
|
|
*/
|
|
|
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp);
|
|
|
|
|
|
- /*
|
|
|
- * xfs_trans_commit normally decrements the vnode ref count
|
|
|
- * when it unlocks the inode. Since we want to return the
|
|
|
- * vnode to the caller, we bump the vnode ref count now.
|
|
|
- */
|
|
|
- IHOLD(ip);
|
|
|
-
|
|
|
error = xfs_bmap_finish(&tp, &free_list, &committed);
|
|
|
if (error)
|
|
|
- goto out_abort_rele;
|
|
|
+ goto out_bmap_cancel;
|
|
|
|
|
|
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
|
|
- if (error) {
|
|
|
- IRELE(ip);
|
|
|
- goto out_dqrele;
|
|
|
- }
|
|
|
+ if (error)
|
|
|
+ goto out_release_inode;
|
|
|
|
|
|
xfs_qm_dqrele(udqp);
|
|
|
xfs_qm_dqrele(gdqp);
|
|
@@ -1469,27 +1454,21 @@ xfs_create(
|
|
|
cancel_flags |= XFS_TRANS_ABORT;
|
|
|
out_trans_cancel:
|
|
|
xfs_trans_cancel(tp, cancel_flags);
|
|
|
- out_dqrele:
|
|
|
+ out_release_inode:
|
|
|
+ /*
|
|
|
+ * Wait until after the current transaction is aborted to
|
|
|
+ * release the inode. This prevents recursive transactions
|
|
|
+ * and deadlocks from xfs_inactive.
|
|
|
+ */
|
|
|
+ if (ip)
|
|
|
+ IRELE(ip);
|
|
|
+
|
|
|
xfs_qm_dqrele(udqp);
|
|
|
xfs_qm_dqrele(gdqp);
|
|
|
|
|
|
if (unlock_dp_on_error)
|
|
|
xfs_iunlock(dp, XFS_ILOCK_EXCL);
|
|
|
- std_return:
|
|
|
return error;
|
|
|
-
|
|
|
- out_abort_rele:
|
|
|
- /*
|
|
|
- * Wait until after the current transaction is aborted to
|
|
|
- * release the inode. This prevents recursive transactions
|
|
|
- * and deadlocks from xfs_inactive.
|
|
|
- */
|
|
|
- xfs_bmap_cancel(&free_list);
|
|
|
- cancel_flags |= XFS_TRANS_ABORT;
|
|
|
- xfs_trans_cancel(tp, cancel_flags);
|
|
|
- IRELE(ip);
|
|
|
- unlock_dp_on_error = B_FALSE;
|
|
|
- goto out_dqrele;
|
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
@@ -2114,9 +2093,8 @@ xfs_symlink(
|
|
|
XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
|
|
|
&first_block, resblks, mval, &nmaps,
|
|
|
&free_list);
|
|
|
- if (error) {
|
|
|
- goto error1;
|
|
|
- }
|
|
|
+ if (error)
|
|
|
+ goto error2;
|
|
|
|
|
|
if (resblks)
|
|
|
resblks -= fs_blocks;
|
|
@@ -2148,7 +2126,7 @@ xfs_symlink(
|
|
|
error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,
|
|
|
&first_block, &free_list, resblks);
|
|
|
if (error)
|
|
|
- goto error1;
|
|
|
+ goto error2;
|
|
|
xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
|
|
|
xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
|
|
|
|
|
@@ -2161,13 +2139,6 @@ xfs_symlink(
|
|
|
xfs_trans_set_sync(tp);
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * xfs_trans_commit normally decrements the vnode ref count
|
|
|
- * when it unlocks the inode. Since we want to return the
|
|
|
- * vnode to the caller, we bump the vnode ref count now.
|
|
|
- */
|
|
|
- IHOLD(ip);
|
|
|
-
|
|
|
error = xfs_bmap_finish(&tp, &free_list, &committed);
|
|
|
if (error) {
|
|
|
goto error2;
|