diff options
author | George Melikov <[email protected]> | 2017-01-27 01:43:28 +0300 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-01-26 14:43:28 -0800 |
commit | 39efbde7c551ae0edcd57db3aab28fd7f2d29d18 (patch) | |
tree | 037a7a6404e3c86e6a24878f9b6e21e09ce09bf3 /include/sys/dmu.h | |
parent | aeacdefedc31b498cfccc0026b83be0bab197a3b (diff) |
OpenZFS 6676 - Race between unique_insert() and unique_remove() causes ZFS fsid change
Authored by: Josef 'Jeff' Sipek <[email protected]>
Reviewed by: Saso Kiselkov <[email protected]>
Reviewed by: Sanjay Nadkarni <[email protected]>
Reviewed by: Dan Vatca <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: George Wilson <[email protected]>
Reviewed by: Sebastien Roy <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Ported-by: George Melikov <[email protected]>
OpenZFS-issue: https://www.illumos.org/issues/6676
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/40510e8
Closes #5667
Diffstat (limited to 'include/sys/dmu.h')
-rw-r--r-- | include/sys/dmu.h | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/include/sys/dmu.h b/include/sys/dmu.h index 3c57de32e..9c8ca7c36 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -549,8 +549,14 @@ typedef struct dmu_buf_user { */ taskq_ent_t dbu_tqent; - /* This instance's eviction function pointer. */ - dmu_buf_evict_func_t *dbu_evict_func; + /* + * This instance's eviction function pointers. + * + * dbu_evict_func_sync is called synchronously and then + * dbu_evict_func_async is executed asynchronously on a taskq. + */ + dmu_buf_evict_func_t *dbu_evict_func_sync; + dmu_buf_evict_func_t *dbu_evict_func_async; #ifdef ZFS_DEBUG /* * Pointer to user's dbuf pointer. NULL for clients that do @@ -572,12 +578,16 @@ typedef struct dmu_buf_user { */ /*ARGSUSED*/ static inline void -dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func, - dmu_buf_t **clear_on_evict_dbufp) +dmu_buf_init_user(dmu_buf_user_t *dbu, dmu_buf_evict_func_t *evict_func_sync, + dmu_buf_evict_func_t *evict_func_async, dmu_buf_t **clear_on_evict_dbufp) { - ASSERT(dbu->dbu_evict_func == NULL); - ASSERT(evict_func != NULL); - dbu->dbu_evict_func = evict_func; + ASSERT(dbu->dbu_evict_func_sync == NULL); + ASSERT(dbu->dbu_evict_func_async == NULL); + + /* must have at least one evict func */ + IMPLY(evict_func_sync == NULL, evict_func_async != NULL); + dbu->dbu_evict_func_sync = evict_func_sync; + dbu->dbu_evict_func_async = evict_func_async; taskq_init_ent(&dbu->dbu_tqent); #ifdef ZFS_DEBUG dbu->dbu_clear_on_evict_dbufp = clear_on_evict_dbufp; |