Mercurial > illumos > illumos-gate
diff usr/src/uts/common/fs/zfs/dsl_dataset.c @ 7595:2ff5700c7efc
6747355 finish closing race condition when setting refreservation
6745276 Replication: appliance panic in dsl_dir_transfer_space+0xf6
author | Matthew Ahrens <Matthew.Ahrens@Sun.COM> |
---|---|
date | Mon, 15 Sep 2008 10:26:45 -0700 |
parents | d29843e8f8a1 |
children | b80e4842ad54 |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Mon Sep 15 08:52:21 2008 -0700 +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Mon Sep 15 10:26:45 2008 -0700 @@ -103,6 +103,7 @@ return; } dmu_buf_will_dirty(ds->ds_dbuf, tx); + mutex_enter(&ds->ds_dir->dd_lock); mutex_enter(&ds->ds_lock); delta = parent_delta(ds, used); ds->ds_phys->ds_used_bytes += used; @@ -114,6 +115,7 @@ compressed, uncompressed, tx); dsl_dir_transfer_space(ds->ds_dir, used - delta, DD_USED_REFRSRV, DD_USED_HEAD, tx); + mutex_exit(&ds->ds_dir->dd_lock); } int @@ -159,6 +161,7 @@ tx->tx_txg, bp, NULL, NULL, pio ? ARC_NOWAIT : ARC_WAIT); ASSERT(err == 0); + mutex_enter(&ds->ds_dir->dd_lock); mutex_enter(&ds->ds_lock); ASSERT(ds->ds_phys->ds_unique_bytes >= used || !DS_UNIQUE_IS_ACCURATE(ds)); @@ -169,6 +172,7 @@ delta, -compressed, -uncompressed, tx); dsl_dir_transfer_space(ds->ds_dir, -used - delta, DD_USED_REFRSRV, DD_USED_HEAD, tx); + mutex_exit(&ds->ds_dir->dd_lock); } else { dprintf_bp(bp, "putting on dead list: %s", ""); VERIFY(0 == bplist_enqueue(&ds->ds_deadlist, bp, tx)); @@ -3005,25 +3009,6 @@ return (err); } -int64_t -dsl_dataset_new_refreservation(dsl_dataset_t *ds, uint64_t new_reservation, - dmu_tx_t *tx) -{ - int64_t delta; - uint64_t unique; - - dmu_buf_will_dirty(ds->ds_dbuf, tx); - - mutex_enter(&ds->ds_lock); - unique = dsl_dataset_unique(ds); - delta = MAX(0, (int64_t)(new_reservation - unique)) - - MAX(0, (int64_t)(ds->ds_reserved - unique)); - ds->ds_reserved = new_reservation; - mutex_exit(&ds->ds_lock); - - return (delta); -} - static int dsl_dataset_set_reservation_check(void *arg1, void *arg2, dmu_tx_t *tx) { @@ -3073,8 +3058,27 @@ dsl_dataset_t *ds = arg1; uint64_t *reservationp = arg2; uint64_t new_reservation = *reservationp; - - dsl_dir_new_refreservation(ds->ds_dir, ds, new_reservation, cr, tx); + uint64_t unique; + int64_t delta; + + dmu_buf_will_dirty(ds->ds_dbuf, tx); + + mutex_enter(&ds->ds_dir->dd_lock); + mutex_enter(&ds->ds_lock); + unique = dsl_dataset_unique(ds); + delta = MAX(0, (int64_t)(new_reservation - unique)) - + MAX(0, (int64_t)(ds->ds_reserved - unique)); + ds->ds_reserved = new_reservation; + mutex_exit(&ds->ds_lock); + + dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx); + mutex_exit(&ds->ds_dir->dd_lock); + dsl_prop_set_uint64_sync(ds->ds_dir, "refreservation", + new_reservation, cr, tx); + + spa_history_internal_log(LOG_DS_REFRESERV, + ds->ds_dir->dd_pool->dp_spa, tx, cr, "%lld dataset = %llu", + (longlong_t)new_reservation, ds->ds_object); } int