From 3253b39fa605a828561817a0a35e9dae05966f15 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 3 Aug 2010 15:56:29 -0700 Subject: [PATCH 1/3] Set bpo->bpo_object = 0 on close to allow retry During spa_load the spl->spa_deferred_bpobj maybe be opened and closed multiple times. It's critical that when the object is closed the bpo->bpo_object is set to zero to indicate the object is closed. If it's not during spl_load_retry the spl->spa_deferred_bpobj can be closes twice resulting in a NULL deref. This appears to have been fixed upstream the same way. --- .topdeps | 1 + .topmsg | 10 ++++++++++ module/zfs/bpobj.c | 1 + 3 files changed, 12 insertions(+) create mode 100644 .topdeps create mode 100644 .topmsg diff --git a/.topdeps b/.topdeps new file mode 100644 index 0000000000..1f7391f92b --- /dev/null +++ b/.topdeps @@ -0,0 +1 @@ +master diff --git a/.topmsg b/.topmsg new file mode 100644 index 0000000000..f1958cb115 --- /dev/null +++ b/.topmsg @@ -0,0 +1,10 @@ +From: Brian Behlendorf +Subject: [PATCH] fix bpobj_close + +During spa_load the spl->spa_deferred_bpobj maybe be opened and closed +multiple times. It's critical that when the object is closed the +bpo->bpo_object is set to zero to indicate the object is closed. +If it's not during spl_load_retry the spl->spa_deferred_bpobj can +be closes twice resulting in a NULL deref. + +This appears to have been fixed upstream the same way. diff --git a/module/zfs/bpobj.c b/module/zfs/bpobj.c index f81c48aca6..54babd86f2 100644 --- a/module/zfs/bpobj.c +++ b/module/zfs/bpobj.c @@ -140,6 +140,7 @@ bpobj_close(bpobj_t *bpo) bpo->bpo_dbuf = NULL; bpo->bpo_phys = NULL; bpo->bpo_cached_dbuf = NULL; + bpo->bpo_object = 0; mutex_destroy(&bpo->bpo_lock); } From 84eae057e72e195c60aa2b7bb179365df9ff4350 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 3 Aug 2010 15:56:49 -0700 Subject: [PATCH 2/3] New TopGit dependency: fix-bpobj_close --- .topdeps | 1 + 1 file changed, 1 insertion(+) diff --git a/.topdeps b/.topdeps index 762336325e..26901127fd 100644 --- a/.topdeps +++ b/.topdeps @@ -28,3 +28,4 @@ fix-stack-vdev_cache_read fix-stack-zio_done fix-stack-dsl_scan_visitbp fix-stack-dbuf_hold_impl +fix-bpobj_close From 3eff30685e5d492bf5d101e37c26f9fed9d55003 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 2 Aug 2010 21:41:42 -0700 Subject: [PATCH 3/3] Set zv->zv_objset for zil_replay() case For the case where we have a zil to replay we need to ensure that zv->zv_objset contains the current objset. Since the caller has a hold on the object set it is safe to pass to zil_replay as part of the zv. Call path zvol_create_minor()->zil_replay()-> zil_parse()->zil_replay_log_record()->zvol_replay_write(). --- module/zfs/zvol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index e93d94897e..16c65d348c 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -1118,6 +1118,7 @@ __zvol_create_minor(const char *name) zv->zv_flags |= ZVOL_RDONLY; zv->zv_volblocksize = doi->doi_data_block_size; + zv->zv_objset = os; if (zil_replay_disable) zil_destroy(dmu_objset_zil(os), B_FALSE); @@ -1130,6 +1131,7 @@ __zvol_create_minor(const char *name) out_dmu_objset_disown: dmu_objset_disown(os, zvol_tag); + zv->zv_objset = NULL; out_doi: kmem_free(doi, sizeof(dmu_object_info_t)); out: