From 57815f6b95a743697e148327725b7f568e75e6ea Mon Sep 17 00:00:00 2001 From: Boris Protopopov Date: Tue, 3 Sep 2013 11:30:56 -0700 Subject: [PATCH] 4089 NULL pointer dereference in arc_read() Reviewed by: Matthew Ahrens Reviewed by: Saso Kiselkov Reviewed by: Garrett D'Amore Approved by: Dan McDonald --- usr/src/uts/common/fs/zfs/arc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c index 121ae751cd96..c5fe8f934f1b 100644 --- a/usr/src/uts/common/fs/zfs/arc.c +++ b/usr/src/uts/common/fs/zfs/arc.c @@ -20,10 +20,10 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ /* @@ -2972,6 +2972,8 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, vdev_t *vd = NULL; uint64_t addr = 0; boolean_t devw = B_FALSE; + enum zio_compress b_compress = ZIO_COMPRESS_OFF; + uint64_t b_asize = 0; if (hdr == NULL) { /* this block is not in the cache */ @@ -3041,10 +3043,12 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, hdr->b_acb = acb; hdr->b_flags |= ARC_IO_IN_PROGRESS; - if (HDR_L2CACHE(hdr) && hdr->b_l2hdr != NULL && + if (hdr->b_l2hdr != NULL && (vd = hdr->b_l2hdr->b_dev->l2ad_vdev) != NULL) { devw = hdr->b_l2hdr->b_dev->l2ad_writing; addr = hdr->b_l2hdr->b_daddr; + b_compress = hdr->b_l2hdr->b_compress; + b_asize = hdr->b_l2hdr->b_asize; /* * Lock out device removal. */ @@ -3092,7 +3096,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, cb->l2rcb_bp = *bp; cb->l2rcb_zb = *zb; cb->l2rcb_flags = zio_flags; - cb->l2rcb_compress = hdr->b_l2hdr->b_compress; + cb->l2rcb_compress = b_compress; ASSERT(addr >= VDEV_LABEL_START_SIZE && addr + size < vd->vdev_psize - @@ -3104,8 +3108,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, * Issue a null zio if the underlying buffer * was squashed to zero size by compression. */ - if (hdr->b_l2hdr->b_compress == - ZIO_COMPRESS_EMPTY) { + if (b_compress == ZIO_COMPRESS_EMPTY) { rzio = zio_null(pio, spa, vd, l2arc_read_done, cb, zio_flags | ZIO_FLAG_DONT_CACHE | @@ -3114,8 +3117,8 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, ZIO_FLAG_DONT_RETRY); } else { rzio = zio_read_phys(pio, vd, addr, - hdr->b_l2hdr->b_asize, - buf->b_data, ZIO_CHECKSUM_OFF, + b_asize, buf->b_data, + ZIO_CHECKSUM_OFF, l2arc_read_done, cb, priority, zio_flags | ZIO_FLAG_DONT_CACHE | ZIO_FLAG_CANFAIL | @@ -3124,8 +3127,7 @@ arc_read(zio_t *pio, spa_t *spa, const blkptr_t *bp, arc_done_func_t *done, } DTRACE_PROBE2(l2arc__read, vdev_t *, vd, zio_t *, rzio); - ARCSTAT_INCR(arcstat_l2_read_bytes, - hdr->b_l2hdr->b_asize); + ARCSTAT_INCR(arcstat_l2_read_bytes, b_asize); if (*arc_flags & ARC_NOWAIT) { zio_nowait(rzio);