| 1134 | } |
| 1135 | |
| 1136 | void |
| 1137 | dmu_tx_commit(dmu_tx_t *tx) |
| 1138 | { |
| 1139 | ASSERT(tx->tx_txg != 0); |
| 1140 | |
| 1141 | /* |
| 1142 | * Go through the transaction's hold list and remove holds on |
| 1143 | * associated dnodes, notifying waiters if no holds remain. |
| 1144 | */ |
| 1145 | for (dmu_tx_hold_t *txh = list_head(&tx->tx_holds); txh != NULL; |
| 1146 | txh = list_next(&tx->tx_holds, txh)) { |
| 1147 | dnode_t *dn = txh->txh_dnode; |
| 1148 | |
| 1149 | if (dn == NULL) |
| 1150 | continue; |
| 1151 | |
| 1152 | mutex_enter(&dn->dn_mtx); |
| 1153 | ASSERT3U(dn->dn_assigned_txg, ==, tx->tx_txg); |
| 1154 | |
| 1155 | if (zfs_refcount_remove(&dn->dn_tx_holds, tx) == 0) { |
| 1156 | dn->dn_assigned_txg = 0; |
| 1157 | cv_broadcast(&dn->dn_notxholds); |
| 1158 | } |
| 1159 | mutex_exit(&dn->dn_mtx); |
| 1160 | } |
| 1161 | |
| 1162 | if (tx->tx_tempreserve_cookie) |
| 1163 | dsl_dir_tempreserve_clear(tx->tx_tempreserve_cookie, tx); |
| 1164 | |
| 1165 | if (!list_is_empty(&tx->tx_callbacks)) |
| 1166 | txg_register_callbacks(&tx->tx_txgh, &tx->tx_callbacks); |
| 1167 | |
| 1168 | if (tx->tx_anyobj == FALSE) |
| 1169 | txg_rele_to_sync(&tx->tx_txgh); |
| 1170 | |
| 1171 | dmu_tx_destroy(tx); |
| 1172 | } |
| 1173 | |
| 1174 | void |
| 1175 | dmu_tx_abort(dmu_tx_t *tx) |