aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/quota/xfs_qm.c7
-rw-r--r--fs/xfs/xfs_inode.c5
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_inode.c22
-rw-r--r--fs/xfs/xfs_vnodeops.c61
5 files changed, 19 insertions, 78 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 206a2815ced..f517963aec0 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1230,13 +1230,6 @@ xfs_qm_qino_alloc(
1230 } 1230 }
1231 1231
1232 /* 1232 /*
1233 * Keep an extra reference to this quota inode. This inode is
1234 * locked exclusively and joined to the transaction already.
1235 */
1236 ASSERT(xfs_isilocked(*ip, XFS_ILOCK_EXCL));
1237 IHOLD(*ip);
1238
1239 /*
1240 * Make the changes in the superblock, and log those too. 1233 * Make the changes in the superblock, and log those too.
1241 * sbfields arg may contain fields other than *QUOTINO; 1234 * sbfields arg may contain fields other than *QUOTINO;
1242 * VERSIONNUM for example. 1235 * VERSIONNUM for example.
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index be7cf625421..c39278b6c87 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1016,8 +1016,8 @@ xfs_ialloc(
1016 * This is because we're setting fields here we need 1016 * This is because we're setting fields here we need
1017 * to prevent others from looking at until we're done. 1017 * to prevent others from looking at until we're done.
1018 */ 1018 */
1019 error = xfs_trans_iget(tp->t_mountp, tp, ino, 1019 error = xfs_iget(tp->t_mountp, tp, ino, XFS_IGET_CREATE,
1020 XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); 1020 XFS_ILOCK_EXCL, &ip);
1021 if (error) 1021 if (error)
1022 return error; 1022 return error;
1023 ASSERT(ip != NULL); 1023 ASSERT(ip != NULL);
@@ -1166,6 +1166,7 @@ xfs_ialloc(
1166 /* 1166 /*
1167 * Log the new values stuffed into the inode. 1167 * Log the new values stuffed into the inode.
1168 */ 1168 */
1169 xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
1169 xfs_trans_log_inode(tp, ip, flags); 1170 xfs_trans_log_inode(tp, ip, flags);
1170 1171
1171 /* now that we have an i_mode we can setup inode ops and unlock */ 1172 /* now that we have an i_mode we can setup inode ops and unlock */
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index c2042b736b8..06a9759b635 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -469,8 +469,6 @@ void xfs_trans_inode_buf(xfs_trans_t *, struct xfs_buf *);
469void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *); 469void xfs_trans_stale_inode_buf(xfs_trans_t *, struct xfs_buf *);
470void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint); 470void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
471void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *); 471void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
472int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
473 xfs_ino_t , uint, uint, struct xfs_inode **);
474void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int); 472void xfs_trans_ichgtime(struct xfs_trans *, struct xfs_inode *, int);
475void xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint); 473void xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint);
476void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *); 474void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *);
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index ccb34532768..16084d8ea23 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -44,28 +44,6 @@ xfs_trans_inode_broot_debug(
44#endif 44#endif
45 45
46/* 46/*
47 * Get an inode and join it to the transaction.
48 */
49int
50xfs_trans_iget(
51 xfs_mount_t *mp,
52 xfs_trans_t *tp,
53 xfs_ino_t ino,
54 uint flags,
55 uint lock_flags,
56 xfs_inode_t **ipp)
57{
58 int error;
59
60 error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp);
61 if (!error && tp) {
62 xfs_trans_ijoin(tp, *ipp);
63 (*ipp)->i_itemp->ili_lock_flags = lock_flags;
64 }
65 return error;
66}
67
68/*
69 * Add a locked inode to the transaction. 47 * Add a locked inode to the transaction.
70 * 48 *
71 * The inode must be locked, and it cannot be associated with any transaction. 49 * The inode must be locked, and it cannot be associated with any transaction.
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index d8e6f8cd6f0..258d4f98eb9 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1310,7 +1310,7 @@ xfs_create(
1310 error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, 1310 error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
1311 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp); 1311 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
1312 if (error) 1312 if (error)
1313 goto std_return; 1313 return error;
1314 1314
1315 if (is_dir) { 1315 if (is_dir) {
1316 rdev = 0; 1316 rdev = 0;
@@ -1390,12 +1390,6 @@ xfs_create(
1390 } 1390 }
1391 1391
1392 /* 1392 /*
1393 * At this point, we've gotten a newly allocated inode.
1394 * It is locked (and joined to the transaction).
1395 */
1396 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
1397
1398 /*
1399 * Now we join the directory inode to the transaction. We do not do it 1393 * Now we join the directory inode to the transaction. We do not do it
1400 * earlier because xfs_dir_ialloc might commit the previous transaction 1394 * earlier because xfs_dir_ialloc might commit the previous transaction
1401 * (and release all the locks). An error from here on will result in 1395 * (and release all the locks). An error from here on will result in
@@ -1440,22 +1434,13 @@ xfs_create(
1440 */ 1434 */
1441 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp); 1435 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp);
1442 1436
1443 /*
1444 * xfs_trans_commit normally decrements the vnode ref count
1445 * when it unlocks the inode. Since we want to return the
1446 * vnode to the caller, we bump the vnode ref count now.
1447 */
1448 IHOLD(ip);
1449
1450 error = xfs_bmap_finish(&tp, &free_list, &committed); 1437 error = xfs_bmap_finish(&tp, &free_list, &committed);
1451 if (error) 1438 if (error)
1452 goto out_abort_rele; 1439 goto out_bmap_cancel;
1453 1440
1454 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); 1441 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1455 if (error) { 1442 if (error)
1456 IRELE(ip); 1443 goto out_release_inode;
1457 goto out_dqrele;
1458 }
1459 1444
1460 xfs_qm_dqrele(udqp); 1445 xfs_qm_dqrele(udqp);
1461 xfs_qm_dqrele(gdqp); 1446 xfs_qm_dqrele(gdqp);
@@ -1469,27 +1454,21 @@ xfs_create(
1469 cancel_flags |= XFS_TRANS_ABORT; 1454 cancel_flags |= XFS_TRANS_ABORT;
1470 out_trans_cancel: 1455 out_trans_cancel:
1471 xfs_trans_cancel(tp, cancel_flags); 1456 xfs_trans_cancel(tp, cancel_flags);
1472 out_dqrele: 1457 out_release_inode:
1458 /*
1459 * Wait until after the current transaction is aborted to
1460 * release the inode. This prevents recursive transactions
1461 * and deadlocks from xfs_inactive.
1462 */
1463 if (ip)
1464 IRELE(ip);
1465
1473 xfs_qm_dqrele(udqp); 1466 xfs_qm_dqrele(udqp);
1474 xfs_qm_dqrele(gdqp); 1467 xfs_qm_dqrele(gdqp);
1475 1468
1476 if (unlock_dp_on_error) 1469 if (unlock_dp_on_error)
1477 xfs_iunlock(dp, XFS_ILOCK_EXCL); 1470 xfs_iunlock(dp, XFS_ILOCK_EXCL);
1478 std_return:
1479 return error; 1471 return error;
1480
1481 out_abort_rele:
1482 /*
1483 * Wait until after the current transaction is aborted to
1484 * release the inode. This prevents recursive transactions
1485 * and deadlocks from xfs_inactive.
1486 */
1487 xfs_bmap_cancel(&free_list);
1488 cancel_flags |= XFS_TRANS_ABORT;
1489 xfs_trans_cancel(tp, cancel_flags);
1490 IRELE(ip);
1491 unlock_dp_on_error = B_FALSE;
1492 goto out_dqrele;
1493} 1472}
1494 1473
1495#ifdef DEBUG 1474#ifdef DEBUG
@@ -2114,9 +2093,8 @@ xfs_symlink(
2114 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, 2093 XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
2115 &first_block, resblks, mval, &nmaps, 2094 &first_block, resblks, mval, &nmaps,
2116 &free_list); 2095 &free_list);
2117 if (error) { 2096 if (error)
2118 goto error1; 2097 goto error2;
2119 }
2120 2098
2121 if (resblks) 2099 if (resblks)
2122 resblks -= fs_blocks; 2100 resblks -= fs_blocks;
@@ -2148,7 +2126,7 @@ xfs_symlink(
2148 error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, 2126 error = xfs_dir_createname(tp, dp, link_name, ip->i_ino,
2149 &first_block, &free_list, resblks); 2127 &first_block, &free_list, resblks);
2150 if (error) 2128 if (error)
2151 goto error1; 2129 goto error2;
2152 xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 2130 xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
2153 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); 2131 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
2154 2132
@@ -2161,13 +2139,6 @@ xfs_symlink(
2161 xfs_trans_set_sync(tp); 2139 xfs_trans_set_sync(tp);
2162 } 2140 }
2163 2141
2164 /*
2165 * xfs_trans_commit normally decrements the vnode ref count
2166 * when it unlocks the inode. Since we want to return the
2167 * vnode to the caller, we bump the vnode ref count now.
2168 */
2169 IHOLD(ip);
2170
2171 error = xfs_bmap_finish(&tp, &free_list, &committed); 2142 error = xfs_bmap_finish(&tp, &free_list, &committed);
2172 if (error) { 2143 if (error) {
2173 goto error2; 2144 goto error2;