]> granicus.if.org Git - zfs/commitdiff
Illumos #3100: zvol rename fails with EBUSY when dirty.
authorMatthew Ahrens <mahrens@delphix.com>
Fri, 24 Aug 2012 14:12:46 +0000 (07:12 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 3 Oct 2012 20:59:02 +0000 (13:59 -0700)
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

include/sys/dmu_objset.h
include/sys/dsl_dataset.h
lib/libzfs/libzfs_dataset.c
module/zfs/dmu_objset.c
module/zfs/dsl_dataset.c
module/zfs/dsl_dir.c
module/zfs/zfs_vfsops.c
module/zfs/zvol.c

index c6d202e2e81a69d46684fe1df4b4d2136e742b5a..013b6ec342f71f7c4744b920dde594f41dfddb0e 100644 (file)
@@ -161,7 +161,6 @@ timestruc_t dmu_objset_snap_cmtime(objset_t *os);
 /* 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,
index 7cff7e3a05caff6c722f44d5639ffb3f585d6bff..38ce3c567586ff768bd3c51b1bf6b381c07c8888 100644 (file)
@@ -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);
 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);
 
index 7ccd941c69202f03963ea5a22911987481a0bea6..7cf78c8f7e762f6745627a9ac822a6320180d444 100644 (file)
@@ -3700,7 +3700,7 @@ zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
            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;
index a34584ebfe7625af46d5fd1ee36051f5ad39fa1a..c1bc1de7be2010d8b8f041dff860ed167da8f935 100644 (file)
@@ -1182,17 +1182,6 @@ dmu_objset_is_dirty(objset_t *os, uint64_t txg)
            !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
index 10e9b19d6e4931c1987fd6a69a955c50cc972a72..21fdd081ced62f9e1c689c249730e7338e9d52c6 100644 (file)
@@ -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 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) {
                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);
        }
 }
 
@@ -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);
        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
index 97b38d209bff315d79c88237f81d913440e5a27b..377df40a8599cbb4c193a6f33a2c90dac5122cc0 100644 (file)
@@ -1066,10 +1066,6 @@ dsl_dir_set_quota_sync(void *arg1, void *arg2, dmu_tx_t *tx)
        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
@@ -1182,10 +1178,6 @@ dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
                    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
index 8fe457e49151c97d6a04b0609a5da8517e25d217..90f9055afdc5021abe93b1d9d587cfc7dce7e837 100644 (file)
@@ -1112,9 +1112,9 @@ zfs_sb_teardown(zfs_sb_t *zsb, boolean_t unmounting)
        /*
         * 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);
index a182f79d3f6f49659011edb13f0175662d9c68ca..5668e1dc0c32c4e1346c54f74fd7de7ff700b928 100644 (file)
@@ -901,8 +901,18 @@ zvol_last_close(zvol_state_t *zv)
 {
        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;
 }