aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/contrib
diff options
context:
space:
mode:
authorAllan Jude <allanjude@FreeBSD.org>2020-06-22 19:03:02 +0000
committerAllan Jude <allanjude@FreeBSD.org>2020-06-22 19:03:02 +0000
commitc5305bb50a034a7bd12220a4e3fd0187d003e28d (patch)
tree970e7c1a625388de5958e9eba0e37ab93155d2e4 /sys/cddl/contrib
parent8e47856b2fe8f19a101a927f3e9631a414df8e02 (diff)
downloadsrc-c5305bb50a034a7bd12220a4e3fd0187d003e28d.tar.gz
src-c5305bb50a034a7bd12220a4e3fd0187d003e28d.zip
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 https://github.com/openzfs/zfs/commit/5dc6af0eec29b119b731c793037fd77214fc9438 Reported by: Pierre Beyssac Obtained from: OpenZFS MFC after: 2 weeks Sponsored by: Klara Inc.
Notes
Notes: svn path=/head/; revision=362505
Diffstat (limited to 'sys/cddl/contrib')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c7
2 files changed, 9 insertions, 4 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
index 35151165e2b1..964aa6c054f5 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c
@@ -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
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
index 3a58bda1b5f8..a026b3bfe02d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -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);