illumos/illumos-gate@
2e2c135528b3edfe9aaf67d1f004dc0202fa1a54
Illumos changeset: 13780:
6da32a929222
3100 zvol rename fails with EBUSY when dirty
Reviewed by: Christopher Siden <chris.siden@delphix.com>
Reviewed by: Adam H. Leventhal <ahl@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Eric Schrock <eric.schrock@delphix.com>
Ported-by: Etienne Dechamps <etienne.dechamps@ovh.net>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #995
/* called from dsl */
void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
boolean_t dmu_objset_is_dirty(objset_t *os, uint64_t txg);
-boolean_t dmu_objset_is_dirty_anywhere(objset_t *os);
objset_t *dmu_objset_create_impl(spa_t *spa, struct dsl_dataset *ds,
blkptr_t *bp, dmu_objset_type_t type, dmu_tx_t *tx);
int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last,
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
+boolean_t dsl_dataset_is_dirty(dsl_dataset_t *ds);
int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf);
zhp->zfs_type == ZFS_TYPE_VOLUME);
/*
- * Destroy all recent snapshots and its dependends.
+ * Destroy all recent snapshots and their dependents.
*/
cb.cb_force = force;
cb.cb_target = snap->zfs_name;
!list_is_empty(&os->os_free_dnodes[txg & TXG_MASK]));
}
-boolean_t
-dmu_objset_is_dirty_anywhere(objset_t *os)
-{
- int t;
-
- for (t = 0; t < TXG_SIZE; t++)
- if (dmu_objset_is_dirty(os, t))
- return (B_TRUE);
- return (B_FALSE);
-}
-
static objset_used_cb_t *used_cbs[DMU_OST_NUMTYPES];
void
}
}
+boolean_t
+dsl_dataset_is_dirty(dsl_dataset_t *ds)
+{
+ int t;
+
+ for (t = 0; t < TXG_SIZE; t++) {
+ if (txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
+ ds, t))
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
/*
* The unique space in the head dataset can be calculated by subtracting
* the space used in the most recent snapshot, that is still being used
if (ds->ds_quota != effective_value) {
dmu_buf_will_dirty(ds->ds_dbuf, tx);
ds->ds_quota = effective_value;
-
- spa_history_log_internal(LOG_DS_REFQUOTA,
- ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu ",
- (longlong_t)ds->ds_quota, ds->ds_object);
}
}
dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
mutex_exit(&ds->ds_dir->dd_lock);
-
- spa_history_log_internal(LOG_DS_REFRESERV,
- ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu",
- (longlong_t)effective_value, ds->ds_object);
}
int
mutex_enter(&dd->dd_lock);
dd->dd_phys->dd_quota = effective_value;
mutex_exit(&dd->dd_lock);
-
- spa_history_log_internal(LOG_DS_QUOTA, dd->dd_pool->dp_spa,
- tx, "%lld dataset = %llu ",
- (longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj);
}
int
delta, 0, 0, tx);
}
mutex_exit(&dd->dd_lock);
-
- spa_history_log_internal(LOG_DS_RESERVATION, dd->dd_pool->dp_spa,
- tx, "%lld dataset = %llu",
- (longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj);
}
int
/*
* Evict cached data
*/
- if (dmu_objset_is_dirty_anywhere(zsb->z_os))
- if (!zfs_is_readonly(zsb))
- txg_wait_synced(dmu_objset_pool(zsb->z_os), 0);
+ if (dsl_dataset_is_dirty(dmu_objset_ds(zsb->z_os)) &&
+ !zfs_is_readonly(zsb))
+ txg_wait_synced(dmu_objset_pool(zsb->z_os), 0);
(void) dmu_objset_evict_dbufs(zsb->z_os);
return (0);
{
zil_close(zv->zv_zilog);
zv->zv_zilog = NULL;
+
dmu_buf_rele(zv->zv_dbuf, zvol_tag);
zv->zv_dbuf = NULL;
+
+ /*
+ * Evict cached data
+ */
+ if (dsl_dataset_is_dirty(dmu_objset_ds(zv->zv_objset)) &&
+ !(zv->zv_flags & ZVOL_RDONLY))
+ txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0);
+ (void) dmu_objset_evict_dbufs(zv->zv_objset);
+
dmu_objset_disown(zv->zv_objset, zvol_tag);
zv->zv_objset = NULL;
}