997 if (tx->tx_dir && asize != 0) {
998 int err = dsl_dir_tempreserve_space(tx->tx_dir, memory,
999 asize, fsize, usize, &tx->tx_tempreserve_cookie, tx);
1000 if (err)
1001 return (err);
1002 }
1003
1004 return (0);
1005 }
1006
1007 static void
1008 dmu_tx_unassign(dmu_tx_t *tx)
1009 {
1010 dmu_tx_hold_t *txh;
1011
1012 if (tx->tx_txg == 0)
1013 return;
1014
1015 txg_rele_to_quiesce(&tx->tx_txgh);
1016
1017 for (txh = list_head(&tx->tx_holds); txh != tx->tx_needassign_txh;
1018 txh = list_next(&tx->tx_holds, txh)) {
1019 dnode_t *dn = txh->txh_dnode;
1020
1021 if (dn == NULL)
1022 continue;
1023 mutex_enter(&dn->dn_mtx);
1024 ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
1025
1026 if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
1027 dn->dn_assigned_txg = 0;
1028 cv_broadcast(&dn->dn_notxholds);
1029 }
1030 mutex_exit(&dn->dn_mtx);
1031 }
1032
1033 txg_rele_to_sync(&tx->tx_txgh);
1034
1035 tx->tx_lasttried_txg = tx->tx_txg;
1036 tx->tx_txg = 0;
1109 if (tx->tx_dir == NULL || delta == 0)
1110 return;
1111
1112 if (delta > 0) {
1113 ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
1114 tx->tx_space_towrite);
1115 (void) refcount_add_many(&tx->tx_space_written, delta, NULL);
1116 } else {
1117 (void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
1118 }
1119 #endif
1120 }
1121
1122 void
1123 dmu_tx_commit(dmu_tx_t *tx)
1124 {
1125 dmu_tx_hold_t *txh;
1126
1127 ASSERT(tx->tx_txg != 0);
1128
1129 while (txh = list_head(&tx->tx_holds)) {
1130 dnode_t *dn = txh->txh_dnode;
1131
1132 list_remove(&tx->tx_holds, txh);
1133 kmem_free(txh, sizeof (dmu_tx_hold_t));
1134 if (dn == NULL)
1135 continue;
1136 mutex_enter(&dn->dn_mtx);
1137 ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
1138
1139 if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
1140 dn->dn_assigned_txg = 0;
1141 cv_broadcast(&dn->dn_notxholds);
1142 }
1143 mutex_exit(&dn->dn_mtx);
1144 dnode_rele(dn, tx);
1145 }
1146
1147 if (tx->tx_tempreserve_cookie)
1148 dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
|
997 if (tx->tx_dir && asize != 0) {
998 int err = dsl_dir_tempreserve_space(tx->tx_dir, memory,
999 asize, fsize, usize, &tx->tx_tempreserve_cookie, tx);
1000 if (err)
1001 return (err);
1002 }
1003
1004 return (0);
1005 }
1006
1007 static void
1008 dmu_tx_unassign(dmu_tx_t *tx)
1009 {
1010 dmu_tx_hold_t *txh;
1011
1012 if (tx->tx_txg == 0)
1013 return;
1014
1015 txg_rele_to_quiesce(&tx->tx_txgh);
1016
1017 /*
1018 * Walk the transaction's hold list, removing the hold on the
1019 * associated dnode, and notifying waiters if the refcount drops to 0.
1020 */
1021 for (txh = list_head(&tx->tx_holds); txh != tx->tx_needassign_txh;
1022 txh = list_next(&tx->tx_holds, txh)) {
1023 dnode_t *dn = txh->txh_dnode;
1024
1025 if (dn == NULL)
1026 continue;
1027 mutex_enter(&dn->dn_mtx);
1028 ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
1029
1030 if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
1031 dn->dn_assigned_txg = 0;
1032 cv_broadcast(&dn->dn_notxholds);
1033 }
1034 mutex_exit(&dn->dn_mtx);
1035 }
1036
1037 txg_rele_to_sync(&tx->tx_txgh);
1038
1039 tx->tx_lasttried_txg = tx->tx_txg;
1040 tx->tx_txg = 0;
1113 if (tx->tx_dir == NULL || delta == 0)
1114 return;
1115
1116 if (delta > 0) {
1117 ASSERT3U(refcount_count(&tx->tx_space_written) + delta, <=,
1118 tx->tx_space_towrite);
1119 (void) refcount_add_many(&tx->tx_space_written, delta, NULL);
1120 } else {
1121 (void) refcount_add_many(&tx->tx_space_freed, -delta, NULL);
1122 }
1123 #endif
1124 }
1125
1126 void
1127 dmu_tx_commit(dmu_tx_t *tx)
1128 {
1129 dmu_tx_hold_t *txh;
1130
1131 ASSERT(tx->tx_txg != 0);
1132
1133 /*
1134 * Go through the transaction's hold list and remove holds on
1135 * associated dnodes, notifying waiters if no holds remain.
1136 */
1137 while (txh = list_head(&tx->tx_holds)) {
1138 dnode_t *dn = txh->txh_dnode;
1139
1140 list_remove(&tx->tx_holds, txh);
1141 kmem_free(txh, sizeof (dmu_tx_hold_t));
1142 if (dn == NULL)
1143 continue;
1144 mutex_enter(&dn->dn_mtx);
1145 ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg);
1146
1147 if (refcount_remove(&dn->dn_tx_holds, tx) == 0) {
1148 dn->dn_assigned_txg = 0;
1149 cv_broadcast(&dn->dn_notxholds);
1150 }
1151 mutex_exit(&dn->dn_mtx);
1152 dnode_rele(dn, tx);
1153 }
1154
1155 if (tx->tx_tempreserve_cookie)
1156 dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx);
|