Mercurial > illumos > illumos-gate
changeset 12659:bdcaf6c09c92
6957089 race between dedup prefetch and table remove
author | George Wilson <George.Wilson@Sun.COM> |
---|---|
date | Mon, 21 Jun 2010 09:44:26 -0700 |
parents | abe3f7fcaa24 |
children | 32abd267e35d |
files | usr/src/uts/common/fs/zfs/ddt.c |
diffstat | 1 files changed, 11 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/ddt.c Mon Jun 21 17:30:17 2010 +0100 +++ b/usr/src/uts/common/fs/zfs/ddt.c Mon Jun 21 09:44:26 2010 -0700 @@ -739,9 +739,9 @@ return; /* - * We remove the DDT once it's empty and only prefetch dedup blocks - * when there are entries in the DDT. Thus no locking is required - * as the DDT can't disappear on us. + * We only remove the DDT once all tables are empty and only + * prefetch dedup blocks when there are entries in the DDT. + * Thus no locking is required as the DDT can't disappear on us. */ ddt = ddt_select(spa, bp); ddt_key_fill(&dde.dde_key, bp); @@ -1077,11 +1077,15 @@ } for (enum ddt_type type = 0; type < DDT_TYPES; type++) { + uint64_t count = 0; for (enum ddt_class class = 0; class < DDT_CLASSES; class++) { - if (!ddt_object_exists(ddt, type, class)) - continue; - ddt_object_sync(ddt, type, class, tx); - if (ddt_object_count(ddt, type, class) == 0) + if (ddt_object_exists(ddt, type, class)) { + ddt_object_sync(ddt, type, class, tx); + count += ddt_object_count(ddt, type, class); + } + } + for (enum ddt_class class = 0; class < DDT_CLASSES; class++) { + if (count == 0 && ddt_object_exists(ddt, type, class)) ddt_object_destroy(ddt, type, class, tx); } }