mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-28 02:44:30 +03:00
Illumos #3100: zvol rename fails with EBUSY when dirty.
illumos/illumos-gate@2e2c135528 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
This commit is contained in:
parent
0677cb6f52
commit
04434775b7
@ -161,7 +161,6 @@ timestruc_t dmu_objset_snap_cmtime(objset_t *os);
|
|||||||
/* called from dsl */
|
/* called from dsl */
|
||||||
void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
|
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(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,
|
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);
|
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,
|
int dmu_objset_open_impl(spa_t *spa, struct dsl_dataset *ds, blkptr_t *bp,
|
||||||
|
@ -258,6 +258,7 @@ int dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new,
|
|||||||
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
|
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
|
||||||
int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last,
|
int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last,
|
||||||
uint64_t *usedp, uint64_t *compp, uint64_t *uncompp);
|
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);
|
int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf);
|
||||||
|
|
||||||
|
@ -3700,7 +3700,7 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
|
|||||||
zhp->zfs_type == ZFS_TYPE_VOLUME);
|
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_force = force;
|
||||||
cb.cb_target = snap->zfs_name;
|
cb.cb_target = snap->zfs_name;
|
||||||
|
@ -1182,17 +1182,6 @@ dmu_objset_is_dirty(objset_t *os, uint64_t txg)
|
|||||||
!list_is_empty(&os->os_free_dnodes[txg & TXG_MASK]));
|
!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];
|
static objset_used_cb_t *used_cbs[DMU_OST_NUMTYPES];
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1231,6 +1231,19 @@ dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 unique space in the head dataset can be calculated by subtracting
|
||||||
* the space used in the most recent snapshot, that is still being used
|
* the space used in the most recent snapshot, that is still being used
|
||||||
@ -3402,10 +3415,6 @@ dsl_dataset_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
|||||||
if (ds->ds_quota != effective_value) {
|
if (ds->ds_quota != effective_value) {
|
||||||
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
dmu_buf_will_dirty(ds->ds_dbuf, tx);
|
||||||
ds->ds_quota = effective_value;
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3509,10 +3518,6 @@ dsl_dataset_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
|||||||
|
|
||||||
dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
|
dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx);
|
||||||
mutex_exit(&ds->ds_dir->dd_lock);
|
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
|
int
|
||||||
|
@ -1066,10 +1066,6 @@ dsl_dir_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
|||||||
mutex_enter(&dd->dd_lock);
|
mutex_enter(&dd->dd_lock);
|
||||||
dd->dd_phys->dd_quota = effective_value;
|
dd->dd_phys->dd_quota = effective_value;
|
||||||
mutex_exit(&dd->dd_lock);
|
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
|
int
|
||||||
@ -1182,10 +1178,6 @@ dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
|
|||||||
delta, 0, 0, tx);
|
delta, 0, 0, tx);
|
||||||
}
|
}
|
||||||
mutex_exit(&dd->dd_lock);
|
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
|
int
|
||||||
|
@ -1112,9 +1112,9 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
|
|||||||
/*
|
/*
|
||||||
* Evict cached data
|
* Evict cached data
|
||||||
*/
|
*/
|
||||||
if (dmu_objset_is_dirty_anywhere(zsb->z_os))
|
if (dsl_dataset_is_dirty(dmu_objset_ds(zsb->z_os)) &&
|
||||||
if (!zfs_is_readonly(zsb))
|
!zfs_is_readonly(zsb))
|
||||||
txg_wait_synced(dmu_objset_pool(zsb->z_os), 0);
|
txg_wait_synced(dmu_objset_pool(zsb->z_os), 0);
|
||||||
(void) dmu_objset_evict_dbufs(zsb->z_os);
|
(void) dmu_objset_evict_dbufs(zsb->z_os);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -901,8 +901,18 @@ zvol_last_close(zvol_state_t *zv)
|
|||||||
{
|
{
|
||||||
zil_close(zv->zv_zilog);
|
zil_close(zv->zv_zilog);
|
||||||
zv->zv_zilog = NULL;
|
zv->zv_zilog = NULL;
|
||||||
|
|
||||||
dmu_buf_rele(zv->zv_dbuf, zvol_tag);
|
dmu_buf_rele(zv->zv_dbuf, zvol_tag);
|
||||||
zv->zv_dbuf = NULL;
|
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);
|
dmu_objset_disown(zv->zv_objset, zvol_tag);
|
||||||
zv->zv_objset = NULL;
|
zv->zv_objset = NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user