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