diff options
author | Chunwei Chen <[email protected]> | 2017-01-19 13:56:36 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-01-19 13:56:36 -0800 |
commit | 040dab993936d832df4c7624bbcdb71c3fb9b34b (patch) | |
tree | 0261aedba3c5e6fdda94a0a10388d065f0802924 /include/sys | |
parent | 76fe529b392068dfb7575739542cd4f69d2d4343 (diff) |
Suspend/resume zvol for recv and rollback
When doing recv and rollback, dsl_dataset_clone_swap_sync_impl will be
called to swap out the ds_objset and do dmu_objset_evict on the old one.
However, currently zv->zv_objset will not be swapped out accordingly, so
if anyone currently holds a fd on the zvol, we risk hitting a use-after-free.
We fix this by introducing the suspend and resume mechanism of zsb to
zv. Before recv or rollback, we use zvol_suspend to block all access to
zv_objset and shut it down. After the recv or rollback, we use zvol_resume
to swap in zv_objset with the new ds_objset and unblock the access.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Closes #4866
Closes #5609
Diffstat (limited to 'include/sys')
-rw-r--r-- | include/sys/zvol.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/include/sys/zvol.h b/include/sys/zvol.h index 2fb20fbf9..f149da977 100644 --- a/include/sys/zvol.h +++ b/include/sys/zvol.h @@ -35,14 +35,14 @@ #define SPEC_MAXOFFSET_T ((1LL << ((NBBY * sizeof (daddr32_t)) + \ DEV_BSHIFT - 1)) - 1) -extern void *zvol_tag; - extern void zvol_create_minors(spa_t *spa, const char *name, boolean_t async); extern void zvol_remove_minors(spa_t *spa, const char *name, boolean_t async); extern void zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname, boolean_t async); #ifdef _KERNEL +typedef struct zvol_state zvol_state_t; + extern int zvol_check_volsize(uint64_t volsize, uint64_t blocksize); extern int zvol_check_volblocksize(const char *name, uint64_t volblocksize); extern int zvol_get_stats(objset_t *os, nvlist_t *nv); @@ -51,6 +51,9 @@ extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx); extern int zvol_set_volsize(const char *, uint64_t); extern int zvol_set_volblocksize(const char *, uint64_t); extern int zvol_set_snapdev(const char *, zprop_source_t, uint64_t); +extern zvol_state_t *zvol_suspend(const char *); +extern int zvol_resume(zvol_state_t *); +extern void *zvol_tag(zvol_state_t *); extern int zvol_init(void); extern void zvol_fini(void); |