svn commit: r323612 - head/sys/geom/mirror

Andriy Gapon avg at FreeBSD.org
Fri Sep 15 13:57:10 UTC 2017


Author: avg
Date: Fri Sep 15 13:57:08 2017
New Revision: 323612
URL: https://svnweb.freebsd.org/changeset/base/323612

Log:
  gmirror: treat ENXIO as disk disconnect, not media error
  
  In theory, all data access errors mean that a member is out of sync
  at most.  But they were treated as more serious errors to avoid the
  situation where a flaky disk gets repeatedly disconnected, re-synchronized,
  reconnected and then disconnected again.
  
  ENXIO is a special error that means that the member disk disappeared,
  so it should get the same handling as the GEOM orphaning event.
  There is a better chance that when the disk is reconnected, it will be
  a good member again.
  
  When ENXIO happens on a read we use the exisiting G_MIRROR_BUMP_SYNCID
  mechanism which means that the mirror's syncid is increased as soon
  as there is a write to the mirror.  That's because no data has got out
  of sync yet, but the problematic memeber is disconnected, so the future
  write will make it stale.
  
  When ENXIO happens on a write we use a new G_MIRROR_BUMP_SYNCID_NOW
  mechanism which means that we update the mirror metadata as soon as
  possible because the problematic memeber is already behind.
  
  Reviewed by:	markj, imp
  MFC after:	3 weeks
  Differential Revision: https://reviews.freebsd.org/D9463

Modified:
  head/sys/geom/mirror/g_mirror.c
  head/sys/geom/mirror/g_mirror.h

Modified: head/sys/geom/mirror/g_mirror.c
==============================================================================
--- head/sys/geom/mirror/g_mirror.c	Fri Sep 15 13:34:00 2017	(r323611)
+++ head/sys/geom/mirror/g_mirror.c	Fri Sep 15 13:57:08 2017	(r323612)
@@ -982,7 +982,13 @@ g_mirror_regular_request(struct bio *bp)
 			if (g_mirror_disconnect_on_failure &&
 			    g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE) > 1)
 			{
-				sc->sc_bump_id |= G_MIRROR_BUMP_GENID;
+				if (bp->bio_error == ENXIO &&
+				    bp->bio_cmd == BIO_READ)
+					sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID;
+				else if (bp->bio_error == ENXIO)
+					sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID_NOW;
+				else
+					sc->sc_bump_id |= G_MIRROR_BUMP_GENID;
 				g_mirror_event_send(disk,
 				    G_MIRROR_DISK_STATE_DISCONNECTED,
 				    G_MIRROR_EVENT_DONTWAIT);
@@ -2517,6 +2523,10 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
 		if ((sc->sc_bump_id & G_MIRROR_BUMP_GENID) != 0) {
 			sc->sc_bump_id &= ~G_MIRROR_BUMP_GENID;
 			g_mirror_bump_genid(sc);
+		}
+		if ((sc->sc_bump_id & G_MIRROR_BUMP_SYNCID_NOW) != 0) {
+			sc->sc_bump_id &= ~G_MIRROR_BUMP_SYNCID_NOW;
+			g_mirror_bump_syncid(sc);
 		}
 		break;
 	default:

Modified: head/sys/geom/mirror/g_mirror.h
==============================================================================
--- head/sys/geom/mirror/g_mirror.h	Fri Sep 15 13:34:00 2017	(r323611)
+++ head/sys/geom/mirror/g_mirror.h	Fri Sep 15 13:57:08 2017	(r323612)
@@ -169,9 +169,11 @@ struct g_mirror_event {
 #define	G_MIRROR_TYPE_AUTOMATIC	1
 
 /* Bump syncid on first write. */
-#define	G_MIRROR_BUMP_SYNCID	0x1
+#define	G_MIRROR_BUMP_SYNCID		0x1
 /* Bump genid immediately. */
-#define	G_MIRROR_BUMP_GENID	0x2
+#define	G_MIRROR_BUMP_GENID		0x2
+/* Bump syncid immediately. */
+#define	G_MIRROR_BUMP_SYNCID_NOW	0x4
 struct g_mirror_softc {
 	u_int		sc_type;	/* Device type (manual/automatic). */
 	u_int		sc_state;	/* Device state. */


More information about the svn-src-head mailing list