MFOpenZFS: 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

5dc6af0eec

Reported by:	Pierre Beyssac
Obtained from:	OpenZFS
MFC after:	2 weeks
Sponsored by:	Klara Inc.
This commit is contained in:
Allan Jude 2020-06-22 19:03:02 +00:00
parent 8e47856b2f
commit c5305bb50a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362505
2 changed files with 9 additions and 4 deletions

View File

@ -325,8 +325,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

View File

@ -2937,8 +2937,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);