Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Sep 2017 08:27:21 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r323796 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201709200827.v8K8RLiK032316@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Wed Sep 20 08:27:21 2017
New Revision: 323796
URL: https://svnweb.freebsd.org/changeset/base/323796

Log:
  fix memory leak in g_bio zone introduced in r320452, another ABD fallout
  
  I overlooked the fact that that ZIO_IOCTL_PIPELINE does not include
  ZIO_STAGE_VDEV_IO_DONE stage.  We do allocate a struct bio for an ioctl
  zio (a disk cache flush), but we never freed it.
  
  This change splits bio handling into two groups, one for normal
  read/write i/o that passes data around and, thus, needs the abd data
  tranform; the other group is for "data-less" i/o such as trim and cache
  flush.
  
  PR:		222288
  Reported by:	Dan Nelson <dnelson@allantgroup.com>
  Tested by:	Borja Marcos <borjam@sarenet.es>
  MFC after:	10 days

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Wed Sep 20 07:28:18 2017	(r323795)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Wed Sep 20 08:27:21 2017	(r323796)
@@ -989,6 +989,15 @@ vdev_geom_io_intr(struct bio *bp)
 		break;
 	}
 
+	/*
+	 * We have to split bio freeing into two parts, because the ABD code
+	 * cannot be called in this context and vdev_op_io_done is not called
+	 * for ZIO_TYPE_IOCTL zio-s.
+	 */
+	if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) {
+		g_destroy_bio(bp);
+		zio->io_bio = NULL;
+	}
 	zio_delay_interrupt(zio);
 }
 
@@ -1090,21 +1099,23 @@ vdev_geom_io_done(zio_t *zio)
 {
 	struct bio *bp = zio->io_bio;
 
+	if (zio->io_type != ZIO_TYPE_READ && zio->io_type != ZIO_TYPE_WRITE) {
+		ASSERT(bp == NULL);
+		return;
+	}
+
 	if (bp == NULL) {
-		ASSERT3S(zio->io_error, !=, 0);
-		IMPLY(zio->io_type == ZIO_TYPE_READ ||
-		    zio->io_type == ZIO_TYPE_WRITE,
-		    zio->io_error == ENXIO);
+		ASSERT3S(zio->io_error, ==, ENXIO);
 		return;
 	}
 
-	if (zio->io_type == ZIO_TYPE_READ) {
+	if (zio->io_type == ZIO_TYPE_READ)
 		abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size);
-	} else if (zio->io_type == ZIO_TYPE_WRITE) {
+	else
 		abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size);
-	}
 
 	g_destroy_bio(bp);
+	zio->io_bio = NULL;
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709200827.v8K8RLiK032316>