From 7c186d74d982bf42538ced234561d322c2dc697f Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Mon, 24 Oct 2016 20:07:48 +0800 Subject: [PATCH] Stop upgrade thread at the end of 'zfs recv' 'zfs recv' could disown a living objset without calling dmu_objset_disown(). This will cause the problem that the objset would be released while upgrading thread is still running. This patch calls dmu_objset_upgrade_stop() in dmu_recv_end(). ZoL-bug-id: https://github.com/zfsonlinux/zfs/issues/5295 Signed-off-by: Jinshan Xiong --- include/sys/dmu_objset.h | 1 + module/zfs/dmu_objset.c | 3 +-- module/zfs/dmu_send.c | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index 68fb5cffb932..c9265f2ca06f 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -181,6 +181,7 @@ void dmu_objset_evict(objset_t *os); void dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx); void dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx); boolean_t dmu_objset_userused_enabled(objset_t *os); +void dmu_objset_upgrade_stop(objset_t *os); int dmu_objset_userspace_upgrade(objset_t *os); boolean_t dmu_objset_userspace_present(objset_t *os); boolean_t dmu_objset_userobjused_enabled(objset_t *os); diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index ac60008a3a80..52a4c3f6897e 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -80,7 +80,6 @@ int dmu_rescan_dnode_threshold = 1 << DN_MAX_INDBLKSHIFT; static void dmu_objset_find_dp_cb(void *arg); static void dmu_objset_upgrade(objset_t *os, dmu_objset_upgrade_cb_t cb); -static void dmu_objset_upgrade_stop(objset_t *os); void dmu_objset_init(void) @@ -1124,7 +1123,7 @@ dmu_objset_upgrade(objset_t *os, dmu_objset_upgrade_cb_t cb) mutex_exit(&os->os_upgrade_lock); } -static void +void dmu_objset_upgrade_stop(objset_t *os) { mutex_enter(&os->os_upgrade_lock); diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c index f9414ea3ab28..b0afecbaf151 100644 --- a/module/zfs/dmu_send.c +++ b/module/zfs/dmu_send.c @@ -3347,6 +3347,11 @@ dmu_recv_new_end(dmu_recv_cookie_t *drc) int dmu_recv_end(dmu_recv_cookie_t *drc, void *owner) { + objset_t *os; + + VERIFY0(dmu_objset_from_ds(drc->drc_ds, &os)); + dmu_objset_upgrade_stop(os); + drc->drc_owner = owner; if (drc->drc_newfs)