From: Brian Behlendorf Date: Tue, 19 Mar 2013 19:05:08 +0000 (-0700) Subject: Add zio_ddt_free()+ddt_phys_decref() error handling X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=commitdiff_plain;h=5dc6af0eec29b119b731c793037fd77214fc9438;p=zfs.git Add zio_ddt_free()+ddt_phys_decref() error handling The assumption in zio_ddt_free() is that ddt_phys_select() must always find a match. However, if that fails due to a damaged DDT or some other reason the code will NULL dereference in ddt_phys_decref(). While this should never happen it has been observed on various platforms. The result is that unless your willing to patch the ZFS code the pool is inaccessible. Therefore, we're choosing to more gracefully handle this case rather than leave it fatal. http://mail.opensolaris.org/pipermail/zfs-discuss/2012-February/050972.html Signed-off-by: Brian Behlendorf Closes #1308 --- diff --git a/module/zfs/ddt.c b/module/zfs/ddt.c index ef86861..2d8763a 100644 --- a/module/zfs/ddt.c +++ b/module/zfs/ddt.c @@ -323,8 +323,10 @@ ddt_phys_addref(ddt_phys_t *ddp) void ddt_phys_decref(ddt_phys_t *ddp) { - ASSERT((int64_t)ddp->ddp_refcnt > 0); - ddp->ddp_refcnt--; + if (ddp) { + ASSERT((int64_t)ddp->ddp_refcnt > 0); + ddp->ddp_refcnt--; + } } void diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 77b1764..0622553 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -2249,8 +2249,11 @@ zio_ddt_free(zio_t *zio) ddt_enter(ddt); freedde = dde = ddt_lookup(ddt, bp, B_TRUE); - ddp = ddt_phys_select(dde, bp); - ddt_phys_decref(ddp); + if (dde) { + ddp = ddt_phys_select(dde, bp); + if (ddp) + ddt_phys_decref(ddp); + } ddt_exit(ddt); return (ZIO_PIPELINE_CONTINUE);