diff options
author | Matthew Ahrens <[email protected]> | 2014-09-12 05:45:50 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2014-10-21 15:26:58 -0700 |
commit | 4b20a6f50999366b9ea17180838235c7733e5a53 (patch) | |
tree | eb371d103ce8a034a2624a50e3a9af66986c5e3c /module/zfs/dsl_dataset.c | |
parent | 6c59307a3c52535513e1ea3b612dac5a594c5b5d (diff) |
Illumos 5150 - zfs clone of a defer_destroy snapshot causes strangeness
When a clone is created of a snapshot that has been marked for
deferred destroy (with "zfs destroy -d"), the clone "inherits" the
defer_destroy flag from the origin, and any snapshots of the clone
"inherit" the defer_destroy flag from the clone. This causes a strange
situation where the clone's snapshots are marked for defer_destroy but
they have no holds or clones. If the clone's snapshot gets a hold or
clone, which is then deleted, we will honor the incorrectly-set
defer_destroy flag and delete the snapshot!
Steps to reproduce:
* zpool create test c1t1d0
* zfs create test/fs
* zfs snapshot test/fs@a
* zfs clone test/fs@a test/clone
* zfs destroy -d test/fs@a
* zfs clone test/fs@a test/clone2
* zfs snapshot test/clone2@a
* zfs hold hld test/clone2@a
* zfs release hld test/clone2@a
* zfs list -r -t all test
<test/clone2@a has been destroyed>
We noticed that this causes dcenter to get very confused, because it
treats snapshots that are marked defer_destroy as not existing. So it
won't see any snapshots of the clone that's marked defer_destroy.
5150 - zfs clone of a defer_destroy snapshot causes strangeness
Reviewed by: Christopher Siden <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Max Grossman <[email protected]>
Reviewed by: Saso Kiselkov <[email protected]>
Reviewed by: Richard Elling <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
References:
https://www.illumos.org/projects/illumos-gate//issues/5150
https://github.com/illumos/illumos-gate/commit/42fcb65
Ported by: Turbo Fredriksson <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #2690
Diffstat (limited to 'module/zfs/dsl_dataset.c')
-rw-r--r-- | module/zfs/dsl_dataset.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 91d9120a5..3d5551cc4 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -686,7 +686,13 @@ dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, dsphys->ds_uncompressed_bytes = origin->ds_phys->ds_uncompressed_bytes; dsphys->ds_bp = origin->ds_phys->ds_bp; - dsphys->ds_flags |= origin->ds_phys->ds_flags; + + /* + * Inherit flags that describe the dataset's contents + * (INCONSISTENT) or properties (Case Insensitive). + */ + dsphys->ds_flags |= origin->ds_phys->ds_flags & + (DS_FLAG_INCONSISTENT | DS_FLAG_CI_DATASET); dmu_buf_will_dirty(origin->ds_dbuf, tx); origin->ds_phys->ds_num_children++; |