Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ata Add WDF_OPEN flag to really disallow opening of ...



details:   https://anonhg.NetBSD.org/src/rev/cc187ae220d7
branches:  trunk
changeset: 827558:cc187ae220d7
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Fri Nov 03 13:01:26 2017 +0000

description:
Add WDF_OPEN flag to really disallow opening of a disk that has been invalidated.

Restore wdbiorestart function to actually retry the failed I/O request instead
of just restarting the queue.

Fix compilation without ATADEBUG.

diffstat:

 sys/dev/ata/wd.c    |  63 ++++++++++++++++++++++++++++++++++------------------
 sys/dev/ata/wdvar.h |   3 +-
 2 files changed, 43 insertions(+), 23 deletions(-)

diffs (156 lines):

diff -r 71b9f5edf8a8 -r cc187ae220d7 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Fri Nov 03 09:59:07 2017 +0000
+++ b/sys/dev/ata/wd.c  Fri Nov 03 13:01:26 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.434 2017/11/01 19:34:46 mlelstv Exp $ */
+/*     $NetBSD: wd.c,v 1.435 2017/11/03 13:01:26 mlelstv Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.434 2017/11/01 19:34:46 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.435 2017/11/03 13:01:26 mlelstv Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -194,6 +194,7 @@
 static void    wdioctlstrategy(struct buf *);
 
 static void    wdstart(device_t);
+static void    wdstart1(struct wd_softc *, struct buf *, struct ata_xfer *);
 static int     wd_diskstart(device_t, struct buf *);
 static int     wd_dumpblocks(device_t, void *, daddr_t, int);
 static void    wd_iosize(device_t, int *);
@@ -607,23 +608,10 @@
        biodone(bp);
 }
 
-static int
-wd_diskstart(device_t dev, struct buf *bp)
+static void
+wdstart1(struct wd_softc *wd, struct buf *bp, struct ata_xfer *xfer)
 {
-       struct wd_softc *wd = device_private(dev);
        struct dk_softc *dksc = &wd->sc_dksc;
-       struct ata_xfer *xfer;
-
-       mutex_enter(&wd->sc_lock);
-
-       xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
-           WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0);
-       if (xfer == NULL) {
-               ATADEBUG_PRINT(("wdstart %s no xfer\n",
-                   dksc->sc_xname), DEBUG_XFERS);
-               mutex_exit(&wd->sc_lock);
-               return EAGAIN;
-       }
 
        KASSERT(bp == xfer->c_bio.bp || xfer->c_bio.bp == NULL);
        KASSERT((xfer->c_flags & (C_WAITACT|C_FREE)) == 0);
@@ -722,6 +710,29 @@
        default:
                panic("wdstart1: bad return code from ata_bio()");
        }
+}
+
+static int
+wd_diskstart(device_t dev, struct buf *bp)
+{
+       struct wd_softc *wd = device_private(dev);
+#ifdef ATADEBUG
+       struct dk_softc *dksc = &wd->sc_dksc;
+#endif
+       struct ata_xfer *xfer;
+
+       mutex_enter(&wd->sc_lock);
+
+       xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
+           WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0);
+       if (xfer == NULL) {
+               ATADEBUG_PRINT(("wd_diskstart %s no xfer\n",
+                   dksc->sc_xname), DEBUG_XFERS);
+               mutex_exit(&wd->sc_lock);
+               return EAGAIN;
+       }
+
+       wdstart1(wd, bp, xfer);
 
        mutex_exit(&wd->sc_lock);
 
@@ -825,7 +836,7 @@
                        /* Rerun ASAP if just requeued */
                        callout_reset(&xfer->c_retry_callout,
                            (xfer->c_bio.error == REQUEUE) ? 1 : RECOVERYTIME,
-                           wdbiorestart, wd);
+                           wdbiorestart, xfer);
 
                        mutex_exit(&wd->sc_lock);
                        return;
@@ -896,13 +907,19 @@
 static void
 wdbiorestart(void *v)
 {
-       struct wd_softc *wd = v;
+       struct ata_xfer *xfer = v;
+       struct buf *bp = xfer->c_bio.bp;
+       struct wd_softc *wd = device_lookup_private(&wd_cd, WDUNIT(bp->b_dev));
+#ifdef ATADEBUG
        struct dk_softc *dksc = &wd->sc_dksc;
+#endif
 
-       ATADEBUG_PRINT(("wdrestart %s\n", dksc->sc_xname),
+       ATADEBUG_PRINT(("wdbiorestart %s\n", dksc->sc_xname),
            DEBUG_XFERS);
 
-       dk_start(dksc, NULL);
+       mutex_enter(&wd->sc_lock);
+       wdstart1(wd, bp, xfer);
+       mutex_exit(&wd->sc_lock);
 }
 
 static void
@@ -985,7 +1002,7 @@
         * If any partition is open, but the disk has been invalidated,
         * disallow further opens.
         */
-       if ((wd->sc_flags & WDF_LOADED) == 0) {
+       if ((wd->sc_flags & (WDF_OPEN | WDF_LOADED)) == WDF_OPEN) {
                if (part != RAW_PART || fmt != S_IFCHR)
                        return EIO;
        }
@@ -1023,6 +1040,7 @@
                wd->sc_flags |= WDF_LOADED;
        }
 
+       wd->sc_flags |= WDF_OPEN;
        return 0;
 
 bad:
@@ -1041,6 +1059,7 @@
        wd_flushcache(wd, AT_WAIT, false);
 
        wd->atabus->ata_delref(wd->drvp);
+       wd->sc_flags &= ~WDF_OPEN;
 
        return 0;
 }
diff -r 71b9f5edf8a8 -r cc187ae220d7 sys/dev/ata/wdvar.h
--- a/sys/dev/ata/wdvar.h       Fri Nov 03 09:59:07 2017 +0000
+++ b/sys/dev/ata/wdvar.h       Fri Nov 03 13:01:26 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdvar.h,v 1.45 2017/11/01 19:34:46 mlelstv Exp $       */
+/*     $NetBSD: wdvar.h,v 1.46 2017/11/03 13:01:26 mlelstv Exp $       */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -54,6 +54,7 @@
 #define WDF_LBA                0x040 /* using LBA mode */
 #define WDF_LBA48      0x100 /* using 48-bit LBA mode */
 #define WDF_FLUSH_PEND 0x200 /* cache flush waits for free xfer */
+#define WDF_OPEN       0x400 /* device is open */
        uint64_t sc_capacity; /* full capacity of the device */
        uint64_t sc_capacity512; /* ... in DEV_BSIZE blocks */
        uint32_t sc_capacity28; /* capacity accessible with LBA28 commands */



Home | Main Index | Thread Index | Old Index