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 <dnel...@allantgroup.com>
  Tested by:    Borja Marcos <bor...@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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to