]> git.proxmox.com Git - mirror_zfs-debian.git/commitdiff
Add zio_ddt_free()+ddt_phys_decref() error handling
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 19 Mar 2013 19:05:08 +0000 (12:05 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 19 Mar 2013 20:01:01 +0000 (13:01 -0700)
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 <behlendorf1@llnl.gov>
Closes #1308

module/zfs/ddt.c
module/zfs/zio.c

index ef868619ab6310d1d97c1196a82daaa95d75dbd9..2d8763a54954f9d96f27cacb9a63b7a919945d3b 100644 (file)
@@ -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
index 77b1764d7403f26638ff825652f31fcb715aaf20..0622553f5f23a32ba069420508755d66094274ec 100644 (file)
@@ -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);