summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_dev.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-05-09 21:25:28 +0000
committerphk <phk@FreeBSD.org>2003-05-09 21:25:28 +0000
commit8ece7cbc43e424a0a5c4071e251ccb97ccf64188 (patch)
tree736c96da992644bfe28faf2d1a98b0136a07e2d4 /sys/geom/geom_dev.c
parentf31a9f552a0783f3a8fbaf57e00d360dd3a8f5b4 (diff)
downloadFreeBSD-src-8ece7cbc43e424a0a5c4071e251ccb97ccf64188.zip
FreeBSD-src-8ece7cbc43e424a0a5c4071e251ccb97ccf64188.tar.gz
When a GEOM (/dev-)device is closed and we find that I/O requests are
still outstanding, give them a chance to complete. If after 10 seconds we still find outstanding I/O requests, complete the close with a console warning that the system is likely to panic later on. This is a workaround for umount -f not quite doing the right thing. Approved by: re/scottl
Diffstat (limited to 'sys/geom/geom_dev.c')
-rw-r--r--sys/geom/geom_dev.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index b090d75..2c69f88 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -215,7 +215,7 @@ g_dev_close(dev_t dev, int flags, int fmt, struct thread *td)
{
struct g_geom *gp;
struct g_consumer *cp;
- int error, r, w, e;
+ int error, r, w, e, i;
gp = dev->si_drv1;
cp = dev->si_drv2;
@@ -236,8 +236,20 @@ g_dev_close(dev_t dev, int flags, int fmt, struct thread *td)
error = ENXIO; /* We were orphaned */
else
error = g_access_rel(cp, r, w, e);
- KASSERT((cp->acr || cp->acw) || (cp->nstart == cp->nend),
- ("final g_dev_close() with outstanding bios"));
+ for (i = 0; i < 10 * hz;) {
+ if (cp->acr != 0 || cp->acw != 0)
+ break;
+ if (cp->nstart == cp->nend)
+ break;
+ tsleep(&i, PRIBIO, "gdevwclose", hz / 10);
+ i += hz / 10;
+ }
+ if (cp->acr == 0 && cp->acw == 0 && cp->nstart != cp->nend) {
+ printf("WARNING: Final close of geom_dev(%s) %s %s",
+ gp->name,
+ "still has outstanding I/O after 10 seconds.",
+ "Completing close anyway, panic may happen later.");
+ }
g_topology_unlock();
PICKUP_GIANT();
g_waitidle();
OpenPOWER on IntegriCloud