Author: avg
Date: Tue Oct 31 10:15:03 2017
New Revision: 325228
URL: https://svnweb.freebsd.org/changeset/base/325228

Log:
  vdev_geom_close: close errored consumer even if vdev_reopening is set
  
  If vdev_geom_close doesn't close the consumer, then the subsequent call
  to vdev_geom_open() would be just a NOP and would always return success.
  Thus, at present vdev_reopen() would always succeed for vdev_geom devices
  even if the underlying provider is in error state.
  The problem was introduced as a result of an optimization in rS308055.
  
  The most significant manifistation of the problem is that
  zio_vdev_io_done() --> vdev_probe() --> SPA_ASYNC_PROBE -->
  spa_async_probe() --> vdev_reopen()
  chain of calls and events becomes a NOP as well.
  This chain is invoked when zio_vdev_io_done() detects an "unexpected"
  error from the lower level I/O.
  Additionally, that call path may race with SPA_ASYNC_REMOVE path because
  of the asynchronous nature of them both.  So, the SPA_ASYNC_PROBE may
  erroneously mark a vdev as being healthy after SPA_ASYNC_REMOVE marked
  it as removed.
  
  Reviewed by:  asomers, mav
  MFC after:    2 weeks
  Differential Revision: https://reviews.freebsd.org/D12731

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     Tue Oct 
31 10:10:13 2017        (r325227)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c     Tue Oct 
31 10:15:03 2017        (r325228)
@@ -934,13 +934,18 @@ skip_open:
 static void
 vdev_geom_close(vdev_t *vd)
 {
+       struct g_consumer *cp;
 
-       if (vd->vdev_reopening)
-               return;
+       cp = vd->vdev_tsd;
 
        DROP_GIANT();
        g_topology_lock();
-       vdev_geom_close_locked(vd);
+
+       if (!vd->vdev_reopening ||
+           (cp != NULL && ((cp->flags & G_CF_ORPHAN) != 0 ||
+           (cp->provider != NULL && cp->provider->error != 0))))
+               vdev_geom_close_locked(vd);
+
        g_topology_unlock();
        PICKUP_GIANT();
 }
_______________________________________________
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