mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
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 <behlendorf1@llnl.gov> Signed-off-by: Chunwei Chen <david.chen@osnexus.com> Closes #4866 Closes #5609
This commit is contained in:
committed by
Brian Behlendorf
parent
76fe529b39
commit
040dab9939
+5
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user